diff --git a/kernel/Makefile b/kernel/Makefile index 63c4538..5d8a0e8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -124,17 +124,7 @@ build/x86_64/os.iso: $(kernel) $(grub_cfg) @rm -r build/isofiles build/riscv32/os.iso: $(kernel) - @cd ../riscv-pk && \ - mkdir -p build && \ - cd build && \ - ../configure \ - --enable-logo \ - --prefix=$(RISCV) \ - --disable-fp-emulation \ - --host=riscv32-unknown-elf \ - --with-payload=$(abspath $(kernel)) && \ - make && \ - cp bbl ../../kernel/$@ + @cp $(kernel) $@ $(kernel): kernel $(assembly_object_files) $(linker_script) @$(ld) -n --gc-sections -T $(linker_script) -o $(kernel) \ diff --git a/kernel/src/arch/riscv32/boot/entry.asm b/kernel/src/arch/riscv32/boot/entry.asm index 6c11050..02fab69 100644 --- a/kernel/src/arch/riscv32/boot/entry.asm +++ b/kernel/src/arch/riscv32/boot/entry.asm @@ -1,8 +1,21 @@ .section .entry - .globl kern_entry -kern_entry: + .global _start +_start: + csrw mie, 0 + csrw mip, 0 + csrw mscratch, 0 + csrw satp, 0 + li t0, -1 + csrw medeleg, t0 + csrw mideleg, t0 + csrw mcounteren, t0 + csrw scounteren, t0 + li t0, 1 << 11 ; MPP = S + csrw mstatus, t0 + la t0, rust_main + csrw mepc, t0 la sp, bootstacktop - tail rust_main + mret .section .bss .align 12 #PGSHIFT diff --git a/kernel/src/arch/riscv32/boot/linker.ld b/kernel/src/arch/riscv32/boot/linker.ld index 288fd94..8914852 100644 --- a/kernel/src/arch/riscv32/boot/linker.ld +++ b/kernel/src/arch/riscv32/boot/linker.ld @@ -4,9 +4,9 @@ See the GNU ld 'info' manual ("info ld") to learn the syntax. */ OUTPUT_ARCH(riscv) -ENTRY(kern_entry) +ENTRY(_start) -BASE_ADDRESS = 0x80020000; /* equal to payload address in bbl */ +BASE_ADDRESS = 0x80000000; SECTIONS { diff --git a/kernel/src/arch/riscv32/io.rs b/kernel/src/arch/riscv32/io.rs index 72c3d55..e392e46 100644 --- a/kernel/src/arch/riscv32/io.rs +++ b/kernel/src/arch/riscv32/io.rs @@ -1,5 +1,5 @@ -use super::bbl::sbi; use core::fmt::{Write, Result, Arguments}; +use core::ptr::{read_volatile, write_volatile}; struct SerialPort; @@ -7,24 +7,39 @@ impl Write for SerialPort { fn write_str(&mut self, s: &str) -> Result { for c in s.bytes() { if c == 127 { - sbi::console_putchar(8); - sbi::console_putchar(' ' as usize); - sbi::console_putchar(8); + putchar(8); + putchar(b' '); + putchar(8); } else { - sbi::console_putchar(c as usize); + putchar(c as u8); } } Ok(()) } } +fn putchar(c: u8) { + unsafe { + while read_volatile(STATUS) & CAN_WRITE == 0 {} + write_volatile(DATA, c as u8); + } +} + pub fn getchar() -> char { - match sbi::console_getchar() as u8 { - 255 => '\0', // null - c => c as char, + unsafe { + while read_volatile(STATUS) & CAN_READ == 0 {} + match read_volatile(DATA) { + 255 => '\0', // null + c => c as char, + } } } pub fn putfmt(fmt: Arguments) { SerialPort.write_fmt(fmt).unwrap(); } + +const DATA: *mut u8 = 0x10000000 as *mut u8; +const STATUS: *const u8 = 0x10000005 as *const u8; +const CAN_READ: u8 = 1 << 1; +const CAN_WRITE: u8 = 1 << 5; diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index bd5e409..4945b26 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -41,6 +41,7 @@ fn remap_the_kernel() { }; static mut SPACE: [u8; 0x1000] = [0; 0x1000]; let mut ms = unsafe { MemorySet::new_from_raw_space(&mut SPACE, kstack) }; + ms.push(MemoryArea::new_identity(0x10000000, 0x10000008, MemoryAttr::default(), "serial")); ms.push(MemoryArea::new_identity(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), "text")); ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); ms.push(MemoryArea::new_identity(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), "rodata")); diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 7f5b32e..921245b 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -1,4 +1,3 @@ -extern crate bbl; extern crate riscv; pub mod io; diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 2903429..95ecefe 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -17,6 +17,7 @@ pub fn setup_page_table(frame: Frame) { p2.set_recursive(RECURSIVE_PAGE_PML4, frame.clone()); // Set kernel identity map + p2[0x40].set(Frame::of_addr(PhysAddr::new(0x10000000)), EF::VALID | EF::READABLE | EF::WRITABLE); p2[KERNEL_PML4].set(Frame::of_addr(PhysAddr::new((KERNEL_PML4 as u32) << 22)), EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE); p2[KERNEL_PML4 + 1].set(Frame::of_addr(PhysAddr::new((KERNEL_PML4 as u32 + 1) << 22)), EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE); @@ -218,10 +219,12 @@ impl InactivePageTable for InactivePageTable0 { impl InactivePageTable0 { fn map_kernel(&mut self) { let table = unsafe { &mut *ROOT_PAGE_TABLE }; + let e0 = table[0x40]; let e1 = table[KERNEL_PML4]; assert!(!e1.is_unused()); self.edit(|_| { + table[0x40] = e0; table[KERNEL_PML4].set(e1.frame(), EF::VALID | EF::GLOBAL); }); } diff --git a/kernel/src/arch/riscv32/timer.rs b/kernel/src/arch/riscv32/timer.rs index b668238..0ddc916 100644 --- a/kernel/src/arch/riscv32/timer.rs +++ b/kernel/src/arch/riscv32/timer.rs @@ -1,5 +1,4 @@ use super::riscv::register::*; -use super::bbl::sbi; #[cfg(target_pointer_width = "64")] pub fn get_cycle() -> u64 { @@ -29,5 +28,12 @@ pub fn init() { pub fn set_next() { // 100Hz @ QEMU let timebase = 100000; - sbi::set_timer(get_cycle() + timebase); + set_timer(get_cycle() + timebase); +} + +fn set_timer(t: u64) { + unsafe { + asm!("csrw 0x321, $0; csrw 0x322, $1" + : : "r"(t as u32), "r"((t >> 32) as u32) : : "volatile"); + } } \ No newline at end of file