Better user programs with a special std. Sleep and exit are calling scheduler instead of wfi.
This commit is contained in:
@@ -6,4 +6,7 @@ build-std = ["core", "compiler_builtins", "alloc"]
|
||||
build-std-features = ["compiler-builtins-mem"]
|
||||
|
||||
[target.riscv64]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tilm.ld",
|
||||
]
|
||||
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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["user/*"]
|
||||
members = ["crates/os-std", "crates/shared", "user/*"]
|
||||
|
||||
[package]
|
||||
name = "kernel-rust"
|
||||
@@ -13,3 +13,4 @@ kernel-macros = { path = "crates/kernel-macros" }
|
||||
log = "0.4"
|
||||
critical-section = { version = "1", features = ["restore-state-bool"] }
|
||||
bffs = { path = "../../../code/bffs", features = ["alloc"] }
|
||||
shared = { path = "crates/shared" }
|
||||
|
||||
12
crates/os-std-macros/Cargo.toml
Normal file
12
crates/os-std-macros/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "os-std-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2", features = ["full"] }
|
||||
1
crates/os-std-macros/src/lib.rs
Normal file
1
crates/os-std-macros/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
8
crates/os-std/Cargo.toml
Normal file
8
crates/os-std/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "os-std"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
os-std-macros = { path = "../os-std-macros" }
|
||||
shared = { path = "../shared" }
|
||||
21
crates/os-std/src/lib.rs
Normal file
21
crates/os-std/src/lib.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
#![no_std]
|
||||
|
||||
mod prelude;
|
||||
|
||||
pub use shared::syscall;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! custom_std_setup {
|
||||
() => {
|
||||
#[panic_handler]
|
||||
fn panic(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
// TODO print
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn _start() {
|
||||
main()
|
||||
}
|
||||
};
|
||||
}
|
||||
1
crates/os-std/src/prelude.rs
Normal file
1
crates/os-std/src/prelude.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
6
crates/shared/Cargo.toml
Normal file
6
crates/shared/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "shared"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
3
crates/shared/src/lib.rs
Normal file
3
crates/shared/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
#![no_std]
|
||||
|
||||
pub mod syscall;
|
||||
@@ -2,6 +2,7 @@ use core::time::Duration;
|
||||
|
||||
#[repr(u64)]
|
||||
pub enum SysCall {
|
||||
Exit = 60,
|
||||
NanoSleep = 101,
|
||||
WriteIntTemp = 998,
|
||||
WriteTemp = 999,
|
||||
@@ -11,6 +12,7 @@ pub enum SysCall {
|
||||
impl From<u64> for SysCall {
|
||||
fn from(value: u64) -> Self {
|
||||
match value {
|
||||
60 => SysCall::Exit,
|
||||
101 => SysCall::NanoSleep,
|
||||
998 => SysCall::WriteIntTemp,
|
||||
999 => SysCall::WriteTemp,
|
||||
@@ -75,6 +77,12 @@ macro_rules! syscall {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn exit() {
|
||||
unsafe {
|
||||
syscall!(SysCall::Exit);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sleep(duration: Duration) {
|
||||
unsafe {
|
||||
let (duration_secs, duration_nanos) = (duration.as_secs(), duration.subsec_nanos() as u64);
|
||||
5
ilm.ld
5
ilm.ld
@@ -2,17 +2,16 @@
|
||||
* ld directives the for barmetal RISCV
|
||||
*/
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(entry)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
RAM (wxa) : ORIGIN = 0x80000000, LENGTH = 128M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
/* The kernel starts at 0x80000000 */
|
||||
. = 0x80000000;
|
||||
.text : {
|
||||
KEEP(*(.text.entry))
|
||||
KEEP(*(.text._start))
|
||||
|
||||
*(.text .text.*)
|
||||
} > RAM
|
||||
|
||||
19
justfile
19
justfile
@@ -3,16 +3,23 @@ cargo_flags := if release != "" { "--release" } else { "" }
|
||||
|
||||
default: run
|
||||
|
||||
build_user_prog prog:
|
||||
cd {{ "user" / prog }} && \
|
||||
RUSTFLAGS="-C relocation-model=pic" cargo b {{ cargo_flags }}
|
||||
riscv64-elf-objcopy -O binary {{ "target/riscv64/debug" / prog }} {{ "user" / prog / prog + ".mem" }}
|
||||
mount_filesystem:
|
||||
# Add some permissions to be able to do next operations without sudo
|
||||
@mountpoint -q mnt || sudo mount -o umask=0022,gid=$(id -g $USER),uid=$(id -u $USER) disk.img mnt
|
||||
|
||||
build: (map_dir "user" "build_user_prog")
|
||||
sync_filesystem:
|
||||
sync
|
||||
|
||||
build_user_prog prog:
|
||||
RUSTFLAGS="-C relocation-model=pic -C link-arg=-Tilm.ld" cargo b {{ cargo_flags }} --package {{ prog }}
|
||||
riscv64-elf-objcopy -O binary {{ "target/riscv64/debug" / prog }} {{ "mnt/usr/bin" / prog }}
|
||||
|
||||
build: mount_filesystem (map_dir "user" "build_user_prog")
|
||||
cargo b {{ cargo_flags }}
|
||||
just sync_filesystem
|
||||
|
||||
run: build
|
||||
cargo r {{ cargo_flags }} --bin kernel-rust
|
||||
cargo r {{ cargo_flags }}
|
||||
|
||||
map_dir dir recipe:
|
||||
@for file in `ls {{ dir }}`; do \
|
||||
|
||||
@@ -10,7 +10,7 @@ pub mod sbi;
|
||||
|
||||
#[unsafe(naked)]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn entry() {
|
||||
pub extern "C" fn _start() {
|
||||
naked_asm!(
|
||||
"
|
||||
la sp, _heap_end
|
||||
|
||||
28
src/fs.rs
28
src/fs.rs
@@ -1,7 +1,33 @@
|
||||
use bffs::io::{IoBase, Read, Seek};
|
||||
use core::{cell::UnsafeCell, ops::Deref};
|
||||
|
||||
use bffs::{
|
||||
io::{IoBase, Read, Seek},
|
||||
Fat32FileSystem,
|
||||
};
|
||||
|
||||
const DISK_ADDR: *const u8 = 0x9000_0000 as *const _;
|
||||
|
||||
pub struct FSTemp(UnsafeCell<Option<Fat32FileSystem<Disk>>>);
|
||||
unsafe impl Sync for FSTemp {}
|
||||
|
||||
impl FSTemp {
|
||||
pub unsafe fn init(&self) {
|
||||
unsafe {
|
||||
*self.0.get() = Some(Fat32FileSystem::new(Disk::new(1024 * 1024 * 16)).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FSTemp {
|
||||
type Target = Fat32FileSystem<Disk>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { (&*self.0.get()).as_ref().unwrap_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
pub static FILE_SYSTEM: FSTemp = FSTemp(UnsafeCell::new(None));
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Disk {
|
||||
pos: u64,
|
||||
|
||||
228
src/interrupt.rs
228
src/interrupt.rs
@@ -1,15 +1,15 @@
|
||||
use alloc::str;
|
||||
use log::info;
|
||||
use shared::syscall::SysCall;
|
||||
|
||||
use crate::{
|
||||
boot::sbi::{EextensionID, TimerFunctionID},
|
||||
clear_csr, generate_trap_handler,
|
||||
process::{sleep, ExecutionContext},
|
||||
clear_csr,
|
||||
process::{exit_process, sleep, ExecutionContext},
|
||||
read_csr,
|
||||
riscv::disable_interrupt,
|
||||
scheduler::scheduler,
|
||||
scheduler::scheduler_without_ret,
|
||||
set_csr,
|
||||
syscall::SysCall,
|
||||
time::{setup_next_timer_interrupt, IRQ_M_TIMER},
|
||||
write_csr,
|
||||
};
|
||||
@@ -87,7 +87,7 @@ unsafe extern "C" fn machine_trap_handler(
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn supervisor_trap_handler(
|
||||
interrupt_state: *mut ExecutionContext,
|
||||
mut interrupt_state: *mut ExecutionContext,
|
||||
scause: u64,
|
||||
_sie: u64,
|
||||
_sip: u64,
|
||||
@@ -96,13 +96,19 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
#[allow(clippy::single_match)]
|
||||
match scause & !(1 << 63) {
|
||||
8 => {
|
||||
// Advance sepc to exit the ecall
|
||||
unsafe {
|
||||
(*interrupt_state).mepc = (*interrupt_state).mepc.byte_add(4);
|
||||
}
|
||||
|
||||
// Environment call from S-mode
|
||||
let syscall_u64: u64 = unsafe { (*interrupt_state).a[0] };
|
||||
let a1: u64 = unsafe { (*interrupt_state).a[1] };
|
||||
let a2: u64 = unsafe { (*interrupt_state).a[2] };
|
||||
let syscall: SysCall = syscall_u64.into();
|
||||
match syscall {
|
||||
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32)),
|
||||
SysCall::Exit => exit_process(&mut interrupt_state),
|
||||
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32), &mut interrupt_state),
|
||||
SysCall::WriteTemp => {
|
||||
info!("Print from user space : {}", unsafe {
|
||||
str::from_raw_parts(a1 as *const u8, a2 as usize)
|
||||
@@ -115,11 +121,6 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
unimplemented!("Syscall {syscall_u64} is not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
// Advance sepc to exit the ecall
|
||||
unsafe {
|
||||
(*interrupt_state).mepc = (*interrupt_state).mepc.byte_add(4);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -137,7 +138,7 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
);
|
||||
}
|
||||
timer_interrupt();
|
||||
return scheduler(unsafe { *interrupt_state });
|
||||
scheduler_without_ret(&mut interrupt_state);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -207,116 +208,107 @@ unsafe extern "C" fn _machine_mode_trap() {
|
||||
mret"
|
||||
)
|
||||
}
|
||||
generate_trap_handler! {
|
||||
_supervisor_mode_trap, supervisor_trap_handler, s
|
||||
#[unsafe(naked)]
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn _supervisor_mode_trap() {
|
||||
naked_asm!(concat!(
|
||||
"
|
||||
// Store sp before it gets modified
|
||||
sd sp, 8-264(sp)
|
||||
addi sp, sp, -264
|
||||
|
||||
# Store the current frame
|
||||
sd ra, 0(sp)
|
||||
// sp
|
||||
sd gp, 16(sp)
|
||||
sd tp, 24(sp)
|
||||
sd a0, 32(sp)
|
||||
sd a1, 40(sp)
|
||||
sd a2, 48(sp)
|
||||
sd a3, 56(sp)
|
||||
sd a4, 64(sp)
|
||||
sd a5, 72(sp)
|
||||
sd a6, 80(sp)
|
||||
sd a7, 88(sp)
|
||||
sd t0, 96(sp)
|
||||
sd t1, 104(sp)
|
||||
sd t2, 112(sp)
|
||||
sd t3, 120(sp)
|
||||
sd t4, 128(sp)
|
||||
sd t5, 136(sp)
|
||||
sd t6, 144(sp)
|
||||
sd s0, 152(sp)
|
||||
sd s1, 160(sp)
|
||||
sd s2, 168(sp)
|
||||
sd s3, 176(sp)
|
||||
sd s4, 184(sp)
|
||||
sd s5, 192(sp)
|
||||
sd s6, 200(sp)
|
||||
sd s7, 208(sp)
|
||||
sd s8, 216(sp)
|
||||
sd s9, 224(sp)
|
||||
sd s10, 232(sp)
|
||||
sd s11, 240(sp)
|
||||
csrr t0, sepc
|
||||
sd t0, 248(sp)
|
||||
csrr t0, sstatus
|
||||
sd t0, 256(sp)
|
||||
|
||||
mv a0, sp
|
||||
csrr a1, scause
|
||||
csrr a2, sie
|
||||
csrr a3, sip
|
||||
jal supervisor_trap_handler
|
||||
|
||||
# Restore registers and sret
|
||||
jal restore_context"
|
||||
))
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! generate_trap_handler {
|
||||
($name:ident, $jump_to:ident, $mode:ident) => {
|
||||
#[unsafe(naked)]
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn $name() {
|
||||
naked_asm!(concat!(
|
||||
"
|
||||
mv t0, sp
|
||||
addi sp, sp, -264
|
||||
#[unsafe(naked)]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn restore_context(context: *const ExecutionContext) -> ! {
|
||||
naked_asm!(concat!(
|
||||
"
|
||||
ld t0, 248(a0)
|
||||
csrw sepc, t0
|
||||
ld t0, 256(a0)
|
||||
csrw sstatus, t0
|
||||
ld ra, 0(a0)
|
||||
ld sp, 8(a0)
|
||||
ld gp, 16(a0)
|
||||
ld tp, 24(a0)
|
||||
ld a1, 40(a0)
|
||||
ld a2, 48(a0)
|
||||
ld a3, 56(a0)
|
||||
ld a4, 64(a0)
|
||||
ld a5, 72(a0)
|
||||
ld a6, 80(a0)
|
||||
ld a7, 88(a0)
|
||||
ld t0, 96(a0)
|
||||
ld t1, 104(a0)
|
||||
ld t2, 112(a0)
|
||||
ld t3, 120(a0)
|
||||
ld t4, 128(a0)
|
||||
ld t5, 136(a0)
|
||||
ld t6, 144(a0)
|
||||
ld s0, 152(a0)
|
||||
ld s1, 160(a0)
|
||||
ld s2, 168(a0)
|
||||
ld s3, 176(a0)
|
||||
ld s4, 184(a0)
|
||||
ld s5, 192(a0)
|
||||
ld s6, 200(a0)
|
||||
ld s7, 208(a0)
|
||||
ld s8, 216(a0)
|
||||
ld s9, 224(a0)
|
||||
ld s10, 232(a0)
|
||||
ld s11, 240(a0)
|
||||
|
||||
# Store the current frame
|
||||
sd ra, 0(sp)
|
||||
sd t0, 8(sp) // sp
|
||||
sd gp, 16(sp)
|
||||
sd tp, 24(sp)
|
||||
sd a0, 32(sp)
|
||||
sd a1, 40(sp)
|
||||
sd a2, 48(sp)
|
||||
sd a3, 56(sp)
|
||||
sd a4, 64(sp)
|
||||
sd a5, 72(sp)
|
||||
sd a6, 80(sp)
|
||||
sd a7, 88(sp)
|
||||
sd t0, 96(sp)
|
||||
sd t1, 104(sp)
|
||||
sd t2, 112(sp)
|
||||
sd t3, 120(sp)
|
||||
sd t4, 128(sp)
|
||||
sd t5, 136(sp)
|
||||
sd t6, 144(sp)
|
||||
sd s0, 152(sp)
|
||||
sd s1, 160(sp)
|
||||
sd s2, 168(sp)
|
||||
sd s3, 176(sp)
|
||||
sd s4, 184(sp)
|
||||
sd s5, 192(sp)
|
||||
sd s6, 200(sp)
|
||||
sd s7, 208(sp)
|
||||
sd s8, 216(sp)
|
||||
sd s9, 224(sp)
|
||||
sd s10, 232(sp)
|
||||
sd s11, 240(sp)
|
||||
csrr t0, sepc
|
||||
sd t0, 248(sp)
|
||||
csrr t0, sstatus
|
||||
sd t0, 256(sp)
|
||||
ld a0, 32(a0)
|
||||
|
||||
mv a0, sp
|
||||
csrr a1, ",
|
||||
stringify!($mode),
|
||||
"cause
|
||||
csrr a2, ",
|
||||
stringify!($mode),
|
||||
"ie
|
||||
csrr a3, ",
|
||||
stringify!($mode),
|
||||
"ip
|
||||
jal ",
|
||||
stringify!($jump_to),
|
||||
"
|
||||
|
||||
# Restore registers
|
||||
ld t0, 248(a0)
|
||||
csrw sepc, t0
|
||||
ld t0, 256(a0)
|
||||
csrw sstatus, t0
|
||||
ld ra, 0(a0)
|
||||
ld sp, 8(a0)
|
||||
ld gp, 16(a0)
|
||||
ld tp, 24(a0)
|
||||
ld a1, 40(a0)
|
||||
ld a2, 48(a0)
|
||||
ld a3, 56(a0)
|
||||
ld a4, 64(a0)
|
||||
ld a5, 72(a0)
|
||||
ld a6, 80(a0)
|
||||
ld a7, 88(a0)
|
||||
ld t0, 96(a0)
|
||||
ld t1, 104(a0)
|
||||
ld t2, 112(a0)
|
||||
ld t3, 120(a0)
|
||||
ld t4, 128(a0)
|
||||
ld t5, 136(a0)
|
||||
ld t6, 144(a0)
|
||||
ld s0, 152(a0)
|
||||
ld s1, 160(a0)
|
||||
ld s2, 168(a0)
|
||||
ld s3, 176(a0)
|
||||
ld s4, 184(a0)
|
||||
ld s5, 192(a0)
|
||||
ld s6, 200(a0)
|
||||
ld s7, 208(a0)
|
||||
ld s8, 216(a0)
|
||||
ld s9, 224(a0)
|
||||
ld s10, 232(a0)
|
||||
ld s11, 240(a0)
|
||||
|
||||
ld a0, 32(a0)
|
||||
|
||||
",
|
||||
stringify!($mode),
|
||||
"ret"
|
||||
))
|
||||
}
|
||||
};
|
||||
sret"
|
||||
))
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@@ -7,7 +7,7 @@ use log::{LevelFilter, SetLoggerError};
|
||||
|
||||
use crate::uart::write_uart;
|
||||
|
||||
fn print(content: String) {
|
||||
pub(crate) fn print(content: String) {
|
||||
write_uart(content);
|
||||
}
|
||||
|
||||
|
||||
23
src/main.rs
23
src/main.rs
@@ -10,18 +10,15 @@
|
||||
macro_metavar_expr_concat
|
||||
)]
|
||||
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use bffs::{io::Read, Fat32FileSystem};
|
||||
use embedded_alloc::LlffHeap as Heap;
|
||||
use log::info;
|
||||
|
||||
use crate::{
|
||||
fs::Disk,
|
||||
fs::FILE_SYSTEM,
|
||||
io::init_log,
|
||||
process::create_process,
|
||||
process::{create_process, create_process_from_file},
|
||||
riscv::enable_supervisor_interrupt,
|
||||
scheduler::{idle, scheduler_init},
|
||||
tests_fat::MemoryDisk,
|
||||
user::{proc2, test},
|
||||
vga::{Color, Vga},
|
||||
};
|
||||
@@ -36,14 +33,12 @@ mod panic_handler;
|
||||
mod process;
|
||||
mod riscv;
|
||||
mod scheduler;
|
||||
mod syscall;
|
||||
mod tests_fat;
|
||||
mod time;
|
||||
mod uart;
|
||||
mod user;
|
||||
mod vga;
|
||||
|
||||
pub const HEAP_SIZE: usize = 40960;
|
||||
pub const HEAP_SIZE: usize = 1024 * 1024; // 1Mo RAM
|
||||
#[global_allocator]
|
||||
static HEAP: Heap = Heap::empty();
|
||||
|
||||
@@ -56,6 +51,7 @@ pub extern "C" fn supervisor_mode_entry() {
|
||||
embedded_alloc::init!(HEAP, HEAP_SIZE);
|
||||
init_log().unwrap();
|
||||
Vga::init();
|
||||
FILE_SYSTEM.init();
|
||||
scheduler_init();
|
||||
}
|
||||
|
||||
@@ -65,16 +61,7 @@ pub extern "C" fn supervisor_mode_entry() {
|
||||
create_process(&test, "proc1");
|
||||
create_process(&proc2, "proc2");
|
||||
|
||||
let fs = Fat32FileSystem::new(Disk::new(1024 * 1024 * 16)).unwrap();
|
||||
let mut bin = fs.open_file("/usr/bin/test").unwrap();
|
||||
let mut content: Vec<u8> = Vec::new();
|
||||
bin.read_to_end(&mut content).unwrap();
|
||||
let test = unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(content.as_ptr()) };
|
||||
|
||||
let test = Box::leak(Box::new(move || {
|
||||
test();
|
||||
}));
|
||||
create_process(test, "dyn_proc");
|
||||
create_process_from_file("/usr/bin/test_pic");
|
||||
|
||||
enable_supervisor_interrupt();
|
||||
idle();
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use core::{arch::riscv64::wfi, time::Duration};
|
||||
use core::time::Duration;
|
||||
|
||||
use alloc::{format, string::String};
|
||||
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
||||
use bffs::{io::Read, path::Path};
|
||||
use shared::syscall::exit;
|
||||
|
||||
use crate::{
|
||||
scheduler::{ACTIVE_PID, PROCESS_COUNT, PROCESS_TABLE},
|
||||
fs::FILE_SYSTEM,
|
||||
scheduler::{scheduler_without_ret, ACTIVE_PID, PROCESS_COUNT, PROCESS_TABLE},
|
||||
time::elapsed_time_since_startup,
|
||||
};
|
||||
|
||||
@@ -54,6 +57,21 @@ impl core::fmt::Debug for Process {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_process_from_file<'a, T: Into<Path<'a>>>(path: T) -> i64 {
|
||||
let path = path.into();
|
||||
let name = path.as_str();
|
||||
let mut bin = FILE_SYSTEM.open_file(path).unwrap();
|
||||
let mut content: Vec<u8> = Vec::new();
|
||||
bin.read_to_end(&mut content).unwrap();
|
||||
let test =
|
||||
unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(Vec::leak(content).as_ptr()) };
|
||||
|
||||
let test = Box::leak(Box::new(move || {
|
||||
test();
|
||||
}));
|
||||
create_process(test, name)
|
||||
}
|
||||
|
||||
pub fn create_process<T: Into<String>, F: Fn()>(code: &'static F, name: T) -> i64 {
|
||||
let mut next_pid = 0;
|
||||
while next_pid < PROCESS_COUNT && unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead }
|
||||
@@ -82,27 +100,21 @@ pub fn create_process<T: Into<String>, F: Fn()>(code: &'static F, name: T) -> i6
|
||||
|
||||
extern "C" fn process_launcher(code: *const &dyn Fn()) {
|
||||
unsafe { (*code)() };
|
||||
terminate_process();
|
||||
// User code didn't exit before the end of its execution, so we call the exit syscall ourselves
|
||||
exit();
|
||||
}
|
||||
|
||||
fn terminate_process() {
|
||||
pub fn exit_process(interrupt_context: &mut *mut ExecutionContext) {
|
||||
unsafe {
|
||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Dead;
|
||||
}
|
||||
loop {}
|
||||
// unsafe {
|
||||
// wfi();
|
||||
// }
|
||||
// scheduler();
|
||||
scheduler_without_ret(interrupt_context)
|
||||
}
|
||||
|
||||
pub fn sleep(duration: Duration) {
|
||||
pub fn sleep(duration: Duration, interrupt_context: &mut *mut ExecutionContext) {
|
||||
unsafe {
|
||||
PROCESS_TABLE[ACTIVE_PID].wake_time = elapsed_time_since_startup() + duration;
|
||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Asleep;
|
||||
}
|
||||
unsafe {
|
||||
wfi();
|
||||
}
|
||||
// scheduler();
|
||||
scheduler_without_ret(interrupt_context)
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ pub fn scheduler_init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scheduler(interrupt_state: ExecutionContext) -> *const ExecutionContext {
|
||||
pub fn scheduler_without_ret(interrupt_state: &mut *mut ExecutionContext) {
|
||||
// info!("scheduler");
|
||||
unsafe {
|
||||
let prev_pid = ACTIVE_PID;
|
||||
PROCESS_TABLE[prev_pid].ctx = interrupt_state;
|
||||
PROCESS_TABLE[prev_pid].ctx = **interrupt_state;
|
||||
|
||||
if PROCESS_TABLE[prev_pid].state == ProcessState::Active {
|
||||
PROCESS_TABLE[prev_pid].state = ProcessState::Activable;
|
||||
@@ -80,6 +80,6 @@ pub fn scheduler(interrupt_state: ExecutionContext) -> *const ExecutionContext {
|
||||
}
|
||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Active;
|
||||
|
||||
&raw const PROCESS_TABLE[ACTIVE_PID].ctx
|
||||
*interrupt_state = &raw mut PROCESS_TABLE[ACTIVE_PID].ctx
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
use core::str;
|
||||
use log::info;
|
||||
|
||||
const DISK_ADDR: usize = 0x9000_0000;
|
||||
|
||||
pub struct MemoryDisk {}
|
||||
|
||||
impl MemoryDisk {
|
||||
pub fn test() {
|
||||
let test = unsafe { str::from_raw_parts(DISK_ADDR as *const u8, 13) };
|
||||
info!("{}", test);
|
||||
}
|
||||
}
|
||||
10
src/user.rs
10
src/user.rs
@@ -1,15 +1,9 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use bffs::{io::Read, Fat32FileSystem};
|
||||
|
||||
use crate::{
|
||||
fs::Disk,
|
||||
syscall::{sleep, write_int_temp, write_string_temp},
|
||||
};
|
||||
use shared::syscall::{sleep, write_int_temp, write_string_temp};
|
||||
|
||||
#[repr(align(32))]
|
||||
struct Alignement([u8; 157]);
|
||||
struct Alignement([u8; include_bytes!("../user/test_pic/test_pic.mem").len()]);
|
||||
|
||||
static PROG: Alignement = Alignement(*include_bytes!("../user/test_pic/test_pic.mem"));
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
os-std = { path = "../../crates/os-std" }
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
println!("cargo::rustc-link-arg=-Tilm.ld");
|
||||
}
|
||||
@@ -1,21 +1,11 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
os_std::custom_std_setup! {}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
use os_std::syscall::write_string_temp;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn entry() {
|
||||
let test = "Hello from PIC program loaded dynamically";
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"ecall",
|
||||
in("a0") 999,
|
||||
in("a1") test.as_ptr(),
|
||||
in("a2") test.len(),
|
||||
clobber_abi("system")
|
||||
);
|
||||
}
|
||||
fn main() {
|
||||
write_string_temp(
|
||||
"Hello from PIC program loaded dynamically with custom std and a better justfile, and syscalls !",
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user