feat(adapter-riscv): boot on QEMU virt with UART hello world

This commit is contained in:
2026-10-18 01:46:47 +02:00
parent dcadb83088
commit 44a0ead7f2
6 changed files with 182 additions and 0 deletions

View 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") };
}
}

View 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]);
}
}
}