1- use std:: borrow:: Cow ;
2- use std:: io:: Write ;
3- use std:: iter:: once;
4-
5- use crate :: chip:: esp32:: partition_table:: PartitionTable ;
6- use crate :: chip:: { Chip , ChipType , EspCommonHeader , SegmentHeader , SpiRegisters , ESP_MAGIC } ;
7- use crate :: elf:: { update_checksum, CodeSegment , FirmwareImage , RomSegment , ESP_CHECKSUM_MAGIC } ;
8- use crate :: flasher:: FlashSize ;
9- use crate :: Error ;
10- use bytemuck:: { bytes_of, Pod , Zeroable } ;
1+ use bytemuck:: bytes_of;
112use sha2:: { Digest , Sha256 } ;
123
13- mod partition_table;
4+ use crate :: {
5+ chip:: {
6+ encode_flash_size, get_segment_padding, save_flash_segment, save_segment, Chip , ChipType ,
7+ EspCommonHeader , ExtendedHeader , SegmentHeader , SpiRegisters , ESP_MAGIC , SEG_HEADER_LEN ,
8+ WP_PIN_DISABLED ,
9+ } ,
10+ elf:: { FirmwareImage , RomSegment , ESP_CHECKSUM_MAGIC } ,
11+ partition_table:: PartitionTable ,
12+ Error ,
13+ } ;
1414
15- pub struct Esp32 ;
15+ use std :: { borrow :: Cow , io :: Write , iter :: once } ;
1616
17- const WP_PIN_DISABLED : u8 = 0xEE ;
17+ pub struct Esp32 ;
1818
1919const IROM_MAP_START : u32 = 0x400d0000 ;
2020const IROM_MAP_END : u32 = 0x40400000 ;
@@ -26,22 +26,9 @@ const BOOT_ADDR: u32 = 0x1000;
2626const PARTION_ADDR : u32 = 0x8000 ;
2727const APP_ADDR : u32 = 0x10000 ;
2828
29- #[ derive( Copy , Clone , Zeroable , Pod ) ]
30- #[ repr( C ) ]
31- struct ExtendedHeader {
32- wp_pin : u8 ,
33- clk_q_drv : u8 ,
34- d_cs_drv : u8 ,
35- gd_wp_drv : u8 ,
36- chip_id : u16 ,
37- min_rev : u8 ,
38- padding : [ u8 ; 8 ] ,
39- append_digest : u8 ,
40- }
41-
4229impl ChipType for Esp32 {
43- const DATE_REG1_VALUE : u32 = 0x15122500 ;
44- const DATE_REG2_VALUE : u32 = 0 ;
30+ const CHIP_DETECT_MAGIC_VALUE : u32 = 0x00f01d83 ;
31+
4532 const SPI_REGISTERS : SpiRegisters = SpiRegisters {
4633 base : 0x3ff42000 ,
4734 usr_offset : 0x1c ,
@@ -60,7 +47,7 @@ impl ChipType for Esp32 {
6047 fn get_flash_segments < ' a > (
6148 image : & ' a FirmwareImage ,
6249 ) -> Box < dyn Iterator < Item = Result < RomSegment < ' a > , Error > > + ' a > {
63- let bootloader = include_bytes ! ( "../../bootloader/bootloader.bin" ) ;
50+ let bootloader = include_bytes ! ( "../../bootloader/esp32- bootloader.bin" ) ;
6451
6552 let partition_table = PartitionTable :: basic ( 0x10000 , 0x3f0000 ) . to_bytes ( ) ;
6653
@@ -167,74 +154,6 @@ impl ChipType for Esp32 {
167154 }
168155}
169156
170- fn encode_flash_size ( size : FlashSize ) -> Result < u8 , Error > {
171- match size {
172- FlashSize :: Flash256Kb => Err ( Error :: UnsupportedFlash ( size as u8 ) ) ,
173- FlashSize :: Flash512Kb => Err ( Error :: UnsupportedFlash ( size as u8 ) ) ,
174- FlashSize :: Flash1Mb => Ok ( 0x00 ) ,
175- FlashSize :: Flash2Mb => Ok ( 0x10 ) ,
176- FlashSize :: Flash4Mb => Ok ( 0x20 ) ,
177- FlashSize :: Flash8Mb => Ok ( 0x30 ) ,
178- FlashSize :: Flash16Mb => Ok ( 0x40 ) ,
179- FlashSize :: FlashRetry => Err ( Error :: UnsupportedFlash ( size as u8 ) ) ,
180- }
181- }
182-
183- const IROM_ALIGN : u32 = 65536 ;
184- const SEG_HEADER_LEN : u32 = 8 ;
185-
186- /// Actual alignment (in data bytes) required for a segment header: positioned
187- /// so that after we write the next 8 byte header, file_offs % IROM_ALIGN ==
188- /// segment.addr % IROM_ALIGN
189- ///
190- /// (this is because the segment's vaddr may not be IROM_ALIGNed, more likely is
191- /// aligned IROM_ALIGN+0x18 to account for the binary file header
192- fn get_segment_padding ( offset : usize , segment : & CodeSegment ) -> u32 {
193- let align_past = ( segment. addr % IROM_ALIGN ) - SEG_HEADER_LEN ;
194- let pad_len = ( IROM_ALIGN - ( ( offset as u32 ) % IROM_ALIGN ) ) + align_past;
195- if pad_len == 0 || pad_len == IROM_ALIGN {
196- 0
197- } else if pad_len > SEG_HEADER_LEN {
198- pad_len - SEG_HEADER_LEN
199- } else {
200- pad_len + IROM_ALIGN - SEG_HEADER_LEN
201- }
202- }
203-
204- fn save_flash_segment (
205- data : & mut Vec < u8 > ,
206- segment : & CodeSegment ,
207- checksum : u8 ,
208- ) -> Result < u8 , Error > {
209- let end_pos = ( data. len ( ) + segment. data . len ( ) ) as u32 + SEG_HEADER_LEN ;
210- let segment_reminder = end_pos % IROM_ALIGN ;
211-
212- let checksum = save_segment ( data, segment, checksum) ?;
213-
214- if segment_reminder < 0x24 {
215- // Work around a bug in ESP-IDF 2nd stage bootloader, that it didn't map the
216- // last MMU page, if an IROM/DROM segment was < 0x24 bytes over the page
217- // boundary.
218- data. write_all ( & [ 0u8 ; 0x24 ] [ 0 ..( 0x24 - segment_reminder as usize ) ] ) ?;
219- }
220- Ok ( checksum)
221- }
222-
223- fn save_segment ( data : & mut Vec < u8 > , segment : & CodeSegment , checksum : u8 ) -> Result < u8 , Error > {
224- let padding = ( 4 - segment. data . len ( ) % 4 ) % 4 ;
225-
226- let header = SegmentHeader {
227- addr : segment. addr ,
228- length : ( segment. data . len ( ) + padding) as u32 ,
229- } ;
230- data. write_all ( bytes_of ( & header) ) ?;
231- data. write_all ( segment. data ) ?;
232- let padding = & [ 0u8 ; 4 ] [ 0 ..padding] ;
233- data. write_all ( padding) ?;
234-
235- Ok ( update_checksum ( segment. data , checksum) )
236- }
237-
238157#[ test]
239158fn test_esp32_rom ( ) {
240159 use std:: fs:: read;
0 commit comments