Try some filesystems
This commit is contained in:
@@ -6,4 +6,4 @@ build-std = ["core", "compiler_builtins", "alloc"]
|
|||||||
build-std-features = ["compiler-builtins-mem"]
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
|
|
||||||
[target.riscv64]
|
[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
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
|||||||
|
|
||||||
**/target
|
**/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
|
disk.img
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ unsafe extern "C" fn machine_trap_handler(
|
|||||||
c if c == EextensionID::Time as usize => match fid {
|
c if c == EextensionID::Time as usize => match fid {
|
||||||
c if c == TimerFunctionID::SetTimer as usize => {
|
c if c == TimerFunctionID::SetTimer as usize => {
|
||||||
clear_csr!(mip, 1 << 5);
|
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 {
|
match syscall {
|
||||||
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32)),
|
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32)),
|
||||||
SysCall::WriteTemp => {
|
SysCall::WriteTemp => {
|
||||||
info!("{}", unsafe {
|
info!("Print from user space : {}", unsafe {
|
||||||
str::from_raw_parts(a1 as *const u8, a2 as usize)
|
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("a0") 0,
|
||||||
in("a6") TimerFunctionID::SetTimer as u64,
|
in("a6") TimerFunctionID::SetTimer as u64,
|
||||||
in("a7") EextensionID::Time as u64,
|
in("a7") EextensionID::Time as u64,
|
||||||
|
clobber_abi("system")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
timer_interrupt();
|
timer_interrupt();
|
||||||
|
|||||||
15
src/main.rs
15
src/main.rs
@@ -5,7 +5,9 @@
|
|||||||
riscv_ext_intrinsics,
|
riscv_ext_intrinsics,
|
||||||
const_trait_impl,
|
const_trait_impl,
|
||||||
iter_map_windows,
|
iter_map_windows,
|
||||||
str_from_raw_parts
|
str_from_raw_parts,
|
||||||
|
macro_metavar_expr,
|
||||||
|
macro_metavar_expr_concat
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use embedded_alloc::LlffHeap as Heap;
|
use embedded_alloc::LlffHeap as Heap;
|
||||||
@@ -13,15 +15,15 @@ use log::info;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
io::init_log,
|
io::init_log,
|
||||||
process::create_processus,
|
process::create_process,
|
||||||
riscv::enable_supervisor_interrupt,
|
riscv::enable_supervisor_interrupt,
|
||||||
scheduler::{idle, scheduler_init},
|
scheduler::{idle, scheduler_init},
|
||||||
|
tests_fat::MemoryDisk,
|
||||||
user::{proc2, test},
|
user::{proc2, test},
|
||||||
vga::{Color, Vga},
|
vga::{Color, Vga},
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
mod boot;
|
mod boot;
|
||||||
mod critical_section;
|
mod critical_section;
|
||||||
mod interrupt;
|
mod interrupt;
|
||||||
@@ -31,6 +33,7 @@ mod process;
|
|||||||
mod riscv;
|
mod riscv;
|
||||||
mod scheduler;
|
mod scheduler;
|
||||||
mod syscall;
|
mod syscall;
|
||||||
|
mod tests_fat;
|
||||||
mod time;
|
mod time;
|
||||||
mod uart;
|
mod uart;
|
||||||
mod user;
|
mod user;
|
||||||
@@ -56,8 +59,10 @@ pub extern "C" fn supervisor_mode_entry() {
|
|||||||
info!("Hello World !");
|
info!("Hello World !");
|
||||||
unsafe { Vga::draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) };
|
unsafe { Vga::draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) };
|
||||||
|
|
||||||
create_processus(test, "proc1");
|
create_process(test, "proc1");
|
||||||
create_processus(proc2, "proc2");
|
create_process(proc2, "proc2");
|
||||||
|
|
||||||
|
MemoryDisk::new();
|
||||||
|
|
||||||
enable_supervisor_interrupt();
|
enable_supervisor_interrupt();
|
||||||
idle();
|
idle();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use core::{arch::riscv64::wfi, time::Duration};
|
|||||||
use alloc::{format, string::String};
|
use alloc::{format, string::String};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
scheduler::{ACTIVE_PID, PROCESSUS_COUNT, PROCESS_TABLE},
|
scheduler::{ACTIVE_PID, PROCESS_COUNT, PROCESS_TABLE},
|
||||||
time::elapsed_time_since_startup,
|
time::elapsed_time_since_startup,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,6 +35,7 @@ pub struct Process {
|
|||||||
pub pid: i64,
|
pub pid: i64,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub state: ProcessState,
|
pub state: ProcessState,
|
||||||
|
pub entry: Option<fn()>,
|
||||||
pub wake_time: Duration,
|
pub wake_time: Duration,
|
||||||
pub ctx: ExecutionContext,
|
pub ctx: ExecutionContext,
|
||||||
pub stack: [u64; STACK_SIZE],
|
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;
|
let mut next_pid = 0;
|
||||||
while next_pid < PROCESSUS_COUNT
|
while next_pid < PROCESS_COUNT && unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead }
|
||||||
&& unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead }
|
|
||||||
{
|
{
|
||||||
next_pid += 1;
|
next_pid += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if next_pid >= PROCESSUS_COUNT {
|
if next_pid >= PROCESS_COUNT {
|
||||||
return -1;
|
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].pid = next_pid as i64;
|
||||||
PROCESS_TABLE[next_pid].name = name.into();
|
PROCESS_TABLE[next_pid].name = name.into();
|
||||||
PROCESS_TABLE[next_pid].state = ProcessState::Activable;
|
PROCESS_TABLE[next_pid].state = ProcessState::Activable;
|
||||||
PROCESS_TABLE[next_pid].ctx.a[0] = code as usize as u64;
|
PROCESS_TABLE[next_pid].entry = Some(code);
|
||||||
PROCESS_TABLE[next_pid].ctx.mepc = processus_launcher as *const _;
|
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.mstatus = 1 << 1 | 1 << 5;
|
||||||
PROCESS_TABLE[next_pid].ctx.sp = &raw const PROCESS_TABLE[next_pid].stack[STACK_SIZE - 1];
|
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
|
next_pid as i64
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn processus_launcher(code: extern "C" fn()) {
|
extern "C" fn process_launcher(code: *const fn()) {
|
||||||
code();
|
unsafe { (*code)() };
|
||||||
terminate_processus();
|
terminate_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn terminate_processus() {
|
fn terminate_process() {
|
||||||
unsafe {
|
unsafe {
|
||||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Dead;
|
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Dead;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ use alloc::string::String;
|
|||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
process::{create_processus, ExecutionContext, Process, ProcessState},
|
process::{create_process, ExecutionContext, Process, ProcessState},
|
||||||
time,
|
time,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PROCESSUS_COUNT: usize = 16;
|
pub const PROCESS_COUNT: usize = 16;
|
||||||
|
|
||||||
pub static mut ACTIVE_PID: usize = 0;
|
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 {
|
array::from_fn(|_| Process {
|
||||||
pid: -1,
|
pid: -1,
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
@@ -29,10 +29,11 @@ pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESSUS_COUNT]> = LazyCell::n
|
|||||||
mstatus: 0,
|
mstatus: 0,
|
||||||
},
|
},
|
||||||
stack: [0; _],
|
stack: [0; _],
|
||||||
|
entry: None,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
pub extern "C" fn idle() {
|
pub fn idle() {
|
||||||
loop {
|
loop {
|
||||||
// write_string_temp("idle");
|
// write_string_temp("idle");
|
||||||
// info!("idle");
|
// info!("idle");
|
||||||
@@ -44,13 +45,13 @@ pub extern "C" fn idle() {
|
|||||||
|
|
||||||
pub fn scheduler_init() {
|
pub fn scheduler_init() {
|
||||||
info!("scheduler init");
|
info!("scheduler init");
|
||||||
for pid in 0..PROCESSUS_COUNT {
|
for pid in 0..PROCESS_COUNT {
|
||||||
unsafe {
|
unsafe {
|
||||||
PROCESS_TABLE[pid].state = ProcessState::Dead;
|
PROCESS_TABLE[pid].state = ProcessState::Dead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
create_processus(idle, "idle");
|
create_process(idle, "idle");
|
||||||
unsafe {
|
unsafe {
|
||||||
PROCESS_TABLE[0].state = ProcessState::Active;
|
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;
|
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 {
|
if PROCESS_TABLE[ACTIVE_PID].state == ProcessState::Activable {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,27 +20,30 @@ impl From<u64> for SysCall {
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
unsafe fn _syscall(
|
unsafe fn _syscall(
|
||||||
syscall: SysCall,
|
syscall: SysCall,
|
||||||
a1: u64,
|
mut a1: u64,
|
||||||
a2: u64,
|
mut a2: u64,
|
||||||
a3: u64,
|
mut a3: u64,
|
||||||
a4: u64,
|
mut a4: u64,
|
||||||
a5: u64,
|
mut a5: u64,
|
||||||
a6: u64,
|
mut a6: u64,
|
||||||
a7: u64,
|
mut a7: u64,
|
||||||
) {
|
) -> (u64, u64, u64, u64, u64, u64, u64, u64) {
|
||||||
|
let mut a0 = syscall as u64;
|
||||||
unsafe {
|
unsafe {
|
||||||
core::arch::asm!(
|
core::arch::asm!(
|
||||||
"ecall",
|
"ecall",
|
||||||
in("a0") syscall as usize,
|
inlateout("a0") a0,
|
||||||
in("a1") a1,
|
inlateout("a1") a1,
|
||||||
in("a2") a2,
|
inlateout("a2") a2,
|
||||||
in("a3") a3,
|
inlateout("a3") a3,
|
||||||
in("a4") a4,
|
inlateout("a4") a4,
|
||||||
in("a5") a5,
|
inlateout("a5") a5,
|
||||||
in("a6") a6,
|
inlateout("a6") a6,
|
||||||
in("a7") a7,
|
inlateout("a7") a7,
|
||||||
|
clobber_abi("system")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! syscall {
|
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 {
|
unsafe {
|
||||||
syscall!(
|
syscall!(
|
||||||
SysCall::WriteTemp,
|
SysCall::WriteTemp,
|
||||||
|
|||||||
14
src/tests_fat.rs
Normal file
14
src/tests_fat.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,18 +2,16 @@ use core::time::Duration;
|
|||||||
|
|
||||||
use crate::syscall::{sleep, write_string_temp};
|
use crate::syscall::{sleep, write_string_temp};
|
||||||
|
|
||||||
pub extern "C" fn test() {
|
pub fn test() {
|
||||||
loop {
|
loop {
|
||||||
write_string_temp("test");
|
write_string_temp("test");
|
||||||
// enable_supervisor_interrupt();
|
|
||||||
sleep(Duration::new(2, 0));
|
sleep(Duration::new(2, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn proc2() {
|
pub fn proc2() {
|
||||||
loop {
|
loop {
|
||||||
write_string_temp("proc2");
|
write_string_temp("proc2");
|
||||||
// enable_supervisor_interrupt();
|
|
||||||
sleep(Duration::new(3, 0));
|
sleep(Duration::new(3, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user