@@ -0,0 +1,2 @@ | |||||
/target | |||||
/build/* |
@@ -0,0 +1,5 @@ | |||||
# This file is automatically @generated by Cargo. | |||||
# It is not intended for manual editing. | |||||
[[package]] | |||||
name = "grove" | |||||
version = "0.1.0" |
@@ -0,0 +1,13 @@ | |||||
[package] | |||||
name = "grove" | |||||
version = "0.1.0" | |||||
authors = ["Isabelle Lesko <me@izzabelle.dev>"] | |||||
edition = "2018" | |||||
[profile.dev] | |||||
panic = "abort" | |||||
[profile.release] | |||||
panic = "abort" | |||||
[dependencies] |
@@ -0,0 +1,21 @@ | |||||
// AArch32 mode | |||||
.section ".text.boot" | |||||
.globl _start | |||||
.org 0x8000 | |||||
_start: | |||||
mov sp, #0x8000 | |||||
ldr r4, =__bss_start | |||||
ldr r9, =__bss_end | |||||
mov r5, #0 | |||||
mov r6, #0 | |||||
mov r7, #0 | |||||
mov r8, #0 | |||||
b 2f | |||||
1: stmia r4!, {r4-r8} | |||||
2: cmp r4, r9 | |||||
blo 1b | |||||
ldr r4, =kernel_main | |||||
blx r3 | |||||
halt: wfe | |||||
b halt | |||||
@@ -0,0 +1,31 @@ | |||||
// AArch64 mode | |||||
.section ".text.boot" | |||||
.globl _start | |||||
.org 0x8000 | |||||
_start: | |||||
mrc p15, 0, r5, c0, c0, 5 | |||||
and r5, r5, #3 | |||||
cmp r5, #0 | |||||
bne halt | |||||
ldr r5, =_start | |||||
mov sp, r5 | |||||
ldr r4, =__bss_start | |||||
ldr r9, =__bss_end | |||||
mov r5, #0 | |||||
mov r6, #0 | |||||
mov r7, #0 | |||||
mov r8, #0 | |||||
b 2f | |||||
1: stmia r4!, {r5-r8} | |||||
2: cmp r4, r9 | |||||
blo 1b | |||||
ldr r3, =kernel_main | |||||
blx r3 | |||||
halt: | |||||
wfe | |||||
b halt |
@@ -0,0 +1,7 @@ | |||||
build-os: | |||||
arm-none-eabi-gcc -mcpu=cortex-a7 -fpic -ffreestanding -c asm/boot-2.s -o build/boot.o | |||||
cargo xbuild --release --target armv7r-none-eabihf | |||||
arm-none-eabi-gcc -T linker.ld -o build/grove.img -ffreestanding -O2 -nostdlib build/boot.o target/target/release/libgrove.rlib | |||||
run-os: build-os | |||||
qemu-system-arm -M raspi2 -kernel build/grove.img -serial stdio |
@@ -0,0 +1,44 @@ | |||||
ENTRY(_start) | |||||
SECTIONS | |||||
{ | |||||
/* Starts at LOADER_ADDR. */ | |||||
. = 0x8000; | |||||
/* For AArch64, use . = 0x80000; */ | |||||
__start = .; | |||||
__text_start = .; | |||||
.text : | |||||
{ | |||||
KEEP(*(.text.boot)) | |||||
*(.text) | |||||
} | |||||
. = ALIGN(4096); | |||||
__text_end = .; | |||||
__rodata_start = .; | |||||
.rodata : | |||||
{ | |||||
*(.rodata) | |||||
} | |||||
. = ALIGN(4096); /* align to page size */ | |||||
__rodata_end = .; | |||||
__data_start = .; | |||||
.data : | |||||
{ | |||||
*(.data) | |||||
} | |||||
. = ALIGN(4096); /* align to page size */ | |||||
__data_end = .; | |||||
__bss_start = .; | |||||
.bss : | |||||
{ | |||||
bss = .; | |||||
*(.bss) | |||||
} | |||||
. = ALIGN(4096); /* align to page size */ | |||||
__bss_end = .; | |||||
__bss_size = __bss_end - __bss_start; | |||||
__end = .; | |||||
} |
@@ -0,0 +1,61 @@ | |||||
#![no_std] | |||||
use core::panic::PanicInfo; | |||||
use core::ptr::{read_volatile, write_volatile}; | |||||
const UART_DR: u32 = 0x3f20_1000; | |||||
const UART_FR: u32 = 0x3f20_1018; | |||||
fn mmio_write(reg: u32, val: u32) { | |||||
unsafe { write_volatile(reg as *mut u32, val) } | |||||
} | |||||
fn mmio_read(reg: u32) -> u32 { | |||||
unsafe { read_volatile(reg as *const u32) } | |||||
} | |||||
fn transmit_fifo_full() -> bool { | |||||
mmio_read(UART_FR) & (1 << 5) > 0 | |||||
} | |||||
fn receive_fifo_empty() -> bool { | |||||
mmio_read(UART_FR) & (1 << 4) > 0 | |||||
} | |||||
fn writec(c: u8) { | |||||
while transmit_fifo_full() {} | |||||
mmio_write(UART_DR, c as u32); | |||||
} | |||||
fn getc() -> u8 { | |||||
while receive_fifo_empty() {} | |||||
mmio_read(UART_DR) as u8 | |||||
} | |||||
fn write(msg: &str) { | |||||
for c in msg.bytes() { | |||||
writec(c); | |||||
} | |||||
} | |||||
#[no_mangle] | |||||
pub extern "C" fn kernel_main() { | |||||
write("hello rust raspberry pi kernel"); | |||||
loop { | |||||
writec(getc()) | |||||
} | |||||
} | |||||
#[no_mangle] | |||||
pub extern "C" fn __aeabi_unwind_cpp_pr0() {} | |||||
#[panic_handler] | |||||
fn panic(_info: &PanicInfo) -> ! { | |||||
loop {} | |||||
} | |||||
#[allow(non_snake_case)] | |||||
#[no_mangle] | |||||
pub extern "C" fn _Unwind_Resume() { | |||||
loop {} | |||||
} |