|
| 1 | +use std::io::{Read, Seek}; |
| 2 | + |
| 3 | +use elf::{ElfStream, abi::PT_LOAD, endian::EndianParse}; |
| 4 | + |
1 | 5 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
2 | 6 | pub enum AddressRangeType { |
3 | 7 | /// May have contents |
@@ -31,85 +35,39 @@ impl Default for AddressRange { |
31 | 35 | } |
32 | 36 | } |
33 | 37 |
|
34 | | -pub const FLASH_SECTOR_ERASE_SIZE: u64 = 4096; |
35 | | -pub const MAIN_RAM_START_RP2040: u64 = 0x20000000; |
36 | | -pub const MAIN_RAM_END_RP2040: u64 = 0x20042000; |
37 | | -pub const MAIN_RAM_START_RP2350: u64 = 0x20000000; |
38 | | -pub const MAIN_RAM_END_RP2350: u64 = 0x20082000; |
39 | | -pub const FLASH_START_RP2040: u64 = 0x10000000; |
40 | | -pub const FLASH_END_RP2040: u64 = 0x15000000; |
41 | | -// From RP2350 datasheet: |
42 | | -// RP2040 required images to be stored at the beginning of flash (0x10000000). RP2350 supports storing executable images |
43 | | -// in a partitions at arbitrary locations, to support more robust upgrade cycles via A/B versions, among other uses. |
44 | | -// Therefore, the values below are possibly incorrect but FLASH_END_RP2040 appears to be incorrect too |
45 | | -pub const FLASH_START_RP2350: u64 = 0x10000000; |
46 | | -pub const FLASH_END_RP2350: u64 = 0x15000000; |
47 | | -pub const XIP_SRAM_START_RP2040: u64 = 0x15000000; |
48 | | -pub const XIP_SRAM_END_RP2040: u64 = 0x15004000; |
49 | | -pub const XIP_SRAM_START_RP2350: u64 = 0x13ffc000; |
50 | | -pub const XIP_SRAM_END_RP2350: u64 = 0x14000000; |
51 | | -pub const MAIN_RAM_BANKED_START_RP2040: u64 = 0x21000000; |
52 | | -pub const MAIN_RAM_BANKED_END_RP2040: u64 = 0x21040000; |
53 | | -pub const ROM_START_RP2040: u64 = 0x00000000; |
54 | | -pub const ROM_END_RP2040: u64 = 0x00004000; |
55 | | -pub const ROM_START_RP2350: u64 = 0x00000000; |
56 | | -pub const ROM_END_RP2350: u64 = 0x00008000; |
| 38 | +pub fn address_ranges_from_elf<E: EndianParse, S: Read + Seek>( |
| 39 | + file: &ElfStream<E, S>, |
| 40 | +) -> Vec<AddressRange> { |
| 41 | + let segments = file.segments(); |
57 | 42 |
|
58 | | -pub const RP2040_ADDRESS_RANGES_FLASH: &[AddressRange] = &[ |
59 | | - AddressRange::new( |
60 | | - FLASH_START_RP2040, |
61 | | - FLASH_END_RP2040, |
62 | | - AddressRangeType::Contents, |
63 | | - ), |
64 | | - AddressRange::new( |
65 | | - MAIN_RAM_START_RP2040, |
66 | | - MAIN_RAM_END_RP2040, |
67 | | - AddressRangeType::NoContents, |
68 | | - ), |
69 | | - AddressRange::new( |
70 | | - MAIN_RAM_BANKED_START_RP2040, |
71 | | - MAIN_RAM_BANKED_END_RP2040, |
72 | | - AddressRangeType::NoContents, |
73 | | - ), |
74 | | -]; |
| 43 | + let mut ranges = Vec::new(); |
75 | 44 |
|
76 | | -pub const RP2040_ADDRESS_RANGES_RAM: &[AddressRange] = &[ |
77 | | - AddressRange::new( |
78 | | - MAIN_RAM_START_RP2040, |
79 | | - MAIN_RAM_END_RP2040, |
80 | | - AddressRangeType::Contents, |
81 | | - ), |
82 | | - AddressRange::new( |
83 | | - XIP_SRAM_START_RP2040, |
84 | | - XIP_SRAM_END_RP2040, |
85 | | - AddressRangeType::Contents, |
86 | | - ), |
87 | | - AddressRange::new(ROM_START_RP2040, ROM_END_RP2040, AddressRangeType::Ignore), // for now we ignore the bootrom if present |
88 | | -]; |
| 45 | + for seg in segments { |
| 46 | + if seg.p_type != PT_LOAD || seg.p_memsz == 0 { |
| 47 | + continue; |
| 48 | + } |
89 | 49 |
|
90 | | -pub const RP2350_ADDRESS_RANGES_FLASH: &[AddressRange] = &[ |
91 | | - AddressRange::new( |
92 | | - FLASH_START_RP2350, |
93 | | - FLASH_END_RP2350, |
94 | | - AddressRangeType::Contents, |
95 | | - ), |
96 | | - AddressRange::new( |
97 | | - MAIN_RAM_START_RP2350, |
98 | | - MAIN_RAM_END_RP2350, |
99 | | - AddressRangeType::NoContents, |
100 | | - ), |
101 | | -]; |
| 50 | + let start = seg.p_paddr; |
| 51 | + let end = start + seg.p_memsz; |
| 52 | + |
| 53 | + if seg.p_filesz > 0 { |
| 54 | + // initialized contents |
| 55 | + ranges.push(AddressRange::new( |
| 56 | + start, |
| 57 | + start + seg.p_filesz, |
| 58 | + AddressRangeType::Contents, |
| 59 | + )); |
| 60 | + } |
102 | 61 |
|
103 | | -pub const RP2350_ADDRESS_RANGES_RAM: &[AddressRange] = &[ |
104 | | - AddressRange::new( |
105 | | - MAIN_RAM_START_RP2350, |
106 | | - MAIN_RAM_END_RP2350, |
107 | | - AddressRangeType::Contents, |
108 | | - ), |
109 | | - AddressRange::new( |
110 | | - XIP_SRAM_START_RP2350, |
111 | | - XIP_SRAM_END_RP2350, |
112 | | - AddressRangeType::Contents, |
113 | | - ), |
114 | | - AddressRange::new(ROM_START_RP2350, ROM_END_RP2350, AddressRangeType::Ignore), // for now we ignore the bootrom if present |
115 | | -]; |
| 62 | + if seg.p_memsz > seg.p_filesz { |
| 63 | + // uninitialized (BSS) |
| 64 | + ranges.push(AddressRange::new( |
| 65 | + start + seg.p_filesz, |
| 66 | + end, |
| 67 | + AddressRangeType::NoContents, |
| 68 | + )); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + ranges |
| 73 | +} |
0 commit comments