feat(adapter-riscv): boot on QEMU virt with UART hello world
This commit is contained in:
17
crates/adapter-riscv/Cargo.toml
Normal file
17
crates/adapter-riscv/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "adapter-riscv"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
types = { workspace = true }
|
||||
domain = { workspace = true }
|
||||
platform = { workspace = true }
|
||||
kernel = { workspace = true }
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
36
crates/adapter-riscv/linker.ld
Normal file
36
crates/adapter-riscv/linker.ld
Normal file
@@ -0,0 +1,36 @@
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x80200000;
|
||||
|
||||
.text : {
|
||||
*(.text.entry)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.bss : {
|
||||
_bss_start = .;
|
||||
*(.bss .bss.*)
|
||||
*(.sbss .sbss.*)
|
||||
_bss_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
_stack_bottom = .;
|
||||
. += 0x10000;
|
||||
_stack_top = .;
|
||||
|
||||
_heap_start = .;
|
||||
}
|
||||
61
crates/adapter-riscv/src/main.rs
Normal file
61
crates/adapter-riscv/src/main.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
mod uart;
|
||||
|
||||
use core::arch::global_asm;
|
||||
use uart::Uart;
|
||||
|
||||
global_asm!(
|
||||
r#"
|
||||
.section .text.entry
|
||||
.globl _start
|
||||
_start:
|
||||
la sp, _stack_top
|
||||
call kmain
|
||||
spin:
|
||||
wfi
|
||||
j spin
|
||||
"#
|
||||
);
|
||||
|
||||
unsafe extern "C" {
|
||||
static _bss_start: u8;
|
||||
static _bss_end: u8;
|
||||
}
|
||||
|
||||
fn zero_bss() {
|
||||
unsafe {
|
||||
let start = &_bss_start as *const u8 as *mut u8;
|
||||
let end = &_bss_end as *const u8 as *mut u8;
|
||||
let len = end as usize - start as usize;
|
||||
core::ptr::write_bytes(start, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn kmain() -> ! {
|
||||
zero_bss();
|
||||
|
||||
let uart = Uart::new();
|
||||
uart.write_str("k-os: booted on RISC-V\n");
|
||||
|
||||
loop {
|
||||
unsafe { core::arch::asm!("wfi") };
|
||||
}
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
let uart = Uart::new();
|
||||
uart.write_str("PANIC: ");
|
||||
if let Some(location) = info.location() {
|
||||
uart.write_str(location.file());
|
||||
uart.put_char(b':');
|
||||
uart.write_dec(location.line() as usize);
|
||||
}
|
||||
uart.put_char(b'\n');
|
||||
loop {
|
||||
unsafe { core::arch::asm!("wfi") };
|
||||
}
|
||||
}
|
||||
60
crates/adapter-riscv/src/uart.rs
Normal file
60
crates/adapter-riscv/src/uart.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
const UART_BASE: usize = 0x10000000;
|
||||
|
||||
pub struct Uart {
|
||||
base: usize,
|
||||
}
|
||||
|
||||
impl Uart {
|
||||
pub fn new() -> Self {
|
||||
Self { base: UART_BASE }
|
||||
}
|
||||
|
||||
pub fn put_char(&self, byte: u8) {
|
||||
let ptr = self.base as *mut u8;
|
||||
unsafe { core::ptr::write_volatile(ptr, byte) };
|
||||
}
|
||||
|
||||
pub fn write_str(&self, s: &str) {
|
||||
for byte in s.bytes() {
|
||||
self.put_char(byte);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_hex(&self, mut value: usize) {
|
||||
self.write_str("0x");
|
||||
if value == 0 {
|
||||
self.put_char(b'0');
|
||||
return;
|
||||
}
|
||||
let mut buf = [0u8; 16];
|
||||
let mut i = 0;
|
||||
while value > 0 {
|
||||
let digit = (value & 0xF) as u8;
|
||||
buf[i] = if digit < 10 { b'0' + digit } else { b'a' + digit - 10 };
|
||||
value >>= 4;
|
||||
i += 1;
|
||||
}
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
self.put_char(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_dec(&self, mut value: usize) {
|
||||
if value == 0 {
|
||||
self.put_char(b'0');
|
||||
return;
|
||||
}
|
||||
let mut buf = [0u8; 20];
|
||||
let mut i = 0;
|
||||
while value > 0 {
|
||||
buf[i] = b'0' + (value % 10) as u8;
|
||||
value /= 10;
|
||||
i += 1;
|
||||
}
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
self.put_char(buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user