move things around
This commit is contained in:
parent
d06d271c9e
commit
9f10ec36b3
@ -102,7 +102,7 @@ struct proc* myproc();
|
|||||||
void procinit(void);
|
void procinit(void);
|
||||||
void scheduler(void) __attribute__((noreturn));
|
void scheduler(void) __attribute__((noreturn));
|
||||||
void sched(void);
|
void sched(void);
|
||||||
void sleep(void*, struct spinlock*);
|
void sleep_lock(void *, struct spinlock *);
|
||||||
void userinit(void);
|
void userinit(void);
|
||||||
int wait(uint64);
|
int wait(uint64);
|
||||||
void wakeup(void*);
|
void wakeup(void*);
|
||||||
|
@ -129,10 +129,10 @@ begin_op(void)
|
|||||||
acquire(&log.lock);
|
acquire(&log.lock);
|
||||||
while(1){
|
while(1){
|
||||||
if(log.committing){
|
if(log.committing){
|
||||||
sleep(&log, &log.lock);
|
sleep_lock(&log, &log.lock);
|
||||||
} else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){
|
} else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){
|
||||||
// this op might exhaust log space; wait for commit.
|
// this op might exhaust log space; wait for commit.
|
||||||
sleep(&log, &log.lock);
|
sleep_lock(&log, &log.lock);
|
||||||
} else {
|
} else {
|
||||||
log.outstanding += 1;
|
log.outstanding += 1;
|
||||||
release(&log.lock);
|
release(&log.lock);
|
||||||
|
@ -87,7 +87,7 @@ pipewrite(struct pipe *pi, uint64 addr, int n)
|
|||||||
}
|
}
|
||||||
if(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
|
if(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
|
||||||
wakeup(&pi->nread);
|
wakeup(&pi->nread);
|
||||||
sleep(&pi->nwrite, &pi->lock);
|
sleep_lock(&pi->nwrite, &pi->lock);
|
||||||
} else {
|
} else {
|
||||||
char ch;
|
char ch;
|
||||||
if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
|
if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
|
||||||
@ -115,7 +115,7 @@ piperead(struct pipe *pi, uint64 addr, int n)
|
|||||||
release(&pi->lock);
|
release(&pi->lock);
|
||||||
return -1;
|
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
|
for(i = 0; i < n; i++){ //DOC: piperead-copy
|
||||||
if(pi->nread == pi->nwrite)
|
if(pi->nread == pi->nwrite)
|
||||||
|
@ -336,7 +336,7 @@ wait(uint64 addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a child to exit.
|
// 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.
|
// Atomically release lock and sleep on chan.
|
||||||
// Reacquires lock when awakened.
|
// 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.
|
// Wake up all processes sleeping on chan.
|
||||||
// Must be called without any p->lock.
|
// Must be called without any p->lock.
|
||||||
|
@ -8,13 +8,16 @@
|
|||||||
// - ctrl-d: end of file
|
// - ctrl-d: end of file
|
||||||
// - ctrl-p: print process list
|
// - ctrl-p: print process list
|
||||||
|
|
||||||
|
pub mod printf;
|
||||||
|
pub mod uart;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
file::{devsw, CONSOLE},
|
fs::file::{devsw, CONSOLE},
|
||||||
proc::{killed, myproc, procdump, sleep_mutex, wakeup},
|
proc::{killed, myproc, procdump, sleep_mutex, wakeup},
|
||||||
sync::spinmutex::SpinMutex,
|
sync::spinmutex::SpinMutex,
|
||||||
uart::{uartinit, uartputc, Uart},
|
|
||||||
};
|
};
|
||||||
use core::{ffi::c_void, ptr::addr_of_mut};
|
use core::{ffi::c_void, ptr::addr_of_mut};
|
||||||
|
use uart::{uartinit, uartputc, Uart};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn either_copyin(dst: *mut c_void, user_src: i32, src: u64, len: u64) -> i32;
|
fn either_copyin(dst: *mut c_void, user_src: i32, src: u64, len: u64) -> i32;
|
@ -15,10 +15,10 @@ pub struct PrintLock {
|
|||||||
macro_rules! print {
|
macro_rules! print {
|
||||||
($($arg:tt)*) => {{
|
($($arg:tt)*) => {{
|
||||||
// Still unsafe because static mut.
|
// 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.
|
// 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(
|
let s: &str = format_no_std::show(
|
||||||
unsafe { buf.as_mut() }.unwrap(),
|
unsafe { buf.as_mut() }.unwrap(),
|
||||||
@ -29,7 +29,7 @@ macro_rules! print {
|
|||||||
$crate::console::consputc(*c);
|
$crate::console::consputc(*c);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { $crate::kalloc::kfree(buf.cast()) };
|
unsafe { $crate::mem::kalloc::kfree(buf.cast()) };
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
pub(crate) use print;
|
pub(crate) use print;
|
@ -5,7 +5,8 @@ pub struct Devsw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
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;
|
pub const CONSOLE: usize = 1;
|
@ -1,6 +1,10 @@
|
|||||||
//! On-disk file system forma.
|
//! On-disk file system forma.
|
||||||
//! Both the kernel and user programs use this header file.
|
//! Both the kernel and user programs use this header file.
|
||||||
|
|
||||||
|
pub mod file;
|
||||||
|
pub mod ramdisk;
|
||||||
|
pub mod virtio_disk;
|
||||||
|
|
||||||
// Root inode
|
// Root inode
|
||||||
pub const ROOTINO: u64 = 1;
|
pub const ROOTINO: u64 = 1;
|
||||||
/// Block size.
|
/// Block size.
|
||||||
@ -77,3 +81,7 @@ pub struct DirectoryEntry {
|
|||||||
pub inum: u16,
|
pub inum: u16,
|
||||||
pub name: [u8; DIRSIZ],
|
pub name: [u8; DIRSIZ],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn iinit();
|
||||||
|
}
|
8
kernel/rustkernel/src/fs/ramdisk.rs
Normal file
8
kernel/rustkernel/src/fs/ramdisk.rs
Normal file
@ -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);
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
//! The virtio spec: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf
|
//! 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
|
//! 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;
|
use core::ffi::c_char;
|
||||||
|
|
||||||
// Virtio MMIO control registers, mapped starting at 0x10001000
|
// Virtio MMIO control registers, mapped starting at 0x10001000
|
@ -13,7 +13,7 @@
|
|||||||
//! - Only one process at a time can use a buffer,
|
//! - Only one process at a time can use a buffer,
|
||||||
//! so do not keep them longer than necessary.
|
//! 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 struct BufferCache {
|
||||||
pub buffers: [Buffer; NBUF],
|
pub buffers: [Buffer; NBUF],
|
3
kernel/rustkernel/src/io/mod.rs
Normal file
3
kernel/rustkernel/src/io/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod bio;
|
||||||
|
pub mod buf;
|
||||||
|
pub mod pipe;
|
@ -7,69 +7,78 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
pub mod bio;
|
|
||||||
pub mod buf;
|
|
||||||
pub mod console;
|
pub mod console;
|
||||||
pub mod file;
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub(crate) mod kalloc;
|
pub mod io;
|
||||||
pub(crate) mod param;
|
pub mod mem;
|
||||||
pub mod printf;
|
|
||||||
pub mod proc;
|
pub mod proc;
|
||||||
pub(crate) mod riscv;
|
pub(crate) mod riscv;
|
||||||
pub mod start;
|
pub mod start;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
pub mod sysproc;
|
|
||||||
pub mod trap;
|
pub mod trap;
|
||||||
pub mod uart;
|
|
||||||
pub mod virtio_disk;
|
|
||||||
|
|
||||||
extern "C" {
|
use crate::proc::cpuid;
|
||||||
// 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 core::ffi::{c_char, CStr};
|
use core::ffi::{c_char, CStr};
|
||||||
|
|
||||||
|
pub(crate) use crate::console::printf::print;
|
||||||
|
|
||||||
pub static mut STARTED: bool = false;
|
pub static mut STARTED: bool = false;
|
||||||
pub static mut PANICKED: 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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn main() -> ! {
|
pub unsafe extern "C" fn main() -> ! {
|
||||||
if cpuid() == 0 {
|
if cpuid() == 0 {
|
||||||
console::consoleinit();
|
console::consoleinit();
|
||||||
printf::printfinit();
|
console::printf::printfinit();
|
||||||
kalloc::kinit();
|
mem::kalloc::kinit();
|
||||||
print!("\nxv6 kernel is booting\n");
|
print!("\nxv6 kernel is booting\n");
|
||||||
kvminit();
|
mem::virtual_memory::kvminit();
|
||||||
kvminithart();
|
mem::virtual_memory::kvminithart();
|
||||||
procinit();
|
proc::procinit();
|
||||||
trap::trapinit();
|
trap::trapinit();
|
||||||
trap::trapinithart();
|
trap::trapinithart();
|
||||||
riscv::plic::plicinit();
|
riscv::plic::plicinit();
|
||||||
riscv::plic::plicinithart();
|
riscv::plic::plicinithart();
|
||||||
binit();
|
io::bio::binit();
|
||||||
iinit();
|
fs::iinit();
|
||||||
fileinit();
|
fs::file::fileinit();
|
||||||
virtio_disk::virtio_disk_init();
|
fs::virtio_disk::virtio_disk_init();
|
||||||
userinit();
|
proc::userinit();
|
||||||
STARTED = true;
|
STARTED = true;
|
||||||
} else {
|
} else {
|
||||||
while !STARTED {
|
while !STARTED {
|
||||||
core::hint::spin_loop();
|
core::hint::spin_loop();
|
||||||
}
|
}
|
||||||
kvminithart();
|
mem::virtual_memory::kvminithart();
|
||||||
trap::trapinithart();
|
trap::trapinithart();
|
||||||
riscv::plic::plicinithart();
|
riscv::plic::plicinithart();
|
||||||
}
|
}
|
||||||
@ -80,9 +89,9 @@ pub unsafe extern "C" fn main() -> ! {
|
|||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! {
|
fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! {
|
||||||
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
|
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
|
||||||
crate::printf::print!("kernel panic: {}\n", s);
|
print!("kernel panic: {}\n", s);
|
||||||
} else {
|
} else {
|
||||||
crate::printf::print!("kernel panic\n");
|
print!("kernel panic\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// crate::printf::print!(" ______\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!(" ||----w |\n");
|
||||||
// crate::printf::print!(" || ||\n");
|
// crate::printf::print!(" || ||\n");
|
||||||
|
|
||||||
crate::printf::print!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗\n");
|
print!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗\n");
|
||||||
crate::printf::print!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║\n");
|
print!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║\n");
|
||||||
crate::printf::print!("█████╗ ██║ ██║██║ █████╔╝ ██║██║\n");
|
print!("█████╗ ██║ ██║██║ █████╔╝ ██║██║\n");
|
||||||
crate::printf::print!("██╔══╝ ██║ ██║██║ ██╔═██╗ ╚═╝╚═╝\n");
|
print!("██╔══╝ ██║ ██║██║ ██╔═██╗ ╚═╝╚═╝\n");
|
||||||
crate::printf::print!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗\n");
|
print!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗\n");
|
||||||
crate::printf::print!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝\n");
|
print!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝\n");
|
||||||
|
|
||||||
unsafe { crate::PANICKED = true };
|
unsafe { crate::PANICKED = true };
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
//! and pipe buffers. Allocates whole 4096-byte pages.
|
//! and pipe buffers. Allocates whole 4096-byte pages.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
mem::memset,
|
||||||
riscv::{memlayout::PHYSTOP, pg_round_up, PGSIZE},
|
riscv::{memlayout::PHYSTOP, pg_round_up, PGSIZE},
|
||||||
string::memset,
|
|
||||||
sync::spinlock::Spinlock,
|
sync::spinlock::Spinlock,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
56
kernel/rustkernel/src/mem/mod.rs
Normal file
56
kernel/rustkernel/src/mem/mod.rs
Normal file
@ -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)
|
||||||
|
}
|
4
kernel/rustkernel/src/mem/virtual_memory.rs
Normal file
4
kernel/rustkernel/src/mem/virtual_memory.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
extern "C" {
|
||||||
|
pub fn kvminit();
|
||||||
|
pub fn kvminithart();
|
||||||
|
}
|
@ -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;
|
|
@ -1,8 +1,7 @@
|
|||||||
#![allow(clippy::comparison_chain)]
|
#![allow(clippy::comparison_chain)]
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
kalloc::kfree,
|
mem::kalloc::kfree,
|
||||||
param::*,
|
|
||||||
riscv::{self, Pagetable, PTE_W},
|
riscv::{self, Pagetable, PTE_W},
|
||||||
sync::spinlock::Spinlock,
|
sync::spinlock::Spinlock,
|
||||||
sync::spinmutex::SpinMutexGuard,
|
sync::spinmutex::SpinMutexGuard,
|
||||||
@ -13,8 +12,8 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub static mut cpus: [Cpu; NCPU];
|
pub static mut cpus: [Cpu; crate::NCPU];
|
||||||
pub static mut proc: [Proc; NPROC];
|
pub static mut proc: [Proc; crate::NPROC];
|
||||||
pub static mut initproc: *mut Proc;
|
pub static mut initproc: *mut Proc;
|
||||||
pub static mut nextpid: i32;
|
pub static mut nextpid: i32;
|
||||||
pub static mut pid_lock: Spinlock;
|
pub static mut pid_lock: Spinlock;
|
||||||
@ -26,6 +25,8 @@ extern "C" {
|
|||||||
// trampoline.S
|
// trampoline.S
|
||||||
pub static mut trampoline: *mut c_char;
|
pub static mut trampoline: *mut c_char;
|
||||||
|
|
||||||
|
pub fn procinit();
|
||||||
|
pub fn userinit();
|
||||||
pub fn forkret();
|
pub fn forkret();
|
||||||
pub fn fork() -> i32;
|
pub fn fork() -> i32;
|
||||||
pub fn exit(status: i32) -> !;
|
pub fn exit(status: i32) -> !;
|
||||||
|
@ -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() {}
|
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{main, param::NCPU, riscv::*};
|
use crate::{main, riscv::*, NCPU};
|
||||||
use core::{arch::asm, ptr::addr_of};
|
use core::{arch::asm, ptr::addr_of};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -1,59 +1,5 @@
|
|||||||
use core::{ffi::c_char, option::Option};
|
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<i32> {
|
pub(crate) unsafe fn strlen_checked(s: *const c_char, max_chars: usize) -> Option<i32> {
|
||||||
for len in 0..max_chars {
|
for len in 0..max_chars {
|
||||||
if (*s.add(len)) == '\0' as i8 {
|
if (*s.add(len)) == '\0' as i8 {
|
||||||
|
@ -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};
|
use core::{mem::size_of, ptr::addr_of_mut};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -46,20 +51,61 @@ pub enum Syscall {
|
|||||||
impl Syscall {
|
impl Syscall {
|
||||||
pub unsafe fn call(&self) -> u64 {
|
pub unsafe fn call(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
Syscall::Fork => sysproc::sys_fork(),
|
Syscall::Fork => proc::fork() as u64,
|
||||||
Syscall::Exit => sysproc::sys_exit(),
|
Syscall::Exit => {
|
||||||
Syscall::Wait => sysproc::sys_wait(),
|
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::Pipe => sys_pipe(),
|
||||||
Syscall::Read => sys_read(),
|
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::Exec => sys_exec(),
|
||||||
Syscall::Fstat => sys_fstat(),
|
Syscall::Fstat => sys_fstat(),
|
||||||
Syscall::Chdir => sys_chdir(),
|
Syscall::Chdir => sys_chdir(),
|
||||||
Syscall::Dup => sys_dup(),
|
Syscall::Dup => sys_dup(),
|
||||||
Syscall::Getpid => sysproc::sys_getpid(),
|
Syscall::Getpid => (*myproc()).pid as u64,
|
||||||
Syscall::Sbrk => sysproc::sys_sbrk(),
|
Syscall::Sbrk => {
|
||||||
Syscall::Sleep => sysproc::sys_sleep(),
|
let mut n = 0i32;
|
||||||
Syscall::Uptime => sysproc::sys_uptime(),
|
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::Open => sys_open(),
|
||||||
Syscall::Write => sys_write(),
|
Syscall::Write => sys_write(),
|
||||||
Syscall::Mknod => sys_mknod(),
|
Syscall::Mknod => sys_mknod(),
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
printf::print,
|
console::printf::print,
|
||||||
proc::{cpuid, exit, killed, mycpu, myproc, r#yield, setkilled, wakeup, ProcState},
|
proc::{cpuid, exit, killed, mycpu, myproc, r#yield, setkilled, wakeup, ProcState},
|
||||||
riscv::*,
|
riscv::*,
|
||||||
sync::spinlock::Spinlock,
|
sync::spinlock::Spinlock,
|
||||||
@ -64,7 +64,7 @@ pub unsafe extern "C" fn devintr() -> i32 {
|
|||||||
let irq = plic::plic_claim();
|
let irq = plic::plic_claim();
|
||||||
|
|
||||||
if irq == UART0_IRQ {
|
if irq == UART0_IRQ {
|
||||||
crate::uart::uartintr();
|
crate::console::uart::uartintr();
|
||||||
} else if irq == VIRTIO0_IRQ {
|
} else if irq == VIRTIO0_IRQ {
|
||||||
virtio_disk_intr();
|
virtio_disk_intr();
|
||||||
} else if irq > 0 {
|
} else if irq > 0 {
|
||||||
|
@ -229,7 +229,7 @@ virtio_disk_rw(struct buf *b, int write)
|
|||||||
if(alloc3_desc(idx) == 0) {
|
if(alloc3_desc(idx) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(&disk.free[0], &disk.vdisk_lock);
|
sleep_lock(&disk.free[0], &disk.vdisk_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// format the three descriptors.
|
// 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.
|
// Wait for virtio_disk_intr() to say request has finished.
|
||||||
while(b->disk == 1) {
|
while(b->disk == 1) {
|
||||||
sleep(b, &disk.vdisk_lock);
|
sleep_lock(b, &disk.vdisk_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
disk.info[idx[0]].b = 0;
|
disk.info[idx[0]].b = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user