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;
11
2
use sha2:: { Digest , Sha256 } ;
12
3
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
+ } ;
14
14
15
- pub struct Esp32 ;
15
+ use std :: { borrow :: Cow , io :: Write , iter :: once } ;
16
16
17
- const WP_PIN_DISABLED : u8 = 0xEE ;
17
+ pub struct Esp32 ;
18
18
19
19
const IROM_MAP_START : u32 = 0x400d0000 ;
20
20
const IROM_MAP_END : u32 = 0x40400000 ;
@@ -26,22 +26,9 @@ const BOOT_ADDR: u32 = 0x1000;
26
26
const PARTION_ADDR : u32 = 0x8000 ;
27
27
const APP_ADDR : u32 = 0x10000 ;
28
28
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
-
42
29
impl 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
+
45
32
const SPI_REGISTERS : SpiRegisters = SpiRegisters {
46
33
base : 0x3ff42000 ,
47
34
usr_offset : 0x1c ,
@@ -60,7 +47,7 @@ impl ChipType for Esp32 {
60
47
fn get_flash_segments < ' a > (
61
48
image : & ' a FirmwareImage ,
62
49
) -> 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" ) ;
64
51
65
52
let partition_table = PartitionTable :: basic ( 0x10000 , 0x3f0000 ) . to_bytes ( ) ;
66
53
@@ -167,74 +154,6 @@ impl ChipType for Esp32 {
167
154
}
168
155
}
169
156
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
-
238
157
#[ test]
239
158
fn test_esp32_rom ( ) {
240
159
use std:: fs:: read;
0 commit comments