| @@ -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 {} | |||||
| } | |||||