@@ -27,6 +27,7 @@ pub struct IdfBootloaderFormat<'a> {
2727 flash_segment : RomSegment < ' a > ,
2828 app_size : u32 ,
2929 part_size : u32 ,
30+ partition_table_offset : u32 ,
3031}
3132
3233impl < ' a > IdfBootloaderFormat < ' a > {
@@ -40,6 +41,7 @@ impl<'a> IdfBootloaderFormat<'a> {
4041 flash_mode : Option < FlashMode > ,
4142 flash_size : Option < FlashSize > ,
4243 flash_freq : Option < FlashFrequency > ,
44+ partition_table_offset : Option < u32 > ,
4345 ) -> Result < Self , Error > {
4446 let partition_table = partition_table
4547 . unwrap_or_else ( || params. default_partition_table ( flash_size. map ( |v| v. size ( ) ) ) ) ;
@@ -178,13 +180,25 @@ impl<'a> IdfBootloaderFormat<'a> {
178180 data : Cow :: Owned ( data) ,
179181 } ;
180182
183+ // If the user did not specify a partition offset, we need to assume that the partition
184+ // offset is (first partition offset) - 0x1000, since this is the most common case.
185+ let partition_table_offset = partition_table_offset. unwrap_or_else ( || {
186+ let partitions = partition_table. partitions ( ) ;
187+ let first_partition = partitions
188+ . iter ( )
189+ . min_by ( |a, b| a. offset ( ) . cmp ( & b. offset ( ) ) )
190+ . unwrap ( ) ;
191+ first_partition. offset ( ) - 0x1000
192+ } ) ;
193+
181194 Ok ( Self {
182195 params,
183196 bootloader,
184197 partition_table,
185198 flash_segment,
186199 app_size,
187200 part_size,
201+ partition_table_offset,
188202 } )
189203 }
190204}
@@ -194,16 +208,39 @@ impl<'a> ImageFormat<'a> for IdfBootloaderFormat<'a> {
194208 where
195209 ' a : ' b ,
196210 {
211+ let bootloader_segment = RomSegment {
212+ addr : self . params . boot_addr ,
213+ data : Cow :: Borrowed ( & self . bootloader ) ,
214+ } ;
215+
216+ let partition_table_segment = RomSegment {
217+ addr : self . partition_table_offset ,
218+ data : Cow :: Owned ( self . partition_table . to_bin ( ) . unwrap ( ) ) ,
219+ } ;
220+
221+ let app_partition = self
222+ . partition_table
223+ . find ( "factory" )
224+ . or_else ( || self . partition_table . find_by_type ( Type :: App ) )
225+ . expect ( "no application partition found" ) ;
226+
227+ if self . flash_segment . data . len ( ) > app_partition. size ( ) as usize {
228+ panic ! (
229+ "image size ({} bytes) is larger partition size ({} bytes)" ,
230+ self . flash_segment. data. len( ) ,
231+ app_partition. size( )
232+ ) ;
233+ }
234+
235+ let app_segment = RomSegment {
236+ addr : app_partition. offset ( ) ,
237+ data : Cow :: Borrowed ( & self . flash_segment . data ) ,
238+ } ;
239+
197240 Box :: new (
198- once ( RomSegment {
199- addr : self . params . boot_addr ,
200- data : Cow :: Borrowed ( & self . bootloader ) ,
201- } )
202- . chain ( once ( RomSegment {
203- addr : self . params . partition_addr ,
204- data : Cow :: Owned ( self . partition_table . to_bin ( ) . unwrap ( ) ) ,
205- } ) )
206- . chain ( once ( self . flash_segment . borrow ( ) ) ) ,
241+ once ( bootloader_segment)
242+ . chain ( once ( partition_table_segment) )
243+ . chain ( once ( app_segment) ) ,
207244 )
208245 }
209246
@@ -334,6 +371,7 @@ pub mod tests {
334371 None ,
335372 None ,
336373 None ,
374+ None ,
337375 )
338376 . unwrap ( ) ;
339377
0 commit comments