From 7797ae7810c7a107c953edc7358b803b45722074 Mon Sep 17 00:00:00 2001 From: hheik <4469778+hheik@users.noreply.github.com> Date: Fri, 3 May 2024 13:22:00 +0300 Subject: [PATCH 1/2] Replaced main.c --- Makefile | 1 - kernel/main.c | 43 -------------------------------- theseus/src/kmain.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++ theseus/src/lib.rs | 1 + theseus/src/riscv.rs | 6 +++++ theseus/src/start.rs | 6 ++--- 6 files changed, 67 insertions(+), 48 deletions(-) delete mode 100644 kernel/main.c create mode 100644 theseus/src/kmain.rs diff --git a/Makefile b/Makefile index 9715e5b..de1e684 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ OBJS = \ $K/kalloc.o \ $K/spinlock.o \ $K/string.o \ - $K/main.o \ $K/vm.o \ $K/proc.o \ $K/swtch.o \ diff --git a/kernel/main.c b/kernel/main.c deleted file mode 100644 index cab0e2a..0000000 --- a/kernel/main.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "types.h" -#include "param.h" -#include "memlayout.h" -#include "riscv.h" -#include "defs.h" - -volatile static int started = 0; - -// start() jumps here in supervisor mode on all CPUs. -void main() { - if (cpuid() == 0) { - consoleinit(); - printfinit(); - printf("\n"); - printf("xv6 kernel is booting\n"); - printf("\n"); - kinit(); // physical page allocator - kvminit(); // create kernel page table - kvminithart(); // turn on paging - procinit(); // process table - trapinit(); // trap vectors - trapinithart(); // install kernel trap vector - plicinit(); // set up interrupt controller - plicinithart(); // ask PLIC for device interrupts - binit(); // buffer cache - iinit(); // inode table - fileinit(); // file table - virtio_disk_init(); // emulated hard disk - userinit(); // first user process - __sync_synchronize(); - started = 1; - } else { - while (started == 0) - ; - __sync_synchronize(); - printf("hart %d starting\n", cpuid()); - kvminithart(); // turn on paging - trapinithart(); // install kernel trap vector - plicinithart(); // ask PLIC for device interrupts - } - - scheduler(); -} diff --git a/theseus/src/kmain.rs b/theseus/src/kmain.rs new file mode 100644 index 0000000..583b4c2 --- /dev/null +++ b/theseus/src/kmain.rs @@ -0,0 +1,58 @@ +use crate::riscv; + +extern "C" { + fn cpuid() -> u64; + fn consoleinit(); + fn printfinit(); + // fn printf(); + fn kinit(); + fn kvminit(); + fn kvminithart(); + fn procinit(); + fn trapinit(); + fn trapinithart(); + fn plicinit(); + fn plicinithart(); + fn binit(); + fn iinit(); + fn fileinit(); + fn virtio_disk_init(); + fn userinit(); + fn scheduler(); +} + +pub static mut started: bool = false; + +pub unsafe fn kmain() { + if cpuid() == 0 { + consoleinit(); + printfinit(); + // printf("\n"); + // printf("xv6 kernel is booting\n"); + // printf("\n"); + kinit(); // physical page allocator + kvminit(); // create kernel page table + kvminithart(); // turn on paging + procinit(); // process table + trapinit(); // trap vectors + trapinithart(); // install kernel trap vector + plicinit(); // set up interrupt controller + plicinithart(); // ask PLIC for device interrupts + binit(); // buffer cache + iinit(); // inode table + fileinit(); // file table + virtio_disk_init(); // emulated hard disk + userinit(); // first user process + riscv::barrier(); + started = true; + } else { + while !started {} + riscv::barrier(); + // printf("hart %d starting\n", cpuid()); + kvminithart(); // turn on paging + trapinithart(); // install kernel trap vector + plicinithart(); // ask PLIC for device interrupts + } + + scheduler(); +} diff --git a/theseus/src/lib.rs b/theseus/src/lib.rs index 59c5e02..359c7a4 100644 --- a/theseus/src/lib.rs +++ b/theseus/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![crate_type = "staticlib"] +pub mod kmain; pub mod memlayout; pub mod param; pub mod riscv; diff --git a/theseus/src/riscv.rs b/theseus/src/riscv.rs index 94994d2..de6377c 100644 --- a/theseus/src/riscv.rs +++ b/theseus/src/riscv.rs @@ -327,3 +327,9 @@ pub fn PX(level: u64, va: u64) -> u64 { // Sv39, to avoid having to sign-extend virtual addresses // that have the high bit set. pub const MAXVA: u64 = 1 << (9 + 9 + 9 + 12 - 1); + +/// Hardware memory barrier +#[inline] +pub unsafe fn barrier() { + asm!("fence") +} diff --git a/theseus/src/start.rs b/theseus/src/start.rs index 9f095d6..4cb49c1 100644 --- a/theseus/src/start.rs +++ b/theseus/src/start.rs @@ -1,6 +1,7 @@ use core::arch::asm; use core::usize; +use crate::kmain::kmain; use crate::memlayout::{CLINT_MTIME, CLINT_MTIMECMP}; use crate::param::NCPU; use crate::riscv as rv; @@ -8,9 +9,6 @@ use crate::riscv as rv; extern "C" { // assembly code in kernelvec.S for machine-mode timer interrupt. fn timervec(); - - // main.c - fn main(); } #[repr(align(16))] @@ -34,7 +32,7 @@ pub unsafe extern "C" fn start() { // set M Exception Program Counter to main, for mret. // requires gcc -mcmodel=medany - rv::w_mepc(main as *const () as u64); + rv::w_mepc(kmain as *const () as u64); // disable paging for now. rv::w_satp(0); From 623c44fcb34a2fd3fe15e4e237e79ea2cbf0dd7c Mon Sep 17 00:00:00 2001 From: hheik <4469778+hheik@users.noreply.github.com> Date: Mon, 6 May 2024 02:25:45 +0300 Subject: [PATCH 2/2] Fixed spinlock halting caused by data misalignment --- kernel/spinlock.c | 6 ------ theseus/src/spinlock.rs | 13 +++++++++++-- theseus/src/uart.rs | 14 ++++++++------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/kernel/spinlock.c b/kernel/spinlock.c index aaf1b09..51252cf 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -8,12 +8,6 @@ #include "proc.h" #include "defs.h" -void initlock(struct spinlock *lk, char *name) { - lk->name = name; - lk->locked = 0; - lk->cpu = 0; -} - // Acquire the lock. // Loops (spins) until the lock is acquired. void acquire(struct spinlock *lk) { diff --git a/theseus/src/spinlock.rs b/theseus/src/spinlock.rs index faeafd0..cfc6ac7 100644 --- a/theseus/src/spinlock.rs +++ b/theseus/src/spinlock.rs @@ -1,9 +1,18 @@ +use core::ptr::null_mut; + // Mutual exclusion lock. #[repr(C)] pub struct SpinLock { // Is the lock held? pub locked: u32, // C boolean // For debugging: - pub name: Option<*mut ()>, // Name of lock. - pub cpu: Option<*mut ()>, // The cpu holding the lock. + pub name: *const u8, // Name of lock. + pub cpu: *mut (), // The cpu holding the lock. +} + +#[no_mangle] +pub unsafe extern "C" fn initlock(lock: *mut SpinLock, name: *const u8) { + (*lock).name = name; + (*lock).locked = 0; + (*lock).cpu = null_mut(); } diff --git a/theseus/src/uart.rs b/theseus/src/uart.rs index 1957f08..1fcbf26 100644 --- a/theseus/src/uart.rs +++ b/theseus/src/uart.rs @@ -1,11 +1,13 @@ -use crate::{memlayout::UART0, spinlock::SpinLock}; -use core::ptr::addr_of_mut; +use crate::{ + memlayout::UART0, + spinlock::{initlock, SpinLock}, +}; +use core::ptr::{addr_of_mut, null, null_mut}; extern "C" { // spinlock.c fn push_off(); fn pop_off(); - fn initlock(spinlock: *mut SpinLock, name: *const u8); fn acquire(spinlock: *mut SpinLock); fn release(spinlock: *mut SpinLock); @@ -60,12 +62,12 @@ pub fn WriteReg(reg: u8, v: u8) { // the transmit output buffer. static mut uart_tx_lock: crate::spinlock::SpinLock = crate::spinlock::SpinLock { locked: 0, - cpu: None, - name: None, + cpu: null_mut(), + name: null(), }; // NOTE: string 'uart\0' for c-implmentation of spinlock. Stupid but works. -static UART_LOCK_NAME: [u8; 5] = [117, 97, 114, 116, 0]; +static UART_LOCK_NAME: [u8; 5] = [0x75, 0x61, 0x72, 0x74, 0]; const UART_TX_BUF_SIZE: usize = 32; static mut uart_tx_buf: [u8; UART_TX_BUF_SIZE] = [0; UART_TX_BUF_SIZE];