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