@@ -27,6 +27,7 @@ pub struct IdfBootloaderFormat<'a> {
27
27
flash_segment : RomSegment < ' a > ,
28
28
app_size : u32 ,
29
29
part_size : u32 ,
30
+ partition_table_offset : u32 ,
30
31
}
31
32
32
33
impl < ' a > IdfBootloaderFormat < ' a > {
@@ -40,6 +41,7 @@ impl<'a> IdfBootloaderFormat<'a> {
40
41
flash_mode : Option < FlashMode > ,
41
42
flash_size : Option < FlashSize > ,
42
43
flash_freq : Option < FlashFrequency > ,
44
+ partition_table_offset : Option < u32 > ,
43
45
) -> Result < Self , Error > {
44
46
let partition_table = partition_table
45
47
. unwrap_or_else ( || params. default_partition_table ( flash_size. map ( |v| v. size ( ) ) ) ) ;
@@ -178,13 +180,25 @@ impl<'a> IdfBootloaderFormat<'a> {
178
180
data : Cow :: Owned ( data) ,
179
181
} ;
180
182
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
+
181
194
Ok ( Self {
182
195
params,
183
196
bootloader,
184
197
partition_table,
185
198
flash_segment,
186
199
app_size,
187
200
part_size,
201
+ partition_table_offset,
188
202
} )
189
203
}
190
204
}
@@ -194,16 +208,39 @@ impl<'a> ImageFormat<'a> for IdfBootloaderFormat<'a> {
194
208
where
195
209
' a : ' b ,
196
210
{
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
+
197
240
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) ) ,
207
244
)
208
245
}
209
246
@@ -334,6 +371,7 @@ pub mod tests {
334
371
None ,
335
372
None ,
336
373
None ,
374
+ None ,
337
375
)
338
376
. unwrap ( ) ;
339
377
0 commit comments