1- use bytemuck:: bytes_of;
2- use sha2:: { Digest , Sha256 } ;
3-
1+ use crate :: elf:: merge_segments;
42use crate :: {
53 chip:: {
64 encode_flash_size, get_segment_padding, save_flash_segment, save_segment, Chip , ChipType ,
@@ -10,7 +8,8 @@ use crate::{
108 elf:: { FirmwareImage , RomSegment , ESP_CHECKSUM_MAGIC } ,
119 Error , PartitionTable ,
1210} ;
13-
11+ use bytemuck:: bytes_of;
12+ use sha2:: { Digest , Sha256 } ;
1413use std:: { borrow:: Cow , io:: Write , iter:: once} ;
1514
1615pub struct Esp32 ;
@@ -75,95 +74,6 @@ impl ChipType for Esp32 {
7574 } ;
7675 let partition_table = partition_table. to_bytes ( ) ;
7776
78- fn get_data < ' a > ( image : & ' a FirmwareImage ) -> Result < RomSegment < ' a > , Error > {
79- let mut data = Vec :: new ( ) ;
80-
81- let header = EspCommonHeader {
82- magic : ESP_MAGIC ,
83- segment_count : 0 ,
84- flash_mode : image. flash_mode as u8 ,
85- flash_config : encode_flash_size ( image. flash_size ) ? + image. flash_frequency as u8 ,
86- entry : image. entry ,
87- } ;
88- data. write_all ( bytes_of ( & header) ) ?;
89-
90- let extended_header = ExtendedHeader {
91- wp_pin : WP_PIN_DISABLED ,
92- clk_q_drv : 0 ,
93- d_cs_drv : 0 ,
94- gd_wp_drv : 0 ,
95- chip_id : 0 ,
96- min_rev : 0 ,
97- padding : [ 0 ; 8 ] ,
98- append_digest : 1 ,
99- } ;
100- data. write_all ( bytes_of ( & extended_header) ) ?;
101-
102- let mut checksum = ESP_CHECKSUM_MAGIC ;
103-
104- let _ = image. segments ( ) . collect :: < Vec < _ > > ( ) ;
105-
106- let mut flash_segments: Vec < _ > = image. rom_segments ( Chip :: Esp32 ) . collect ( ) ;
107- flash_segments. sort ( ) ;
108- let mut ram_segments: Vec < _ > = image. ram_segments ( Chip :: Esp32 ) . collect ( ) ;
109- ram_segments. sort ( ) ;
110- let mut ram_segments = ram_segments. into_iter ( ) ;
111-
112- let mut segment_count = 0 ;
113-
114- for segment in flash_segments {
115- loop {
116- let pad_len = get_segment_padding ( data. len ( ) , & segment) ;
117- if pad_len > 0 {
118- if pad_len > SEG_HEADER_LEN {
119- if let Some ( ram_segment) = ram_segments. next ( ) {
120- checksum = save_segment ( & mut data, & ram_segment, checksum) ?;
121- segment_count += 1 ;
122- continue ;
123- }
124- }
125- let pad_header = SegmentHeader {
126- addr : 0 ,
127- length : pad_len as u32 ,
128- } ;
129- data. write_all ( bytes_of ( & pad_header) ) ?;
130- for _ in 0 ..pad_len {
131- data. write_all ( & [ 0 ] ) ?;
132- }
133- segment_count += 1 ;
134- } else {
135- break ;
136- }
137- }
138- checksum = save_flash_segment ( & mut data, & segment, checksum) ?;
139- segment_count += 1 ;
140- }
141-
142- for segment in ram_segments {
143- checksum = save_segment ( & mut data, & segment, checksum) ?;
144- segment_count += 1 ;
145- }
146-
147- let padding = 15 - ( data. len ( ) % 16 ) ;
148- let padding = & [ 0u8 ; 16 ] [ 0 ..padding as usize ] ;
149- data. write_all ( padding) ?;
150-
151- data. write_all ( & [ checksum] ) ?;
152-
153- // since we added some dummy segments, we need to patch the segment count
154- data[ 1 ] = segment_count as u8 ;
155-
156- let mut hasher = Sha256 :: new ( ) ;
157- hasher. update ( & data) ;
158- let hash = hasher. finalize ( ) ;
159- data. write_all ( & hash) ?;
160-
161- Ok ( RomSegment {
162- addr : APP_ADDR ,
163- data : Cow :: Owned ( data) ,
164- } )
165- }
166-
16777 Box :: new (
16878 once ( Ok ( RomSegment {
16979 addr : BOOT_ADDR ,
@@ -173,7 +83,7 @@ impl ChipType for Esp32 {
17383 addr : PARTION_ADDR ,
17484 data : Cow :: Owned ( partition_table) ,
17585 } ) ) )
176- . chain ( once ( get_data ( image) ) ) ,
86+ . chain ( once ( get_data ( image, 0 ) ) ) ,
17787 )
17888 }
17989}
@@ -196,3 +106,98 @@ fn test_esp32_rom() {
196106 assert_eq ! ( expected_bin. len( ) , buff. len( ) ) ;
197107 assert_eq ! ( & expected_bin. as_slice( ) , & buff) ;
198108}
109+
110+ // shared between all esp32 family chips
111+ pub ( crate ) fn get_data < ' a > (
112+ image : & ' a FirmwareImage ,
113+ chip_id : u16 ,
114+ ) -> Result < RomSegment < ' a > , Error > {
115+ let mut data = Vec :: new ( ) ;
116+
117+ let header = EspCommonHeader {
118+ magic : ESP_MAGIC ,
119+ segment_count : 0 ,
120+ flash_mode : image. flash_mode as u8 ,
121+ flash_config : encode_flash_size ( image. flash_size ) ? + image. flash_frequency as u8 ,
122+ entry : image. entry ,
123+ } ;
124+ data. write_all ( bytes_of ( & header) ) ?;
125+
126+ let extended_header = ExtendedHeader {
127+ wp_pin : WP_PIN_DISABLED ,
128+ clk_q_drv : 0 ,
129+ d_cs_drv : 0 ,
130+ gd_wp_drv : 0 ,
131+ chip_id,
132+ min_rev : 0 ,
133+ padding : [ 0 ; 8 ] ,
134+ append_digest : 1 ,
135+ } ;
136+ data. write_all ( bytes_of ( & extended_header) ) ?;
137+
138+ let mut checksum = ESP_CHECKSUM_MAGIC ;
139+
140+ let _ = image. segments ( ) . collect :: < Vec < _ > > ( ) ;
141+
142+ let flash_segments: Vec < _ > = merge_segments ( image. rom_segments ( Chip :: Esp32s2 ) . collect ( ) ) ;
143+ let mut ram_segments: Vec < _ > = merge_segments ( image. ram_segments ( Chip :: Esp32s2 ) . collect ( ) ) ;
144+
145+ let mut segment_count = 0 ;
146+
147+ for segment in flash_segments {
148+ loop {
149+ let pad_len = get_segment_padding ( data. len ( ) , & segment) ;
150+ if pad_len > 0 {
151+ if pad_len > SEG_HEADER_LEN {
152+ if let Some ( ram_segment) = ram_segments. first_mut ( ) {
153+ // save up to `pad_len` from the ram segment, any remaining bits in the ram segments will be saved later
154+ let pad_segment = ram_segment. split_off ( pad_len as usize ) ;
155+ checksum = save_segment ( & mut data, & pad_segment, checksum) ?;
156+ if ram_segment. data ( ) . is_empty ( ) {
157+ ram_segments. remove ( 0 ) ;
158+ }
159+ segment_count += 1 ;
160+ continue ;
161+ }
162+ }
163+ let pad_header = SegmentHeader {
164+ addr : 0 ,
165+ length : pad_len as u32 ,
166+ } ;
167+ data. write_all ( bytes_of ( & pad_header) ) ?;
168+ for _ in 0 ..pad_len {
169+ data. write_all ( & [ 0 ] ) ?;
170+ }
171+ segment_count += 1 ;
172+ } else {
173+ break ;
174+ }
175+ }
176+ checksum = save_flash_segment ( & mut data, & segment, checksum) ?;
177+ segment_count += 1 ;
178+ }
179+
180+ for segment in ram_segments {
181+ checksum = save_segment ( & mut data, & segment, checksum) ?;
182+ segment_count += 1 ;
183+ }
184+
185+ let padding = 15 - ( data. len ( ) % 16 ) ;
186+ let padding = & [ 0u8 ; 16 ] [ 0 ..padding as usize ] ;
187+ data. write_all ( padding) ?;
188+
189+ data. write_all ( & [ checksum] ) ?;
190+
191+ // since we added some dummy segments, we need to patch the segment count
192+ data[ 1 ] = segment_count as u8 ;
193+
194+ let mut hasher = Sha256 :: new ( ) ;
195+ hasher. update ( & data) ;
196+ let hash = hasher. finalize ( ) ;
197+ data. write_all ( & hash) ?;
198+
199+ Ok ( RomSegment {
200+ addr : APP_ADDR ,
201+ data : Cow :: Owned ( data) ,
202+ } )
203+ }
0 commit comments