# [−] [src] Crate r0

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

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)