Initial Cortex-M4F bootstrap code
This commit is contained in:
commit
5f62d443dc
8 changed files with 220 additions and 0 deletions
5
.cargo/config.toml
Normal file
5
.cargo/config.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[build]
|
||||||
|
target = "thumbv7em-none-eabihf"
|
||||||
|
|
||||||
|
[target.thumbv7em-none-eabihf]
|
||||||
|
rustflags = ["-C", "link-arg=-Tlink.x"]
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wocchi"
|
||||||
|
version = "0.1.0"
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "wocchi"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "wocchi"
|
||||||
|
test = false
|
||||||
|
bench = false
|
66
link.x
Normal file
66
link.x
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/* SoC Memory Layout */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x00000000, LENGTH = 512K
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Declare the program entrypoint, each sections and variable called from it will not be
|
||||||
|
discarded by the linker. */
|
||||||
|
ENTRY(reset_handler);
|
||||||
|
|
||||||
|
PROVIDE(reset_handler = default_exception_handler);
|
||||||
|
PROVIDE(nmi_handler = default_exception_handler);
|
||||||
|
PROVIDE(hardfault_handler = default_exception_handler);
|
||||||
|
PROVIDE(memmanager_handler = default_exception_handler);
|
||||||
|
PROVIDE(busfault_handler = default_exception_handler);
|
||||||
|
PROVIDE(usagefault_handler = default_exception_handler);
|
||||||
|
PROVIDE(svcall_handler = default_exception_handler);
|
||||||
|
PROVIDE(debugmonitor_handler = default_exception_handler);
|
||||||
|
PROVIDE(pendsv_handler = default_exception_handler);
|
||||||
|
PROVIDE(systick_handler = default_exception_handler);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
_sp_init = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
|
||||||
|
.vector_table ORIGIN(FLASH) :
|
||||||
|
{
|
||||||
|
KEEP(*(.vector_table .vector_table));
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text .text.*);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_section_start = .;
|
||||||
|
*(.bss .bss.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_section_end = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.data : AT(ADDR(.rodata) + SIZEOF(.rodata))
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_section_start = .;
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_section_end = .;
|
||||||
|
} > RAM
|
||||||
|
_data_section_lma = LOADADDR(.data);
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx .ARM.exidx.*);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
shell.nix
Normal file
22
shell.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {
|
||||||
|
crossSystem = (import <nixpkgs/lib>).systems.examples.armv7l-hf-multiplatform;
|
||||||
|
overlays = [(import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
packages = with pkgs.buildPackages; [
|
||||||
|
rust-analyzer
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs.buildPackages; [
|
||||||
|
(rust-bin.stable.latest.default.override {
|
||||||
|
extensions = [ "rust-src" ];
|
||||||
|
targets = [ "thumbv7em-none-eabihf" ];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = "${pkgs.stdenv.cc.targetPrefix}cc";
|
||||||
|
};
|
||||||
|
}
|
92
src/bootstrap.s
Normal file
92
src/bootstrap.s
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/* Use the UAL syntax */
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
/* Symbols declared in the linker script */
|
||||||
|
.global _sp_init
|
||||||
|
.global _bss_section_start
|
||||||
|
.global _bss_section_end
|
||||||
|
.global _data_section_start
|
||||||
|
.global _data_section_end
|
||||||
|
.global _data_section_lma
|
||||||
|
|
||||||
|
/* Main function of the program to which this script is linked */
|
||||||
|
.global main
|
||||||
|
|
||||||
|
/* ARM vector table (aka isr_vector) */
|
||||||
|
.section .vector_table
|
||||||
|
.align 2
|
||||||
|
.word _sp_init /* Initialisation value of the stack pointer register */
|
||||||
|
/* Exceptions handlers */
|
||||||
|
.word reset_handler /* Reset Exception */
|
||||||
|
.word nmi_handler /* NMI Exception */
|
||||||
|
.word hardfault_handler /* HardFault Exception */
|
||||||
|
.word memmanager_handler /* MemManage Exception */
|
||||||
|
.word busfault_handler /* BusFault Exception */
|
||||||
|
.word usagefault_handler /* UsageFault Exception */
|
||||||
|
.word 0 /* Reserved */
|
||||||
|
.word 0 /* Reserved */
|
||||||
|
.word 0 /* Reserved */
|
||||||
|
.word 0 /* Reserved */
|
||||||
|
.word svcall_handler /* SVCall Exception */
|
||||||
|
.word debugmonitor_handler /* DebugMonitor Exception */
|
||||||
|
.word 0 /* Reserved */
|
||||||
|
.word pendsv_handler /* PendSV Exception */
|
||||||
|
.word systick_handler /* SysTick Exception */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align
|
||||||
|
|
||||||
|
.global default_exception_handler
|
||||||
|
.thumb_func
|
||||||
|
default_exception_handler:
|
||||||
|
b .
|
||||||
|
|
||||||
|
/* The CPU Reset Exception Handler, initializing register and data section, then call the main function */
|
||||||
|
.global reset_handler
|
||||||
|
.thumb_func
|
||||||
|
reset_handler:
|
||||||
|
/* Initialize the CPU general purpose registers */
|
||||||
|
mov r0, 0
|
||||||
|
mov r1, 0
|
||||||
|
mov r2, 0
|
||||||
|
mov r3, 0
|
||||||
|
mov r4, 0
|
||||||
|
mov r5, 0
|
||||||
|
mov r6, 0
|
||||||
|
mov r7, 0
|
||||||
|
mov r8, 0
|
||||||
|
mov r9, 0
|
||||||
|
mov r10, 0
|
||||||
|
mov r11, 0
|
||||||
|
mov r12, 0
|
||||||
|
|
||||||
|
/* .bss section initialization (see linker script) */
|
||||||
|
bss_init:
|
||||||
|
mov r0, 0
|
||||||
|
ldr r1, =_bss_section_start
|
||||||
|
ldr r2, =_bss_section_end
|
||||||
|
|
||||||
|
bss_init_loop:
|
||||||
|
/* Fill the section word-by-word with zeros */
|
||||||
|
cmp r1, r2
|
||||||
|
beq data_init
|
||||||
|
str r0, [r1], 4
|
||||||
|
b bss_init_loop
|
||||||
|
|
||||||
|
/* Data section initialization */
|
||||||
|
data_init:
|
||||||
|
ldr r1, =_data_section_start
|
||||||
|
ldr r2, =_data_section_end
|
||||||
|
ldr r3, =_data_section_lma
|
||||||
|
|
||||||
|
/* Load the initial values of the variables from the section LMA */
|
||||||
|
data_init_loop:
|
||||||
|
cmp r1, r2
|
||||||
|
beq bootstrap_end
|
||||||
|
ldr r0, [r3], 4
|
||||||
|
str r0, [r1], 4
|
||||||
|
b data_init_loop
|
||||||
|
|
||||||
|
/* Bootstrap completed, branch to Rust code now ! */
|
||||||
|
bootstrap_end:
|
||||||
|
bl main
|
16
src/main.rs
Normal file
16
src/main.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use core::{arch::global_asm, panic::PanicInfo};
|
||||||
|
|
||||||
|
global_asm!(include_str!("bootstrap.s"));
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_: &PanicInfo<'_>) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn main() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
Loading…
Reference in a new issue