Skip to content
This repository was archived by the owner on Jan 24, 2022. It is now read-only.

Commit 16eec4b

Browse files
committed
add a .uninit section
that contains static variables that will not be initialized by the runtime this implements only the linker section described in RFC #116 so that downstream libraries / framework can leverage it without (a) forking this crate or (b) requiring the end user to pass additional linker scripts to the linker when building their crate. This commit doesn't add the user interface described in RFC #116; instead it documents how to use this linker section in the advanced section of the crate level documentation
1 parent 3d4e730 commit 16eec4b

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

link.x.in

+9-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ SECTIONS
112112
__edata = .;
113113
} > RAM AT > FLASH
114114

115-
116115
/* LMA of .data */
117116
__sidata = LOADADDR(.data);
118117

@@ -126,7 +125,15 @@ SECTIONS
126125
__ebss = .;
127126
} > RAM
128127

129-
/* Place the heap right after `.bss` */
128+
/* ### .uninit */
129+
.uninit (NOLOAD) : ALIGN(4)
130+
{
131+
. = ALIGN(4);
132+
*(.uninit .uninit.*);
133+
. = ALIGN(4);
134+
} > RAM
135+
136+
/* Place the heap right after `.uninit` */
130137
. = ALIGN(4);
131138
__sheap = .;
132139

src/lib.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -360,13 +360,31 @@
360360
//! }
361361
//! ```
362362
//!
363-
//! ## `pre_init!`
363+
//! ## Uninitialized static variables
364364
//!
365-
//! A user-defined function can be run at the start of the reset handler, before RAM is
366-
//! initialized. The macro `pre_init!` can be called to set the function to be run. The function is
367-
//! intended to perform actions that cannot wait the time it takes for RAM to be initialized, such
368-
//! as disabling a watchdog. As the function is called before RAM is initialized, any access of
369-
//! static variables will result in undefined behavior.
365+
//! The `.uninit` linker section can be used to leave `static mut` variables uninitialized. One use
366+
//! case of unitialized static variables is to avoid zeroing large statically allocated buffers (say
367+
//! to be used as thread stacks) -- this can considerably reduce initialization time on devices that
368+
//! operate at low frequencies.
369+
//!
370+
//! The only correct way to use this section is by placing `static mut` variables with type
371+
//! [`MaybeUninit`] in it.
372+
//!
373+
//! [`MaybeUninit`]: https://doc.rust-lang.org/core/mem/union.MaybeUninit.html
374+
//!
375+
//! ``` ignore
376+
//! use core::mem::MaybeUninit;
377+
//!
378+
//! const STACK_SIZE: usize = 8 * 1024;
379+
//! const NTHREADS: usize = 4;
380+
//!
381+
//! #[link_section = ".uninit.STACKS"]
382+
//! static mut STACKS: MaybeUninit<[[u8; STACK_SIZE]; NTHREADS]> = MaybeUninit::uninit();
383+
//! ```
384+
//!
385+
//! Be very careful with the `link_section` attribute because it's easy to misuse in ways that cause
386+
//! undefined behavior. At some point in the future we may add an attribute to safely place static
387+
//! variables in this section.
370388
371389
// # Developer notes
372390
//

0 commit comments

Comments
 (0)