diff --git a/.cargo/config.toml b/.cargo/config.toml index 171e577..535da60 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,4 +6,4 @@ build-std = ["core", "compiler_builtins", "alloc"] build-std-features = ["compiler-builtins-mem"] [target.riscv64] -runner = "qemu-system-riscv64 -machine virt -device bochs-display -bios none -m 128M -kernel" +runner = "qemu-system-riscv64 -machine virt -device bochs-display -bios none -m 512M -device loader,file=/home/julien/ensimag/TPs/kernel/disk.img,addr=0x90000000 -kernel" diff --git a/.gitignore b/.gitignore index c5e60db..0f27428 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ **/target Cargo.lock + +disk.img diff --git a/src/interrupt.rs b/src/interrupt.rs index 5f05327..b3a12b1 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -47,7 +47,7 @@ unsafe extern "C" fn machine_trap_handler( c if c == EextensionID::Time as usize => match fid { c if c == TimerFunctionID::SetTimer as usize => { clear_csr!(mip, 1 << 5); - setup_next_timer_interrupt(); + // setup_next_timer_interrupt(); } _ => {} }, @@ -104,7 +104,7 @@ unsafe extern "C" fn supervisor_trap_handler( match syscall { SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32)), SysCall::WriteTemp => { - info!("{}", unsafe { + info!("Print from user space : {}", unsafe { str::from_raw_parts(a1 as *const u8, a2 as usize) }) } @@ -130,6 +130,7 @@ unsafe extern "C" fn supervisor_trap_handler( in("a0") 0, in("a6") TimerFunctionID::SetTimer as u64, in("a7") EextensionID::Time as u64, + clobber_abi("system") ); } timer_interrupt(); diff --git a/src/main.rs b/src/main.rs index 0ba881f..5d0abe9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,9 @@ riscv_ext_intrinsics, const_trait_impl, iter_map_windows, - str_from_raw_parts + str_from_raw_parts, + macro_metavar_expr, + macro_metavar_expr_concat )] use embedded_alloc::LlffHeap as Heap; @@ -13,15 +15,15 @@ use log::info; use crate::{ io::init_log, - process::create_processus, + process::create_process, riscv::enable_supervisor_interrupt, scheduler::{idle, scheduler_init}, + tests_fat::MemoryDisk, user::{proc2, test}, vga::{Color, Vga}, }; extern crate alloc; - mod boot; mod critical_section; mod interrupt; @@ -31,6 +33,7 @@ mod process; mod riscv; mod scheduler; mod syscall; +mod tests_fat; mod time; mod uart; mod user; @@ -56,8 +59,10 @@ pub extern "C" fn supervisor_mode_entry() { info!("Hello World !"); unsafe { Vga::draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) }; - create_processus(test, "proc1"); - create_processus(proc2, "proc2"); + create_process(test, "proc1"); + create_process(proc2, "proc2"); + + MemoryDisk::new(); enable_supervisor_interrupt(); idle(); diff --git a/src/process.rs b/src/process.rs index 27ffe88..5d6d0e8 100644 --- a/src/process.rs +++ b/src/process.rs @@ -3,7 +3,7 @@ use core::{arch::riscv64::wfi, time::Duration}; use alloc::{format, string::String}; use crate::{ - scheduler::{ACTIVE_PID, PROCESSUS_COUNT, PROCESS_TABLE}, + scheduler::{ACTIVE_PID, PROCESS_COUNT, PROCESS_TABLE}, time::elapsed_time_since_startup, }; @@ -35,6 +35,7 @@ pub struct Process { pub pid: i64, pub name: String, pub state: ProcessState, + pub entry: Option, pub wake_time: Duration, pub ctx: ExecutionContext, pub stack: [u64; STACK_SIZE], @@ -53,15 +54,14 @@ impl core::fmt::Debug for Process { } } -pub fn create_processus>(code: extern "C" fn(), name: T) -> i64 { +pub fn create_process>(code: fn(), name: T) -> i64 { let mut next_pid = 0; - while next_pid < PROCESSUS_COUNT - && unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead } + while next_pid < PROCESS_COUNT && unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead } { next_pid += 1; } - if next_pid >= PROCESSUS_COUNT { + if next_pid >= PROCESS_COUNT { return -1; } @@ -69,8 +69,10 @@ pub fn create_processus>(code: extern "C" fn(), name: T) -> i64 PROCESS_TABLE[next_pid].pid = next_pid as i64; PROCESS_TABLE[next_pid].name = name.into(); PROCESS_TABLE[next_pid].state = ProcessState::Activable; - PROCESS_TABLE[next_pid].ctx.a[0] = code as usize as u64; - PROCESS_TABLE[next_pid].ctx.mepc = processus_launcher as *const _; + PROCESS_TABLE[next_pid].entry = Some(code); + PROCESS_TABLE[next_pid].ctx.a[0] = + PROCESS_TABLE[next_pid].entry.as_ref().unwrap_unchecked() as *const fn() as u64; + PROCESS_TABLE[next_pid].ctx.mepc = process_launcher as *const _; PROCESS_TABLE[next_pid].ctx.mstatus = 1 << 1 | 1 << 5; PROCESS_TABLE[next_pid].ctx.sp = &raw const PROCESS_TABLE[next_pid].stack[STACK_SIZE - 1]; } @@ -78,12 +80,12 @@ pub fn create_processus>(code: extern "C" fn(), name: T) -> i64 next_pid as i64 } -extern "C" fn processus_launcher(code: extern "C" fn()) { - code(); - terminate_processus(); +extern "C" fn process_launcher(code: *const fn()) { + unsafe { (*code)() }; + terminate_process(); } -fn terminate_processus() { +fn terminate_process() { unsafe { PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Dead; } diff --git a/src/scheduler.rs b/src/scheduler.rs index 05c5f0d..66d8725 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -4,14 +4,14 @@ use alloc::string::String; use log::info; use crate::{ - process::{create_processus, ExecutionContext, Process, ProcessState}, + process::{create_process, ExecutionContext, Process, ProcessState}, time, }; -pub const PROCESSUS_COUNT: usize = 16; +pub const PROCESS_COUNT: usize = 16; pub static mut ACTIVE_PID: usize = 0; -pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESSUS_COUNT]> = LazyCell::new(|| { +pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESS_COUNT]> = LazyCell::new(|| { array::from_fn(|_| Process { pid: -1, name: String::new(), @@ -29,10 +29,11 @@ pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESSUS_COUNT]> = LazyCell::n mstatus: 0, }, stack: [0; _], + entry: None, }) }); -pub extern "C" fn idle() { +pub fn idle() { loop { // write_string_temp("idle"); // info!("idle"); @@ -44,13 +45,13 @@ pub extern "C" fn idle() { pub fn scheduler_init() { info!("scheduler init"); - for pid in 0..PROCESSUS_COUNT { + for pid in 0..PROCESS_COUNT { unsafe { PROCESS_TABLE[pid].state = ProcessState::Dead; } } - create_processus(idle, "idle"); + create_process(idle, "idle"); unsafe { PROCESS_TABLE[0].state = ProcessState::Active; } @@ -72,7 +73,7 @@ pub fn scheduler(interrupt_state: ExecutionContext) -> *const ExecutionContext { { PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Activable; } - ACTIVE_PID = (ACTIVE_PID + 1) % PROCESSUS_COUNT; + ACTIVE_PID = (ACTIVE_PID + 1) % PROCESS_COUNT; if PROCESS_TABLE[ACTIVE_PID].state == ProcessState::Activable { break; } diff --git a/src/syscall.rs b/src/syscall.rs index 44e6936..aed5995 100644 --- a/src/syscall.rs +++ b/src/syscall.rs @@ -20,27 +20,30 @@ impl From for SysCall { #[allow(clippy::too_many_arguments)] unsafe fn _syscall( syscall: SysCall, - a1: u64, - a2: u64, - a3: u64, - a4: u64, - a5: u64, - a6: u64, - a7: u64, -) { + mut a1: u64, + mut a2: u64, + mut a3: u64, + mut a4: u64, + mut a5: u64, + mut a6: u64, + mut a7: u64, +) -> (u64, u64, u64, u64, u64, u64, u64, u64) { + let mut a0 = syscall as u64; unsafe { core::arch::asm!( "ecall", - in("a0") syscall as usize, - in("a1") a1, - in("a2") a2, - in("a3") a3, - in("a4") a4, - in("a5") a5, - in("a6") a6, - in("a7") a7, + inlateout("a0") a0, + inlateout("a1") a1, + inlateout("a2") a2, + inlateout("a3") a3, + inlateout("a4") a4, + inlateout("a5") a5, + inlateout("a6") a6, + inlateout("a7") a7, + clobber_abi("system") ); } + (a0, a1, a2, a3, a4, a5, a6, a7) } macro_rules! syscall { @@ -77,7 +80,7 @@ pub fn sleep(duration: Duration) { } } -pub fn write_string_temp(content: &str) { +pub fn write_string_temp(content: &'static str) { unsafe { syscall!( SysCall::WriteTemp, diff --git a/src/tests_fat.rs b/src/tests_fat.rs new file mode 100644 index 0000000..4f87839 --- /dev/null +++ b/src/tests_fat.rs @@ -0,0 +1,14 @@ +use core::str; +use log::info; + +const DISK_ADDR: usize = 0x9000_0000; +const DISK_SIZE: usize = 16 * 1024 * 1024; // 16MB + +pub struct MemoryDisk {} + +impl MemoryDisk { + pub fn new() { + let test = unsafe { str::from_raw_parts(DISK_ADDR as *const u8, 13) }; + info!("{}", test); + } +} diff --git a/src/user.rs b/src/user.rs index 5082b30..b3579f2 100644 --- a/src/user.rs +++ b/src/user.rs @@ -2,18 +2,16 @@ use core::time::Duration; use crate::syscall::{sleep, write_string_temp}; -pub extern "C" fn test() { +pub fn test() { loop { write_string_temp("test"); - // enable_supervisor_interrupt(); sleep(Duration::new(2, 0)); } } -pub extern "C" fn proc2() { +pub fn proc2() { loop { write_string_temp("proc2"); - // enable_supervisor_interrupt(); sleep(Duration::new(3, 0)); } }