move things around

This commit is contained in:
Garen Tyler 2023-10-21 23:24:33 -06:00
parent d06d271c9e
commit 9f10ec36b3
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
28 changed files with 215 additions and 241 deletions

View File

@ -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*);

View File

@ -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);

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View 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);
}

View File

@ -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

View File

@ -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],

View File

@ -0,0 +1,3 @@
pub mod bio;
pub mod buf;
pub mod pipe;

View File

@ -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 };

View File

@ -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::{

View 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)
}

View File

@ -0,0 +1,4 @@
extern "C" {
pub fn kvminit();
pub fn kvminithart();
}

View File

@ -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;

View File

@ -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) -> !;

View File

@ -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() {}

View File

@ -1,4 +1,4 @@
use crate::{main, param::NCPU, riscv::*};
use crate::{main, riscv::*, NCPU};
use core::{arch::asm, ptr::addr_of};
extern "C" {

View File

@ -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<i32> {
for len in 0..max_chars {
if (*s.add(len)) == '\0' as i8 {

View File

@ -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(),

View File

@ -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
}

View File

@ -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 {

View File

@ -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;