diff --git a/os/build.rs b/os/build.rs index e32fa7ab..d7658983 100644 --- a/os/build.rs +++ b/os/build.rs @@ -1,5 +1,5 @@ +use std::fs::{read_dir, File}; use std::io::{Result, Write}; -use std::fs::{File, read_dir}; fn main() { println!("cargo:rerun-if-changed=../user/src/"); @@ -22,35 +22,46 @@ fn insert_app_data() -> Result<()> { .collect(); apps.sort(); - writeln!(f, r#" + writeln!( + f, + r#" .align 3 .section .data .global _num_app _num_app: - .quad {}"#, apps.len())?; + .quad {}"#, + apps.len() + )?; for i in 0..apps.len() { writeln!(f, r#" .quad app_{}_start"#, i)?; } writeln!(f, r#" .quad app_{}_end"#, apps.len() - 1)?; - writeln!(f, r#" + writeln!( + f, + r#" .global _app_names -_app_names:"#)?; +_app_names:"# + )?; for app in apps.iter() { writeln!(f, r#" .string "{}""#, app)?; } for (idx, app) in apps.iter().enumerate() { println!("app_{}: {}", idx, app); - writeln!(f, r#" + writeln!( + f, + r#" .section .data .global app_{0}_start .global app_{0}_end .align 3 app_{0}_start: .incbin "{2}{1}" -app_{0}_end:"#, idx, app, TARGET_PATH)?; +app_{0}_end:"#, + idx, app, TARGET_PATH + )?; } Ok(()) -} \ No newline at end of file +} diff --git a/os/src/console.rs b/os/src/console.rs index 2bd55930..dda4911a 100644 --- a/os/src/console.rs +++ b/os/src/console.rs @@ -1,5 +1,5 @@ -use core::fmt::{self, Write}; use crate::sbi::console_putchar; +use core::fmt::{self, Write}; struct Stdout; @@ -29,5 +29,3 @@ macro_rules! println { $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)); } } - - diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index 3f5462ab..af3e5152 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -1,10 +1,15 @@ -use core::panic::PanicInfo; use crate::sbi::shutdown; +use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo) -> ! { if let Some(location) = info.location() { - println!("[kernel] Panicked at {}:{} {}", location.file(), location.line(), info.message().unwrap()); + println!( + "[kernel] Panicked at {}:{} {}", + location.file(), + location.line(), + info.message().unwrap() + ); } else { println!("[kernel] Panicked: {}", info.message().unwrap()); } diff --git a/os/src/loader.rs b/os/src/loader.rs index bfdc3970..585c4b34 100644 --- a/os/src/loader.rs +++ b/os/src/loader.rs @@ -2,22 +2,24 @@ use alloc::vec::Vec; use lazy_static::*; pub fn get_num_app() -> usize { - extern "C" { fn _num_app(); } + extern "C" { + fn _num_app(); + } unsafe { (_num_app as usize as *const usize).read_volatile() } } pub fn get_app_data(app_id: usize) -> &'static [u8] { - extern "C" { fn _num_app(); } + extern "C" { + fn _num_app(); + } let num_app_ptr = _num_app as usize as *const usize; let num_app = get_num_app(); - let app_start = unsafe { - core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) - }; + let app_start = unsafe { core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) }; assert!(app_id < num_app); unsafe { core::slice::from_raw_parts( app_start[app_id] as *const u8, - app_start[app_id + 1] - app_start[app_id] + app_start[app_id + 1] - app_start[app_id], ) } } @@ -25,7 +27,9 @@ pub fn get_app_data(app_id: usize) -> &'static [u8] { lazy_static! { static ref APP_NAMES: Vec<&'static str> = { let num_app = get_num_app(); - extern "C" { fn _app_names(); } + extern "C" { + fn _app_names(); + } let mut start = _app_names as usize as *const u8; let mut v = Vec::new(); unsafe { @@ -44,7 +48,6 @@ lazy_static! { }; } - #[allow(unused)] pub fn get_app_data_by_name(name: &str) -> Option<&'static [u8]> { let num_app = get_num_app(); @@ -59,4 +62,4 @@ pub fn list_apps() { println!("{}", app); } println!("**************/"); -} \ No newline at end of file +} diff --git a/os/src/main.rs b/os/src/main.rs index 51f2ec02..b31681b1 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -10,16 +10,16 @@ extern crate bitflags; #[macro_use] mod console; -mod lang_items; -mod sbi; -mod syscall; -mod trap; -mod loader; mod config; +mod lang_items; +mod loader; +mod mm; +mod sbi; +mod sync; +mod syscall; mod task; mod timer; -mod sync; -mod mm; +mod trap; use core::arch::global_asm; @@ -32,10 +32,8 @@ fn clear_bss() { fn ebss(); } unsafe { - core::slice::from_raw_parts_mut( - sbss as usize as *mut u8, - ebss as usize - sbss as usize, - ).fill(0); + core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize) + .fill(0); } } @@ -53,4 +51,4 @@ pub fn rust_main() -> ! { loader::list_apps(); task::run_tasks(); panic!("Unreachable in rust_main!"); -} \ No newline at end of file +} diff --git a/os/src/mm/address.rs b/os/src/mm/address.rs index 1be9ae74..12864870 100644 --- a/os/src/mm/address.rs +++ b/os/src/mm/address.rs @@ -1,5 +1,5 @@ -use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS}; use super::PageTableEntry; +use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS}; use core::fmt::{self, Debug, Formatter}; const PA_WIDTH_SV39: usize = 56; @@ -48,35 +48,59 @@ impl Debug for PhysPageNum { /// usize -> T: usize.into() impl From for PhysAddr { - fn from(v: usize) -> Self { Self(v & ( (1 << PA_WIDTH_SV39) - 1 )) } + fn from(v: usize) -> Self { + Self(v & ((1 << PA_WIDTH_SV39) - 1)) + } } impl From for PhysPageNum { - fn from(v: usize) -> Self { Self(v & ( (1 << PPN_WIDTH_SV39) - 1 )) } + fn from(v: usize) -> Self { + Self(v & ((1 << PPN_WIDTH_SV39) - 1)) + } } impl From for VirtAddr { - fn from(v: usize) -> Self { Self(v & ( (1 << VA_WIDTH_SV39) - 1 )) } + fn from(v: usize) -> Self { + Self(v & ((1 << VA_WIDTH_SV39) - 1)) + } } impl From for VirtPageNum { - fn from(v: usize) -> Self { Self(v & ( (1 << VPN_WIDTH_SV39) - 1 )) } + fn from(v: usize) -> Self { + Self(v & ((1 << VPN_WIDTH_SV39) - 1)) + } } impl From for usize { - fn from(v: PhysAddr) -> Self { v.0 } + fn from(v: PhysAddr) -> Self { + v.0 + } } impl From for usize { - fn from(v: PhysPageNum) -> Self { v.0 } + fn from(v: PhysPageNum) -> Self { + v.0 + } } impl From for usize { - fn from(v: VirtAddr) -> Self { v.0 } + fn from(v: VirtAddr) -> Self { + v.0 + } } impl From for usize { - fn from(v: VirtPageNum) -> Self { v.0 } + fn from(v: VirtPageNum) -> Self { + v.0 + } } impl VirtAddr { - pub fn floor(&self) -> VirtPageNum { VirtPageNum(self.0 / PAGE_SIZE) } - pub fn ceil(&self) -> VirtPageNum { VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) } - pub fn page_offset(&self) -> usize { self.0 & (PAGE_SIZE - 1) } - pub fn aligned(&self) -> bool { self.page_offset() == 0 } + pub fn floor(&self) -> VirtPageNum { + VirtPageNum(self.0 / PAGE_SIZE) + } + pub fn ceil(&self) -> VirtPageNum { + VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) + } + pub fn page_offset(&self) -> usize { + self.0 & (PAGE_SIZE - 1) + } + pub fn aligned(&self) -> bool { + self.page_offset() == 0 + } } impl From for VirtPageNum { fn from(v: VirtAddr) -> Self { @@ -85,13 +109,23 @@ impl From for VirtPageNum { } } impl From for VirtAddr { - fn from(v: VirtPageNum) -> Self { Self(v.0 << PAGE_SIZE_BITS) } + fn from(v: VirtPageNum) -> Self { + Self(v.0 << PAGE_SIZE_BITS) + } } impl PhysAddr { - pub fn floor(&self) -> PhysPageNum { PhysPageNum(self.0 / PAGE_SIZE) } - pub fn ceil(&self) -> PhysPageNum { PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) } - pub fn page_offset(&self) -> usize { self.0 & (PAGE_SIZE - 1) } - pub fn aligned(&self) -> bool { self.page_offset() == 0 } + pub fn floor(&self) -> PhysPageNum { + PhysPageNum(self.0 / PAGE_SIZE) + } + pub fn ceil(&self) -> PhysPageNum { + PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) + } + pub fn page_offset(&self) -> usize { + self.0 & (PAGE_SIZE - 1) + } + pub fn aligned(&self) -> bool { + self.page_offset() == 0 + } } impl From for PhysPageNum { fn from(v: PhysAddr) -> Self { @@ -100,7 +134,9 @@ impl From for PhysPageNum { } } impl From for PhysAddr { - fn from(v: PhysPageNum) -> Self { Self(v.0 << PAGE_SIZE_BITS) } + fn from(v: PhysPageNum) -> Self { + Self(v.0 << PAGE_SIZE_BITS) + } } impl VirtPageNum { @@ -117,23 +153,17 @@ impl VirtPageNum { impl PhysAddr { pub fn get_mut(&self) -> &'static mut T { - unsafe { - (self.0 as *mut T).as_mut().unwrap() - } + unsafe { (self.0 as *mut T).as_mut().unwrap() } } } impl PhysPageNum { pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] { let pa: PhysAddr = self.clone().into(); - unsafe { - core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) - } + unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) } } pub fn get_bytes_array(&self) -> &'static mut [u8] { let pa: PhysAddr = self.clone().into(); - unsafe { - core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) - } + unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) } } pub fn get_mut(&self) -> &'static mut T { let pa: PhysAddr = self.clone().into(); @@ -151,41 +181,57 @@ impl StepByOne for VirtPageNum { } #[derive(Copy, Clone)] -pub struct SimpleRange where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +pub struct SimpleRange +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ l: T, r: T, } -impl SimpleRange where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +impl SimpleRange +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ pub fn new(start: T, end: T) -> Self { assert!(start <= end, "start {:?} > end {:?}!", start, end); Self { l: start, r: end } } - pub fn get_start(&self) -> T { self.l } - pub fn get_end(&self) -> T { self.r } + pub fn get_start(&self) -> T { + self.l + } + pub fn get_end(&self) -> T { + self.r + } } -impl IntoIterator for SimpleRange where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +impl IntoIterator for SimpleRange +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ type Item = T; type IntoIter = SimpleRangeIterator; fn into_iter(self) -> Self::IntoIter { SimpleRangeIterator::new(self.l, self.r) } } -pub struct SimpleRangeIterator where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +pub struct SimpleRangeIterator +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ current: T, end: T, } -impl SimpleRangeIterator where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +impl SimpleRangeIterator +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ pub fn new(l: T, r: T) -> Self { - Self { current: l, end: r, } + Self { current: l, end: r } } } -impl Iterator for SimpleRangeIterator where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, { +impl Iterator for SimpleRangeIterator +where + T: StepByOne + Copy + PartialEq + PartialOrd + Debug, +{ type Item = T; fn next(&mut self) -> Option { if self.current == self.end { diff --git a/os/src/mm/frame_allocator.rs b/os/src/mm/frame_allocator.rs index 85d06cce..66b3c121 100644 --- a/os/src/mm/frame_allocator.rs +++ b/os/src/mm/frame_allocator.rs @@ -1,9 +1,9 @@ use super::{PhysAddr, PhysPageNum}; -use alloc::vec::Vec; -use crate::sync::UPSafeCell; use crate::config::MEMORY_END; -use lazy_static::*; +use crate::sync::UPSafeCell; +use alloc::vec::Vec; use core::fmt::{self, Debug, Formatter}; +use lazy_static::*; pub struct FrameTracker { pub ppn: PhysPageNum, @@ -62,22 +62,17 @@ impl FrameAllocator for StackFrameAllocator { fn alloc(&mut self) -> Option { if let Some(ppn) = self.recycled.pop() { Some(ppn.into()) + } else if self.current == self.end { + None } else { - if self.current == self.end { - None - } else { - self.current += 1; - Some((self.current - 1).into()) - } + self.current += 1; + Some((self.current - 1).into()) } } fn dealloc(&mut self, ppn: PhysPageNum) { let ppn = ppn.0; // validity check - if ppn >= self.current || self.recycled - .iter() - .find(|&v| {*v == ppn}) - .is_some() { + if ppn >= self.current || self.recycled.iter().find(|&v| *v == ppn).is_some() { panic!("Frame ppn={:#x} has not been allocated!", ppn); } // recycle @@ -88,18 +83,18 @@ impl FrameAllocator for StackFrameAllocator { type FrameAllocatorImpl = StackFrameAllocator; lazy_static! { - pub static ref FRAME_ALLOCATOR: UPSafeCell = unsafe { - UPSafeCell::new(FrameAllocatorImpl::new()) - }; + pub static ref FRAME_ALLOCATOR: UPSafeCell = + unsafe { UPSafeCell::new(FrameAllocatorImpl::new()) }; } pub fn init_frame_allocator() { extern "C" { fn ekernel(); } - FRAME_ALLOCATOR - .exclusive_access() - .init(PhysAddr::from(ekernel as usize).ceil(), PhysAddr::from(MEMORY_END).floor()); + FRAME_ALLOCATOR.exclusive_access().init( + PhysAddr::from(ekernel as usize).ceil(), + PhysAddr::from(MEMORY_END).floor(), + ); } pub fn frame_alloc() -> Option { @@ -110,9 +105,7 @@ pub fn frame_alloc() -> Option { } fn frame_dealloc(ppn: PhysPageNum) { - FRAME_ALLOCATOR - .exclusive_access() - .dealloc(ppn); + FRAME_ALLOCATOR.exclusive_access().dealloc(ppn); } #[allow(unused)] @@ -131,4 +124,4 @@ pub fn frame_allocator_test() { } drop(v); println!("frame_allocator_test passed!"); -} \ No newline at end of file +} diff --git a/os/src/mm/heap_allocator.rs b/os/src/mm/heap_allocator.rs index 2c7468f2..b802bbd3 100644 --- a/os/src/mm/heap_allocator.rs +++ b/os/src/mm/heap_allocator.rs @@ -1,5 +1,5 @@ -use buddy_system_allocator::LockedHeap; use crate::config::KERNEL_HEAP_SIZE; +use buddy_system_allocator::LockedHeap; #[global_allocator] static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index 84262537..b5bad756 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -1,21 +1,15 @@ -use super::{PageTable, PageTableEntry, PTEFlags}; -use super::{VirtPageNum, VirtAddr, PhysPageNum, PhysAddr}; -use super::{FrameTracker, frame_alloc}; -use super::{VPNRange, StepByOne}; -use alloc::collections::BTreeMap; -use alloc::vec::Vec; -use riscv::register::satp; -use alloc::sync::Arc; -use lazy_static::*; +use super::{frame_alloc, FrameTracker}; +use super::{PTEFlags, PageTable, PageTableEntry}; +use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; +use super::{StepByOne, VPNRange}; +use crate::config::{MEMORY_END, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE}; use crate::sync::UPSafeCell; -use crate::config::{ - MEMORY_END, - PAGE_SIZE, - TRAMPOLINE, - TRAP_CONTEXT, - USER_STACK_SIZE -}; +use alloc::collections::BTreeMap; +use alloc::sync::Arc; +use alloc::vec::Vec; use core::arch::asm; +use lazy_static::*; +use riscv::register::satp; extern "C" { fn stext(); @@ -31,9 +25,8 @@ extern "C" { } lazy_static! { - pub static ref KERNEL_SPACE: Arc> = Arc::new(unsafe { - UPSafeCell::new(MemorySet::new_kernel()) - }); + pub static ref KERNEL_SPACE: Arc> = + Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) }); } pub struct MemorySet { @@ -52,17 +45,24 @@ impl MemorySet { self.page_table.token() } /// Assume that no conflicts. - pub fn insert_framed_area(&mut self, start_va: VirtAddr, end_va: VirtAddr, permission: MapPermission) { - self.push(MapArea::new( - start_va, - end_va, - MapType::Framed, - permission, - ), None); + pub fn insert_framed_area( + &mut self, + start_va: VirtAddr, + end_va: VirtAddr, + permission: MapPermission, + ) { + self.push( + MapArea::new(start_va, end_va, MapType::Framed, permission), + None, + ); } pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) { - if let Some((idx, area)) = self.areas.iter_mut().enumerate() - .find(|(_, area)| area.vpn_range.get_start() == start_vpn) { + if let Some((idx, area)) = self + .areas + .iter_mut() + .enumerate() + .find(|(_, area)| area.vpn_range.get_start() == start_vpn) + { area.unmap(&mut self.page_table); self.areas.remove(idx); } @@ -91,42 +91,60 @@ impl MemorySet { println!(".text [{:#x}, {:#x})", stext as usize, etext as usize); println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize); println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize); - println!(".bss [{:#x}, {:#x})", sbss_with_stack as usize, ebss as usize); + println!( + ".bss [{:#x}, {:#x})", + sbss_with_stack as usize, ebss as usize + ); println!("mapping .text section"); - memory_set.push(MapArea::new( - (stext as usize).into(), - (etext as usize).into(), - MapType::Identical, - MapPermission::R | MapPermission::X, - ), None); + memory_set.push( + MapArea::new( + (stext as usize).into(), + (etext as usize).into(), + MapType::Identical, + MapPermission::R | MapPermission::X, + ), + None, + ); println!("mapping .rodata section"); - memory_set.push(MapArea::new( - (srodata as usize).into(), - (erodata as usize).into(), - MapType::Identical, - MapPermission::R, - ), None); + memory_set.push( + MapArea::new( + (srodata as usize).into(), + (erodata as usize).into(), + MapType::Identical, + MapPermission::R, + ), + None, + ); println!("mapping .data section"); - memory_set.push(MapArea::new( - (sdata as usize).into(), - (edata as usize).into(), - MapType::Identical, - MapPermission::R | MapPermission::W, - ), None); + memory_set.push( + MapArea::new( + (sdata as usize).into(), + (edata as usize).into(), + MapType::Identical, + MapPermission::R | MapPermission::W, + ), + None, + ); println!("mapping .bss section"); - memory_set.push(MapArea::new( - (sbss_with_stack as usize).into(), - (ebss as usize).into(), - MapType::Identical, - MapPermission::R | MapPermission::W, - ), None); + memory_set.push( + MapArea::new( + (sbss_with_stack as usize).into(), + (ebss as usize).into(), + MapType::Identical, + MapPermission::R | MapPermission::W, + ), + None, + ); println!("mapping physical memory"); - memory_set.push(MapArea::new( - (ekernel as usize).into(), - MEMORY_END.into(), - MapType::Identical, - MapPermission::R | MapPermission::W, - ), None); + memory_set.push( + MapArea::new( + (ekernel as usize).into(), + MEMORY_END.into(), + MapType::Identical, + MapPermission::R | MapPermission::W, + ), + None, + ); memory_set } /// Include sections in elf and trampoline and TrapContext and user stack, @@ -149,19 +167,20 @@ impl MemorySet { let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into(); let mut map_perm = MapPermission::U; let ph_flags = ph.flags(); - if ph_flags.is_read() { map_perm |= MapPermission::R; } - if ph_flags.is_write() { map_perm |= MapPermission::W; } - if ph_flags.is_execute() { map_perm |= MapPermission::X; } - let map_area = MapArea::new( - start_va, - end_va, - MapType::Framed, - map_perm, - ); + if ph_flags.is_read() { + map_perm |= MapPermission::R; + } + if ph_flags.is_write() { + map_perm |= MapPermission::W; + } + if ph_flags.is_execute() { + map_perm |= MapPermission::X; + } + let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm); max_end_vpn = map_area.vpn_range.get_end(); memory_set.push( map_area, - Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]) + Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]), ); } } @@ -171,20 +190,30 @@ impl MemorySet { // guard page user_stack_bottom += PAGE_SIZE; let user_stack_top = user_stack_bottom + USER_STACK_SIZE; - memory_set.push(MapArea::new( - user_stack_bottom.into(), - user_stack_top.into(), - MapType::Framed, - MapPermission::R | MapPermission::W | MapPermission::U, - ), None); + memory_set.push( + MapArea::new( + user_stack_bottom.into(), + user_stack_top.into(), + MapType::Framed, + MapPermission::R | MapPermission::W | MapPermission::U, + ), + None, + ); // map TrapContext - memory_set.push(MapArea::new( - TRAP_CONTEXT.into(), - TRAMPOLINE.into(), - MapType::Framed, - MapPermission::R | MapPermission::W, - ), None); - (memory_set, user_stack_top, elf.header.pt2.entry_point() as usize) + memory_set.push( + MapArea::new( + TRAP_CONTEXT.into(), + TRAMPOLINE.into(), + MapType::Framed, + MapPermission::R | MapPermission::W, + ), + None, + ); + ( + memory_set, + user_stack_top, + elf.header.pt2.entry_point() as usize, + ) } pub fn from_existed_user(user_space: &MemorySet) -> MemorySet { let mut memory_set = Self::new_bare(); @@ -198,7 +227,9 @@ impl MemorySet { for vpn in area.vpn_range { let src_ppn = user_space.translate(vpn).unwrap().ppn(); let dst_ppn = memory_set.translate(vpn).unwrap().ppn(); - dst_ppn.get_bytes_array().copy_from_slice(src_ppn.get_bytes_array()); + dst_ppn + .get_bytes_array() + .copy_from_slice(src_ppn.get_bytes_array()); } } memory_set @@ -231,7 +262,7 @@ impl MapArea { start_va: VirtAddr, end_va: VirtAddr, map_type: MapType, - map_perm: MapPermission + map_perm: MapPermission, ) -> Self { let start_vpn: VirtPageNum = start_va.floor(); let end_vpn: VirtPageNum = end_va.ceil(); @@ -330,15 +361,27 @@ pub fn remap_test() { let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into(); let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into(); assert_eq!( - kernel_space.page_table.translate(mid_text.floor()).unwrap().writable(), + kernel_space + .page_table + .translate(mid_text.floor()) + .unwrap() + .writable(), false ); assert_eq!( - kernel_space.page_table.translate(mid_rodata.floor()).unwrap().writable(), + kernel_space + .page_table + .translate(mid_rodata.floor()) + .unwrap() + .writable(), false, ); assert_eq!( - kernel_space.page_table.translate(mid_data.floor()).unwrap().executable(), + kernel_space + .page_table + .translate(mid_data.floor()) + .unwrap() + .executable(), false, ); println!("remap_test passed!"); diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index 30e05577..52c5223a 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -1,21 +1,16 @@ -mod heap_allocator; mod address; mod frame_allocator; -mod page_table; +mod heap_allocator; mod memory_set; +mod page_table; -use page_table::{PageTable, PTEFlags}; -use address::{VPNRange, StepByOne}; -pub use address::{PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}; -pub use frame_allocator::{FrameTracker, frame_alloc}; -pub use page_table::{ - PageTableEntry, - translated_byte_buffer, - translated_str, - translated_refmut, -}; -pub use memory_set::{MemorySet, KERNEL_SPACE, MapPermission}; +pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; +use address::{StepByOne, VPNRange}; +pub use frame_allocator::{frame_alloc, FrameTracker}; pub use memory_set::remap_test; +pub use memory_set::{MapPermission, MemorySet, KERNEL_SPACE}; +pub use page_table::{translated_byte_buffer, translated_refmut, translated_str, PageTableEntry}; +use page_table::{PTEFlags, PageTable}; pub fn init() { heap_allocator::init_heap(); diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index a13bae23..419f088e 100644 --- a/os/src/mm/page_table.rs +++ b/os/src/mm/page_table.rs @@ -1,15 +1,7 @@ -use super::{ - frame_alloc, - PhysPageNum, - FrameTracker, - VirtPageNum, - VirtAddr, - PhysAddr, - StepByOne -}; -use alloc::vec::Vec; -use alloc::vec; +use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; use bitflags::*; bitflags! { @@ -38,9 +30,7 @@ impl PageTableEntry { } } pub fn empty() -> Self { - PageTableEntry { - bits: 0, - } + PageTableEntry { bits: 0 } } pub fn ppn(&self) -> PhysPageNum { (self.bits >> 10 & ((1usize << 44) - 1)).into() @@ -132,19 +122,17 @@ impl PageTable { *pte = PageTableEntry::empty(); } pub fn translate(&self, vpn: VirtPageNum) -> Option { - self.find_pte(vpn) - .map(|pte| {pte.clone()}) + self.find_pte(vpn).map(|pte| pte.clone()) } pub fn translate_va(&self, va: VirtAddr) -> Option { - self.find_pte(va.clone().floor()) - .map(|pte| { - //println!("translate_va:va = {:?}", va); - let aligned_pa: PhysAddr = pte.ppn().into(); - //println!("translate_va:pa_align = {:?}", aligned_pa); - let offset = va.page_offset(); - let aligned_pa_usize: usize = aligned_pa.into(); - (aligned_pa_usize + offset).into() - }) + self.find_pte(va.clone().floor()).map(|pte| { + //println!("translate_va:va = {:?}", va); + let aligned_pa: PhysAddr = pte.ppn().into(); + //println!("translate_va:pa_align = {:?}", aligned_pa); + let offset = va.page_offset(); + let aligned_pa_usize: usize = aligned_pa.into(); + (aligned_pa_usize + offset).into() + }) } pub fn token(&self) -> usize { 8usize << 60 | self.root_ppn.0 @@ -159,10 +147,7 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<& while start < end { let start_va = VirtAddr::from(start); let mut vpn = start_va.floor(); - let ppn = page_table - .translate(vpn) - .unwrap() - .ppn(); + let ppn = page_table.translate(vpn).unwrap().ppn(); vpn.step(); let mut end_va: VirtAddr = vpn.into(); end_va = end_va.min(VirtAddr::from(end)); @@ -181,7 +166,10 @@ pub fn translated_str(token: usize, ptr: *const u8) -> String { let mut string = String::new(); let mut va = ptr as usize; loop { - let ch: u8 = *(page_table.translate_va(VirtAddr::from(va)).unwrap().get_mut()); + let ch: u8 = *(page_table + .translate_va(VirtAddr::from(va)) + .unwrap() + .get_mut()); if ch == 0 { break; } else { @@ -197,6 +185,8 @@ pub fn translated_refmut(token: usize, ptr: *mut T) -> &'static mut T { let page_table = PageTable::from_token(token); let va = ptr as usize; //println!("translated_refmut: before translate_va"); - page_table.translate_va(VirtAddr::from(va)).unwrap().get_mut() + page_table + .translate_va(VirtAddr::from(va)) + .unwrap() + .get_mut() } - diff --git a/os/src/sbi.rs b/os/src/sbi.rs index c8ecbf1d..2e2804b2 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -43,4 +43,3 @@ pub fn shutdown() -> ! { sbi_call(SBI_SHUTDOWN, 0, 0, 0); panic!("It should shutdown!"); } - diff --git a/os/src/sync/mod.rs b/os/src/sync/mod.rs index 77295248..d1ce5bcf 100644 --- a/os/src/sync/mod.rs +++ b/os/src/sync/mod.rs @@ -1,3 +1,3 @@ mod up; -pub use up::UPSafeCell; \ No newline at end of file +pub use up::UPSafeCell; diff --git a/os/src/sync/up.rs b/os/src/sync/up.rs index 642668c1..c7b2c9ee 100644 --- a/os/src/sync/up.rs +++ b/os/src/sync/up.rs @@ -18,10 +18,12 @@ impl UPSafeCell { /// User is responsible to guarantee that inner struct is only used in /// uniprocessor. pub unsafe fn new(value: T) -> Self { - Self { inner: RefCell::new(value) } + Self { + inner: RefCell::new(value), + } } /// Panic if the data has been borrowed. pub fn exclusive_access(&self) -> RefMut<'_, T> { self.inner.borrow_mut() } -} \ No newline at end of file +} diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index a10b53e9..557f282c 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -1,6 +1,6 @@ use crate::mm::translated_byte_buffer; -use crate::task::{current_user_token, suspend_current_and_run_next}; use crate::sbi::console_getchar; +use crate::task::{current_user_token, suspend_current_and_run_next}; const FD_STDIN: usize = 0; const FD_STDOUT: usize = 1; @@ -13,7 +13,7 @@ pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { print!("{}", core::str::from_utf8(buffer).unwrap()); } len as isize - }, + } _ => { panic!("Unsupported fd in sys_write!"); } @@ -36,11 +36,13 @@ pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize { } let ch = c as u8; let mut buffers = translated_byte_buffer(current_user_token(), buf, len); - unsafe { buffers[0].as_mut_ptr().write_volatile(ch); } + unsafe { + buffers[0].as_mut_ptr().write_volatile(ch); + } 1 } _ => { panic!("Unsupported fd in sys_read!"); } } -} \ No newline at end of file +} diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 81ade837..583f1e12 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -28,4 +28,3 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { _ => panic!("Unsupported syscall_id: {}", syscall_id), } } - diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index b425d87d..871cec22 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,16 +1,10 @@ +use crate::loader::get_app_data_by_name; +use crate::mm::{translated_refmut, translated_str}; use crate::task::{ + add_task, current_task, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, - exit_current_and_run_next, - current_task, - current_user_token, - add_task, }; use crate::timer::get_time_ms; -use crate::mm::{ - translated_str, - translated_refmut, -}; -use crate::loader::get_app_data_by_name; use alloc::sync::Arc; pub fn sys_exit(exit_code: i32) -> ! { @@ -65,21 +59,20 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { // ---- access current TCB exclusively let mut inner = task.inner_exclusive_access(); - if inner.children + if inner + .children .iter() - .find(|p| {pid == -1 || pid as usize == p.getpid()}) - .is_none() { + .find(|p| pid == -1 || pid as usize == p.getpid()) + .is_none() + { return -1; // ---- release current PCB } - let pair = inner.children - .iter() - .enumerate() - .find(|(_, p)| { - // ++++ temporarily access child PCB lock exclusively - p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid()) - // ++++ release child PCB - }); + let pair = inner.children.iter().enumerate().find(|(_, p)| { + // ++++ temporarily access child PCB lock exclusively + p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid()) + // ++++ release child PCB + }); if let Some((idx, _)) = pair { let child = inner.children.remove(idx); // confirm that child will be deallocated after removing from children list @@ -94,4 +87,4 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { -2 } // ---- release current PCB lock automatically -} \ No newline at end of file +} diff --git a/os/src/task/context.rs b/os/src/task/context.rs index d25cc2c8..e4f59d8a 100644 --- a/os/src/task/context.rs +++ b/os/src/task/context.rs @@ -23,4 +23,3 @@ impl TaskContext { } } } - diff --git a/os/src/task/manager.rs b/os/src/task/manager.rs index 2e3708d7..542a0b87 100644 --- a/os/src/task/manager.rs +++ b/os/src/task/manager.rs @@ -1,5 +1,5 @@ -use crate::sync::UPSafeCell; use super::TaskControlBlock; +use crate::sync::UPSafeCell; use alloc::collections::VecDeque; use alloc::sync::Arc; use lazy_static::*; @@ -11,7 +11,9 @@ pub struct TaskManager { /// A simple FIFO scheduler. impl TaskManager { pub fn new() -> Self { - Self { ready_queue: VecDeque::new(), } + Self { + ready_queue: VecDeque::new(), + } } pub fn add(&mut self, task: Arc) { self.ready_queue.push_back(task); @@ -22,9 +24,8 @@ impl TaskManager { } lazy_static! { - pub static ref TASK_MANAGER: UPSafeCell = unsafe { - UPSafeCell::new(TaskManager::new()) - }; + pub static ref TASK_MANAGER: UPSafeCell = + unsafe { UPSafeCell::new(TaskManager::new()) }; } pub fn add_task(task: Arc) { @@ -33,4 +34,4 @@ pub fn add_task(task: Arc) { pub fn fetch_task() -> Option> { TASK_MANAGER.exclusive_access().fetch() -} \ No newline at end of file +} diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index d5301040..bc67daf6 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -1,28 +1,23 @@ mod context; +mod manager; +mod pid; +mod processor; mod switch; mod task; -mod manager; -mod processor; -mod pid; use crate::loader::get_app_data_by_name; +use alloc::sync::Arc; +use lazy_static::*; +use manager::fetch_task; use switch::__switch; use task::{TaskControlBlock, TaskStatus}; -use alloc::sync::Arc; -use manager::fetch_task; -use lazy_static::*; pub use context::TaskContext; -pub use processor::{ - run_tasks, - current_task, - current_user_token, - current_trap_cx, - take_current_task, - schedule, -}; pub use manager::add_task; -pub use pid::{PidHandle, pid_alloc, KernelStack}; +pub use pid::{pid_alloc, KernelStack, PidHandle}; +pub use processor::{ + current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task, +}; pub fn suspend_current_and_run_next() { // There must be an application running. @@ -76,9 +71,9 @@ pub fn exit_current_and_run_next(exit_code: i32) { } lazy_static! { - pub static ref INITPROC: Arc = Arc::new( - TaskControlBlock::new(get_app_data_by_name("initproc").unwrap()) - ); + pub static ref INITPROC: Arc = Arc::new(TaskControlBlock::new( + get_app_data_by_name("initproc").unwrap() + )); } pub fn add_initproc() { diff --git a/os/src/task/pid.rs b/os/src/task/pid.rs index 517cd1d4..f460f063 100644 --- a/os/src/task/pid.rs +++ b/os/src/task/pid.rs @@ -1,12 +1,8 @@ +use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE}; +use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE}; +use crate::sync::UPSafeCell; use alloc::vec::Vec; use lazy_static::*; -use crate::sync::UPSafeCell; -use crate::mm::{KERNEL_SPACE, MapPermission, VirtAddr}; -use crate::config::{ - PAGE_SIZE, - TRAMPOLINE, - KERNEL_STACK_SIZE, -}; struct PidAllocator { current: usize, @@ -32,16 +28,16 @@ impl PidAllocator { assert!(pid < self.current); assert!( self.recycled.iter().find(|ppid| **ppid == pid).is_none(), - "pid {} has been deallocated!", pid + "pid {} has been deallocated!", + pid ); self.recycled.push(pid); } } lazy_static! { - static ref PID_ALLOCATOR : UPSafeCell = unsafe { - UPSafeCell::new(PidAllocator::new()) - }; + static ref PID_ALLOCATOR: UPSafeCell = + unsafe { UPSafeCell::new(PidAllocator::new()) }; } pub struct PidHandle(pub usize); @@ -72,23 +68,23 @@ impl KernelStack { pub fn new(pid_handle: &PidHandle) -> Self { let pid = pid_handle.0; let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(pid); - KERNEL_SPACE - .exclusive_access() - .insert_framed_area( - kernel_stack_bottom.into(), - kernel_stack_top.into(), - MapPermission::R | MapPermission::W, - ); - KernelStack { - pid: pid_handle.0, - } + KERNEL_SPACE.exclusive_access().insert_framed_area( + kernel_stack_bottom.into(), + kernel_stack_top.into(), + MapPermission::R | MapPermission::W, + ); + KernelStack { pid: pid_handle.0 } } #[allow(unused)] - pub fn push_on_top(&self, value: T) -> *mut T where - T: Sized, { + pub fn push_on_top(&self, value: T) -> *mut T + where + T: Sized, + { let kernel_stack_top = self.get_top(); let ptr_mut = (kernel_stack_top - core::mem::size_of::()) as *mut T; - unsafe { *ptr_mut = value; } + unsafe { + *ptr_mut = value; + } ptr_mut } pub fn get_top(&self) -> usize { @@ -105,4 +101,4 @@ impl Drop for KernelStack { .exclusive_access() .remove_area_with_start_vpn(kernel_stack_bottom_va.into()); } -} \ No newline at end of file +} diff --git a/os/src/task/processor.rs b/os/src/task/processor.rs index a9f9db8c..6ad4534c 100644 --- a/os/src/task/processor.rs +++ b/os/src/task/processor.rs @@ -1,10 +1,10 @@ +use super::__switch; +use super::{fetch_task, TaskStatus}; use super::{TaskContext, TaskControlBlock}; +use crate::sync::UPSafeCell; +use crate::trap::TrapContext; use alloc::sync::Arc; use lazy_static::*; -use super::{fetch_task, TaskStatus}; -use super::__switch; -use crate::trap::TrapContext; -use crate::sync::UPSafeCell; pub struct Processor { current: Option>, @@ -30,9 +30,7 @@ impl Processor { } lazy_static! { - pub static ref PROCESSOR: UPSafeCell = unsafe { - UPSafeCell::new(Processor::new()) - }; + pub static ref PROCESSOR: UPSafeCell = unsafe { UPSafeCell::new(Processor::new()) }; } pub fn run_tasks() { @@ -50,10 +48,7 @@ pub fn run_tasks() { // release processor manually drop(processor); unsafe { - __switch( - idle_task_cx_ptr, - next_task_cx_ptr, - ); + __switch(idle_task_cx_ptr, next_task_cx_ptr); } } } @@ -74,7 +69,10 @@ pub fn current_user_token() -> usize { } pub fn current_trap_cx() -> &'static mut TrapContext { - current_task().unwrap().inner_exclusive_access().get_trap_cx() + current_task() + .unwrap() + .inner_exclusive_access() + .get_trap_cx() } pub fn schedule(switched_task_cx_ptr: *mut TaskContext) { @@ -82,9 +80,6 @@ pub fn schedule(switched_task_cx_ptr: *mut TaskContext) { let idle_task_cx_ptr = processor.get_idle_task_cx_ptr(); drop(processor); unsafe { - __switch( - switched_task_cx_ptr, - idle_task_cx_ptr, - ); + __switch(switched_task_cx_ptr, idle_task_cx_ptr); } } diff --git a/os/src/task/switch.rs b/os/src/task/switch.rs index dd3a2d3e..59f8b1a0 100644 --- a/os/src/task/switch.rs +++ b/os/src/task/switch.rs @@ -4,8 +4,5 @@ use core::arch::global_asm; global_asm!(include_str!("switch.S")); extern "C" { - pub fn __switch( - current_task_cx_ptr: *mut TaskContext, - next_task_cx_ptr: *const TaskContext - ); + pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext); } diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 8108ea88..cd346d59 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,12 +1,12 @@ -use crate::mm::{MemorySet, PhysPageNum, KERNEL_SPACE, VirtAddr}; -use crate::trap::{TrapContext, trap_handler}; -use crate::config::TRAP_CONTEXT; -use crate::sync::UPSafeCell; -use core::cell::RefMut; use super::TaskContext; -use super::{PidHandle, pid_alloc, KernelStack}; -use alloc::sync::{Weak, Arc}; +use super::{pid_alloc, KernelStack, PidHandle}; +use crate::config::TRAP_CONTEXT; +use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE}; +use crate::sync::UPSafeCell; +use crate::trap::{trap_handler, TrapContext}; +use alloc::sync::{Arc, Weak}; use alloc::vec::Vec; +use core::cell::RefMut; pub struct TaskControlBlock { // immutable @@ -66,16 +66,18 @@ impl TaskControlBlock { let task_control_block = Self { pid: pid_handle, kernel_stack, - inner: unsafe { UPSafeCell::new(TaskControlBlockInner { - trap_cx_ppn, - base_size: user_sp, - task_cx: TaskContext::goto_trap_return(kernel_stack_top), - task_status: TaskStatus::Ready, - memory_set, - parent: None, - children: Vec::new(), - exit_code: 0, - })}, + inner: unsafe { + UPSafeCell::new(TaskControlBlockInner { + trap_cx_ppn, + base_size: user_sp, + task_cx: TaskContext::goto_trap_return(kernel_stack_top), + task_status: TaskStatus::Ready, + memory_set, + parent: None, + children: Vec::new(), + exit_code: 0, + }) + }, }; // prepare TrapContext in user space let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx(); @@ -117,9 +119,7 @@ impl TaskControlBlock { // ---- access parent PCB exclusively let mut parent_inner = self.inner_exclusive_access(); // copy user space(include trap context) - let memory_set = MemorySet::from_existed_user( - &parent_inner.memory_set - ); + let memory_set = MemorySet::from_existed_user(&parent_inner.memory_set); let trap_cx_ppn = memory_set .translate(VirtAddr::from(TRAP_CONTEXT).into()) .unwrap() @@ -131,16 +131,18 @@ impl TaskControlBlock { let task_control_block = Arc::new(TaskControlBlock { pid: pid_handle, kernel_stack, - inner: unsafe { UPSafeCell::new(TaskControlBlockInner { - trap_cx_ppn, - base_size: parent_inner.base_size, - task_cx: TaskContext::goto_trap_return(kernel_stack_top), - task_status: TaskStatus::Ready, - memory_set, - parent: Some(Arc::downgrade(self)), - children: Vec::new(), - exit_code: 0, - })}, + inner: unsafe { + UPSafeCell::new(TaskControlBlockInner { + trap_cx_ppn, + base_size: parent_inner.base_size, + task_cx: TaskContext::goto_trap_return(kernel_stack_top), + task_status: TaskStatus::Ready, + memory_set, + parent: Some(Arc::downgrade(self)), + children: Vec::new(), + exit_code: 0, + }) + }, }); // add child parent_inner.children.push(task_control_block.clone()); @@ -163,4 +165,4 @@ pub enum TaskStatus { Ready, Running, Zombie, -} \ No newline at end of file +} diff --git a/os/src/timer.rs b/os/src/timer.rs index 92d50e3a..048aa3b7 100644 --- a/os/src/timer.rs +++ b/os/src/timer.rs @@ -1,6 +1,6 @@ -use riscv::register::time; -use crate::sbi::set_timer; use crate::config::CLOCK_FREQ; +use crate::sbi::set_timer; +use riscv::register::time; const TICKS_PER_SEC: usize = 100; const MSEC_PER_SEC: usize = 1000; @@ -15,4 +15,4 @@ pub fn get_time_ms() -> usize { pub fn set_next_trigger() { set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC); -} \ No newline at end of file +} diff --git a/os/src/trap/context.rs b/os/src/trap/context.rs index 8c5175f7..2f6084f0 100644 --- a/os/src/trap/context.rs +++ b/os/src/trap/context.rs @@ -1,4 +1,4 @@ -use riscv::register::sstatus::{Sstatus, self, SPP}; +use riscv::register::sstatus::{self, Sstatus, SPP}; #[repr(C)] pub struct TrapContext { @@ -11,7 +11,9 @@ pub struct TrapContext { } impl TrapContext { - pub fn set_sp(&mut self, sp: usize) { self.x[2] = sp; } + pub fn set_sp(&mut self, sp: usize) { + self.x[2] = sp; + } pub fn app_init_context( entry: usize, sp: usize, diff --git a/os/src/trap/mod.rs b/os/src/trap/mod.rs index 541ff305..7fa1dd7f 100644 --- a/os/src/trap/mod.rs +++ b/os/src/trap/mod.rs @@ -1,27 +1,17 @@ mod context; -use riscv::register::{ - mtvec::TrapMode, - stvec, - scause::{ - self, - Trap, - Exception, - Interrupt, - }, - stval, - sie, -}; +use crate::config::{TRAMPOLINE, TRAP_CONTEXT}; use crate::syscall::syscall; use crate::task::{ - exit_current_and_run_next, - suspend_current_and_run_next, - current_user_token, - current_trap_cx, + current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, }; use crate::timer::set_next_trigger; -use crate::config::{TRAP_CONTEXT, TRAMPOLINE}; -use core::arch::{global_asm, asm}; +use core::arch::{asm, global_asm}; +use riscv::register::{ + mtvec::TrapMode, + scause::{self, Exception, Interrupt, Trap}, + sie, stval, stvec, +}; global_asm!(include_str!("trap.S")); @@ -42,7 +32,9 @@ fn set_user_trap_entry() { } pub fn enable_timer_interrupt() { - unsafe { sie::set_stimer(); } + unsafe { + sie::set_stimer(); + } } #[no_mangle] @@ -61,12 +53,12 @@ pub fn trap_handler() -> ! { cx = current_trap_cx(); cx.x[10] = result as usize; } - Trap::Exception(Exception::StoreFault) | - Trap::Exception(Exception::StorePageFault) | - Trap::Exception(Exception::InstructionFault) | - Trap::Exception(Exception::InstructionPageFault) | - Trap::Exception(Exception::LoadFault) | - Trap::Exception(Exception::LoadPageFault) => { + Trap::Exception(Exception::StoreFault) + | Trap::Exception(Exception::StorePageFault) + | Trap::Exception(Exception::InstructionFault) + | Trap::Exception(Exception::InstructionPageFault) + | Trap::Exception(Exception::LoadFault) + | Trap::Exception(Exception::LoadPageFault) => { println!( "[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.", scause.cause(), @@ -86,7 +78,11 @@ pub fn trap_handler() -> ! { suspend_current_and_run_next(); } _ => { - panic!("Unsupported trap {:?}, stval = {:#x}!", scause.cause(), stval); + panic!( + "Unsupported trap {:?}, stval = {:#x}!", + scause.cause(), + stval + ); } } trap_return(); @@ -119,4 +115,4 @@ pub fn trap_from_kernel() -> ! { panic!("a trap {:?} from kernel!", scause::read().cause()); } -pub use context::{TrapContext}; +pub use context::TrapContext; diff --git a/user/src/bin/exit.rs b/user/src/bin/exit.rs index 5bde550b..60510c90 100644 --- a/user/src/bin/exit.rs +++ b/user/src/bin/exit.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{fork, yield_, waitpid, exit, wait}; +use user_lib::{exit, fork, wait, waitpid, yield_}; const MAGIC: i32 = -0x10384; @@ -13,7 +13,9 @@ pub fn main() -> i32 { let pid = fork(); if pid == 0 { println!("I am the child."); - for _ in 0..7 { yield_(); } + for _ in 0..7 { + yield_(); + } exit(MAGIC); } else { println!("I am parent, fork a child pid {}", pid); @@ -26,4 +28,3 @@ pub fn main() -> i32 { println!("exit pass."); 0 } - diff --git a/user/src/bin/fantastic_text.rs b/user/src/bin/fantastic_text.rs index bb51db30..a3402ff6 100644 --- a/user/src/bin/fantastic_text.rs +++ b/user/src/bin/fantastic_text.rs @@ -41,4 +41,4 @@ pub fn main() -> i32 { println!("{}", color_text!(text, i)); } 0 -} \ No newline at end of file +} diff --git a/user/src/bin/forktest.rs b/user/src/bin/forktest.rs index a7d523a8..5374a56c 100644 --- a/user/src/bin/forktest.rs +++ b/user/src/bin/forktest.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{fork, wait, exit}; +use user_lib::{exit, fork, wait}; const MAX_CHILD: usize = 30; diff --git a/user/src/bin/forktest2.rs b/user/src/bin/forktest2.rs index d08a4120..c91ce152 100644 --- a/user/src/bin/forktest2.rs +++ b/user/src/bin/forktest2.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{fork, wait, getpid, exit, sleep, get_time}; +use user_lib::{exit, fork, get_time, getpid, sleep, wait}; static NUM: usize = 30; @@ -14,7 +14,8 @@ pub fn main() -> i32 { let pid = fork(); if pid == 0 { let current_time = get_time(); - let sleep_length = (current_time as i32 as isize) * (current_time as i32 as isize) % 1000 + 1000; + let sleep_length = + (current_time as i32 as isize) * (current_time as i32 as isize) % 1000 + 1000; println!("pid {} sleep for {} ms", getpid(), sleep_length); sleep(sleep_length as usize); println!("pid {} OK!", getpid()); @@ -30,4 +31,4 @@ pub fn main() -> i32 { assert!(wait(&mut exit_code) < 0); println!("forktest2 test passed!"); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/forktest_simple.rs b/user/src/bin/forktest_simple.rs index 821fba64..29a624b4 100644 --- a/user/src/bin/forktest_simple.rs +++ b/user/src/bin/forktest_simple.rs @@ -25,4 +25,4 @@ pub fn main() -> i32 { println!("child process pid = {}, exit code = {}", pid, exit_code); 0 } -} \ No newline at end of file +} diff --git a/user/src/bin/forktree.rs b/user/src/bin/forktree.rs index 2debf6c5..bfcfc4ca 100644 --- a/user/src/bin/forktree.rs +++ b/user/src/bin/forktree.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{sleep, getpid, fork, exit, yield_}; +use user_lib::{exit, fork, getpid, sleep, yield_}; const DEPTH: usize = 4; diff --git a/user/src/bin/hello_world.rs b/user/src/bin/hello_world.rs index de4a6a92..10d3f26c 100644 --- a/user/src/bin/hello_world.rs +++ b/user/src/bin/hello_world.rs @@ -8,4 +8,4 @@ extern crate user_lib; pub fn main() -> i32 { println!("Hello world from user mode program!"); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/initproc.rs b/user/src/bin/initproc.rs index 6d30fdb6..71bed27e 100644 --- a/user/src/bin/initproc.rs +++ b/user/src/bin/initproc.rs @@ -4,12 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{ - fork, - wait, - exec, - yield_, -}; +use user_lib::{exec, fork, wait, yield_}; #[no_mangle] fn main() -> i32 { @@ -25,10 +20,9 @@ fn main() -> i32 { } println!( "[initproc] Released a zombie process, pid={}, exit_code={}", - pid, - exit_code, + pid, exit_code, ); } } 0 -} \ No newline at end of file +} diff --git a/user/src/bin/matrix.rs b/user/src/bin/matrix.rs index 8f1357ea..b282d58f 100644 --- a/user/src/bin/matrix.rs +++ b/user/src/bin/matrix.rs @@ -1,10 +1,11 @@ #![no_std] #![no_main] +#![allow(clippy::needless_range_loop)] #[macro_use] extern crate user_lib; -use user_lib::{fork, wait, yield_, exit, getpid, get_time}; +use user_lib::{exit, fork, get_time, getpid, wait, yield_}; static NUM: usize = 30; const N: usize = 10; @@ -27,6 +28,7 @@ fn work(times: isize) { for i in 0..N { for j in 0..N { c[i][j] = 0; + #[allow(clippy::needless_range_loop)] for k in 0..N { c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % P; } diff --git a/user/src/bin/sleep.rs b/user/src/bin/sleep.rs index beba78c6..641a4f9d 100644 --- a/user/src/bin/sleep.rs +++ b/user/src/bin/sleep.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{sleep, exit, get_time, fork, waitpid}; +use user_lib::{exit, fork, get_time, sleep, waitpid}; fn sleepy() { let time: usize = 100; @@ -27,4 +27,4 @@ pub fn main() -> i32 { println!("use {} msecs.", get_time() - current_time); println!("sleep pass."); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/sleep_simple.rs b/user/src/bin/sleep_simple.rs index 4c058f87..7015a3d4 100644 --- a/user/src/bin/sleep_simple.rs +++ b/user/src/bin/sleep_simple.rs @@ -13,7 +13,11 @@ pub fn main() -> i32 { println!("current time_msec = {}", start); sleep(100); let end = get_time(); - println!("time_msec = {} after sleeping 100 ticks, delta = {}ms!", end, end - start); + println!( + "time_msec = {} after sleeping 100 ticks, delta = {}ms!", + end, + end - start + ); println!("r_sleep passed!"); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/stack_overflow.rs b/user/src/bin/stack_overflow.rs index e0ea471d..5d365f5d 100644 --- a/user/src/bin/stack_overflow.rs +++ b/user/src/bin/stack_overflow.rs @@ -5,7 +5,7 @@ extern crate user_lib; fn f(d: usize) { - println!("d = {}",d); + println!("d = {}", d); f(d + 1); } @@ -14,4 +14,4 @@ pub fn main() -> i32 { println!("It should trigger segmentation fault!"); f(0); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/user_shell.rs b/user/src/bin/user_shell.rs index 796bddb5..cdcb9721 100644 --- a/user/src/bin/user_shell.rs +++ b/user/src/bin/user_shell.rs @@ -1,5 +1,6 @@ #![no_std] #![no_main] +#![allow(clippy::println_empty_string)] extern crate alloc; @@ -12,8 +13,8 @@ const DL: u8 = 0x7fu8; const BS: u8 = 0x08u8; use alloc::string::String; -use user_lib::{fork, exec, waitpid}; use user_lib::console::getchar; +use user_lib::{exec, fork, waitpid}; #[no_mangle] pub fn main() -> i32 { @@ -59,4 +60,4 @@ pub fn main() -> i32 { } } } -} \ No newline at end of file +} diff --git a/user/src/bin/usertests.rs b/user/src/bin/usertests.rs index 7a4a6d7b..62bc8388 100644 --- a/user/src/bin/usertests.rs +++ b/user/src/bin/usertests.rs @@ -32,9 +32,12 @@ pub fn main() -> i32 { let mut exit_code: i32 = Default::default(); let wait_pid = waitpid(pid as usize, &mut exit_code); assert_eq!(pid, wait_pid); - println!("\x1b[32mUsertests: Test {} in Process {} exited with code {}\x1b[0m", test, pid, exit_code); + println!( + "\x1b[32mUsertests: Test {} in Process {} exited with code {}\x1b[0m", + test, pid, exit_code + ); } } println!("Usertests passed!"); 0 -} \ No newline at end of file +} diff --git a/user/src/bin/yield.rs b/user/src/bin/yield.rs index 55032e40..78b1468c 100644 --- a/user/src/bin/yield.rs +++ b/user/src/bin/yield.rs @@ -14,4 +14,4 @@ pub fn main() -> i32 { } println!("yield pass."); 0 -} \ No newline at end of file +} diff --git a/user/src/lang_items.rs b/user/src/lang_items.rs index c90d297f..3aee17ba 100644 --- a/user/src/lang_items.rs +++ b/user/src/lang_items.rs @@ -2,9 +2,14 @@ fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { let err = panic_info.message().unwrap(); if let Some(location) = panic_info.location() { - println!("Panicked at {}:{}, {}", location.file(), location.line(), err); + println!( + "Panicked at {}:{}, {}", + location.file(), + location.line(), + err + ); } else { println!("Panicked: {}", err); } loop {} -} \ No newline at end of file +} diff --git a/user/src/lib.rs b/user/src/lib.rs index 378dbca7..be1255db 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -5,11 +5,11 @@ #[macro_use] pub mod console; -mod syscall; mod lang_items; +mod syscall; -use syscall::*; use buddy_system_allocator::LockedHeap; +use syscall::*; const USER_HEAP_SIZE: usize = 16384; @@ -39,18 +39,36 @@ fn main() -> i32 { panic!("Cannot find main!"); } -pub fn read(fd: usize, buf: &mut [u8]) -> isize { sys_read(fd, buf) } -pub fn write(fd: usize, buf: &[u8]) -> isize { sys_write(fd, buf) } -pub fn exit(exit_code: i32) -> ! { sys_exit(exit_code); } -pub fn yield_() -> isize { sys_yield() } -pub fn get_time() -> isize { sys_get_time() } -pub fn getpid() -> isize { sys_getpid() } -pub fn fork() -> isize { sys_fork() } -pub fn exec(path: &str) -> isize { sys_exec(path) } +pub fn read(fd: usize, buf: &mut [u8]) -> isize { + sys_read(fd, buf) +} +pub fn write(fd: usize, buf: &[u8]) -> isize { + sys_write(fd, buf) +} +pub fn exit(exit_code: i32) -> ! { + sys_exit(exit_code); +} +pub fn yield_() -> isize { + sys_yield() +} +pub fn get_time() -> isize { + sys_get_time() +} +pub fn getpid() -> isize { + sys_getpid() +} +pub fn fork() -> isize { + sys_fork() +} +pub fn exec(path: &str) -> isize { + sys_exec(path) +} pub fn wait(exit_code: &mut i32) -> isize { loop { match sys_waitpid(-1, exit_code as *mut _) { - -2 => { yield_(); } + -2 => { + yield_(); + } // -1 or a real pid exit_pid => return exit_pid, } @@ -60,7 +78,9 @@ pub fn wait(exit_code: &mut i32) -> isize { pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { loop { match sys_waitpid(pid as isize, exit_code as *mut _) { - -2 => { yield_(); } + -2 => { + yield_(); + } // -1 or a real pid exit_pid => return exit_pid, } diff --git a/user/src/syscall.rs b/user/src/syscall.rs index dfe3966e..a37fadb3 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -25,7 +25,10 @@ fn syscall(id: usize, args: [usize; 3]) -> isize { } pub fn sys_read(fd: usize, buffer: &mut [u8]) -> isize { - syscall(SYSCALL_READ, [fd, buffer.as_mut_ptr() as usize, buffer.len()]) + syscall( + SYSCALL_READ, + [fd, buffer.as_mut_ptr() as usize, buffer.len()], + ) } pub fn sys_write(fd: usize, buffer: &[u8]) -> isize {