Skip to content

Commit f5d53a9

Browse files
Add skip-data-init feature to disable .data section initialization
1 parent 1436479 commit f5d53a9

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

cortex-m-rt/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ set-vtor = []
4848
set-msplim = []
4949
zero-init-ram = []
5050
paint-stack = []
51+
skip-data-init = []
5152

5253
[package.metadata.docs.rs]
5354
features = ["device"]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//! Example demonstrating the skip-data-init feature
2+
//!
3+
//! This feature is useful when using bootloaders (like RP2040's boot2) that:
4+
//! 1. Copy all data from Flash to RAM
5+
//! 2. Unmap the Flash from memory space
6+
//! 3. Jump to the Reset handler
7+
//!
8+
//! In such scenarios, the default cortex-m-rt data initialization would fail
9+
//! because it tries to copy from Flash which is no longer accessible.
10+
//!
11+
//! To use this feature, enable it in your Cargo.toml:
12+
//! ```toml
13+
//! [dependencies]
14+
//! cortex-m-rt = { version = "0.7", features = ["skip-data-init"] }
15+
//! ```
16+
//!
17+
//! And ensure your bootloader or linker script properly initializes .data before
18+
//! jumping to Reset.
19+
20+
#![no_main]
21+
#![no_std]
22+
23+
use panic_halt as _;
24+
25+
use cortex_m_rt::entry;
26+
27+
static mut COUNTER: u32 = 42;
28+
29+
#[entry]
30+
fn main() -> ! {
31+
unsafe {
32+
COUNTER += 1;
33+
}
34+
35+
loop {
36+
cortex_m::asm::nop();
37+
}
38+
}

cortex-m-rt/src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,30 @@
208208
//! where the stack has been used the 'paint' will have been 'scrubbed off' and the memory will
209209
//! have a value other than `STACK_PAINT_VALUE`.
210210
//!
211+
//! ## `skip-data-init`
212+
//!
213+
//! If this feature is enabled, the `.data` section initialization is skipped during startup.
214+
//! By default, cortex-m-rt copies the `.data` section from its load address (LMA) in Flash
215+
//! to its virtual address (VMA) in RAM. However, in some scenarios this copy is unnecessary
216+
//! or undesirable:
217+
//!
218+
//! - When using bootloaders like RP2040's boot2 that copy all data from Flash to RAM and then
219+
//! unmap the Flash, the cortex-m-rt data initialization would fail because Flash is no longer
220+
//! accessible.
221+
//! - When the `.data` section is already placed in RAM at the correct address (LMA equals VMA).
222+
//!
223+
//! When this feature is enabled, it is the user's responsibility to ensure that the `.data`
224+
//! section is properly initialized before the program's main function is called. This can be
225+
//! done by:
226+
//!
227+
//! - Using a bootloader that copies the data before jumping to the Reset handler
228+
//! - Setting `__sidata = ADDR(.data)` in the linker script to make LMA equal to VMA (though this
229+
//! wastes Flash space)
230+
//! - Other custom initialization mechanisms
231+
//!
232+
//! **WARNING:** Using this feature without ensuring proper `.data` initialization will result
233+
//! in undefined behavior if your program uses initialized static variables.
234+
//!
211235
//! # Inspection
212236
//!
213237
//! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
@@ -603,6 +627,7 @@ cfg_global_asm! {
603627
1:",
604628

605629
// Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
630+
#[cfg(not(feature = "skip-data-init"))]
606631
"ldr r0, =__sdata
607632
ldr r1, =__edata
608633
ldr r2, =__sidata

0 commit comments

Comments
 (0)