6
6
7
7
#include < cstdio>
8
8
#include < map>
9
+ #include < set>
9
10
#include < vector>
10
11
#include < cstring>
11
12
#include < cstdarg>
@@ -21,6 +22,8 @@ typedef unsigned int uint;
21
22
#define ERROR_READ_FAILED -4
22
23
#define ERROR_WRITE_FAILED -5
23
24
25
+ #define FLASH_SECTOR_ERASE_SIZE 4096u
26
+
24
27
static char error_msg[512 ];
25
28
static bool verbose;
26
29
@@ -295,6 +298,28 @@ int elf2uf2(FILE *in, FILE *out) {
295
298
MAIN_RAM_START, sp);
296
299
}
297
300
#endif
301
+ } else {
302
+ // Fill in empty dummy uf2 pages to align the binary to flash sectors (except for the last sector which we don't
303
+ // need to pad, and choose not to to avoid making all SDK UF2s bigger)
304
+ // That workaround is required because the bootrom uses the block number for erase sector calculations:
305
+ // https://github.com/raspberrypi/pico-bootrom/blob/c09c7f08550e8a36fc38dc74f8873b9576de99eb/bootrom/virtual_disk.c#L205
306
+
307
+ std::set<uint32_t > touched_sectors;
308
+ for (auto & page_entry : pages) {
309
+ uint32_t sector = page_entry.first / FLASH_SECTOR_ERASE_SIZE;
310
+ touched_sectors.insert (sector);
311
+ }
312
+
313
+ uint32_t last_page = pages.rbegin ()->first ;
314
+ for (uint32_t sector : touched_sectors) {
315
+ for (uint32_t page = sector * FLASH_SECTOR_ERASE_SIZE; page < (sector + 1 ) * FLASH_SECTOR_ERASE_SIZE; page += PAGE_SIZE) {
316
+ if (page < last_page) {
317
+ // Create a dummy page, if it does not exist yet. note that all present pages are first
318
+ // zeroed before they are filled with any contents, so a dummy page will be all zeros.
319
+ auto &dummy = pages[page];
320
+ }
321
+ }
322
+ }
298
323
}
299
324
uf2_block block;
300
325
block.magic_start0 = UF2_MAGIC_START0;
@@ -308,7 +333,8 @@ int elf2uf2(FILE *in, FILE *out) {
308
333
block.target_addr = page_entry.first ;
309
334
block.block_no = page_num++;
310
335
if (verbose) {
311
- printf (" Page %d / %d %08x\n " , block.block_no , block.num_blocks , block.target_addr );
336
+ printf (" Page %d / %d %08x%s\n " , block.block_no , block.num_blocks , block.target_addr ,
337
+ page_entry.second .empty () ? " (padding)" : " " );
312
338
}
313
339
memset (block.data , 0 , sizeof (block.data ));
314
340
rc = realize_page (in, page_entry.second , block.data , sizeof (block.data ));
0 commit comments