From 9f10ec36b3280f5620d4c4abd8a92e0368e7a63b Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Sat, 21 Oct 2023 23:24:33 -0600 Subject: [PATCH] move things around --- kernel/defs.h | 2 +- kernel/log.c | 4 +- kernel/pipe.c | 4 +- kernel/proc.c | 4 +- .../src/{console.rs => console/mod.rs} | 7 +- kernel/rustkernel/src/{ => console}/printf.rs | 6 +- kernel/rustkernel/src/{ => console}/uart.rs | 0 kernel/rustkernel/src/{ => fs}/file.rs | 3 +- kernel/rustkernel/src/{fs.rs => fs/mod.rs} | 8 ++ kernel/rustkernel/src/fs/ramdisk.rs | 8 ++ kernel/rustkernel/src/{ => fs}/virtio_disk.rs | 2 +- kernel/rustkernel/src/{ => io}/bio.rs | 2 +- kernel/rustkernel/src/{ => io}/buf.rs | 0 kernel/rustkernel/src/io/mod.rs | 3 + kernel/rustkernel/src/{ => io}/pipe.rs | 0 kernel/rustkernel/src/lib.rs | 93 ++++++++++--------- kernel/rustkernel/src/{ => mem}/kalloc.rs | 2 +- kernel/rustkernel/src/mem/mod.rs | 56 +++++++++++ kernel/rustkernel/src/mem/virtual_memory.rs | 4 + kernel/rustkernel/src/param.rs | 26 ------ kernel/rustkernel/src/proc.rs | 9 +- kernel/rustkernel/src/ramdisk.rs | 8 -- kernel/rustkernel/src/start.rs | 2 +- kernel/rustkernel/src/string.rs | 54 ----------- kernel/rustkernel/src/syscall.rs | 64 +++++++++++-- kernel/rustkernel/src/sysproc.rs | 77 --------------- kernel/rustkernel/src/trap.rs | 4 +- kernel/virtio_disk.c | 4 +- 28 files changed, 215 insertions(+), 241 deletions(-) rename kernel/rustkernel/src/{console.rs => console/mod.rs} (98%) rename kernel/rustkernel/src/{ => console}/printf.rs (85%) rename kernel/rustkernel/src/{ => console}/uart.rs (100%) rename kernel/rustkernel/src/{ => fs}/file.rs (65%) rename kernel/rustkernel/src/{fs.rs => fs/mod.rs} (96%) create mode 100644 kernel/rustkernel/src/fs/ramdisk.rs rename kernel/rustkernel/src/{ => fs}/virtio_disk.rs (99%) rename kernel/rustkernel/src/{ => io}/bio.rs (98%) rename kernel/rustkernel/src/{ => io}/buf.rs (100%) create mode 100644 kernel/rustkernel/src/io/mod.rs rename kernel/rustkernel/src/{ => io}/pipe.rs (100%) rename kernel/rustkernel/src/{ => mem}/kalloc.rs (99%) create mode 100644 kernel/rustkernel/src/mem/mod.rs create mode 100644 kernel/rustkernel/src/mem/virtual_memory.rs delete mode 100644 kernel/rustkernel/src/param.rs delete mode 100644 kernel/rustkernel/src/ramdisk.rs delete mode 100644 kernel/rustkernel/src/sysproc.rs diff --git a/kernel/defs.h b/kernel/defs.h index b0a6b1a..fff6729 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -102,7 +102,7 @@ struct proc* myproc(); void procinit(void); void scheduler(void) __attribute__((noreturn)); void sched(void); -void sleep(void*, struct spinlock*); +void sleep_lock(void *, struct spinlock *); void userinit(void); int wait(uint64); void wakeup(void*); diff --git a/kernel/log.c b/kernel/log.c index 5b58306..87a2fef 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -129,10 +129,10 @@ begin_op(void) acquire(&log.lock); while(1){ if(log.committing){ - sleep(&log, &log.lock); + sleep_lock(&log, &log.lock); } else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){ // this op might exhaust log space; wait for commit. - sleep(&log, &log.lock); + sleep_lock(&log, &log.lock); } else { log.outstanding += 1; release(&log.lock); diff --git a/kernel/pipe.c b/kernel/pipe.c index f6b501a..85cd88b 100644 --- a/kernel/pipe.c +++ b/kernel/pipe.c @@ -87,7 +87,7 @@ pipewrite(struct pipe *pi, uint64 addr, int n) } if(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full wakeup(&pi->nread); - sleep(&pi->nwrite, &pi->lock); + sleep_lock(&pi->nwrite, &pi->lock); } else { char ch; if(copyin(pr->pagetable, &ch, addr + i, 1) == -1) @@ -115,7 +115,7 @@ piperead(struct pipe *pi, uint64 addr, int n) release(&pi->lock); return -1; } - sleep(&pi->nread, &pi->lock); //DOC: piperead-sleep + sleep_lock(&pi->nread, &pi->lock); // DOC: piperead-sleep } for(i = 0; i < n; i++){ //DOC: piperead-copy if(pi->nread == pi->nwrite) diff --git a/kernel/proc.c b/kernel/proc.c index 959d7db..98fa5ea 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -336,7 +336,7 @@ wait(uint64 addr) } // Wait for a child to exit. - sleep(p, &wait_lock); //DOC: wait-sleep + sleep_lock(p, &wait_lock); // DOC: wait-sleep } } @@ -412,7 +412,7 @@ forkret(void) // Atomically release lock and sleep on chan. // Reacquires lock when awakened. -void sleep(void *chan, struct spinlock *lk); +void sleep_lock(void *chan, struct spinlock *lk); // Wake up all processes sleeping on chan. // Must be called without any p->lock. diff --git a/kernel/rustkernel/src/console.rs b/kernel/rustkernel/src/console/mod.rs similarity index 98% rename from kernel/rustkernel/src/console.rs rename to kernel/rustkernel/src/console/mod.rs index fcb8a60..4e79259 100644 --- a/kernel/rustkernel/src/console.rs +++ b/kernel/rustkernel/src/console/mod.rs @@ -8,13 +8,16 @@ // - ctrl-d: end of file // - ctrl-p: print process list +pub mod printf; +pub mod uart; + use crate::{ - file::{devsw, CONSOLE}, + fs::file::{devsw, CONSOLE}, proc::{killed, myproc, procdump, sleep_mutex, wakeup}, sync::spinmutex::SpinMutex, - uart::{uartinit, uartputc, Uart}, }; use core::{ffi::c_void, ptr::addr_of_mut}; +use uart::{uartinit, uartputc, Uart}; extern "C" { fn either_copyin(dst: *mut c_void, user_src: i32, src: u64, len: u64) -> i32; diff --git a/kernel/rustkernel/src/printf.rs b/kernel/rustkernel/src/console/printf.rs similarity index 85% rename from kernel/rustkernel/src/printf.rs rename to kernel/rustkernel/src/console/printf.rs index f62ac97..1a17c51 100644 --- a/kernel/rustkernel/src/printf.rs +++ b/kernel/rustkernel/src/console/printf.rs @@ -15,10 +15,10 @@ pub struct PrintLock { macro_rules! print { ($($arg:tt)*) => {{ // Still unsafe because static mut. - let _guard = unsafe { $crate::printf::PRINT_LOCK.lock() }; + let _guard = unsafe { $crate::console::printf::PRINT_LOCK.lock() }; // Allocate a page of memory as the buffer and release it when we're done. - let buf = unsafe { $crate::kalloc::kalloc() as *mut [u8; 4096] }; + let buf = unsafe { $crate::mem::kalloc::kalloc() as *mut [u8; 4096] }; let s: &str = format_no_std::show( unsafe { buf.as_mut() }.unwrap(), @@ -29,7 +29,7 @@ macro_rules! print { $crate::console::consputc(*c); } - unsafe { $crate::kalloc::kfree(buf.cast()) }; + unsafe { $crate::mem::kalloc::kfree(buf.cast()) }; }}; } pub(crate) use print; diff --git a/kernel/rustkernel/src/uart.rs b/kernel/rustkernel/src/console/uart.rs similarity index 100% rename from kernel/rustkernel/src/uart.rs rename to kernel/rustkernel/src/console/uart.rs diff --git a/kernel/rustkernel/src/file.rs b/kernel/rustkernel/src/fs/file.rs similarity index 65% rename from kernel/rustkernel/src/file.rs rename to kernel/rustkernel/src/fs/file.rs index 874ea2a..70391cb 100644 --- a/kernel/rustkernel/src/file.rs +++ b/kernel/rustkernel/src/fs/file.rs @@ -5,7 +5,8 @@ pub struct Devsw { } extern "C" { - pub static mut devsw: [Devsw; crate::param::NDEV]; + pub static mut devsw: [Devsw; crate::NDEV]; + pub fn fileinit(); } pub const CONSOLE: usize = 1; diff --git a/kernel/rustkernel/src/fs.rs b/kernel/rustkernel/src/fs/mod.rs similarity index 96% rename from kernel/rustkernel/src/fs.rs rename to kernel/rustkernel/src/fs/mod.rs index 3f47f0a..3d0980d 100644 --- a/kernel/rustkernel/src/fs.rs +++ b/kernel/rustkernel/src/fs/mod.rs @@ -1,6 +1,10 @@ //! On-disk file system forma. //! Both the kernel and user programs use this header file. +pub mod file; +pub mod ramdisk; +pub mod virtio_disk; + // Root inode pub const ROOTINO: u64 = 1; /// Block size. @@ -77,3 +81,7 @@ pub struct DirectoryEntry { pub inum: u16, pub name: [u8; DIRSIZ], } + +extern "C" { + pub fn iinit(); +} diff --git a/kernel/rustkernel/src/fs/ramdisk.rs b/kernel/rustkernel/src/fs/ramdisk.rs new file mode 100644 index 0000000..fe017a8 --- /dev/null +++ b/kernel/rustkernel/src/fs/ramdisk.rs @@ -0,0 +1,8 @@ +//! Ramdisk that uses the disk image loaded by qemu -initrd fs.img + +use crate::io::buf::Buffer; + +extern "C" { + pub fn ramdiskinit(); + pub fn ramdiskrw(buffer: *mut Buffer); +} diff --git a/kernel/rustkernel/src/virtio_disk.rs b/kernel/rustkernel/src/fs/virtio_disk.rs similarity index 99% rename from kernel/rustkernel/src/virtio_disk.rs rename to kernel/rustkernel/src/fs/virtio_disk.rs index 959714d..100b10c 100644 --- a/kernel/rustkernel/src/virtio_disk.rs +++ b/kernel/rustkernel/src/fs/virtio_disk.rs @@ -6,7 +6,7 @@ //! The virtio spec: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf //! qemu ... -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -use crate::{buf::Buffer, sync::spinlock::Spinlock}; +use crate::{io::buf::Buffer, sync::spinlock::Spinlock}; use core::ffi::c_char; // Virtio MMIO control registers, mapped starting at 0x10001000 diff --git a/kernel/rustkernel/src/bio.rs b/kernel/rustkernel/src/io/bio.rs similarity index 98% rename from kernel/rustkernel/src/bio.rs rename to kernel/rustkernel/src/io/bio.rs index 565ff20..747376f 100644 --- a/kernel/rustkernel/src/bio.rs +++ b/kernel/rustkernel/src/io/bio.rs @@ -13,7 +13,7 @@ //! - Only one process at a time can use a buffer, //! so do not keep them longer than necessary. -use crate::{buf::Buffer, param::NBUF, sync::spinlock::Spinlock}; +use crate::{io::buf::Buffer, sync::spinlock::Spinlock, NBUF}; pub struct BufferCache { pub buffers: [Buffer; NBUF], diff --git a/kernel/rustkernel/src/buf.rs b/kernel/rustkernel/src/io/buf.rs similarity index 100% rename from kernel/rustkernel/src/buf.rs rename to kernel/rustkernel/src/io/buf.rs diff --git a/kernel/rustkernel/src/io/mod.rs b/kernel/rustkernel/src/io/mod.rs new file mode 100644 index 0000000..c9bccf1 --- /dev/null +++ b/kernel/rustkernel/src/io/mod.rs @@ -0,0 +1,3 @@ +pub mod bio; +pub mod buf; +pub mod pipe; diff --git a/kernel/rustkernel/src/pipe.rs b/kernel/rustkernel/src/io/pipe.rs similarity index 100% rename from kernel/rustkernel/src/pipe.rs rename to kernel/rustkernel/src/io/pipe.rs diff --git a/kernel/rustkernel/src/lib.rs b/kernel/rustkernel/src/lib.rs index 0890ac9..6ad6d00 100644 --- a/kernel/rustkernel/src/lib.rs +++ b/kernel/rustkernel/src/lib.rs @@ -7,69 +7,78 @@ extern crate alloc; extern crate core; -pub mod bio; -pub mod buf; pub mod console; -pub mod file; pub mod fs; -pub(crate) mod kalloc; -pub(crate) mod param; -pub mod printf; +pub mod io; +pub mod mem; pub mod proc; pub(crate) mod riscv; pub mod start; pub mod string; pub mod sync; pub mod syscall; -pub mod sysproc; pub mod trap; -pub mod uart; -pub mod virtio_disk; -extern "C" { - // pub fn printfinit(); - // pub fn kinit(); - pub fn kvminit(); - pub fn kvminithart(); - pub fn procinit(); - pub fn binit(); - pub fn iinit(); - pub fn fileinit(); - pub fn userinit(); - // pub fn scheduler(); -} - -use crate::{printf::print, proc::cpuid}; +use crate::proc::cpuid; use core::ffi::{c_char, CStr}; +pub(crate) use crate::console::printf::print; + pub static mut STARTED: bool = false; pub static mut PANICKED: bool = false; +/// Maximum number of processes +pub const NPROC: usize = 64; +/// Maximum number of CPUs +pub const NCPU: usize = 8; +/// Maximum number of open files per process +pub const NOFILE: usize = 16; +/// Maximum number of open files per system +pub const NFILE: usize = 100; +/// Maximum number of active inodes +pub const NINODE: usize = 50; +/// Maximum major device number +pub const NDEV: usize = 10; +/// Device number of file system root disk +pub const ROOTDEV: usize = 1; +/// Max exec arguments +pub const MAXARG: usize = 32; +/// Max num of blocks any FS op writes +pub const MAXOPBLOCKS: usize = 10; +/// Max data blocks in on-disk log +pub const LOGSIZE: usize = MAXOPBLOCKS * 3; +/// Size of disk block cache +pub const NBUF: usize = MAXOPBLOCKS * 3; +/// Size of file system in blocks +pub const FSSIZE: usize = 2000; +/// Maximum file path size +pub const MAXPATH: usize = 128; + #[no_mangle] pub unsafe extern "C" fn main() -> ! { if cpuid() == 0 { console::consoleinit(); - printf::printfinit(); - kalloc::kinit(); + console::printf::printfinit(); + mem::kalloc::kinit(); print!("\nxv6 kernel is booting\n"); - kvminit(); - kvminithart(); - procinit(); + mem::virtual_memory::kvminit(); + mem::virtual_memory::kvminithart(); + proc::procinit(); trap::trapinit(); trap::trapinithart(); riscv::plic::plicinit(); riscv::plic::plicinithart(); - binit(); - iinit(); - fileinit(); - virtio_disk::virtio_disk_init(); - userinit(); + io::bio::binit(); + fs::iinit(); + fs::file::fileinit(); + fs::virtio_disk::virtio_disk_init(); + proc::userinit(); STARTED = true; } else { while !STARTED { core::hint::spin_loop(); } - kvminithart(); + mem::virtual_memory::kvminithart(); trap::trapinithart(); riscv::plic::plicinithart(); } @@ -80,9 +89,9 @@ pub unsafe extern "C" fn main() -> ! { #[panic_handler] fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { if let Some(s) = panic_info.payload().downcast_ref::<&str>() { - crate::printf::print!("kernel panic: {}\n", s); + print!("kernel panic: {}\n", s); } else { - crate::printf::print!("kernel panic\n"); + print!("kernel panic\n"); } // crate::printf::print!(" ______\n"); @@ -94,12 +103,12 @@ fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { // crate::printf::print!(" ||----w |\n"); // crate::printf::print!(" || ||\n"); - crate::printf::print!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗\n"); - crate::printf::print!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║\n"); - crate::printf::print!("█████╗ ██║ ██║██║ █████╔╝ ██║██║\n"); - crate::printf::print!("██╔══╝ ██║ ██║██║ ██╔═██╗ ╚═╝╚═╝\n"); - crate::printf::print!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗\n"); - crate::printf::print!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝\n"); + print!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗\n"); + print!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║\n"); + print!("█████╗ ██║ ██║██║ █████╔╝ ██║██║\n"); + print!("██╔══╝ ██║ ██║██║ ██╔═██╗ ╚═╝╚═╝\n"); + print!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗\n"); + print!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝\n"); unsafe { crate::PANICKED = true }; diff --git a/kernel/rustkernel/src/kalloc.rs b/kernel/rustkernel/src/mem/kalloc.rs similarity index 99% rename from kernel/rustkernel/src/kalloc.rs rename to kernel/rustkernel/src/mem/kalloc.rs index 79f5dff..ad90b25 100644 --- a/kernel/rustkernel/src/kalloc.rs +++ b/kernel/rustkernel/src/mem/kalloc.rs @@ -3,8 +3,8 @@ //! and pipe buffers. Allocates whole 4096-byte pages. use crate::{ + mem::memset, riscv::{memlayout::PHYSTOP, pg_round_up, PGSIZE}, - string::memset, sync::spinlock::Spinlock, }; use core::{ diff --git a/kernel/rustkernel/src/mem/mod.rs b/kernel/rustkernel/src/mem/mod.rs new file mode 100644 index 0000000..edd2990 --- /dev/null +++ b/kernel/rustkernel/src/mem/mod.rs @@ -0,0 +1,56 @@ +pub mod kalloc; +pub mod virtual_memory; + +#[no_mangle] +pub unsafe extern "C" fn memset(dst: *mut u8, data: i32, max_bytes: u32) -> *mut u8 { + for i in 0..max_bytes { + *dst.add(i as usize) = data as u8; + } + dst +} + +#[no_mangle] +pub unsafe extern "C" fn memcmp(mut a: *const u8, mut b: *const u8, max_bytes: u32) -> i32 { + for _ in 0..max_bytes { + if *a != *b { + return (*a - *b) as i32; + } else { + a = a.add(1); + b = b.add(1); + } + } + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn memmove(mut dst: *mut u8, mut src: *const u8, max_bytes: u32) -> *mut u8 { + if max_bytes == 0 { + return dst; + } + + // If src starts before dst and src + max_bytes + // is after d, the memory regions overlap. + if src < dst && src.add(max_bytes as usize) > dst { + dst = dst.add(max_bytes as usize); + src = src.add(max_bytes as usize); + + for _ in 0..max_bytes { + dst = dst.sub(1); + src = src.sub(1); + *dst = *src; + } + } else { + for _ in 0..max_bytes { + *dst = *src; + dst = dst.add(1); + src = src.add(1); + } + } + + dst +} + +#[no_mangle] +pub unsafe extern "C" fn memcpy(dst: *mut u8, src: *const u8, max_bytes: u32) -> *mut u8 { + memmove(dst, src, max_bytes) +} diff --git a/kernel/rustkernel/src/mem/virtual_memory.rs b/kernel/rustkernel/src/mem/virtual_memory.rs new file mode 100644 index 0000000..e4f2da8 --- /dev/null +++ b/kernel/rustkernel/src/mem/virtual_memory.rs @@ -0,0 +1,4 @@ +extern "C" { + pub fn kvminit(); + pub fn kvminithart(); +} diff --git a/kernel/rustkernel/src/param.rs b/kernel/rustkernel/src/param.rs deleted file mode 100644 index 8fc097c..0000000 --- a/kernel/rustkernel/src/param.rs +++ /dev/null @@ -1,26 +0,0 @@ -/// Maximum number of processes -pub const NPROC: usize = 64; -/// Maximum number of CPUs -pub const NCPU: usize = 8; -/// Maximum number of open files per process -pub const NOFILE: usize = 16; -/// Maximum number of open files per system -pub const NFILE: usize = 100; -/// Maximum number of active inodes -pub const NINODE: usize = 50; -/// Maximum major device number -pub const NDEV: usize = 10; -/// Device number of file system root disk -pub const ROOTDEV: usize = 1; -/// Max exec arguments -pub const MAXARG: usize = 32; -/// Max num of blocks any FS op writes -pub const MAXOPBLOCKS: usize = 10; -/// Max data blocks in on-disk log -pub const LOGSIZE: usize = MAXOPBLOCKS * 3; -/// Size of disk block cache -pub const NBUF: usize = MAXOPBLOCKS * 3; -/// Size of file system in blocks -pub const FSSIZE: usize = 2000; -/// Maximum file path size -pub const MAXPATH: usize = 128; diff --git a/kernel/rustkernel/src/proc.rs b/kernel/rustkernel/src/proc.rs index 8be4f23..2100caa 100644 --- a/kernel/rustkernel/src/proc.rs +++ b/kernel/rustkernel/src/proc.rs @@ -1,8 +1,7 @@ #![allow(clippy::comparison_chain)] use crate::{ - kalloc::kfree, - param::*, + mem::kalloc::kfree, riscv::{self, Pagetable, PTE_W}, sync::spinlock::Spinlock, sync::spinmutex::SpinMutexGuard, @@ -13,8 +12,8 @@ use core::{ }; extern "C" { - pub static mut cpus: [Cpu; NCPU]; - pub static mut proc: [Proc; NPROC]; + pub static mut cpus: [Cpu; crate::NCPU]; + pub static mut proc: [Proc; crate::NPROC]; pub static mut initproc: *mut Proc; pub static mut nextpid: i32; pub static mut pid_lock: Spinlock; @@ -26,6 +25,8 @@ extern "C" { // trampoline.S pub static mut trampoline: *mut c_char; + pub fn procinit(); + pub fn userinit(); pub fn forkret(); pub fn fork() -> i32; pub fn exit(status: i32) -> !; diff --git a/kernel/rustkernel/src/ramdisk.rs b/kernel/rustkernel/src/ramdisk.rs deleted file mode 100644 index 91e01b9..0000000 --- a/kernel/rustkernel/src/ramdisk.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Ramdisk that uses the disk image loaded by qemu -initrd fs.img - -extern "C" { - pub fn ramdiskrw(buffer: *mut Buf); -} - -#[no_mangle] -pub extern "C" fn ramdiskinit() {} diff --git a/kernel/rustkernel/src/start.rs b/kernel/rustkernel/src/start.rs index 7f398a4..a2c4380 100644 --- a/kernel/rustkernel/src/start.rs +++ b/kernel/rustkernel/src/start.rs @@ -1,4 +1,4 @@ -use crate::{main, param::NCPU, riscv::*}; +use crate::{main, riscv::*, NCPU}; use core::{arch::asm, ptr::addr_of}; extern "C" { diff --git a/kernel/rustkernel/src/string.rs b/kernel/rustkernel/src/string.rs index 40c09e1..fd1d467 100644 --- a/kernel/rustkernel/src/string.rs +++ b/kernel/rustkernel/src/string.rs @@ -1,59 +1,5 @@ use core::{ffi::c_char, option::Option}; -#[no_mangle] -pub unsafe extern "C" fn memset(dst: *mut u8, data: i32, max_bytes: u32) -> *mut u8 { - for i in 0..max_bytes { - *dst.add(i as usize) = data as u8; - } - dst -} - -#[no_mangle] -pub unsafe extern "C" fn memcmp(mut a: *const u8, mut b: *const u8, max_bytes: u32) -> i32 { - for _ in 0..max_bytes { - if *a != *b { - return (*a - *b) as i32; - } else { - a = a.add(1); - b = b.add(1); - } - } - 0 -} - -#[no_mangle] -pub unsafe extern "C" fn memmove(mut dst: *mut u8, mut src: *const u8, max_bytes: u32) -> *mut u8 { - if max_bytes == 0 { - return dst; - } - - // If src starts before dst and src + max_bytes - // is after d, the memory regions overlap. - if src < dst && src.add(max_bytes as usize) > dst { - dst = dst.add(max_bytes as usize); - src = src.add(max_bytes as usize); - - for _ in 0..max_bytes { - dst = dst.sub(1); - src = src.sub(1); - *dst = *src; - } - } else { - for _ in 0..max_bytes { - *dst = *src; - dst = dst.add(1); - src = src.add(1); - } - } - - dst -} - -#[no_mangle] -pub unsafe extern "C" fn memcpy(dst: *mut u8, src: *const u8, max_bytes: u32) -> *mut u8 { - memmove(dst, src, max_bytes) -} - pub(crate) unsafe fn strlen_checked(s: *const c_char, max_chars: usize) -> Option { for len in 0..max_chars { if (*s.add(len)) == '\0' as i8 { diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index 563aac5..c2d949c 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -1,4 +1,9 @@ -use crate::{printf::print, proc::myproc, riscv::Pagetable, string::strlen, sysproc}; +use crate::{ + console::printf::print, + proc::{self, myproc, sleep_lock}, + riscv::Pagetable, + string::strlen, +}; use core::{mem::size_of, ptr::addr_of_mut}; extern "C" { @@ -46,20 +51,61 @@ pub enum Syscall { impl Syscall { pub unsafe fn call(&self) -> u64 { match self { - Syscall::Fork => sysproc::sys_fork(), - Syscall::Exit => sysproc::sys_exit(), - Syscall::Wait => sysproc::sys_wait(), + Syscall::Fork => proc::fork() as u64, + Syscall::Exit => { + let mut n = 0i32; + argint(0, addr_of_mut!(n)); + proc::exit(n) + } + Syscall::Wait => { + let mut p = 0u64; + argaddr(0, addr_of_mut!(p)); + proc::wait(p) as u64 + } Syscall::Pipe => sys_pipe(), Syscall::Read => sys_read(), - Syscall::Kill => sysproc::sys_kill(), + Syscall::Kill => { + let mut pid = 0i32; + argint(0, addr_of_mut!(pid)); + proc::kill(pid) as u64 + } Syscall::Exec => sys_exec(), Syscall::Fstat => sys_fstat(), Syscall::Chdir => sys_chdir(), Syscall::Dup => sys_dup(), - Syscall::Getpid => sysproc::sys_getpid(), - Syscall::Sbrk => sysproc::sys_sbrk(), - Syscall::Sleep => sysproc::sys_sleep(), - Syscall::Uptime => sysproc::sys_uptime(), + Syscall::Getpid => (*myproc()).pid as u64, + Syscall::Sbrk => { + let mut n = 0i32; + argint(0, addr_of_mut!(n)); + let addr = (*myproc()).sz; + + if proc::growproc(n) < 0 { + -1i64 as u64 + } else { + addr + } + } + Syscall::Sleep => { + use crate::trap::{ticks, tickslock}; + + let mut n = 0i32; + argint(0, addr_of_mut!(n)); + + let _guard = tickslock.lock(); + while ticks < ticks + n as u32 { + if proc::killed(myproc()) > 0 { + tickslock.unlock(); + return -1i64 as u64; + } + sleep_lock(addr_of_mut!(ticks).cast(), addr_of_mut!(tickslock).cast()) + } + 0 + } + // Returns how many clock tick interrupts have occured since start. + Syscall::Uptime => { + let _guard = crate::trap::tickslock.lock(); + crate::trap::ticks as u64 + } Syscall::Open => sys_open(), Syscall::Write => sys_write(), Syscall::Mknod => sys_mknod(), diff --git a/kernel/rustkernel/src/sysproc.rs b/kernel/rustkernel/src/sysproc.rs deleted file mode 100644 index b74ecb6..0000000 --- a/kernel/rustkernel/src/sysproc.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::{ - proc::{exit, fork, growproc, kill, killed, myproc, sleep_lock, wait}, - syscall::{argaddr, argint}, -}; -use core::ptr::addr_of_mut; - -#[no_mangle] -pub unsafe extern "C" fn sys_exit() -> u64 { - let mut n = 0i32; - argint(0, addr_of_mut!(n)); - exit(n) -} - -#[no_mangle] -pub unsafe extern "C" fn sys_getpid() -> u64 { - (*myproc()).pid as u64 -} - -#[no_mangle] -pub unsafe extern "C" fn sys_fork() -> u64 { - fork() as u64 -} - -#[no_mangle] -pub unsafe extern "C" fn sys_wait() -> u64 { - let mut p = 0u64; - argaddr(0, addr_of_mut!(p)); - wait(p) as u64 -} - -#[no_mangle] -pub unsafe extern "C" fn sys_sbrk() -> u64 { - let mut n = 0i32; - argint(0, addr_of_mut!(n)); - let addr = (*myproc()).sz; - - if growproc(n) < 0 { - -1i64 as u64 - } else { - addr - } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_sleep() -> u64 { - let mut n = 0i32; - argint(0, addr_of_mut!(n)); - - let _guard = crate::trap::tickslock.lock(); - let ticks = crate::trap::ticks; - while crate::trap::ticks < ticks + n as u32 { - if killed(myproc()) > 0 { - crate::trap::tickslock.unlock(); - return -1i64 as u64; - } - sleep_lock( - addr_of_mut!(crate::trap::ticks).cast(), - addr_of_mut!(crate::trap::tickslock).cast(), - ) - } - 0 -} - -#[no_mangle] -pub unsafe extern "C" fn sys_kill() -> u64 { - let mut pid = 0i32; - argint(0, addr_of_mut!(pid)); - kill(pid) as u64 -} - -/// Returns how many clock tick interrupts have occurred since start. -#[no_mangle] -pub unsafe extern "C" fn sys_uptime() -> u64 { - let _guard = crate::trap::tickslock.lock(); - let ticks = crate::trap::ticks; - ticks as u64 -} diff --git a/kernel/rustkernel/src/trap.rs b/kernel/rustkernel/src/trap.rs index b6d83bd..4c0ed73 100644 --- a/kernel/rustkernel/src/trap.rs +++ b/kernel/rustkernel/src/trap.rs @@ -1,5 +1,5 @@ use crate::{ - printf::print, + console::printf::print, proc::{cpuid, exit, killed, mycpu, myproc, r#yield, setkilled, wakeup, ProcState}, riscv::*, sync::spinlock::Spinlock, @@ -64,7 +64,7 @@ pub unsafe extern "C" fn devintr() -> i32 { let irq = plic::plic_claim(); if irq == UART0_IRQ { - crate::uart::uartintr(); + crate::console::uart::uartintr(); } else if irq == VIRTIO0_IRQ { virtio_disk_intr(); } else if irq > 0 { diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c index ae6c164..b3f5445 100644 --- a/kernel/virtio_disk.c +++ b/kernel/virtio_disk.c @@ -229,7 +229,7 @@ virtio_disk_rw(struct buf *b, int write) if(alloc3_desc(idx) == 0) { break; } - sleep(&disk.free[0], &disk.vdisk_lock); + sleep_lock(&disk.free[0], &disk.vdisk_lock); } // format the three descriptors. @@ -282,7 +282,7 @@ virtio_disk_rw(struct buf *b, int write) // Wait for virtio_disk_intr() to say request has finished. while(b->disk == 1) { - sleep(b, &disk.vdisk_lock); + sleep_lock(b, &disk.vdisk_lock); } disk.info[idx[0]].b = 0;