Try some filesystems
This commit is contained in:
@@ -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
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
||||
|
||||
**/target
|
||||
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 == 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();
|
||||
|
||||
15
src/main.rs
15
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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
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};
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user