summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-12-12 20:38:24 -0700
committerJosh Rahm <joshuarahm@gmail.com>2022-12-12 20:38:54 -0700
commitef3a1919ce5c87179e8f1d7a3b1b835151fdf50f (patch)
tree600a70a334df03ebbaa2c7928ff0863e3ca614a0
downloadstm32l4-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/config8
-rw-r--r--.gitignore1
-rw-r--r--Cargo.toml17
-rw-r--r--Makefile18
-rw-r--r--linker_script.ld58
-rw-r--r--openocd.cfg2
-rw-r--r--src/main.rs61
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 {}
+}