Try some filesystems

This commit is contained in:
2026-02-13 15:52:43 +01:00
parent 369ff5fef4
commit a53e11d6dd
9 changed files with 73 additions and 47 deletions

View File

@@ -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"

2
.gitignore vendored
View File

@@ -2,3 +2,5 @@
**/target
Cargo.lock
disk.img

View File

@@ -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();

View File

@@ -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();

View File

@@ -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<fn()>,
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<T: Into<String>>(code: extern "C" fn(), name: T) -> i64 {
pub fn create_process<T: Into<String>>(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<T: Into<String>>(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<T: Into<String>>(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;
}

View File

@@ -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;
}

View File

@@ -20,27 +20,30 @@ impl From<u64> 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,

14
src/tests_fat.rs Normal file
View File

@@ -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);
}
}

View File

@@ -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));
}
}