Skip to content

Conversation

@BenChung
Copy link
Contributor

@BenChung BenChung commented Oct 7, 2025

This implements the skip-data-copy feature, which disables loading the .data section (containing statically allocated variables) in cases when that section is either:

  • Already loaded and possible, or
  • No longer valid when the startup code runs.

This occurs for example with boot2 using the BOOT_LOADER_RAM_MEMCPY option, which copies the .data section and then de-initializes XIP before relinquishing control leaving the contents of .data at the LMA undefined.

This fixes #609. Tested on a RP2040 in a pico. The test project is https://github.com/BenChung/RP2040_boot2_run_from_ram, which panics without this fix, or works correctly with this patch (shown on the branch https://github.com/BenChung/RP2040_boot2_run_from_ram/tree/fixed).

@adamgreig
Copy link
Member

Thanks for the PR and apologies for the long wait for a review.

I'm generally fine with the idea but I had a couple of questions:

  • Can this be done just by changing the linker script/memory addresses, i.e. setting FLASH in memory.x to a RAM address? The bootloader should be able to copy the whole image into RAM and it will all already be linked correctly to run from RAM.
  • Don't you have a problem where anything in rodata would still be inaccessible if that memory region is no longer available, even if the bootloader has copied everything from data to initialise RAM for you? I believe the contents of rodata and the initial values for data start life in the same place but rodata is then accessed from that section directly at runtime.
  • Maybe it should be called skip-data-init instead since we use init to refer to this process in zero-init-ram for instance

@BenChung
Copy link
Contributor Author

Sorry, it's been a bit so I'm somewhat fuzzy now on all the implications.

Can this be done just by changing the linker script/memory addresses, i.e. setting FLASH in memory.x to a RAM address? The bootloader should be able to copy the whole image into RAM and it will all already be linked correctly to run from RAM.

No. If you do this the linker will try and put everything in RAM to begin with, and I think that this will work until you power cycle the board.

Don't you have a problem where anything in rodata would still be inaccessible if that memory region is no longer available, even if the bootloader has copied everything from data to initialise RAM for you? I believe the contents of rodata and the initial values for data start life in the same place but rodata is then accessed from that section directly at runtime.

IIRC, the boot2 bootloader copies all of the RAM AT > FLASH blocks (including rodata) and sets up the pointers for that so that rodata still works at runtime while running in a copy-to-flash setup. This would be required anyways because a major reason to run from RAM is so that you can use the flash pins to do something else after initialization.

Maybe it should be called skip-data-init instead since we use init to refer to this process in zero-init-ram for instance

Seems reasonable to me.

@thejpster
Copy link
Contributor

thejpster commented Jan 6, 2026

This seems fine to me. We could probably also have the same effect by testing it __sidata is set to zero, but the current approach is less run-time code.

@jonathanpallant
Copy link
Contributor

Approved wearing the right hat

@jannic
Copy link
Member

jannic commented Jan 6, 2026

And successfully tested using rp2040-hal. Good job!

@jonathanpallant jonathanpallant added this pull request to the merge queue Jan 6, 2026
Merged via the queue into rust-embedded:master with commit 1a3734d Jan 6, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add feature to disable .data copy when using a copying bootloader

5 participants