diff options
Diffstat (limited to 'src/init')
-rw-r--r-- | src/init/core.rs | 29 | ||||
-rw-r--r-- | src/init/load.rs | 37 | ||||
-rw-r--r-- | src/init/mod.rs | 2 |
3 files changed, 68 insertions, 0 deletions
diff --git a/src/init/core.rs b/src/init/core.rs new file mode 100644 index 0000000..51f1e6a --- /dev/null +++ b/src/init/core.rs @@ -0,0 +1,29 @@ +#[link_section = ".on_reset"] +#[no_mangle] +pub static __RESET_VECTOR: fn() -> ! = on_reset; + +/** + * The init sections are run. The order in which they are run is deterined by the name of the + * section the pointer to the function is located in. By convention the section name is 'inits.nnn' + * where 'nnn' is a number from 000-999. + */ +fn run_init_sections() -> () { + extern "C" { + static mut _sinits: extern "C" fn() -> (); + static mut _einits: extern "C" fn() -> (); + } + unsafe { + let mut cursor: *mut extern "C" fn() -> () = &mut _sinits; + let einits_end: *mut extern "C" fn() -> () = &mut _einits; + + while cursor < einits_end { + cursor.read()(); + cursor = cursor.offset(1); + } + } +} + +fn on_reset() -> ! { + run_init_sections(); + loop {} +} diff --git a/src/init/load.rs b/src/init/load.rs new file mode 100644 index 0000000..ce7b681 --- /dev/null +++ b/src/init/load.rs @@ -0,0 +1,37 @@ +/** Load into the data segments */ +#[link_section = ".inits.005"] +#[no_mangle] +static __LOAD_DATA_SEGMENTS: fn() -> () = data_segments; + +/** Loads the .data segment data from flash to memory if required. */ +fn data_segments() -> () { + extern "C" { + static mut __data_load: u32; + static mut __data_store_start: u32; + static mut __data_store_end: u32; + static mut __bss_start: u32; + static mut __bss_end: u32; + } + + unsafe { + let mut data_load_addr: *mut u32 = &mut __data_load; + let mut store_cursor: *mut u32 = &mut __data_store_start; + let data_store_end_addr: *mut u32 = &mut __data_store_end; + + while store_cursor < data_store_end_addr { + store_cursor.write_volatile(*data_load_addr); + data_load_addr = data_load_addr.offset(1); + store_cursor = store_cursor.offset(1); + } + + let bss_end: *mut u32 = &mut __bss_end; + let mut bss_cursor: *mut u32 = &mut __bss_start; + + while bss_cursor < bss_end { + bss_cursor.write_volatile(0); + bss_cursor = bss_cursor.offset(1); + } + } + + return; +} diff --git a/src/init/mod.rs b/src/init/mod.rs new file mode 100644 index 0000000..2e609f3 --- /dev/null +++ b/src/init/mod.rs @@ -0,0 +1,2 @@ +pub mod core; +pub mod load; |