Crate r0 [] [src]

Initialization code ("crt0") written in Rust

This is for bare metal systems where there is no ELF loader or OS to take care of initializing RAM for the program.

Initializing RAM

On the linker script side, we must assign names (symbols) to the boundaries of the .bss and .data sections.

.bss : ALIGN(4)
{
    _sbss = .;
    *(.bss.*);
    _ebss = ALIGN(4);
} > RAM

.data : ALIGN(4)
{
    _sdata = .;
    *(.data.*);
    _edata = ALIGN(4);
} > RAM AT > FLASH

_sidata = LOADADDR(.data);

On the Rust side, we must bind to those symbols using an extern block.

unsafe fn before_main() {
    // The type, `u32`, indicates that the memory is 4-byte aligned
    extern "C" {
        static mut _sbss: u32;
        static mut _ebss: u32;

        static mut _sdata: u32;
        static mut _edata: u32;

        static _sidata: u32;
    }

    zero_bss(&mut _sbss, &mut _ebss);
    init_data(&mut _sdata, &mut _edata, &_sidata);
}

.init_array & .pre_init_array

This crate also provides an API to add "life before main" functionality to bare metal systems.

On the linker script side, instruct the linker to keep the .init_array sections from input object files. Store the start and end address of the merged .init_array section.

.text :
{
  /* .. */
  _init_array_start = ALIGN(4);
  KEEP(*(.init_array));
  _init_array_end = ALIGN(4);
  /* .. */
}

On the startup code, invoke the run_init_array function before you call the user main.

unsafe fn start() {
    extern "C" {
        static _init_array_start: extern "C" fn();
        static _init_array_end: extern "C" fn();
    }

    ::r0::run_init_array(&_init_array_start, &_init_array_end);

    extern "C" {
        fn main(argc: isize, argv: *const *const u8) -> isize;
    }

    main();
}

Then the user application can use this crate init_array! macro to run code before main.

init_array!(before_main, {
    println!("Hello");
});

fn main() {
    println!("World");
}

Macros

init_array
pre_init_array

Functions

init_data

Initializes the .data section

run_init_array
zero_bss

Zeroes the .bss section