diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Cargo.toml | 18 | ||||
| -rw-r--r-- | Makefile | 29 | ||||
| -rw-r--r-- | src/_arch/arm/asm.rs | 9 | ||||
| -rw-r--r-- | src/_arch/arm/cpu.rs | 10 | ||||
| -rw-r--r-- | src/_arch/arm/cpu/boot.rs | 12 | ||||
| -rw-r--r-- | src/_arch/arm/cpu/boot.s | 84 | ||||
| -rw-r--r-- | src/bsp/raspberrypi/linker.ld | 40 | ||||
| -rw-r--r-- | src/cpu.rs | 7 | ||||
| -rw-r--r-- | src/cpu/boot.rs | 3 | ||||
| -rw-r--r-- | src/main.rs | 29 | ||||
| -rw-r--r-- | src/panic_wait.rs | 9 | ||||
| -rw-r--r-- | src/uart.rs | 31 | 
13 files changed, 283 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c3afac7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "ghOSt" +version = "0.1.0" +edition = "2021" +authors = [ "Sergey Bilovytskyy <c@localhost>" ] + +[profile.release] +lto = true + +[features] +default = [] +bsp_rpi2 = [] + +[[bin]] +name = "kernel" +path = "src/main.rs" + +[dependencies] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9beb347 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +BSP ?= rpi2 +DEBUG ?= 0 +AUTO ?= 0 +DEV_SERIAL ?= /dev/ttyUSB0 +TARGET=armv7a-none-eabi +QEMU_BINARY=qemu-system-arm +QEMU_MACHINE_TYPE=raspi2b +QEMU_RELEASE_ARGS=-cpu=cortex-a7 -m 1G -display none +OBJDUMP_BINARY=arm-none-eabi-objdump +NM_BINARY=arm-none-eabi-nm +READELF_BINARY=arm-none-eabi-readelf +LINKER_FILE=src/bsp/raspberrypi/linker.ld +RUSTC_MISC_ARGS=-C target-cpu=cortex-a7 +QEMU_RELEASE_ARGS=-chardev stdio,id=char0,mux=on,logfile=serial.log,signal=on -serial chardev:char0 -mon chardev=char0 +KERNEL_ELF=target/$(TARGET)/release/kernel +RUSTFLAGS=-C link-arg=-T$(LINKER_FILE) $(RUSTC_MISC_ARGS) +RUSTFLAGS_PEDANTIC=$(RUSTFLAGS) -D warnings -D missing_docs +FEATURES=--features bsp_$(BSP) +COMPILER_ARGS=--target=$(TARGET) $(FEATURES) --release +RUSTC_CMD=cargo rustc $(COMPILER_ARGS) +export LINKER_FILE + +.PHONY: build clean + +build: +	@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(RUSTC_CMD) + +clean: +	rm -rf target diff --git a/src/_arch/arm/asm.rs b/src/_arch/arm/asm.rs new file mode 100644 index 0000000..c400f2f --- /dev/null +++ b/src/_arch/arm/asm.rs @@ -0,0 +1,9 @@ +//! Wrapping ARMv7-A Instructions + +/// WFE +/// #[inline(always)] +pub fn wfe() { +    unsafe { +        core::arch::asm!("wfe", options(nomem, nostack)) +    } +} diff --git a/src/_arch/arm/cpu.rs b/src/_arch/arm/cpu.rs new file mode 100644 index 0000000..1ca6fab --- /dev/null +++ b/src/_arch/arm/cpu.rs @@ -0,0 +1,10 @@ +//! Architectural processor code. +mod asm; +pub use asm::*; + +/// Pause execution +pub fn wait_forever() -> ! { +    loop { +        asm::wfe() +    } +} diff --git a/src/_arch/arm/cpu/boot.rs b/src/_arch/arm/cpu/boot.rs new file mode 100644 index 0000000..9ea2330 --- /dev/null +++ b/src/_arch/arm/cpu/boot.rs @@ -0,0 +1,12 @@ +//! Architectural boot code +//!  # Boot code for ARM +//!  crate::cpu::boot::arch_boot + +use core::arch::global_asm; +global_asm!(include_str!("boot.s")); + +/// The Rust entry of the `kernel` binary. +#[no_mangle] +pub unsafe fn _start_rust() -> ! { +    crate::kernel_init() +} diff --git a/src/_arch/arm/cpu/boot.s b/src/_arch/arm/cpu/boot.s new file mode 100644 index 0000000..fd2a652 --- /dev/null +++ b/src/_arch/arm/cpu/boot.s @@ -0,0 +1,84 @@ +.equ _core_id_mask, 0b11 +.section .text.boot + +.global _start +_start: +reset: +	cpsid aif +	mrc p15, #0, r1, c0, c0, #5 +	and r1, r1, #_core_id_mask +	cmp r1, #1 +	beq core1run +	cmp r1, #2 +	beq core2run +	cmp r1, #3 +	beq core3run + +	ldr r0, =vector +	mcr p15, 0, r0, c12, c0, 0 +	cps #0x12 +	ldr sp, =core0_irq_stack +	cps #0x11 +	ldr sp, =core0_fiq_stack +	cps #0x1B +	ldr sp, =core0_undefined_stack +	cps #0x17 +	ldr sp, =core0_data_stack +	cps #0x1f +	ldr sp, =core0_sys_stack +	cps #0x13 +	ldr sp, =core0_svc_stack + +	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, =_start_rust +	blx r3 + +core1run: +core2run: +core3run: +.global io_halt +undefined: +io_halt: +	wfi +	b io_halt + +.align 5 +vector: +	ldr pc, reset_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler + +reset_handler: .word reset +undefined_handler: .word undefined + +.section .bss.sysstacks +.align 4 +	.space 4096 +core0_undefined_stack: +	.space 4096 +core0_svc_stack: +	.space 4096 +core0_data_stack: +	.space 4096 +core0_irq_stack: +	.space 4096 +core0_fiq_stack: +	.space 4096 +core0_sys_stack: diff --git a/src/bsp/raspberrypi/linker.ld b/src/bsp/raspberrypi/linker.ld new file mode 100644 index 0000000..aa60bbb --- /dev/null +++ b/src/bsp/raspberrypi/linker.ld @@ -0,0 +1,40 @@ +ENTRY(_start) + +SECTIONS +{ +	. = 0x8000; +	__start = .; +	__text_start = .; +	.text : +	{ +		KEEP(*(.text.boot)) +		KEEP(*(.text.exceptions)) +		KEEP(*(.text.kernel)) +		*(.text*) +	} +	. = 0x208000; +	__text_end = .; + +	__data_start = .; +	.data : +	{ +		*(.data*) +		__stacks_start = .; +		KEEP(*(.data.stacks)) +	} +	. = ALIGN(4096); +	__data_end = .; + +	__bss_start = .; +	.bss : +	{ +		bss = .; +		. = ALIGN(4096); +		KEEP(*(.bss.sysstacks)) +		*(.bss) +		*(.bss*) +	} +	. = ALIGN(4096); +	__bss_end = .; +	__end = .; +} diff --git a/src/cpu.rs b/src/cpu.rs new file mode 100644 index 0000000..62fcf99 --- /dev/null +++ b/src/cpu.rs @@ -0,0 +1,7 @@ +//! Processor code. +#[cfg(target_arch = "arm")] +#[path = "_arch/arm/cpu.rs"] +mod arch_cpu; +pub use arch_cpu::{wait_forever}; + +mod boot; diff --git a/src/cpu/boot.rs b/src/cpu/boot.rs new file mode 100644 index 0000000..9ef25bd --- /dev/null +++ b/src/cpu/boot.rs @@ -0,0 +1,3 @@ +//! Boot code +#[path = "../_arch/arm/cpu/boot.rs"] +mod arch_boot; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9697ca8 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,29 @@ +//! Kernel Code + +#![allow(non_snake_case)] +#![allow(clippy::upper_case_acronyms,dead_code)] +#![feature(format_args_nl)] +#![feature(panic_info_message)] +#![feature(trait_alias)] +#![feature(exclusive_range_pattern)] +#![no_main] +#![no_std] + +mod cpu; +mod panic_wait; +mod uart; +use crate::uart::*; + +/// Initialization Code +unsafe fn kernel_init() -> ! { +    uart_init(); + +    kernel_main() +} + +fn kernel_main() -> ! { +    write_char(b'a'); +    write_char(b'b'); +    loop { +    } +} diff --git a/src/panic_wait.rs b/src/panic_wait.rs new file mode 100644 index 0000000..33097d8 --- /dev/null +++ b/src/panic_wait.rs @@ -0,0 +1,9 @@ +//! A panic handler that infinitely waits + +use core::panic::PanicInfo; + +/// Panic handler +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { +    unimplemented!() +} diff --git a/src/uart.rs b/src/uart.rs new file mode 100644 index 0000000..7c048e0 --- /dev/null +++ b/src/uart.rs @@ -0,0 +1,31 @@ +pub unsafe fn uart_init() { +    let UART0_CR = 0x3F201030 as *mut u32; +    let UART0_ICR = 0x3F201044 as *mut u32; +    let UART0_IBRD = 0x3F201024 as *mut u32; +    let UART0_FBRD = 0x3F201028 as *mut u32; +    let UART0_LCRH = 0x3F20102C as *mut u32; +    let UART0_IMSC = 0x3F201038 as *mut u32; +    let GPPUD = 0x3F200094 as *mut u32; +    let GPPUDCLK0 = 0x3F200098 as *mut u32; +    *UART0_CR = 0; +    *GPPUD = 0; +    for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));} +    *GPPUDCLK0 = (1 << 14) | (1 << 15); +    for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));} +    *GPPUDCLK0 = 0; +    *UART0_ICR = 0x7FF; +    *UART0_IBRD = 9; +    *UART0_FBRD = 49; +    *UART0_LCRH = (1<<4)|(1<<5)|(1<<6); +    *UART0_IMSC = (1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10); +    *UART0_CR = (1<<0) | (1<<8) | (1<<9); +} + +pub fn write_char(ch: u8) { +    let UART0_DR = 0x3F201000 as *mut u32; +    let UART0_FR = 0x3F201018 as *mut u32; +    unsafe { +        while *UART0_FR & 0x20 != 0 {core::arch::asm!("nop", options(nomem, nostack));} +        *UART0_DR = ch as u32; +    } +} | 
