From 4e0b510895859b201a32c3886292df67d2518012 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Thu, 4 Oct 2018 13:23:32 +0800 Subject: [PATCH 01/22] Finish comment for ristv boot. --- crate/bbl/Cargo.lock | 4 ++++ crate/bit-allocator/Cargo.lock | 14 ++++++++++++++ crate/memory/Cargo.lock | 4 ++++ crate/process/Cargo.lock | 23 +++++++++++++++++++++++ crate/sync/Cargo.lock | 4 ++++ kernel/src/arch/riscv32/memory.rs | 18 +++++++++++++++--- kernel/src/arch/riscv32/mod.rs | 5 +++++ kernel/src/arch/riscv32/paging.rs | 6 ++++++ kernel/src/arch/riscv32/timer.rs | 2 ++ kernel/src/consts.rs | 2 ++ user/ucore-ulib/Cargo.lock | 4 ++++ 11 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 crate/bbl/Cargo.lock create mode 100644 crate/bit-allocator/Cargo.lock create mode 100644 crate/memory/Cargo.lock create mode 100644 crate/process/Cargo.lock create mode 100644 crate/sync/Cargo.lock create mode 100644 user/ucore-ulib/Cargo.lock diff --git a/crate/bbl/Cargo.lock b/crate/bbl/Cargo.lock new file mode 100644 index 0000000..1204b21 --- /dev/null +++ b/crate/bbl/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "bbl" +version = "0.1.0" + diff --git a/crate/bit-allocator/Cargo.lock b/crate/bit-allocator/Cargo.lock new file mode 100644 index 0000000..bbeb945 --- /dev/null +++ b/crate/bit-allocator/Cargo.lock @@ -0,0 +1,14 @@ +[[package]] +name = "bit-allocator" +version = "0.1.0" +dependencies = [ + "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit_field" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" diff --git a/crate/memory/Cargo.lock b/crate/memory/Cargo.lock new file mode 100644 index 0000000..c6ef475 --- /dev/null +++ b/crate/memory/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ucore-memory" +version = "0.1.0" + diff --git a/crate/process/Cargo.lock b/crate/process/Cargo.lock new file mode 100644 index 0000000..a665837 --- /dev/null +++ b/crate/process/Cargo.lock @@ -0,0 +1,23 @@ +[[package]] +name = "cfg-if" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucore-process" +version = "0.1.0" +dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" +"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" diff --git a/crate/sync/Cargo.lock b/crate/sync/Cargo.lock new file mode 100644 index 0000000..5309d3c --- /dev/null +++ b/crate/sync/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ucore-sync" +version = "0.1.0" + diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 0f9cfb6..45ba782 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -4,13 +4,14 @@ use super::riscv::{addr::*, register::sstatus}; use ucore_memory::PAGE_SIZE; pub fn init() { - #[repr(align(4096))] + #[repr(align(4096))] // align the PageData struct to 4096 bytes struct PageData([u8; PAGE_SIZE]); static PAGE_TABLE_ROOT: PageData = PageData([0; PAGE_SIZE]); unsafe { sstatus::set_sum(); } // Allow user memory access - let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32)); - super::paging::setup_page_table(frame); + let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32)); + super::paging::setup_page_table(frame); // set up page table + // initialize heap and Frame allocator init_frame_allocator(); remap_the_kernel(); init_heap(); @@ -23,9 +24,19 @@ fn init_frame_allocator() { let mut ba = FRAME_ALLOCATOR.lock(); use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; + // keep memory for the kernel heap and set other physical memory available in BitAlloc ba.insert(to_range(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, MEMORY_END)); info!("FrameAllocator init end"); + /* + * @param: + * start: start address + * end: end address + * @brief: + * transform the memory address to the page number + * @retval: + * the page number range from start address to end address + */ fn to_range(start: usize, end: usize) -> Range { let page_start = (start - MEMORY_OFFSET) / PAGE_SIZE; let page_end = (end - MEMORY_OFFSET - 1) / PAGE_SIZE + 1; @@ -35,6 +46,7 @@ fn init_frame_allocator() { fn remap_the_kernel() { use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; + // set up kernel stack let kstack = Stack { top: bootstacktop as usize, bottom: bootstack as usize + PAGE_SIZE, diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 13d9ad3..140c712 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -11,10 +11,15 @@ pub mod compiler_rt; #[no_mangle] pub extern fn rust_main() -> ! { println!("Hello RISCV! {}", 123); + // First init log mod, so that we can print log info. ::logging::init(); + // Init interrupt handling. interrupt::init(); + // Init physical memory management and heap memory::init(); + // Init timer interrupt timer::init(); + ::kmain(); } diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 680448b..f6bbe77 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -10,6 +10,12 @@ use ucore_memory::memory_set::*; use ucore_memory::PAGE_SIZE; use ucore_memory::paging::*; +/* +* @param: +* Frame: page table root frame +* @brief: +* setup page table in the frame +*/ // need 1 page pub fn setup_page_table(frame: Frame) { let p2 = unsafe { &mut *(frame.start_address().as_u32() as *mut RvPageTable) }; diff --git a/kernel/src/arch/riscv32/timer.rs b/kernel/src/arch/riscv32/timer.rs index 4fb16eb..a8e9bce 100644 --- a/kernel/src/arch/riscv32/timer.rs +++ b/kernel/src/arch/riscv32/timer.rs @@ -26,12 +26,14 @@ pub fn init() { info!("timer: init end"); } +// set the next timer interrupt pub fn set_next() { // 100Hz @ QEMU let timebase = 250000; set_timer(get_cycle() + timebase); } +// set time for timer interrupt fn set_timer(t: u64) { #[cfg(feature = "no_bbl")] unsafe { diff --git a/kernel/src/consts.rs b/kernel/src/consts.rs index 4dddae0..d713b95 100644 --- a/kernel/src/consts.rs +++ b/kernel/src/consts.rs @@ -8,6 +8,7 @@ pub use self::x86_64::*; pub const MAX_CPU_NUM: usize = 8; pub const MAX_PROCESS_NUM: usize = 48; +// Memory address for riscv32 #[cfg(target_arch = "riscv32")] mod riscv { // Physical address available on THINPAD: @@ -26,6 +27,7 @@ mod riscv { pub const USER32_STACK_OFFSET: usize = USER_STACK_OFFSET; } +// Memory address for x86_64 #[cfg(target_arch = "x86_64")] mod x86_64 { // Copy from Redox consts.rs: diff --git a/user/ucore-ulib/Cargo.lock b/user/ucore-ulib/Cargo.lock new file mode 100644 index 0000000..ea99e3c --- /dev/null +++ b/user/ucore-ulib/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ucore-ulib" +version = "0.1.0" + From ddb679ce2b7594ee17966b2a2670587361bdf660 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Thu, 4 Oct 2018 20:56:11 +0800 Subject: [PATCH 02/22] update comment for bbl module, but have not finished. --- crate/bbl/src/sbi.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/crate/bbl/src/sbi.rs b/crate/bbl/src/sbi.rs index b8782b7..87007cd 100644 --- a/crate/bbl/src/sbi.rs +++ b/crate/bbl/src/sbi.rs @@ -1,5 +1,13 @@ //! Port from sbi.h +//! +//! This code is used for OS to use hardware outside with calling these implements +/* +** @brief translate implement calling message to RISCV asm +** @param which: usize ecall type +** arg0, arg1, arg2: usize ecall args +** @retval ret: usize the result of the asm +*/ #[inline(always)] fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { let ret; @@ -13,18 +21,38 @@ fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { ret } +/* +** @brief output char to console +** @param ch: usize the char to output to console +** @retval none +*/ pub fn console_putchar(ch: usize) { sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0); } +/* +** @brief input char from console +** @param none +** @retval ch: usize the char get from console +*/ pub fn console_getchar() -> usize { sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) } +/* +** @brief call this function to shutdown +** @param none +** @retval none +*/ pub fn shutdown() { sbi_call(SBI_SHUTDOWN, 0, 0, 0); } +/* +** @brief set a timer when running +** @param stime_value: u64 time to be set +** @retval none +*/ pub fn set_timer(stime_value: u64) { #[cfg(target_pointer_width = "32")] sbi_call(SBI_SET_TIMER, stime_value as usize, (stime_value >> 32) as usize, 0); @@ -32,22 +60,47 @@ pub fn set_timer(stime_value: u64) { sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0); } +/* +** @brief clear the ipi +** @param none +** @retval none +*/ pub fn clear_ipi() { sbi_call(SBI_CLEAR_IPI, 0, 0, 0); } +/* +** @brief +** @param +** @retval none +*/ pub fn send_ipi(hart_mask: *const usize) { sbi_call(SBI_SEND_IPI, hart_mask as usize, 0, 0); } +/* +** @brief +** @param +** @retval none +*/ pub fn remote_fence_i(hart_mask: *const usize) { sbi_call(SBI_REMOTE_FENCE_I, hart_mask as usize, 0, 0); } +/* +** @brief +** @param +** @retval none +*/ pub fn remote_sfence_vma(hart_mask: *const usize, _start: usize, _size: usize) { sbi_call(SBI_REMOTE_SFENCE_VMA, hart_mask as usize, 0, 0); } +/* +** @brief +** @param +** @retval none +*/ pub fn remote_sfence_vma_asid(hart_mask: *const usize, _start: usize, _size: usize, _asid: usize) { sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask as usize, 0, 0); } From f37e66a24cc21a42b3fa7f724fcbc2a20271d3c3 Mon Sep 17 00:00:00 2001 From: chenqiuhao1997 Date: Thu, 4 Oct 2018 21:02:22 +0800 Subject: [PATCH 03/22] should not update in the git --- crate/bbl/Cargo.lock | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 crate/bbl/Cargo.lock diff --git a/crate/bbl/Cargo.lock b/crate/bbl/Cargo.lock deleted file mode 100644 index 1204b21..0000000 --- a/crate/bbl/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "bbl" -version = "0.1.0" - From da85d76a0d717ebd44d18b27acd5f1412861f6f1 Mon Sep 17 00:00:00 2001 From: chenqiuhao1997 Date: Thu, 4 Oct 2018 21:02:41 +0800 Subject: [PATCH 04/22] Delete Cargo.lock --- crate/bit-allocator/Cargo.lock | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 crate/bit-allocator/Cargo.lock diff --git a/crate/bit-allocator/Cargo.lock b/crate/bit-allocator/Cargo.lock deleted file mode 100644 index bbeb945..0000000 --- a/crate/bit-allocator/Cargo.lock +++ /dev/null @@ -1,14 +0,0 @@ -[[package]] -name = "bit-allocator" -version = "0.1.0" -dependencies = [ - "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit_field" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" From 6c92a4a48f1e8b7fead5906bd73ebce954a1e472 Mon Sep 17 00:00:00 2001 From: chenqiuhao1997 Date: Thu, 4 Oct 2018 21:02:58 +0800 Subject: [PATCH 05/22] Delete Cargo.lock --- crate/memory/Cargo.lock | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 crate/memory/Cargo.lock diff --git a/crate/memory/Cargo.lock b/crate/memory/Cargo.lock deleted file mode 100644 index c6ef475..0000000 --- a/crate/memory/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ucore-memory" -version = "0.1.0" - From 1c6a02bb487855f62abae4abbf1b024cf78415f6 Mon Sep 17 00:00:00 2001 From: chenqiuhao1997 Date: Thu, 4 Oct 2018 21:03:25 +0800 Subject: [PATCH 06/22] Delete Cargo.lock --- crate/process/Cargo.lock | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 crate/process/Cargo.lock diff --git a/crate/process/Cargo.lock b/crate/process/Cargo.lock deleted file mode 100644 index a665837..0000000 --- a/crate/process/Cargo.lock +++ /dev/null @@ -1,23 +0,0 @@ -[[package]] -name = "cfg-if" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ucore-process" -version = "0.1.0" -dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" From 142103883b2ae878a8d6bfe781871c1be07fd6bd Mon Sep 17 00:00:00 2001 From: chenqiuhao1997 Date: Thu, 4 Oct 2018 21:03:39 +0800 Subject: [PATCH 07/22] Delete Cargo.lock --- crate/sync/Cargo.lock | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 crate/sync/Cargo.lock diff --git a/crate/sync/Cargo.lock b/crate/sync/Cargo.lock deleted file mode 100644 index 5309d3c..0000000 --- a/crate/sync/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ucore-sync" -version = "0.1.0" - From 96c79520cf6f341b1e30ef753e815e74063f55e8 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Thu, 4 Oct 2018 21:44:25 +0800 Subject: [PATCH 08/22] Add Cargo.lock to gitignore. --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 637c5b1..679723a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ build target /kernel/src/arch/x86_64/interrupt/vector.asm +/crate/bit-allocator/Cargo.lock +/crate/memory/Cargo.lock +/crate/bbl/Cargo.lock +/crate/sync/Cargo.lock +/crate/process/Cargo.lock \ No newline at end of file From c4b53dc8e53d7ffe23d80c8af1a5ad3256905404 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Fri, 5 Oct 2018 09:28:17 +0800 Subject: [PATCH 09/22] finish comment of sync --- crate/sync/src/main.rs | 2 ++ crate/sync/src/monitor.rs | 3 +++ crate/sync/src/mutex.rs | 3 +++ 3 files changed, 8 insertions(+) diff --git a/crate/sync/src/main.rs b/crate/sync/src/main.rs index 49c86fa..0837505 100644 --- a/crate/sync/src/main.rs +++ b/crate/sync/src/main.rs @@ -1,3 +1,5 @@ +//! entrance to test the communication in processes with solving five philosophers problem + mod mutex; mod monitor; diff --git a/crate/sync/src/monitor.rs b/crate/sync/src/monitor.rs index 2c7cb8d..b984fbc 100644 --- a/crate/sync/src/monitor.rs +++ b/crate/sync/src/monitor.rs @@ -1,3 +1,5 @@ +//! solve the five philosophers problem with monitor + use std::thread; use std::sync::{Mutex, Condvar, Arc}; use std::time::Duration; @@ -51,6 +53,7 @@ struct Table { fork_condvar: Vec, } +// the main function to test pub fn main() { let table = Arc::new(Table { fork_status: Mutex::new(vec![false; 5]), diff --git a/crate/sync/src/mutex.rs b/crate/sync/src/mutex.rs index 06b3223..eeef0f4 100644 --- a/crate/sync/src/mutex.rs +++ b/crate/sync/src/mutex.rs @@ -1,3 +1,5 @@ +//! solve the five philosophers problem with mutex + use std::thread; use std::sync::{Mutex, Arc}; use std::time::Duration; @@ -35,6 +37,7 @@ struct Table { forks: Vec>, } +// the main function to test pub fn main() { let table = Arc::new(Table { forks: vec![ From e4300d3515978ca288145afb88b006102ee17519 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 10:58:15 +0800 Subject: [PATCH 10/22] Add more comment in kernel but not finished --- kernel/src/arch/riscv32/context.rs | 1 + kernel/src/fs.rs | 2 ++ kernel/src/lib.rs | 16 ++++++++++------ kernel/src/process/mod.rs | 4 ++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs index 4a00cfa..0a6037d 100644 --- a/kernel/src/arch/riscv32/context.rs +++ b/kernel/src/arch/riscv32/context.rs @@ -11,6 +11,7 @@ pub struct TrapFrame { } /// 用于在内核栈中构造新线程的中断帧 +/// The trapframe for building new process in kernel impl TrapFrame { fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { use core::mem::zeroed; diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index fe20c6c..748cc12 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -15,6 +15,7 @@ _binary_user_riscv_img_end: "#); pub fn shell() { + // load riscv32/x86_64 user program #[cfg(target_arch = "riscv32")] let device = { extern { @@ -36,6 +37,7 @@ pub fn shell() { const BUF_SIZE: usize = 0x40000; let layout = Layout::from_size_align(BUF_SIZE, 0x1000).unwrap(); let buf = unsafe{ slice::from_raw_parts_mut(alloc(layout), BUF_SIZE) }; + // start interaction loop { print!(">> "); use console::get_line; diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 4a23294..28ef150 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -61,16 +61,20 @@ pub mod arch; pub mod arch; pub fn kmain() -> ! { + // Init the first kernel process(idle proc) process::init(); + // enable the interrupt unsafe { arch::interrupt::enable(); } - fs::shell(); + // the test is not supported in riscv32(maybe) + //thread::test::local_key(); + //thread::test::unpack(); + //sync::test::philosopher_using_mutex(); + //sync::test::philosopher_using_monitor(); + //sync::mpsc::test::test_all(); -// thread::test::local_key(); -// thread::test::unpack(); -// sync::test::philosopher_using_mutex(); -// sync::test::philosopher_using_monitor(); -// sync::mpsc::test::test_all(); + // come into shell + fs::shell(); loop {} } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 569f3d2..41355f4 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -9,6 +9,10 @@ mod context; type Processor = Processor_; +/* +* @brief: +* initialize a new kernel process (idleproc) +*/ pub fn init() { PROCESSOR.call_once(|| SpinNoIrqLock::new({ From b3e2ca8aa07a1080c2bef5b25b119cbeb6e75695 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 11:08:50 +0800 Subject: [PATCH 11/22] Merge conflict --- crate/process/src/processor.rs | 2 +- crate/sync/src/main.rs | 2 ++ crate/sync/src/monitor.rs | 3 +++ crate/sync/src/mutex.rs | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crate/process/src/processor.rs b/crate/process/src/processor.rs index 9083dad..2117528 100644 --- a/crate/process/src/processor.rs +++ b/crate/process/src/processor.rs @@ -176,7 +176,7 @@ impl Processor_ { to.status = Status::Running; self.scheduler.remove(pid); - info!("switch from {} to {} {:x?}", pid0, pid, to.context); + //info!("switch from {} to {} {:x?}", pid0, pid, to.context); unsafe { from.context.switch(&mut to.context); } } diff --git a/crate/sync/src/main.rs b/crate/sync/src/main.rs index 49c86fa..0837505 100644 --- a/crate/sync/src/main.rs +++ b/crate/sync/src/main.rs @@ -1,3 +1,5 @@ +//! entrance to test the communication in processes with solving five philosophers problem + mod mutex; mod monitor; diff --git a/crate/sync/src/monitor.rs b/crate/sync/src/monitor.rs index 2c7cb8d..b984fbc 100644 --- a/crate/sync/src/monitor.rs +++ b/crate/sync/src/monitor.rs @@ -1,3 +1,5 @@ +//! solve the five philosophers problem with monitor + use std::thread; use std::sync::{Mutex, Condvar, Arc}; use std::time::Duration; @@ -51,6 +53,7 @@ struct Table { fork_condvar: Vec, } +// the main function to test pub fn main() { let table = Arc::new(Table { fork_status: Mutex::new(vec![false; 5]), diff --git a/crate/sync/src/mutex.rs b/crate/sync/src/mutex.rs index 06b3223..eeef0f4 100644 --- a/crate/sync/src/mutex.rs +++ b/crate/sync/src/mutex.rs @@ -1,3 +1,5 @@ +//! solve the five philosophers problem with mutex + use std::thread; use std::sync::{Mutex, Arc}; use std::time::Duration; @@ -35,6 +37,7 @@ struct Table { forks: Vec>, } +// the main function to test pub fn main() { let table = Arc::new(Table { forks: vec![ From e05be94c800101654cf471d233d3c26c32d226c0 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Fri, 5 Oct 2018 12:01:00 +0800 Subject: [PATCH 12/22] finish the comment of the process --- crate/process/src/processor.rs | 133 ++++++++++++++++++++++++++++++--- crate/process/src/scheduler.rs | 36 ++++++++- crate/process/src/thread.rs | 54 ++++++++++--- 3 files changed, 204 insertions(+), 19 deletions(-) diff --git a/crate/process/src/processor.rs b/crate/process/src/processor.rs index 9083dad..80545e3 100644 --- a/crate/process/src/processor.rs +++ b/crate/process/src/processor.rs @@ -50,6 +50,13 @@ impl Process { // TODO: 除schedule()外的其它函数,应该只设置进程状态,不应调用schedule impl Processor_ { + + /* + ** @brief create a new Processor + ** @param init_context: T initiate context + ** scheduler: S the scheduler to use + ** @retval the Processor created + */ pub fn new(init_context: T, scheduler: S) -> Self { let init_proc = Process { pid: 0, @@ -70,15 +77,30 @@ impl Processor_ { } } + /* + ** @brief set the priority of current process + ** @param priority: u8 the priority to set + ** @retval none + */ pub fn set_priority(&mut self, priority: u8) { self.scheduler.set_priority(self.current_pid, priority); } + /* + ** @brief mark the current process to reschedule + ** @param none + ** @retval none + */ pub fn set_reschedule(&mut self) { let pid = self.current_pid; self.set_status(pid, Status::Ready); } + /* + ** @brief allocate the pid of the process + ** @param none + ** @retval the pid allocated + */ fn alloc_pid(&self) -> Pid { let mut next: Pid = 0; for &i in self.procs.keys() { @@ -91,6 +113,12 @@ impl Processor_ { return next; } + /* + ** @brief set the status of the process + ** @param pid: Pid the pid of process which needs to be set + ** status: Status the status to be set + ** @retval none + */ fn set_status(&mut self, pid: Pid, status: Status) { let status0 = self.get(pid).status.clone(); match (&status0, &status) { @@ -103,8 +131,12 @@ impl Processor_ { self.get_mut(pid).status = status; } - /// Called by timer. - /// Handle events. + /* + ** @brief Called by timer. + ** Handle events. + ** @param none + ** @retval none + */ pub fn tick(&mut self) { let current_pid = self.current_pid; if self.scheduler.tick(current_pid) { @@ -127,10 +159,20 @@ impl Processor_ { } } + /* + ** @brief get now time + ** @param none + ** @retval the time got + */ pub fn get_time(&self) -> usize { self.event_hub.get_time() } + /* + ** @brief add a new process + ** @param context: T the context fo the process + ** @retval the pid of new process + */ pub fn add(&mut self, context: T) -> Pid { let pid = self.alloc_pid(); let process = Process { @@ -144,8 +186,12 @@ impl Processor_ { pid } - /// Called every interrupt end - /// Do schedule ONLY IF current status != Running + /* + ** @brief Called every interrupt end + ** Do schedule ONLY IF current status != Running + ** @param none + ** @retval none + */ pub fn schedule(&mut self) { if self.get(self.current_pid).status == Status::Running { return; @@ -154,9 +200,13 @@ impl Processor_ { self.switch_to(pid); } - /// Switch process to `pid`, switch page table if necessary. - /// Store `rsp` and point it to target kernel stack. - /// The current status must be set before, and not be `Running`. + /* + ** @brief Switch process to `pid`, switch page table if necessary. + Store `rsp` and point it to target kernel stack. + The current status must be set before, and not be `Running`. + ** @param the pid of the process to switch + ** @retval none + */ fn switch_to(&mut self, pid: Pid) { // for debug print let pid0 = self.current_pid; @@ -180,23 +230,57 @@ impl Processor_ { unsafe { from.context.switch(&mut to.context); } } + /* + ** @brief get process by pid + ** @param pid: Pid the pid of the process + ** @retval the process struct + */ fn get(&self, pid: Pid) -> &Process { self.procs.get(&pid).unwrap() } + + /* + ** @brief get mut process struct by pid + ** @param pid: Pid the pid of the process + ** @retval the mut process struct + */ fn get_mut(&mut self, pid: Pid) -> &mut Process { self.procs.get_mut(&pid).unwrap() } + + /* + ** @brief get context of current process + ** @param none + ** @retval current context + */ pub fn current_context(&self) -> &T { &self.get(self.current_pid).context } + + /* + ** @brief get pid of current process + ** @param none + ** @retval current pid + */ pub fn current_pid(&self) -> Pid { self.current_pid } + /* + ** @brief kill a process by pid + ** @param pid: Pid the pid of the process to kill + ** @retval none + */ pub fn kill(&mut self, pid: Pid) { self.exit(pid, 0x1000); // TODO: error code for killed } + /* + ** @brief exit a process by pid + ** @param pid: Pid the pid to exit + ** error_code: ErrorCode the error code when exiting + ** @retval none + */ pub fn exit(&mut self, pid: Pid, error_code: ErrorCode) { info!("{} exit, code: {}", pid, error_code); self.set_status(pid, Status::Exited(error_code)); @@ -207,18 +291,40 @@ impl Processor_ { } } + /* + ** @brief let a process to sleep for a while + ** @param pid: Pid the pid of the process to sleep + ** time: usize the time to sleep + ** @retval none + */ pub fn sleep(&mut self, pid: Pid, time: usize) { self.set_status(pid, Status::Sleeping); self.event_hub.push(time, Event::Wakeup(pid)); } + + /* + ** @brief let a process to sleep until wake up + ** @param pid: Pid the pid of the process to sleep + ** @retval none + */ pub fn sleep_(&mut self, pid: Pid) { self.set_status(pid, Status::Sleeping); } + + /* + ** @brief wake up al sleeping process + ** @param pid: Pid the pid of the process to wake up + ** @retval none + */ pub fn wakeup_(&mut self, pid: Pid) { self.set_status(pid, Status::Ready); } - /// Let current process wait for another + /* + ** @brief Let current process wait for another + ** @param pid: Pid the pid of the process to wait for + ** @retval the result of wait + */ pub fn current_wait_for(&mut self, pid: Pid) -> WaitResult { info!("current {} wait for {:?}", self.current_pid, pid); if self.procs.values().filter(|&p| p.parent == self.current_pid).next().is_none() { @@ -236,7 +342,11 @@ impl Processor_ { WaitResult::Ok(pid, exit_code) } - /// Try to find a exited wait target + /* + ** @brief Try to find a exited wait target + ** @param pid: Pid the pid of the process to wait for + ** @retval the pid found or none + */ fn try_wait(&mut self, pid: Pid) -> Option { match pid { 0 => self.procs.values() @@ -246,6 +356,11 @@ impl Processor_ { } } + /* + ** @brief find one process which is waiting for the input process + ** @param pid: Pid the pid of the target process + ** @retval the pid of the waiting process or none + */ fn find_waiter(&self, pid: Pid) -> Option { self.procs.values().find(|&p| { p.status == Status::Waiting(pid) || diff --git a/crate/process/src/scheduler.rs b/crate/process/src/scheduler.rs index 4d8e696..cfc42a4 100644 --- a/crate/process/src/scheduler.rs +++ b/crate/process/src/scheduler.rs @@ -2,18 +2,51 @@ use alloc::{collections::BinaryHeap, vec::Vec}; type Pid = usize; -/// + +// implements of process scheduler pub trait Scheduler { + + /* + ** @brief add a new process + ** @param pid: Pid the pid of the process to add + ** @retval none + */ fn insert(&mut self, pid: Pid); + + /* + ** @brief remove a processs from the list + ** @param pid: Pid the pid of the process to remove + ** @retval none + */ fn remove(&mut self, pid: Pid); + + /* + ** @brief choose a process to run next + ** @param none + ** @retval Option the pid of the process to run or none + */ fn select(&mut self) -> Option; + + /* + ** @brief when a clock interrupt occurs, update the list and check whether need to reschedule + ** @param current: Pid the pid of the process which is running now + ** @retval bool if need to reschedule + */ fn tick(&mut self, current: Pid) -> bool; // need reschedule? + + /* + ** @brief set the priority of the process + ** @param pid: Pid the pid of the process to be set + ** priority: u8 the priority to be set + ** @retval none + */ fn set_priority(&mut self, pid: Pid, priority: u8); } pub use self::rr::RRScheduler; pub use self::stride::StrideScheduler; +// use round-robin scheduling mod rr { use super::*; @@ -106,6 +139,7 @@ mod rr { } } +// use stride scheduling mod stride { use super::*; diff --git a/crate/process/src/thread.rs b/crate/process/src/thread.rs index 1a93dd8..3e45c58 100644 --- a/crate/process/src/thread.rs +++ b/crate/process/src/thread.rs @@ -50,7 +50,11 @@ pub struct ThreadMod { } impl ThreadMod { - /// Gets a handle to the thread that invokes it. + /* + ** @brief Gets a handle to the thread that invokes it. + ** @param none + ** @retval the thread to get + */ pub fn current() -> Thread { Thread { pid: S::processor().current_pid(), @@ -58,7 +62,11 @@ impl ThreadMod { } } - /// Puts the current thread to sleep for the specified amount of time. + /* + ** @brief Puts the current thread to sleep for the specified amount of time. + ** @param dur: Duration the time to sleep + ** @retval none + */ pub fn sleep(dur: Duration) { let time = dur_to_ticks(dur); info!("sleep: {:?} ticks", time); @@ -72,7 +80,11 @@ impl ThreadMod { } } - /// Spawns a new thread, returning a JoinHandle for it. + /* + ** @brief Spawns a new thread, returning a JoinHandle for it. + ** @param f: F the thread to start + ** @retval JoinHandle the JoinHandle of the new thread + */ pub fn spawn(f: F) -> JoinHandle where F: Send + 'static + FnOnce() -> T, @@ -103,7 +115,11 @@ impl ThreadMod { } } - /// Cooperatively gives up a timeslice to the OS scheduler. + /* + ** @brief Cooperatively gives up a timeslice to the OS scheduler. + ** @param none + ** @retval none + */ pub fn yield_now() { info!("yield:"); let mut processor = S::processor(); @@ -111,7 +127,11 @@ impl ThreadMod { processor.schedule(); } - /// Blocks unless or until the current thread's token is made available. + /* + ** @brief Blocks unless or until the current thread's token is made available. + ** @param none + ** @retval none + */ pub fn park() { info!("park:"); let mut processor = S::processor(); @@ -128,12 +148,20 @@ pub struct Thread { } impl Thread { - /// Atomically makes the handle's token available if it is not already. + /* + ** @brief Atomically makes the handle's token available if it is not already. + ** @param none + ** @retval none + */ pub fn unpark(&self) { let mut processor = S::processor(); processor.wakeup_(self.pid); } - /// Gets the thread's unique identifier. + /* + ** @brief Gets the thread's unique identifier. + ** @param none + ** @retval usize the the thread's unique identifier + */ pub fn id(&self) -> usize { self.pid } @@ -146,11 +174,19 @@ pub struct JoinHandle { } impl JoinHandle { - /// Extracts a handle to the underlying thread. + /* + ** @brief Extracts a handle to the underlying thread. + ** @param none + ** @retval the thread of the handle + */ pub fn thread(&self) -> &Thread { &self.thread } - /// Waits for the associated thread to finish. + /* + ** @brief Waits for the associated thread to finish. + ** @param none + ** @retval Result the result of the associated thread + */ pub fn join(self) -> Result { let mut processor = S::processor(); match processor.current_wait_for(self.thread.pid) { From 2264f69ef7f51638f9bf9481f084d436b00a6382 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 12:36:50 +0800 Subject: [PATCH 13/22] Add reports --- docs/OSTrain2018docs-g4/expr1/report-lcy.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/OSTrain2018docs-g4/expr1/report-lcy.md diff --git a/docs/OSTrain2018docs-g4/expr1/report-lcy.md b/docs/OSTrain2018docs-g4/expr1/report-lcy.md new file mode 100644 index 0000000..43e5b4e --- /dev/null +++ b/docs/OSTrain2018docs-g4/expr1/report-lcy.md @@ -0,0 +1,11 @@ +# Rust OS 实验一分析报告 +## 1 环境配置 +依据[RustOS开发文档](https://rucore.gitbook.io/rust-os-docs/kai-fa-huan-jing-pei-zhi)中的说明进行安装。编辑器采用VSCode+Rust插件。 +成功重现RustOS的交叉编译和在qemu上的x86-64和riscv32的运行步骤重现。 + +## 2 注释完善 +我负责kernel模块的注释完善工作,主要对arch=riscv32从启动到进入shell涉及的代码注释进行了完善,其余部分注释尚未完成有待后续分析完善。 + +## 3 分析测试 +### 3.0 现有测试分析 +现有框架下已经有sync和thread的test但是riscv32下这些test均无法编译通过,询问王润基后推测原因是目前编译器对RISCV原子指令支持不全。因此尝试从ucore lab中移植一些test过来,便于后续lab的裁剪。 From 5b4aefdb0d42b260a822815e8a7b2852c627a1f8 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 19:38:14 +0800 Subject: [PATCH 14/22] Add comment for riscv32 context --- kernel/src/arch/riscv32/context.rs | 61 +++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs index 0a6037d..82b3c9d 100644 --- a/kernel/src/arch/riscv32/context.rs +++ b/kernel/src/arch/riscv32/context.rs @@ -3,44 +3,69 @@ use super::super::riscv::register::*; #[derive(Debug, Clone)] #[repr(C)] pub struct TrapFrame { - pub x: [usize; 32], - pub sstatus: sstatus::Sstatus, - pub sepc: usize, - pub sbadaddr: usize, - pub scause: scause::Scause, + pub x: [usize; 32], // general registers + pub sstatus: sstatus::Sstatus, // Supervisor Status Register + pub sepc: usize, // Supervisor exception program counter (here is used to save the process program entry addr?) + pub sbadaddr: usize, // Supervisor bad address + pub scause: scause::Scause, // scause register: record the cause of exception/interrupt/trap } -/// 用于在内核栈中构造新线程的中断帧 -/// The trapframe for building new process in kernel +/// Generate the trapframe for building new thread in kernel impl TrapFrame { + /* + * @param: + * entry: program entry for the thread + * arg: a0 + * sp: stack top + * @brief: + * generate a trapfram for building a new kernel thread + * @retval: + * the trapframe for new kernel thread + */ fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { use core::mem::zeroed; let mut tf: Self = unsafe { zeroed() }; tf.x[10] = arg; // a0 - tf.x[2] = sp; + tf.x[2] = sp; tf.sepc = entry as usize; tf.sstatus = sstatus::read(); + // Supervisor Previous Interrupt Enable tf.sstatus.set_spie(true); + // Supervisor Interrupt Disable tf.sstatus.set_sie(false); + // Supervisor Previous Privilege Mode is Supervisor tf.sstatus.set_spp(sstatus::SPP::Supervisor); tf } + + /* + * @param: + * entry_addr: program entry for the thread + * sp: stack top + * @brief: + * generate a trapfram for building a new user thread + * @retval: + * the trapframe for new user thread + */ fn new_user_thread(entry_addr: usize, sp: usize) -> Self { use core::mem::zeroed; let mut tf: Self = unsafe { zeroed() }; tf.x[2] = sp; tf.sepc = entry_addr; tf.sstatus = sstatus::read(); + // Supervisor Previous Interrupt Disable ? tf.sstatus.set_spie(false); // Enable interrupt + // Supervisor Previous Privilege Mode is User tf.sstatus.set_spp(sstatus::SPP::User); tf } + pub fn is_user(&self) -> bool { unimplemented!() } } -/// 新线程的内核栈初始内容 +/// kernel stack contents for a new thread #[derive(Debug)] #[repr(C)] pub struct InitStack { @@ -49,8 +74,16 @@ pub struct InitStack { } impl InitStack { + /* + * @param: + * stack_top: the pointer to kernel stack stop + * @brief: + * save the InitStack on the kernel stack stop + * @retval: + * a Context with ptr in it + */ unsafe fn push_at(self, stack_top: usize) -> Context { - let ptr = (stack_top as *mut Self).offset(-1); + let ptr = (stack_top as *mut Self).offset(-1); //real kernel stack top *ptr = self; Context(ptr as usize) } @@ -74,6 +107,7 @@ impl ContextData { } } +/// A struct only contain one usize element #[derive(Debug)] pub struct Context(usize); @@ -133,10 +167,17 @@ impl Context { : : : : "volatile" ) } + /* + * @brief: + * generate a null Context + * @retval: + * a null Context + */ pub unsafe fn null() -> Self { Context(0) } + pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self { InitStack { context: ContextData::new(cr3), From 65df061ec698a392aa0edc9a700a1f39f77668c1 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 22:16:07 +0800 Subject: [PATCH 15/22] Update expr1 report. --- docs/OSTrain2018docs-g4/expr1/report-lcy.md | 29 ++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) mode change 100644 => 100755 docs/OSTrain2018docs-g4/expr1/report-lcy.md diff --git a/docs/OSTrain2018docs-g4/expr1/report-lcy.md b/docs/OSTrain2018docs-g4/expr1/report-lcy.md old mode 100644 new mode 100755 index 43e5b4e..52aea10 --- a/docs/OSTrain2018docs-g4/expr1/report-lcy.md +++ b/docs/OSTrain2018docs-g4/expr1/report-lcy.md @@ -8,4 +8,31 @@ ## 3 分析测试 ### 3.0 现有测试分析 -现有框架下已经有sync和thread的test但是riscv32下这些test均无法编译通过,询问王润基后推测原因是目前编译器对RISCV原子指令支持不全。因此尝试从ucore lab中移植一些test过来,便于后续lab的裁剪。 +现有RustOS shell下已经包含了一部分测试程序,测试结果如下(以下测试结果基于arch=riscv32下): +| 测试程序 | 是否通过 | 错误原因分析 | +| :------: | :------: | :------: | +| waitkill | 通过 | | +| sleep | 通过 | | +| spin | 通过 | | +| sh | 未通过 | unknown syscall id: 0x66, args: [0, 7000ff97, 1, 7000ff70, 25, 73]
可能是由于尚未实现sh这一系统调用 | +| forktest | 通过 | | +| faultread | 未通过 | [INFO] open: path: "stdin:", flags: 0
[INFO] open: path: "stdout:", flags: 1
[ERROR] Process 2 error
推测是标准输入输出的错误? | +| forktree | 未通过 | PANIC in src/lang.rs at line 22
out of memory
似乎是由于“目前所有没被wait过的进程退出后,内存不会被回收”导致的问题| +| divzero | 通过 | | +| yield | 通过 | | +| faultreadkernel | 未通过| 原因同faultread | +| exit | 通过 | | +| softint | 未实现? | | +| badsegment | 通过 | | +| hello | 通过 | | +| ls | 未实现 | | +| priority | 通过 | | +| badarg | 未通过 | PANIC in /home/lcy1996/.rustup/toolchains/nightly-2018-09-18-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/option.rs at line 345
called \`Option::unwrap()\` on a \`None\` value
内核bug?错误原因需要进一步探索| +| testbss | 未通过 | PANIC in /home/lcy1996/.rustup/toolchains/nightly-2018-09-18-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/option.rs at line 1000
failed to allocate frame
内核bug?错误原因需要进一步探索| +| pgdir | 未通过 | [ERROR] unknown syscall id: 0x1f, args: [a, ffff6ad9, 2, 0, 15, ffffffff]
推测原因是尚未实现0x1f这个系统调用 | +| matrix | 通过 | | +| sleepkill | 未通过 | PANIC in /home/lcy1996/Documents/OSTrain/RustOS/crate/process/src/event_hub.rs at line 55
attempt to add with overflow
推测与forktree出错原因相同| + +此外现有框架下已经有sync和thread的test但是riscv32下这些test均无法编译通过,询问王润基后推测原因是目前编译器对RISCV原子指令支持不全。因此尝试从ucore lab中移植一些test过来,便于后续lab的裁剪。 + + From 91455d163d88e5bf86211c4822b34ced373fef33 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Fri, 5 Oct 2018 23:39:28 +0800 Subject: [PATCH 16/22] Finish comment riscv context. --- kernel/src/arch/riscv32/context.rs | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs index 82b3c9d..2a61cf4 100644 --- a/kernel/src/arch/riscv32/context.rs +++ b/kernel/src/arch/riscv32/context.rs @@ -103,6 +103,7 @@ struct ContextData { impl ContextData { fn new(satp: usize) -> Self { + // satp(asid) just like cr3, save the physical address for Page directory? ContextData { ra: __trapret as usize, satp, ..ContextData::default() } } } @@ -177,24 +178,59 @@ impl Context { Context(0) } - + /* + * @param: + * entry: program entry for the thread + * arg: a0 + * kstack_top: kernel stack top + * cr3: cr3 register, save the physical address of Page directory + * @brief: + * generate the content of kernel stack for the new kernel thread and save it's address at kernel stack top - 1 + * @retval: + * a Context struct with the pointer to the kernel stack top - 1 as its only element + */ pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self { InitStack { context: ContextData::new(cr3), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), }.push_at(kstack_top) } + + /* + * @param: + * entry_addr: program entry for the thread + * ustack_top: user stack top + * kstack_top: kernel stack top + * is32: whether the cpu is 32 bit or not + * cr3: cr3 register, save the physical address of Page directory + * @brief: + * generate the content of kernel stack for the new user thread and save it's address at kernel stack top - 1 + * @retval: + * a Context struct with the pointer to the kernel stack top - 1 as its only element + */ pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, is32: bool, cr3: usize) -> Self { InitStack { context: ContextData::new(cr3), tf: TrapFrame::new_user_thread(entry_addr, ustack_top), }.push_at(kstack_top) } + + /* + * @param: + * TrapFrame: the trapframe of the forked process(thread) + * kstack_top: kernel stack top + * cr3: cr3 register, save the physical address of Page directory + * @brief: + * fork and generate a new process(thread) Context according to the TrapFrame and save it's address at kernel stack top - 1 + * @retval: + * a Context struct with the pointer to the kernel stack top - 1 as its only element + */ pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self { InitStack { context: ContextData::new(cr3), tf: { let mut tf = tf.clone(); + // fork function's ret value, the new process is 0 tf.x[10] = 0; // a0 tf }, From 2157e4bbcfa97fa61d5be67c0a2e01956b07007b Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Sat, 6 Oct 2018 01:45:56 +0800 Subject: [PATCH 17/22] Add comment for interrutp and trap code --- docs/OSTrain2018docs-g4/expr1/report-lcy.md | 6 +-- kernel/src/arch/riscv32/context.rs | 2 +- kernel/src/arch/riscv32/interrupt.rs | 52 ++++++++++++++++++++- kernel/src/trap.rs | 10 ++++ 4 files changed, 65 insertions(+), 5 deletions(-) mode change 100755 => 100644 docs/OSTrain2018docs-g4/expr1/report-lcy.md diff --git a/docs/OSTrain2018docs-g4/expr1/report-lcy.md b/docs/OSTrain2018docs-g4/expr1/report-lcy.md old mode 100755 new mode 100644 index 52aea10..7d5d8dc --- a/docs/OSTrain2018docs-g4/expr1/report-lcy.md +++ b/docs/OSTrain2018docs-g4/expr1/report-lcy.md @@ -16,11 +16,11 @@ | spin | 通过 | | | sh | 未通过 | unknown syscall id: 0x66, args: [0, 7000ff97, 1, 7000ff70, 25, 73]
可能是由于尚未实现sh这一系统调用 | | forktest | 通过 | | -| faultread | 未通过 | [INFO] open: path: "stdin:", flags: 0
[INFO] open: path: "stdout:", flags: 1
[ERROR] Process 2 error
推测是标准输入输出的错误? | +| faultread | 通过 | [INFO] open: path: "stdin:", flags: 0
[INFO] open: path: "stdout:", flags: 1
[ERROR] Process 2 error
系统似乎成功处理了该异常并正确结束该进程? | | forktree | 未通过 | PANIC in src/lang.rs at line 22
out of memory
似乎是由于“目前所有没被wait过的进程退出后,内存不会被回收”导致的问题| | divzero | 通过 | | | yield | 通过 | | -| faultreadkernel | 未通过| 原因同faultread | +| faultreadkernel | 通过 | 原因同faultread | | exit | 通过 | | | softint | 未实现? | | | badsegment | 通过 | | @@ -29,7 +29,7 @@ | priority | 通过 | | | badarg | 未通过 | PANIC in /home/lcy1996/.rustup/toolchains/nightly-2018-09-18-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/option.rs at line 345
called \`Option::unwrap()\` on a \`None\` value
内核bug?错误原因需要进一步探索| | testbss | 未通过 | PANIC in /home/lcy1996/.rustup/toolchains/nightly-2018-09-18-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/option.rs at line 1000
failed to allocate frame
内核bug?错误原因需要进一步探索| -| pgdir | 未通过 | [ERROR] unknown syscall id: 0x1f, args: [a, ffff6ad9, 2, 0, 15, ffffffff]
推测原因是尚未实现0x1f这个系统调用 | +| pgdir | 未通过 | [ERROR] unknown syscall id: 0x1f, args: [a, ffff6ad9, 2, 0, 15, ffffffff]
阅读syscall.rs推测原因是尚未实现0x1f(PGDIR)这个系统调用 | | matrix | 通过 | | | sleepkill | 未通过 | PANIC in /home/lcy1996/Documents/OSTrain/RustOS/crate/process/src/event_hub.rs at line 55
attempt to add with overflow
推测与forktree出错原因相同| diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs index 2a61cf4..0dc73e8 100644 --- a/kernel/src/arch/riscv32/context.rs +++ b/kernel/src/arch/riscv32/context.rs @@ -5,7 +5,7 @@ use super::super::riscv::register::*; pub struct TrapFrame { pub x: [usize; 32], // general registers pub sstatus: sstatus::Sstatus, // Supervisor Status Register - pub sepc: usize, // Supervisor exception program counter (here is used to save the process program entry addr?) + pub sepc: usize, // Supervisor exception program counter, save the trap virtual address (here is used to save the process program entry addr?) pub sbadaddr: usize, // Supervisor bad address pub scause: scause::Scause, // scause register: record the cause of exception/interrupt/trap } diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index 58ed672..a3784c5 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -4,6 +4,10 @@ pub use self::context::*; #[path = "context.rs"] mod context; +/* +* @brief: +* initialize the interrupt status +*/ pub fn init() { extern { fn __alltraps(); @@ -18,11 +22,21 @@ pub fn init() { info!("interrupt: init end"); } +/* +* @brief: +* enable interrupt +*/ #[inline(always)] pub unsafe fn enable() { sstatus::set_sie(); } +/* +* @brief: +* store and disable interrupt +* @retbal: +* a usize value store the origin sie +*/ #[inline(always)] pub unsafe fn disable_and_store() -> usize { let e = sstatus::read().sie() as usize; @@ -30,6 +44,12 @@ pub unsafe fn disable_and_store() -> usize { e } +/* +* @param: +* flags: input flag +* @brief: +* enable interrupt if flags != 0 +*/ #[inline(always)] pub unsafe fn restore(flags: usize) { if flags != 0 { @@ -37,6 +57,12 @@ pub unsafe fn restore(flags: usize) { } } +/* +* @param: +* TrapFrame: the trapFrame of the Interrupt/Exception/Trap to be processed +* @brief: +* process the Interrupt/Exception/Trap +*/ #[no_mangle] pub extern fn rust_trap(tf: &mut TrapFrame) { use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E}; @@ -51,17 +77,33 @@ pub extern fn rust_trap(tf: &mut TrapFrame) { trace!("Interrupt end"); } +/* +* @brief: +* process timer interrupt +*/ fn timer() { ::trap::timer(); super::timer::set_next(); } +/* +* @param: +* TrapFrame: the Trapframe for the syscall +* @brief: +* process syscall +*/ fn syscall(tf: &mut TrapFrame) { tf.sepc += 4; // Must before syscall, because of fork. let ret = ::syscall::syscall(tf.x[10], [tf.x[11], tf.x[12], tf.x[13], tf.x[14], tf.x[15], tf.x[16]], tf); tf.x[10] = ret as usize; } +/* +* @param: +* TrapFrame: the Trapframe for the illegal inst exception +* @brief: +* process IllegalInstruction exception +*/ fn illegal_inst(tf: &mut TrapFrame) { if !emulate_mul_div(tf) { ::trap::error(tf); @@ -69,6 +111,14 @@ fn illegal_inst(tf: &mut TrapFrame) { } /// Migrate from riscv-pk +/* +* @param: +* TrapFrame: the Trapframe for the illegal inst exception +* @brief: +* emulate the multiply and divide operation (if not this kind of operation return false) +* @retval: +* a bool indicates whether emulate the multiply and divide operation successfully +*/ fn emulate_mul_div(tf: &mut TrapFrame) -> bool { let insn = unsafe { *(tf.sepc as *const usize) }; let rs1 = tf.x[get_reg(insn, RS1)]; @@ -94,7 +144,7 @@ fn emulate_mul_div(tf: &mut TrapFrame) -> bool { return false; }; tf.x[get_reg(insn, RD)] = rd; - tf.sepc += 4; + tf.sepc += 4; // jump to next instruction return true; fn get_reg(inst: usize, offset: usize) -> usize { diff --git a/kernel/src/trap.rs b/kernel/src/trap.rs index 42c7abc..5430e43 100644 --- a/kernel/src/trap.rs +++ b/kernel/src/trap.rs @@ -1,6 +1,10 @@ use process::*; use arch::interrupt::TrapFrame; +/* +* @brief: +* process timer interrupt +*/ pub fn timer() { let mut processor = processor(); processor.tick(); @@ -12,6 +16,12 @@ pub fn before_return() { } } +/* +* @param: +* TrapFrame: the error's trapframe +* @brief: +* process the error trap, if processor inited then exit else panic! +*/ pub fn error(tf: &TrapFrame) -> ! { if let Some(processor) = PROCESSOR.try() { let mut processor = processor.lock(); From cef2d792bea4973e945ec5da8191d854852eba00 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Mon, 8 Oct 2018 01:47:13 +0800 Subject: [PATCH 18/22] Add part of comments for riscv32 module --- kernel/src/arch/riscv32/memory.rs | 12 ++++++++++++ kernel/src/arch/riscv32/paging.rs | 12 ++++++++++++ kernel/src/arch/riscv32/timer.rs | 22 ++++++++++++++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 45ba782..6075cca 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -3,6 +3,10 @@ use memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, M use super::riscv::{addr::*, register::sstatus}; use ucore_memory::PAGE_SIZE; +/* +* @brief: +* Init the mermory management module, allow memory access and set up page table and init heap and frame allocator +*/ pub fn init() { #[repr(align(4096))] // align the PageData struct to 4096 bytes struct PageData([u8; PAGE_SIZE]); @@ -17,6 +21,10 @@ pub fn init() { init_heap(); } +/* +* @brief: +* Init frame allocator, here use a BitAlloc implemented by segment tree. +*/ fn init_frame_allocator() { use bit_allocator::BitAlloc; use core::ops::Range; @@ -44,6 +52,10 @@ fn init_frame_allocator() { } } +/* +* @brief: +* remmap the kernel memory address +*/ fn remap_the_kernel() { use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; // set up kernel stack diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index f6bbe77..834c830 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -42,10 +42,22 @@ pub struct PageEntry(PageTableEntry); impl PageTable for ActivePageTable { type Entry = PageEntry; + /* + * @param: + * addr: the virtual addr to be matched + * target: the physical addr to be matched with addr + * @brief: + * map the virtual address 'addr' to the physical address 'target' in pagetable. + * @retval: + * the matched PageEntry + */ fn map(&mut self, addr: usize, target: usize) -> &mut PageEntry { + // the flag for the new page entry let flags = EF::VALID | EF::READABLE | EF::WRITABLE; + // here page is for the virtual address while frame is for the physical, both of them is 4096 bytes align let page = Page::of_addr(VirtAddr::new(addr)); let frame = Frame::of_addr(PhysAddr::new(target as u32)); + // map the page to the frame using FrameAllocatorForRiscv self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv) .unwrap().flush(); self.get_entry(addr) diff --git a/kernel/src/arch/riscv32/timer.rs b/kernel/src/arch/riscv32/timer.rs index a8e9bce..1961bc5 100644 --- a/kernel/src/arch/riscv32/timer.rs +++ b/kernel/src/arch/riscv32/timer.rs @@ -1,11 +1,19 @@ use super::riscv::register::*; use super::bbl::sbi; +/* +* @brief: +* get timer cycle for 64 bit cpu +*/ #[cfg(target_pointer_width = "64")] pub fn get_cycle() -> u64 { time::read() as u64 } +/* +* @brief: +* get timer cycle for 32 bit cpu +*/ #[cfg(target_pointer_width = "32")] pub fn get_cycle() -> u64 { loop { @@ -18,6 +26,10 @@ pub fn get_cycle() -> u64 { } } +/* +* @brief: +* enable supervisor timer interrupt and set next timer interrupt +*/ pub fn init() { // Enable supervisor timer interrupt unsafe { sie::set_stimer(); } @@ -26,14 +38,20 @@ pub fn init() { info!("timer: init end"); } -// set the next timer interrupt +/* +* @brief: +* set the next timer interrupt +*/ pub fn set_next() { // 100Hz @ QEMU let timebase = 250000; set_timer(get_cycle() + timebase); } -// set time for timer interrupt +/* +* @brief: +* set time for timer interrupt +*/ fn set_timer(t: u64) { #[cfg(feature = "no_bbl")] unsafe { From 96cdf37b15b7170b02d21db7175aa338f53afe42 Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Tue, 9 Oct 2018 21:11:14 +0800 Subject: [PATCH 19/22] Add some comment for paging and add proposal doc --- docs/OSTrain2018docs-g4/expr2/proposal.md | 39 +++++++++++++++++++++++ kernel/src/arch/riscv32/interrupt.rs | 1 + kernel/src/arch/riscv32/paging.rs | 38 ++++++++++++++++++++++ kernel/src/consts.rs | 3 ++ 4 files changed, 81 insertions(+) create mode 100755 docs/OSTrain2018docs-g4/expr2/proposal.md diff --git a/docs/OSTrain2018docs-g4/expr2/proposal.md b/docs/OSTrain2018docs-g4/expr2/proposal.md new file mode 100755 index 0000000..185a383 --- /dev/null +++ b/docs/OSTrain2018docs-g4/expr2/proposal.md @@ -0,0 +1,39 @@ +# Rust OS 教学lab实验的制作 方案设计文档 +## 1 实验目标 +* 补全部分Rust OS尚未实现的基础功能 +* 从现有Rust OS中裁剪出一个子集用于教学lab +* 参考现有ucore OS实验设计Rust OS教学lab(基于riscv32)并完成相关测试代码的编写 +* 完成教学实验说明文档,并补充每一个lab所需的代码注释 +* 尝试配置基于浏览器的虚拟机实验环境 + +## 2 背景 +现有的操作系统大实验是基于ucore OS完成的,总共由8个小实验完成,包含了操作系统从启动到进入shell的全过程,内容包括硬件启动,异常处理,内存管理,进程管理,同步互斥,文件系统等操作系统基础知识点。[ucore OS lab](https://github.com/chyyuu/ucore_os_lab)已经具有十分完善的[教学文档](https://objectkuan.gitbooks.io/ucore-docs/content/index.html)。 + +ucoreOS lab基于x86结构,主要由C语言完成编写。x86架构由于其向后兼容性等种种原因,整体结构比较复杂,作为教学操作系统门槛比较高。相比较而言riscv32架构简洁高效,易于实现,是教学用cpu结构的不二选择。此外C语言的安全性一直以来饱受诟病。相较C语言,Rust语言更加简洁、安全,模块性好,可复用性强,可以通过采用现有库文件更优雅的解决文件。**最重要的是王润基等同学已经参照ucore OS实现了一个比较完整的基于x86_64和riscv32的Rust OS**,因此我们决定再次基础上进行完善并裁剪出一个基于riscv32的教学用RustOS lab。 + +## 3 实验设计与分工 +### 3.1 完善现有Rust OS基础功能 +现有Rust OS在riscv32环境下还存在一些bugs或unimplemented features,要想完成一个类似于ucore OS lab的教学实验框架,首先要把这些漏洞完善。现简单将每个lab目前待完善的地方和负责填坑的人列举如下: +**lab1:**主要涉及实验框架的编译、调试,OS bootloader启动过程。现有实验框架已经完成,不需要完善。 +**lab2:**主要涉及物理内存管理,由于riscv32结构的物理内存管理仅通过一个二级页表来实现,不像x86架构下还需要兼容段表(虽然最终只是一个自映射),因此这部分比原本的ucore OS lab会更简洁、易理解一些。另外RustOS 的现有物理内存分配算法是通过线段树实现的,且相较原本的内存分配算法复用性更好。本分内容已经完成。 +**lab3:**该部分实验主要涉及虚存管理部分,**目前RUST OS仅针对x86_64结构实现了page fault的处理**,后续需要完成riscv32的page fault处理和虚存管理部分。 +**lab4:**主要涉及内核线程创建和调度,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 +**lab5:**主要涉及用户线程管理,此部分内容似乎同样已经完成,是否存在问题有待后续测试。**事实上之前测试中似乎又提到没有wait过的进程退出内存不会被回收,有待完善。** +**lab6:**此部分主要涉及进程调度器的相关内容,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 +**lab7:**@陈秋昊 +**lab8:**@朱书聪 +其中前6个lab现有框架已经实现完成,主要涉及虚存管理和进程管理的部分内容有待完善,此部分计划由刘辰屹来完成。lab7在riscv32下的完善计划由陈秋昊来完成,lab8的完善计划由朱书聪来完成。上述为暂时的分工,实际分工视各部分难度大小再进行调整。 +此部分计划在第5周结束前完成。 + +### 3.2 教学lab的裁剪和测试程序的编写 +此部分内容计划在第6周结束前完成 + +### 3.3 教学lab文档编写 +此部分内容计划在第7周结束前完成,可能向后顺延至第8周 + +### 3.4 在浏览器中运行Rust OS lab +目前没有能够探索到实现此计划的可行性,待定。 + +## 4 参考文献 +ucore OS lab实验指导书:https://objectkuan.gitbooks.io/ucore-docs/content/index.html +王润基同学的Rust OS开发文档:https://rucore.gitbook.io/rust-os-docs/ \ No newline at end of file diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index a3784c5..4e73f31 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -67,6 +67,7 @@ pub unsafe fn restore(flags: usize) { pub extern fn rust_trap(tf: &mut TrapFrame) { use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E}; trace!("Interrupt: {:?}", tf.scause.cause()); + // page should be processed here but not now match tf.scause.cause() { Trap::Interrupt(I::SupervisorTimer) => timer(), Trap::Exception(E::IllegalInstruction) => illegal_inst(tf), diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 834c830..69eef0a 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -63,33 +63,71 @@ impl PageTable for ActivePageTable { self.get_entry(addr) } + /* + * @param: + * addr: virtual address of which the mapped physical frame should be unmapped + * @bridf: + ^ unmap the virtual addresses' mapped physical frame + */ fn unmap(&mut self, addr: usize) { let page = Page::of_addr(VirtAddr::new(addr)); let (frame, flush) = self.0.unmap(page).unwrap(); flush.flush(); } + /* + * @param: + * addr:input virtual address + * @brief: + * get the pageEntry of 'addr' + * @retval: + * a mutable PageEntry reference of 'addr' + */ fn get_entry(&mut self, addr: usize) -> &mut PageEntry { let page = Page::of_addr(VirtAddr::new(addr)); + // ??? let _ = self.0.translate_page(page); let entry_addr = ((addr >> 10) & 0x003ffffc) | (RECURSIVE_PAGE_PML4 << 22); unsafe { &mut *(entry_addr as *mut PageEntry) } } + /* + * @param: + * addr:the input (virutal) address + * @brief: + * get the addr's memory page slice + * @retval: + * a mutable reference slice of 'addr' 's page + */ fn get_page_slice_mut<'a, 'b>(&'a mut self, addr: usize) -> &'b mut [u8] { use core::slice; unsafe { slice::from_raw_parts_mut((addr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) } } + /* + * @param: + * addr: virtual address + * @brief: + * get the address's content + * @retval: + * the content(u8) of 'addr' + */ fn read(&mut self, addr: usize) -> u8 { unsafe { *(addr as *const u8) } } + /* + * @param: + * addr: virtual address + * @brief: + * write the address's content + */ fn write(&mut self, addr: usize, data: u8) { unsafe { *(addr as *mut u8) = data; } } } +// define the ROOT_PAGE_TABLE, and the virtual address of it? const ROOT_PAGE_TABLE: *mut RvPageTable = (((RECURSIVE_PAGE_PML4 << 10) | (RECURSIVE_PAGE_PML4 + 1)) << 12) as *mut RvPageTable; diff --git a/kernel/src/consts.rs b/kernel/src/consts.rs index d713b95..be597e0 100644 --- a/kernel/src/consts.rs +++ b/kernel/src/consts.rs @@ -15,8 +15,11 @@ mod riscv { // [0x80000000, 0x80800000] const P2_SIZE: usize = 1 << 22; const P2_MASK: usize = 0x3ff << 22; + // RECURSIVE_PAGE_PML4 indicate the index of the self-maping entry in root pagetable pub const RECURSIVE_PAGE_PML4: usize = 0x3fe; + // KERNEL_OFFSET indicate (virtual kernel address - physical kernel address) ??? pub const KERNEL_OFFSET: usize = 0; + // KERNEL_PML4 indicate the index of the kernel entry in root pagetable pub const KERNEL_PML4: usize = 0x8000_0000 >> 22; pub const KERNEL_HEAP_OFFSET: usize = 0x8020_0000; pub const KERNEL_HEAP_SIZE: usize = 0x0020_0000; From 0ba43762ff342bc0a1e4195701f182bd75f6a906 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Tue, 9 Oct 2018 21:17:00 +0800 Subject: [PATCH 20/22] update report --- docs/OSTrain2018docs-g4/expr2/proposal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/OSTrain2018docs-g4/expr2/proposal.md b/docs/OSTrain2018docs-g4/expr2/proposal.md index 185a383..a795707 100755 --- a/docs/OSTrain2018docs-g4/expr2/proposal.md +++ b/docs/OSTrain2018docs-g4/expr2/proposal.md @@ -20,7 +20,7 @@ ucoreOS lab基于x86结构,主要由C语言完成编写。x86架构由于其 **lab4:**主要涉及内核线程创建和调度,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 **lab5:**主要涉及用户线程管理,此部分内容似乎同样已经完成,是否存在问题有待后续测试。**事实上之前测试中似乎又提到没有wait过的进程退出内存不会被回收,有待完善。** **lab6:**此部分主要涉及进程调度器的相关内容,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 -**lab7:**@陈秋昊 +**lab7:**主要涉及的是进程间的同步、共享资源的竞争,要求熟悉掌握信号量的原理,管程与条件变量的原理与实现,并用其来解决哲学家问题。但是目前的rustOS-riscv中由于编译器对于原子指令的支持问题,导致相关功能未能实现,需要寻求解决的办法来完善该实验。而且x86_64下该模块与kernel尚未分离,导致结构不够清晰需要进行调整。 **lab8:**@朱书聪 其中前6个lab现有框架已经实现完成,主要涉及虚存管理和进程管理的部分内容有待完善,此部分计划由刘辰屹来完成。lab7在riscv32下的完善计划由陈秋昊来完成,lab8的完善计划由朱书聪来完成。上述为暂时的分工,实际分工视各部分难度大小再进行调整。 此部分计划在第5周结束前完成。 From 5a1cc4178dc2d06a891fc8f8a4a96d8aad412d5f Mon Sep 17 00:00:00 2001 From: lcy1996 <992195697@qq.com> Date: Tue, 9 Oct 2018 21:17:14 +0800 Subject: [PATCH 21/22] Modified proposal --- docs/OSTrain2018docs-g4/expr2/proposal.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/OSTrain2018docs-g4/expr2/proposal.md b/docs/OSTrain2018docs-g4/expr2/proposal.md index 185a383..ebbed69 100755 --- a/docs/OSTrain2018docs-g4/expr2/proposal.md +++ b/docs/OSTrain2018docs-g4/expr2/proposal.md @@ -14,13 +14,21 @@ ucoreOS lab基于x86结构,主要由C语言完成编写。x86架构由于其 ## 3 实验设计与分工 ### 3.1 完善现有Rust OS基础功能 现有Rust OS在riscv32环境下还存在一些bugs或unimplemented features,要想完成一个类似于ucore OS lab的教学实验框架,首先要把这些漏洞完善。现简单将每个lab目前待完善的地方和负责填坑的人列举如下: + **lab1:**主要涉及实验框架的编译、调试,OS bootloader启动过程。现有实验框架已经完成,不需要完善。 + **lab2:**主要涉及物理内存管理,由于riscv32结构的物理内存管理仅通过一个二级页表来实现,不像x86架构下还需要兼容段表(虽然最终只是一个自映射),因此这部分比原本的ucore OS lab会更简洁、易理解一些。另外RustOS 的现有物理内存分配算法是通过线段树实现的,且相较原本的内存分配算法复用性更好。本分内容已经完成。 + **lab3:**该部分实验主要涉及虚存管理部分,**目前RUST OS仅针对x86_64结构实现了page fault的处理**,后续需要完成riscv32的page fault处理和虚存管理部分。 + **lab4:**主要涉及内核线程创建和调度,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 + **lab5:**主要涉及用户线程管理,此部分内容似乎同样已经完成,是否存在问题有待后续测试。**事实上之前测试中似乎又提到没有wait过的进程退出内存不会被回收,有待完善。** + **lab6:**此部分主要涉及进程调度器的相关内容,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 + **lab7:**@陈秋昊 + **lab8:**@朱书聪 其中前6个lab现有框架已经实现完成,主要涉及虚存管理和进程管理的部分内容有待完善,此部分计划由刘辰屹来完成。lab7在riscv32下的完善计划由陈秋昊来完成,lab8的完善计划由朱书聪来完成。上述为暂时的分工,实际分工视各部分难度大小再进行调整。 此部分计划在第5周结束前完成。 From 24d0de8c42af3a542089f1e19133068a4fe5f8fd Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Tue, 9 Oct 2018 21:19:32 +0800 Subject: [PATCH 22/22] update report --- docs/OSTrain2018docs-g4/expr2/proposal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/OSTrain2018docs-g4/expr2/proposal.md b/docs/OSTrain2018docs-g4/expr2/proposal.md index a795707..917d141 100755 --- a/docs/OSTrain2018docs-g4/expr2/proposal.md +++ b/docs/OSTrain2018docs-g4/expr2/proposal.md @@ -20,7 +20,7 @@ ucoreOS lab基于x86结构,主要由C语言完成编写。x86架构由于其 **lab4:**主要涉及内核线程创建和调度,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 **lab5:**主要涉及用户线程管理,此部分内容似乎同样已经完成,是否存在问题有待后续测试。**事实上之前测试中似乎又提到没有wait过的进程退出内存不会被回收,有待完善。** **lab6:**此部分主要涉及进程调度器的相关内容,现有框架中本部分内容已经完成,是否存在问题有待后续测试。 -**lab7:**主要涉及的是进程间的同步、共享资源的竞争,要求熟悉掌握信号量的原理,管程与条件变量的原理与实现,并用其来解决哲学家问题。但是目前的rustOS-riscv中由于编译器对于原子指令的支持问题,导致相关功能未能实现,需要寻求解决的办法来完善该实验。而且x86_64下该模块与kernel尚未分离,导致结构不够清晰需要进行调整。 +**lab7:**主要涉及的是进程间的同步、共享资源的竞争,要求熟悉掌握信号量的原理,管程与条件变量的原理与实现,并用其来解决哲学家问题。**但是目前的rustOS-riscv中由于编译器对于原子指令的支持问题,导致相关功能未能实现**,需要寻求解决的办法来完善该实验。而且x86_64下该模块与kernel尚未分离,导致结构不够清晰需要进行调整。 **lab8:**@朱书聪 其中前6个lab现有框架已经实现完成,主要涉及虚存管理和进程管理的部分内容有待完善,此部分计划由刘辰屹来完成。lab7在riscv32下的完善计划由陈秋昊来完成,lab8的完善计划由朱书聪来完成。上述为暂时的分工,实际分工视各部分难度大小再进行调整。 此部分计划在第5周结束前完成。