-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discontiguous UF2 files not written consistently #19
Comments
yes this is a bug; see raspberrypi/pico-sdk#762 the next (SDK1.3.1) version of see also #9 |
Ah. Yes, I missed that when reading the code: https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/virtual_disk.c#L205 - that likely needs to be derived from the transfer address rather than the block number. If my current understanding of that code is correct, it's using the top 28 bits of the block number to select a bit in the erase bitmask. So, what it's actually tracking is whether any erases have been performed for a particular group of 16 incoming blocks. (With the side effect that it will unconditionally erase one flash sector per group of 16 blocks.) So the behavior I'm seeing results from a combination of two things:
So the mitigation seems to be: Ensure that each set of UF2 records that share the top 28 bits of the block number (that is, each consecutive group of 16 by block number) address the same 4kiB erase sector. (This is equivalent to your comment about padding partially filled 4K sectors, but more specific, because I'm going to go implement it.) Are y'all open to a patch? Is this something you might consider fixing in a future mask revision? |
This class of bug seems like it has the potential to be pretty common, so the mitigations are not hardcoded as rp2040-specific. However, there is an rp2040-specific _check_ in the info command now.
I've added the mitigation described above to uf2l as well as added a check to the file validator that can detect files that will trip this bug. I'm happy to prepare a PR to fix the ROM if you're open to it. |
Your understanding is exactly correct. Sure we will accept a patch, which we would include if RP2040 does ever get another mask revision |
Hi! I am admittedly doing something slightly odd, but that odd thing may have exposed a bug in the firmware loading code.
The build system for Hubris lays out separately compiled tasks in isolated memory containers. This means that its Flash footprint consists of a series of (power-of-two-aligned) chunks, many of which are not full. For instance,
For instance, in the example layout above, there's a gap between the end of the kernel text (at ...2db8, or ...2e00 when rounded up to the next Flash sector) and the beginning of the next program's text at ...3000.
I've altered our build system to produce UF2 and I've tested it in two different modes. In "contiguous" mode, it generates zero-filled records for gaps like the one described above. In "discontiguous" mode, it does not (and the block count and whatnot is reduced accordingly). The datasheet didn't talk me out of doing discontiguous UF2s; indeed, section 2.8.4.2 mentions offhand that
I went and studied
virtual_disk.c
and associated code, and it looks like it's trying to do the right thing even if blocks are discontiguous, out of order, etc. So, it sure looks like this should work!However, when loading in discontiguous mode, the Flash is not being written correctly. Specifically, the Flash will be written up to the final sector in a contiguous region, and then the first few sectors of the region after the gap are erased but not written, so they read back as FF FF etc. Example (from a conversation through gdb+openocd):
The UF2 record that should have been written there reads:
The problem extends up until address ...3500 at which point sectors start being written correctly again. (This is a curious point for things to change, as it's not an erase sector boundary.)
So, I am either missing something, or there's a subtle bug here.
I have attached gzip'd UF2 images of the firmware (compiled for Pi Pico) in both contiguous mode (works!) and discontiguous mode (fails as described above). If you try it, the "working" case should blink the LED at about 1 Hz, while the failure case will set the LED and then hard fault when it jumps into an erased flash sector.
contiguous.uf2.gz
discontiguous.uf2.gz
The text was updated successfully, but these errors were encountered: