diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2022-12-12 20:38:24 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2022-12-12 20:38:54 -0700 |
commit | ef3a1919ce5c87179e8f1d7a3b1b835151fdf50f (patch) | |
tree | 600a70a334df03ebbaa2c7928ff0863e3ca614a0 | |
download | stm32l4-rust-ef3a1919ce5c87179e8f1d7a3b1b835151fdf50f.tar.gz stm32l4-rust-ef3a1919ce5c87179e8f1d7a3b1b835151fdf50f.tar.bz2 stm32l4-rust-ef3a1919ce5c87179e8f1d7a3b1b835151fdf50f.zip |
Start writing bare-metal stm32 kernel in rust
-rw-r--r-- | .cargo/config | 8 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.toml | 17 | ||||
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | linker_script.ld | 58 | ||||
-rw-r--r-- | openocd.cfg | 2 | ||||
-rw-r--r-- | src/main.rs | 61 |
7 files changed, 165 insertions, 0 deletions
diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..3edf06e --- /dev/null +++ b/.cargo/config @@ -0,0 +1,8 @@ +[build] +target = "thumbv7em-none-eabihf" + +[target.thumbv7em-none-eabihf] +# runner = "arm-none-eabi-gdb -tui -q -x debug.gdb" +rustflags = [ + "-C", "link-arg=-Tlinker_script.ld", +] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2f8a759 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "stm32l4-rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + + +[profile.release] +codegen-units = 1 +debug = true +incremental = false +lto = true +opt-level = 's' +panic = "abort" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..73b176d --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ + +all: + cargo build + +main.bin: target/thumbv7em-none-eabihf/debug/stm32l4-rust + arm-unknown-eabi-objcopy -O binary target/thumbv7em-none-eabihf/debug/stm32l4-rust main.bin + +flash: main.bin + openocd -f openocd.cfg -c "program main.bin reset exit 0x08000000" + +target/thumbv7em-none-eabihf/debug/stm32l4-rust: + cargo build + +clean: + cargo clean + +debug: + arm-unknown-eabi-gdb -tui -ex 'tar ext :3333' -ex 'file target/thumbv7em-none-eabihf/debug/stm32l4-rust' diff --git a/linker_script.ld b/linker_script.ld new file mode 100644 index 0000000..37b90a4 --- /dev/null +++ b/linker_script.ld @@ -0,0 +1,58 @@ +MEMORY +{ + flash : org = 0x08000000, len = 256k + sram1 : org = 0x20000000, len = 48k + sram2 : org = 0x10000000, len = 16k +} + +SECTIONS +{ + /* By default the start of the stack is at the top of sram1. */ + PROVIDE(_stack_start = ORIGIN(sram1) + LENGTH(sram1)); + + /* Vector-offset table. */ + .vectors ORIGIN(flash) : ALIGN(0x04) { + LONG(_stack_start); /* Store the start of the stack. */ + KEEP(*(.on_reset)); + + . = ORIGIN(flash) + 0x0dc; + } >flash + + /** Text data is stored after the vector table. */ + PROVIDE(_stext = ADDR(.vectors) + SIZEOF(.vectors)); + .text _stext : ALIGN(0x04) { + *(.text .text.*); + . = ALIGN(0x04); + _etext = .; + + /* Readonly data should be stored in flash. */ + *(.rodata .rodata.*) + } >flash + + /* the data segment where static data is stored. This is linked to reference + * variables in sram2, but the data is stored persistently in the flash. + * + * The Application has to load the data from the flash to */ + .data : ALIGN(0x04) { + __data_load = LOADADDR(.data); + __data_store_start = .; + *(.data .data.*); + __data_store_end = .; + } > sram2 AT > flash + + /* block starting symbol (bss). This is data initialized to 0. The application + * is responsible for zeroing out this data. */ + .bss : ALIGN(0x04) { + __bss_start = .; + *(.bss .bss.*); + __bss_end = .; + } > sram2 + + /* Sections that should be discarded. */ + /DISCARD/ : + { + *(.ARM.exidx); + *(.ARM.exidx.*); + *(.ARM.extab.*); + } +} diff --git a/openocd.cfg b/openocd.cfg new file mode 100644 index 0000000..1fb1807 --- /dev/null +++ b/openocd.cfg @@ -0,0 +1,2 @@ +source [find interface/stlink-v2-1.cfg] +source [find target/stm32l4x.cfg] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a3e8071 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,61 @@ +#![no_main] +#![no_std] + +use core::panic::PanicInfo; + +#[link_section = ".on_reset"] +#[no_mangle] +pub static __RESET_VECTOR: fn() -> ! = on_reset; + +#[no_mangle] +pub static mut DEADBEEF: u32 = 0xdeadbeef; +pub static mut OTHER: u32 = 0; + +/** Load into the data segments */ +pub fn load_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; +} + +pub fn on_reset() -> ! { + load_data_segments(); + + unsafe { + DEADBEEF += 100; + OTHER = DEADBEEF; + } + + loop {} +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} |