Skip to content

Commit 0d2591e

Browse files
authored
Pad all but last sector in flash binary to write whole of sector (#800)
1 parent 81bdcb6 commit 0d2591e

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

tools/elf2uf2/main.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <cstdio>
88
#include <map>
9+
#include <set>
910
#include <vector>
1011
#include <cstring>
1112
#include <cstdarg>
@@ -21,6 +22,8 @@ typedef unsigned int uint;
2122
#define ERROR_READ_FAILED -4
2223
#define ERROR_WRITE_FAILED -5
2324

25+
#define FLASH_SECTOR_ERASE_SIZE 4096u
26+
2427
static char error_msg[512];
2528
static bool verbose;
2629

@@ -295,6 +298,28 @@ int elf2uf2(FILE *in, FILE *out) {
295298
MAIN_RAM_START, sp);
296299
}
297300
#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+
}
298323
}
299324
uf2_block block;
300325
block.magic_start0 = UF2_MAGIC_START0;
@@ -308,7 +333,8 @@ int elf2uf2(FILE *in, FILE *out) {
308333
block.target_addr = page_entry.first;
309334
block.block_no = page_num++;
310335
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)": "");
312338
}
313339
memset(block.data, 0, sizeof(block.data));
314340
rc = realize_page(in, page_entry.second, block.data, sizeof(block.data));

0 commit comments

Comments
 (0)