@@ -4,6 +4,7 @@ use std::{borrow::Cow, io::Write, iter::once, mem::size_of};
44
55use bytemuck:: { bytes_of, from_bytes, Pod , Zeroable } ;
66use esp_idf_part:: { Partition , PartitionTable , Type } ;
7+ use log:: debug;
78use sha2:: { Digest , Sha256 } ;
89
910use crate :: {
@@ -135,11 +136,22 @@ impl<'a> IdfBootloaderFormat<'a> {
135136 } ;
136137
137138 // fetch the generated header from the bootloader
138- let mut header: ImageHeader = * from_bytes ( & bootloader[ 0 ..size_of :: < ImageHeader > ( ) ] ) ;
139+ let mut calc_bootloader_size = 0 ;
140+ let bootloader_header_size = size_of :: < ImageHeader > ( ) ;
141+ calc_bootloader_size += bootloader_header_size;
142+ let mut header: ImageHeader = * from_bytes ( & bootloader[ 0 ..bootloader_header_size] ) ;
139143 if header. magic != ESP_MAGIC {
140144 return Err ( Error :: InvalidBootloader ) ;
141145 }
142146
147+ for _ in 0 ..header. segment_count {
148+ let segment: SegmentHeader = * from_bytes (
149+ & bootloader
150+ [ calc_bootloader_size..calc_bootloader_size + size_of :: < SegmentHeader > ( ) ] ,
151+ ) ;
152+ calc_bootloader_size += segment. length as usize + size_of :: < SegmentHeader > ( ) ;
153+ }
154+
143155 // update the header if a user has specified any custom arguments
144156 if let Some ( mode) = flash_settings. mode {
145157 header. flash_mode = mode as u8 ;
@@ -157,11 +169,24 @@ impl<'a> IdfBootloaderFormat<'a> {
157169 ) ;
158170
159171 // re-calculate hash of the bootloader - needed since we modified the header
160- let bootloader_len = bootloader. len ( ) ;
172+ // the hash is at the end of the bootloader, but the bootloader bytes are padded.
173+ // the real end of the bootloader is the end of the segments plus the 16-byte aligned 1-byte checksum.
174+ // the checksum is stored in the last byte so that the file is a multiple of 16 bytes.
175+ calc_bootloader_size += 1 ; // add checksum size
176+ calc_bootloader_size = calc_bootloader_size + ( ( 16 - ( calc_bootloader_size % 16 ) ) % 16 ) ;
177+ let bootloader_sha_start = calc_bootloader_size;
178+ calc_bootloader_size += 32 ; // add sha256 size
179+ let bootloader_sha_end = calc_bootloader_size;
180+
161181 let mut hasher = Sha256 :: new ( ) ;
162- hasher. update ( & bootloader[ ..bootloader_len - 32 ] ) ;
182+ hasher. update ( & bootloader[ ..bootloader_sha_start ] ) ;
163183 let hash = hasher. finalize ( ) ;
164- bootloader. to_mut ( ) [ bootloader_len - 32 ..] . copy_from_slice ( & hash) ;
184+ debug ! (
185+ "Updating bootloader SHA256 from {} to {}" ,
186+ hex:: encode( & bootloader[ bootloader_sha_start..bootloader_sha_end] ) ,
187+ hex:: encode( hash)
188+ ) ;
189+ bootloader. to_mut ( ) [ bootloader_sha_start..bootloader_sha_end] . copy_from_slice ( & hash) ;
165190
166191 // write the header of the app
167192 // use the same settings as the bootloader
0 commit comments