diff --git a/easy-fs-fuse/src/main.rs b/easy-fs-fuse/src/main.rs index cf07b618..cac1b797 100644 --- a/easy-fs-fuse/src/main.rs +++ b/easy-fs-fuse/src/main.rs @@ -1,12 +1,9 @@ -use easy_fs::{ - BlockDevice, - EasyFileSystem, -}; -use std::fs::{File, OpenOptions, read_dir}; -use std::io::{Read, Write, Seek, SeekFrom}; -use std::sync::Mutex; +use clap::{App, Arg}; +use easy_fs::{BlockDevice, EasyFileSystem}; +use std::fs::{read_dir, File, OpenOptions}; +use std::io::{Read, Seek, SeekFrom, Write}; use std::sync::Arc; -use clap::{Arg, App}; +use std::sync::Mutex; const BLOCK_SZ: usize = 512; @@ -34,17 +31,19 @@ fn main() { fn easy_fs_pack() -> std::io::Result<()> { let matches = App::new("EasyFileSystem packer") - .arg(Arg::with_name("source") - .short("s") - .long("source") - .takes_value(true) - .help("Executable source dir(with backslash)") + .arg( + Arg::with_name("source") + .short("s") + .long("source") + .takes_value(true) + .help("Executable source dir(with backslash)"), ) - .arg(Arg::with_name("target") - .short("t") - .long("target") - .takes_value(true) - .help("Executable target dir(with backslash)") + .arg( + Arg::with_name("target") + .short("t") + .long("target") + .takes_value(true) + .help("Executable target dir(with backslash)"), ) .get_matches(); let src_path = matches.value_of("source").unwrap(); @@ -60,11 +59,7 @@ fn easy_fs_pack() -> std::io::Result<()> { f }))); // 16MiB, at most 4095 files - let efs = EasyFileSystem::create( - block_file.clone(), - 16 * 2048, - 1, - ); + let efs = EasyFileSystem::create(block_file, 16 * 2048, 1); let root_inode = Arc::new(EasyFileSystem::root_inode(&efs)); let apps: Vec<_> = read_dir(src_path) .unwrap() @@ -103,11 +98,7 @@ fn efs_test() -> std::io::Result<()> { f.set_len(8192 * 512).unwrap(); f }))); - EasyFileSystem::create( - block_file.clone(), - 4096, - 1, - ); + EasyFileSystem::create(block_file.clone(), 4096, 1); let efs = EasyFileSystem::open(block_file.clone()); let root_inode = EasyFileSystem::root_inode(&efs); root_inode.create("filea"); @@ -121,17 +112,11 @@ fn efs_test() -> std::io::Result<()> { //let mut buffer = [0u8; 512]; let mut buffer = [0u8; 233]; let len = filea.read_at(0, &mut buffer); - assert_eq!( - greet_str, - core::str::from_utf8(&buffer[..len]).unwrap(), - ); + assert_eq!(greet_str, core::str::from_utf8(&buffer[..len]).unwrap(),); let mut random_str_test = |len: usize| { filea.clear(); - assert_eq!( - filea.read_at(0, &mut buffer), - 0, - ); + assert_eq!(filea.read_at(0, &mut buffer), 0,); let mut str = String::new(); use rand; // random digit @@ -148,9 +133,7 @@ fn efs_test() -> std::io::Result<()> { break; } offset += len; - read_str.push_str( - core::str::from_utf8(&read_buffer[..len]).unwrap() - ); + read_str.push_str(core::str::from_utf8(&read_buffer[..len]).unwrap()); } assert_eq!(str, read_str); }; diff --git a/easy-fs/src/bitmap.rs b/easy-fs/src/bitmap.rs index 4feaa9cf..2cea613e 100644 --- a/easy-fs/src/bitmap.rs +++ b/easy-fs/src/bitmap.rs @@ -1,9 +1,5 @@ +use super::{get_block_cache, BlockDevice, BLOCK_SZ}; use alloc::sync::Arc; -use super::{ - BlockDevice, - BLOCK_SZ, - get_block_cache, -}; type BitmapBlock = [u64; 64]; @@ -17,7 +13,7 @@ pub struct Bitmap { /// Return (block_pos, bits64_pos, inner_pos) fn decomposition(mut bit: usize) -> (usize, usize, usize) { let block_pos = bit / BLOCK_BITS; - bit = bit % BLOCK_BITS; + bit %= BLOCK_BITS; (block_pos, bit / 64, bit % 64) } @@ -34,14 +30,15 @@ impl Bitmap { let pos = get_block_cache( block_id + self.start_block_id as usize, Arc::clone(block_device), - ).lock().modify(0, |bitmap_block: &mut BitmapBlock| { + ) + .lock() + .modify(0, |bitmap_block: &mut BitmapBlock| { if let Some((bits64_pos, inner_pos)) = bitmap_block .iter() .enumerate() .find(|(_, bits64)| **bits64 != u64::MAX) - .map(|(bits64_pos, bits64)| { - (bits64_pos, bits64.trailing_ones() as usize) - }) { + .map(|(bits64_pos, bits64)| (bits64_pos, bits64.trailing_ones() as usize)) + { // modify cache bitmap_block[bits64_pos] |= 1u64 << inner_pos; Some(block_id * BLOCK_BITS + bits64_pos * 64 + inner_pos as usize) @@ -58,16 +55,15 @@ impl Bitmap { pub fn dealloc(&self, block_device: &Arc, bit: usize) { let (block_pos, bits64_pos, inner_pos) = decomposition(bit); - get_block_cache( - block_pos + self.start_block_id, - Arc::clone(block_device) - ).lock().modify(0, |bitmap_block: &mut BitmapBlock| { - assert!(bitmap_block[bits64_pos] & (1u64 << inner_pos) > 0); - bitmap_block[bits64_pos] -= 1u64 << inner_pos; - }); + get_block_cache(block_pos + self.start_block_id, Arc::clone(block_device)) + .lock() + .modify(0, |bitmap_block: &mut BitmapBlock| { + assert!(bitmap_block[bits64_pos] & (1u64 << inner_pos) > 0); + bitmap_block[bits64_pos] -= 1u64 << inner_pos; + }); } pub fn maximum(&self) -> usize { self.blocks * BLOCK_BITS } -} \ No newline at end of file +} diff --git a/easy-fs/src/block_cache.rs b/easy-fs/src/block_cache.rs index ba945b1d..4b90294a 100644 --- a/easy-fs/src/block_cache.rs +++ b/easy-fs/src/block_cache.rs @@ -1,7 +1,4 @@ -use super::{ - BLOCK_SZ, - BlockDevice, -}; +use super::{BlockDevice, BLOCK_SZ}; use alloc::collections::VecDeque; use alloc::sync::Arc; use lazy_static::*; @@ -16,10 +13,7 @@ pub struct BlockCache { impl BlockCache { /// Load a new BlockCache from disk. - pub fn new( - block_id: usize, - block_device: Arc - ) -> Self { + pub fn new(block_id: usize, block_device: Arc) -> Self { let mut cache = [0u8; BLOCK_SZ]; block_device.read_block(block_id, &mut cache); Self { @@ -34,14 +28,20 @@ impl BlockCache { &self.cache[offset] as *const _ as usize } - pub fn get_ref(&self, offset: usize) -> &T where T: Sized { + pub fn get_ref(&self, offset: usize) -> &T + where + T: Sized, + { let type_size = core::mem::size_of::(); assert!(offset + type_size <= BLOCK_SZ); let addr = self.addr_of_offset(offset); - unsafe { &*(addr as *const T) } + unsafe { &*(addr as *const T) } } - pub fn get_mut(&mut self, offset: usize) -> &mut T where T: Sized { + pub fn get_mut(&mut self, offset: usize) -> &mut T + where + T: Sized, + { let type_size = core::mem::size_of::(); assert!(offset + type_size <= BLOCK_SZ); self.modified = true; @@ -53,7 +53,7 @@ impl BlockCache { f(self.get_ref(offset)) } - pub fn modify(&mut self, offset:usize, f: impl FnOnce(&mut T) -> V) -> V { + pub fn modify(&mut self, offset: usize, f: impl FnOnce(&mut T) -> V) -> V { f(self.get_mut(offset)) } @@ -79,7 +79,9 @@ pub struct BlockCacheManager { impl BlockCacheManager { pub fn new() -> Self { - Self { queue: VecDeque::new() } + Self { + queue: VecDeque::new(), + } } pub fn get_block_cache( @@ -87,27 +89,28 @@ impl BlockCacheManager { block_id: usize, block_device: Arc, ) -> Arc> { - if let Some(pair) = self.queue - .iter() - .find(|pair| pair.0 == block_id) { - Arc::clone(&pair.1) + if let Some(pair) = self.queue.iter().find(|pair| pair.0 == block_id) { + Arc::clone(&pair.1) } else { // substitute if self.queue.len() == BLOCK_CACHE_SIZE { // from front to tail - if let Some((idx, _)) = self.queue + if let Some((idx, _)) = self + .queue .iter() .enumerate() - .find(|(_, pair)| Arc::strong_count(&pair.1) == 1) { + .find(|(_, pair)| Arc::strong_count(&pair.1) == 1) + { self.queue.drain(idx..=idx); } else { panic!("Run out of BlockCache!"); } } // load block into mem and push back - let block_cache = Arc::new(Mutex::new( - BlockCache::new(block_id, Arc::clone(&block_device)) - )); + let block_cache = Arc::new(Mutex::new(BlockCache::new( + block_id, + Arc::clone(&block_device), + ))); self.queue.push_back((block_id, Arc::clone(&block_cache))); block_cache } @@ -115,16 +118,17 @@ impl BlockCacheManager { } lazy_static! { - pub static ref BLOCK_CACHE_MANAGER: Mutex = Mutex::new( - BlockCacheManager::new() - ); + pub static ref BLOCK_CACHE_MANAGER: Mutex = + Mutex::new(BlockCacheManager::new()); } pub fn get_block_cache( block_id: usize, - block_device: Arc + block_device: Arc, ) -> Arc> { - BLOCK_CACHE_MANAGER.lock().get_block_cache(block_id, block_device) + BLOCK_CACHE_MANAGER + .lock() + .get_block_cache(block_id, block_device) } pub fn block_cache_sync_all() { diff --git a/easy-fs/src/block_dev.rs b/easy-fs/src/block_dev.rs index 7a282751..8a01eddb 100644 --- a/easy-fs/src/block_dev.rs +++ b/easy-fs/src/block_dev.rs @@ -1,6 +1,6 @@ use core::any::Any; -pub trait BlockDevice : Send + Sync + Any { +pub trait BlockDevice: Send + Sync + Any { fn read_block(&self, block_id: usize, buf: &mut [u8]); fn write_block(&self, block_id: usize, buf: &[u8]); } diff --git a/easy-fs/src/efs.rs b/easy-fs/src/efs.rs index 8b7adf26..82e95ae0 100644 --- a/easy-fs/src/efs.rs +++ b/easy-fs/src/efs.rs @@ -1,16 +1,10 @@ -use alloc::sync::Arc; -use spin::Mutex; use super::{ - BlockDevice, - Bitmap, + block_cache_sync_all, get_block_cache, Bitmap, BlockDevice, DiskInode, DiskInodeType, Inode, SuperBlock, - DiskInode, - DiskInodeType, - Inode, - get_block_cache, - block_cache_sync_all, }; use crate::BLOCK_SZ; +use alloc::sync::Arc; +use spin::Mutex; pub struct EasyFileSystem { pub block_device: Arc, @@ -50,39 +44,36 @@ impl EasyFileSystem { }; // clear all blocks for i in 0..total_blocks { - get_block_cache( - i as usize, - Arc::clone(&block_device) - ) - .lock() - .modify(0, |data_block: &mut DataBlock| { - for byte in data_block.iter_mut() { *byte = 0; } - }); + get_block_cache(i as usize, Arc::clone(&block_device)) + .lock() + .modify(0, |data_block: &mut DataBlock| { + for byte in data_block.iter_mut() { + *byte = 0; + } + }); } // initialize SuperBlock - get_block_cache(0, Arc::clone(&block_device)) - .lock() - .modify(0, |super_block: &mut SuperBlock| { - super_block.initialize( - total_blocks, - inode_bitmap_blocks, - inode_area_blocks, - data_bitmap_blocks, - data_area_blocks, - ); - }); + get_block_cache(0, Arc::clone(&block_device)).lock().modify( + 0, + |super_block: &mut SuperBlock| { + super_block.initialize( + total_blocks, + inode_bitmap_blocks, + inode_area_blocks, + data_bitmap_blocks, + data_area_blocks, + ); + }, + ); // write back immediately // create a inode for root node "/" assert_eq!(efs.alloc_inode(), 0); let (root_inode_block_id, root_inode_offset) = efs.get_disk_inode_pos(0); - get_block_cache( - root_inode_block_id as usize, - Arc::clone(&block_device) - ) - .lock() - .modify(root_inode_offset, |disk_inode: &mut DiskInode| { - disk_inode.initialize(DiskInodeType::Directory); - }); + get_block_cache(root_inode_block_id as usize, Arc::clone(&block_device)) + .lock() + .modify(root_inode_offset, |disk_inode: &mut DiskInode| { + disk_inode.initialize(DiskInodeType::Directory); + }); block_cache_sync_all(); Arc::new(Mutex::new(efs)) } @@ -97,10 +88,7 @@ impl EasyFileSystem { super_block.inode_bitmap_blocks + super_block.inode_area_blocks; let efs = Self { block_device, - inode_bitmap: Bitmap::new( - 1, - super_block.inode_bitmap_blocks as usize - ), + inode_bitmap: Bitmap::new(1, super_block.inode_bitmap_blocks as usize), data_bitmap: Bitmap::new( (1 + inode_total_blocks) as usize, super_block.data_bitmap_blocks as usize, @@ -117,19 +105,17 @@ impl EasyFileSystem { // acquire efs lock temporarily let (block_id, block_offset) = efs.lock().get_disk_inode_pos(0); // release efs lock - Inode::new( - block_id, - block_offset, - Arc::clone(efs), - block_device, - ) + Inode::new(block_id, block_offset, Arc::clone(efs), block_device) } pub fn get_disk_inode_pos(&self, inode_id: u32) -> (u32, usize) { let inode_size = core::mem::size_of::(); let inodes_per_block = (BLOCK_SZ / inode_size) as u32; let block_id = self.inode_area_start_block + inode_id / inodes_per_block; - (block_id, (inode_id % inodes_per_block) as usize * inode_size) + ( + block_id, + (inode_id % inodes_per_block) as usize * inode_size, + ) } pub fn get_data_block_id(&self, data_block_id: u32) -> u32 { @@ -146,18 +132,16 @@ impl EasyFileSystem { } pub fn dealloc_data(&mut self, block_id: u32) { - get_block_cache( - block_id as usize, - Arc::clone(&self.block_device) - ) - .lock() - .modify(0, |data_block: &mut DataBlock| { - data_block.iter_mut().for_each(|p| { *p = 0; }) - }); + get_block_cache(block_id as usize, Arc::clone(&self.block_device)) + .lock() + .modify(0, |data_block: &mut DataBlock| { + data_block.iter_mut().for_each(|p| { + *p = 0; + }) + }); self.data_bitmap.dealloc( &self.block_device, - (block_id - self.data_area_start_block) as usize + (block_id - self.data_area_start_block) as usize, ) } - -} \ No newline at end of file +} diff --git a/easy-fs/src/layout.rs b/easy-fs/src/layout.rs index c6f7b315..618484cf 100644 --- a/easy-fs/src/layout.rs +++ b/easy-fs/src/layout.rs @@ -1,11 +1,7 @@ -use core::fmt::{Debug, Formatter, Result}; -use super::{ - BLOCK_SZ, - BlockDevice, - get_block_cache, -}; +use super::{get_block_cache, BlockDevice, BLOCK_SZ}; use alloc::sync::Arc; use alloc::vec::Vec; +use core::fmt::{Debug, Formatter, Result}; const EFS_MAGIC: u32 = 0x3b800001; const INODE_DIRECT_COUNT: usize = 28; @@ -115,7 +111,8 @@ impl DiskInode { if data_blocks > INDIRECT1_BOUND { total += 1; // sub indirect1 - total += (data_blocks - INDIRECT1_BOUND + INODE_INDIRECT1_COUNT - 1) / INODE_INDIRECT1_COUNT; + total += + (data_blocks - INDIRECT1_BOUND + INODE_INDIRECT1_COUNT - 1) / INODE_INDIRECT1_COUNT; } total as u32 } @@ -135,22 +132,16 @@ impl DiskInode { }) } else { let last = inner_id - INDIRECT1_BOUND; - let indirect1 = get_block_cache( - self.indirect2 as usize, - Arc::clone(block_device) - ) - .lock() - .read(0, |indirect2: &IndirectBlock| { - indirect2[last / INODE_INDIRECT1_COUNT] - }); - get_block_cache( - indirect1 as usize, - Arc::clone(block_device) - ) - .lock() - .read(0, |indirect1: &IndirectBlock| { - indirect1[last % INODE_INDIRECT1_COUNT] - }) + let indirect1 = get_block_cache(self.indirect2 as usize, Arc::clone(block_device)) + .lock() + .read(0, |indirect2: &IndirectBlock| { + indirect2[last / INODE_INDIRECT1_COUNT] + }); + get_block_cache(indirect1 as usize, Arc::clone(block_device)) + .lock() + .read(0, |indirect1: &IndirectBlock| { + indirect1[last % INODE_INDIRECT1_COUNT] + }) } } pub fn increase_size( @@ -169,7 +160,7 @@ impl DiskInode { current_blocks += 1; } // alloc indirect1 - if total_blocks > INODE_DIRECT_COUNT as u32{ + if total_blocks > INODE_DIRECT_COUNT as u32 { if current_blocks == INODE_DIRECT_COUNT as u32 { self.indirect1 = new_blocks.next().unwrap(); } @@ -179,17 +170,14 @@ impl DiskInode { return; } // fill indirect1 - get_block_cache( - self.indirect1 as usize, - Arc::clone(block_device) - ) - .lock() - .modify(0, |indirect1: &mut IndirectBlock| { - while current_blocks < total_blocks.min(INODE_INDIRECT1_COUNT as u32) { - indirect1[current_blocks as usize] = new_blocks.next().unwrap(); - current_blocks += 1; - } - }); + get_block_cache(self.indirect1 as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect1: &mut IndirectBlock| { + while current_blocks < total_blocks.min(INODE_INDIRECT1_COUNT as u32) { + indirect1[current_blocks as usize] = new_blocks.next().unwrap(); + current_blocks += 1; + } + }); // alloc indirect2 if total_blocks > INODE_INDIRECT1_COUNT as u32 { if current_blocks == INODE_INDIRECT1_COUNT as u32 { @@ -206,33 +194,27 @@ impl DiskInode { let a1 = total_blocks as usize / INODE_INDIRECT1_COUNT; let b1 = total_blocks as usize % INODE_INDIRECT1_COUNT; // alloc low-level indirect1 - get_block_cache( - self.indirect2 as usize, - Arc::clone(block_device) - ) - .lock() - .modify(0, |indirect2: &mut IndirectBlock| { - while (a0 < a1) || (a0 == a1 && b0 < b1) { - if b0 == 0 { - indirect2[a0] = new_blocks.next().unwrap(); - } - // fill current - get_block_cache( - indirect2[a0] as usize, - Arc::clone(block_device) - ) - .lock() - .modify(0, |indirect1: &mut IndirectBlock| { - indirect1[b0] = new_blocks.next().unwrap(); - }); - // move to next - b0 += 1; - if b0 == INODE_INDIRECT1_COUNT { - b0 = 0; - a0 += 1; + get_block_cache(self.indirect2 as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect2: &mut IndirectBlock| { + while (a0 < a1) || (a0 == a1 && b0 < b1) { + if b0 == 0 { + indirect2[a0] = new_blocks.next().unwrap(); + } + // fill current + get_block_cache(indirect2[a0] as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect1: &mut IndirectBlock| { + indirect1[b0] = new_blocks.next().unwrap(); + }); + // move to next + b0 += 1; + if b0 == INODE_INDIRECT1_COUNT { + b0 = 0; + a0 += 1; + } } - } - }); + }); } /// Clear size to zero and return blocks that should be deallocated. @@ -258,18 +240,15 @@ impl DiskInode { return v; } // indirect1 - get_block_cache( - self.indirect1 as usize, - Arc::clone(block_device), - ) - .lock() - .modify(0, |indirect1: &mut IndirectBlock| { - while current_blocks < data_blocks.min(INODE_INDIRECT1_COUNT) { - v.push(indirect1[current_blocks]); - //indirect1[current_blocks] = 0; - current_blocks += 1; - } - }); + get_block_cache(self.indirect1 as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect1: &mut IndirectBlock| { + while current_blocks < data_blocks.min(INODE_INDIRECT1_COUNT) { + v.push(indirect1[current_blocks]); + //indirect1[current_blocks] = 0; + current_blocks += 1; + } + }); self.indirect1 = 0; // indirect2 block if data_blocks > INODE_INDIRECT1_COUNT { @@ -282,45 +261,33 @@ impl DiskInode { assert!(data_blocks <= INODE_INDIRECT2_COUNT); let a1 = data_blocks / INODE_INDIRECT1_COUNT; let b1 = data_blocks % INODE_INDIRECT1_COUNT; - get_block_cache( - self.indirect2 as usize, - Arc::clone(block_device), - ) - .lock() - .modify(0, |indirect2: &mut IndirectBlock| { - // full indirect1 blocks - for i in 0..a1 { - v.push(indirect2[i]); - get_block_cache( - indirect2[i] as usize, - Arc::clone(block_device), - ) - .lock() - .modify(0, |indirect1: &mut IndirectBlock| { - for j in 0..INODE_INDIRECT1_COUNT { - v.push(indirect1[j]); - //indirect1[j] = 0; - } - }); - //indirect2[i] = 0; - } - // last indirect1 block - if b1 > 0 { - v.push(indirect2[a1]); - get_block_cache( - indirect2[a1] as usize, - Arc::clone(block_device), - ) - .lock() - .modify(0, |indirect1: &mut IndirectBlock| { - for j in 0..b1 { - v.push(indirect1[j]); - //indirect1[j] = 0; - } - }); - //indirect2[a1] = 0; - } - }); + get_block_cache(self.indirect2 as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect2: &mut IndirectBlock| { + // full indirect1 blocks + for entry in indirect2.iter_mut().take(a1) { + v.push(*entry); + get_block_cache(*entry as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect1: &mut IndirectBlock| { + for entry in indirect1.iter() { + v.push(*entry); + } + }); + } + // last indirect1 block + if b1 > 0 { + v.push(indirect2[a1]); + get_block_cache(indirect2[a1] as usize, Arc::clone(block_device)) + .lock() + .modify(0, |indirect1: &mut IndirectBlock| { + for entry in indirect1.iter().take(b1) { + v.push(*entry); + } + }); + //indirect2[a1] = 0; + } + }); self.indirect2 = 0; v } @@ -355,7 +322,9 @@ impl DiskInode { }); read_size += block_read_size; // move to next block - if end_current_block == end { break; } + if end_current_block == end { + break; + } start_block += 1; start = end_current_block; } @@ -381,7 +350,7 @@ impl DiskInode { let block_write_size = end_current_block - start; get_block_cache( self.get_block_id(start_block as u32, block_device) as usize, - Arc::clone(block_device) + Arc::clone(block_device), ) .lock() .modify(0, |data_block: &mut DataBlock| { @@ -391,7 +360,9 @@ impl DiskInode { }); write_size += block_write_size; // move to next block - if end_current_block == end { break; } + if end_current_block == end { + break; + } start_block += 1; start = end_current_block; } @@ -423,20 +394,10 @@ impl DirEntry { } } pub fn as_bytes(&self) -> &[u8] { - unsafe { - core::slice::from_raw_parts( - self as *const _ as usize as *const u8, - DIRENT_SZ, - ) - } + unsafe { core::slice::from_raw_parts(self as *const _ as usize as *const u8, DIRENT_SZ) } } pub fn as_bytes_mut(&mut self) -> &mut [u8] { - unsafe { - core::slice::from_raw_parts_mut( - self as *mut _ as usize as *mut u8, - DIRENT_SZ, - ) - } + unsafe { core::slice::from_raw_parts_mut(self as *mut _ as usize as *mut u8, DIRENT_SZ) } } pub fn name(&self) -> &str { let len = (0usize..).find(|i| self.name[*i] == 0).unwrap(); @@ -445,4 +406,4 @@ impl DirEntry { pub fn inode_number(&self) -> u32 { self.inode_number } -} \ No newline at end of file +} diff --git a/easy-fs/src/lib.rs b/easy-fs/src/lib.rs index afb957ac..fa36e6b7 100644 --- a/easy-fs/src/lib.rs +++ b/easy-fs/src/lib.rs @@ -2,17 +2,17 @@ extern crate alloc; +mod bitmap; +mod block_cache; mod block_dev; -mod layout; mod efs; -mod bitmap; +mod layout; mod vfs; -mod block_cache; pub const BLOCK_SZ: usize = 512; +use bitmap::Bitmap; +use block_cache::{block_cache_sync_all, get_block_cache}; pub use block_dev::BlockDevice; pub use efs::EasyFileSystem; -pub use vfs::Inode; use layout::*; -use bitmap::Bitmap; -use block_cache::{get_block_cache, block_cache_sync_all}; \ No newline at end of file +pub use vfs::Inode; diff --git a/easy-fs/src/vfs.rs b/easy-fs/src/vfs.rs index 9534c39a..d67948f5 100644 --- a/easy-fs/src/vfs.rs +++ b/easy-fs/src/vfs.rs @@ -1,15 +1,9 @@ use super::{ - BlockDevice, - DiskInode, - DiskInodeType, - DirEntry, - EasyFileSystem, - DIRENT_SZ, - get_block_cache, - block_cache_sync_all, + block_cache_sync_all, get_block_cache, BlockDevice, DirEntry, DiskInode, DiskInodeType, + EasyFileSystem, DIRENT_SZ, }; -use alloc::sync::Arc; use alloc::string::String; +use alloc::sync::Arc; use alloc::vec::Vec; use spin::{Mutex, MutexGuard}; @@ -37,35 +31,25 @@ impl Inode { } fn read_disk_inode(&self, f: impl FnOnce(&DiskInode) -> V) -> V { - get_block_cache( - self.block_id, - Arc::clone(&self.block_device) - ).lock().read(self.block_offset, f) + get_block_cache(self.block_id, Arc::clone(&self.block_device)) + .lock() + .read(self.block_offset, f) } fn modify_disk_inode(&self, f: impl FnOnce(&mut DiskInode) -> V) -> V { - get_block_cache( - self.block_id, - Arc::clone(&self.block_device) - ).lock().modify(self.block_offset, f) + get_block_cache(self.block_id, Arc::clone(&self.block_device)) + .lock() + .modify(self.block_offset, f) } - fn find_inode_id( - &self, - name: &str, - disk_inode: &DiskInode, - ) -> Option { + fn find_inode_id(&self, name: &str, disk_inode: &DiskInode) -> Option { // assert it is a directory assert!(disk_inode.is_dir()); let file_count = (disk_inode.size as usize) / DIRENT_SZ; let mut dirent = DirEntry::empty(); for i in 0..file_count { assert_eq!( - disk_inode.read_at( - DIRENT_SZ * i, - dirent.as_bytes_mut(), - &self.block_device, - ), + disk_inode.read_at(DIRENT_SZ * i, dirent.as_bytes_mut(), &self.block_device,), DIRENT_SZ, ); if dirent.name() == name { @@ -78,8 +62,7 @@ impl Inode { pub fn find(&self, name: &str) -> Option> { let fs = self.fs.lock(); self.read_disk_inode(|disk_inode| { - self.find_inode_id(name, disk_inode) - .map(|inode_id| { + self.find_inode_id(name, disk_inode).map(|inode_id| { let (block_id, block_offset) = fs.get_disk_inode_pos(inode_id); Arc::new(Self::new( block_id, @@ -110,26 +93,25 @@ impl Inode { pub fn create(&self, name: &str) -> Option> { let mut fs = self.fs.lock(); - if self.modify_disk_inode(|root_inode| { + let op = |root_inode: &DiskInode| { // assert it is a directory assert!(root_inode.is_dir()); // has the file been created? self.find_inode_id(name, root_inode) - }).is_some() { + }; + if self.read_disk_inode(op).is_some() { return None; } // create a new file // alloc a inode with an indirect block let new_inode_id = fs.alloc_inode(); // initialize inode - let (new_inode_block_id, new_inode_block_offset) - = fs.get_disk_inode_pos(new_inode_id); - get_block_cache( - new_inode_block_id as usize, - Arc::clone(&self.block_device) - ).lock().modify(new_inode_block_offset, |new_inode: &mut DiskInode| { - new_inode.initialize(DiskInodeType::File); - }); + let (new_inode_block_id, new_inode_block_offset) = fs.get_disk_inode_pos(new_inode_id); + get_block_cache(new_inode_block_id as usize, Arc::clone(&self.block_device)) + .lock() + .modify(new_inode_block_offset, |new_inode: &mut DiskInode| { + new_inode.initialize(DiskInodeType::File); + }); self.modify_disk_inode(|root_inode| { // append file in the dirent let file_count = (root_inode.size as usize) / DIRENT_SZ; @@ -165,11 +147,7 @@ impl Inode { for i in 0..file_count { let mut dirent = DirEntry::empty(); assert_eq!( - disk_inode.read_at( - i * DIRENT_SZ, - dirent.as_bytes_mut(), - &self.block_device, - ), + disk_inode.read_at(i * DIRENT_SZ, dirent.as_bytes_mut(), &self.block_device,), DIRENT_SZ, ); v.push(String::from(dirent.name())); @@ -180,9 +158,7 @@ impl Inode { pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize { let _fs = self.fs.lock(); - self.read_disk_inode(|disk_inode| { - disk_inode.read_at(offset, buf, &self.block_device) - }) + self.read_disk_inode(|disk_inode| disk_inode.read_at(offset, buf, &self.block_device)) } pub fn write_at(&self, offset: usize, buf: &[u8]) -> usize { diff --git a/os/src/config.rs b/os/src/config.rs index dce95ec4..0af32704 100644 --- a/os/src/config.rs +++ b/os/src/config.rs @@ -17,26 +17,24 @@ pub const CLOCK_FREQ: usize = 403000000 / 62; pub const CLOCK_FREQ: usize = 12500000; #[cfg(feature = "board_qemu")] -pub const MMIO: &[(usize, usize)] = &[ - (0x10001000, 0x1000), -]; +pub const MMIO: &[(usize, usize)] = &[(0x10001000, 0x1000)]; #[cfg(feature = "board_k210")] pub const MMIO: &[(usize, usize)] = &[ // we don't need clint in S priv when running // we only need claim/complete for target0 after initializing - (0x0C00_0000, 0x3000), /* PLIC */ - (0x0C20_0000, 0x1000), /* PLIC */ - (0x3800_0000, 0x1000), /* UARTHS */ - (0x3800_1000, 0x1000), /* GPIOHS */ - (0x5020_0000, 0x1000), /* GPIO */ - (0x5024_0000, 0x1000), /* SPI_SLAVE */ - (0x502B_0000, 0x1000), /* FPIOA */ - (0x502D_0000, 0x1000), /* TIMER0 */ - (0x502E_0000, 0x1000), /* TIMER1 */ - (0x502F_0000, 0x1000), /* TIMER2 */ - (0x5044_0000, 0x1000), /* SYSCTL */ - (0x5200_0000, 0x1000), /* SPI0 */ - (0x5300_0000, 0x1000), /* SPI1 */ - (0x5400_0000, 0x1000), /* SPI2 */ -]; \ No newline at end of file + (0x0C00_0000, 0x3000), /* PLIC */ + (0x0C20_0000, 0x1000), /* PLIC */ + (0x3800_0000, 0x1000), /* UARTHS */ + (0x3800_1000, 0x1000), /* GPIOHS */ + (0x5020_0000, 0x1000), /* GPIO */ + (0x5024_0000, 0x1000), /* SPI_SLAVE */ + (0x502B_0000, 0x1000), /* FPIOA */ + (0x502D_0000, 0x1000), /* TIMER0 */ + (0x502E_0000, 0x1000), /* TIMER1 */ + (0x502F_0000, 0x1000), /* TIMER2 */ + (0x5044_0000, 0x1000), /* SYSCTL */ + (0x5200_0000, 0x1000), /* SPI0 */ + (0x5300_0000, 0x1000), /* SPI1 */ + (0x5400_0000, 0x1000), /* SPI2 */ +]; 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/drivers/block/mod.rs b/os/src/drivers/block/mod.rs index f79b8b81..67436fd2 100644 --- a/os/src/drivers/block/mod.rs +++ b/os/src/drivers/block/mod.rs @@ -1,9 +1,9 @@ -mod virtio_blk; mod sdcard; +mod virtio_blk; -use lazy_static::*; use alloc::sync::Arc; use easy_fs::BlockDevice; +use lazy_static::*; #[cfg(feature = "board_qemu")] type BlockDeviceImpl = virtio_blk::VirtIOBlock; @@ -21,10 +21,12 @@ pub fn block_device_test() { let mut write_buffer = [0u8; 512]; let mut read_buffer = [0u8; 512]; for i in 0..512 { - for byte in write_buffer.iter_mut() { *byte = i as u8; } + for byte in write_buffer.iter_mut() { + *byte = i as u8; + } block_device.write_block(i as usize, &write_buffer); block_device.read_block(i as usize, &mut read_buffer); assert_eq!(write_buffer, read_buffer); } println!("block device test passed!"); -} \ No newline at end of file +} diff --git a/os/src/drivers/block/sdcard.rs b/os/src/drivers/block/sdcard.rs index e550cc01..8603b2f9 100644 --- a/os/src/drivers/block/sdcard.rs +++ b/os/src/drivers/block/sdcard.rs @@ -2,21 +2,21 @@ #![allow(non_camel_case_types)] #![allow(unused)] -use k210_pac::{Peripherals, SPI0}; +use super::BlockDevice; +use crate::sync::UPSafeCell; +use core::convert::TryInto; use k210_hal::prelude::*; +use k210_pac::{Peripherals, SPI0}; use k210_soc::{ + fpioa::{self, io}, //dmac::{dma_channel, DMAC, DMACExt}, gpio, gpiohs, - spi::{aitm, frame_format, tmod, work_mode, SPI, SPIExt, SPIImpl}, - fpioa::{self, io}, - sysctl, sleep::usleep, + spi::{aitm, frame_format, tmod, work_mode, SPIExt, SPIImpl, SPI}, + sysctl, }; -use crate::sync::UPSafeCell; use lazy_static::*; -use super::BlockDevice; -use core::convert::TryInto; pub struct SDCard { spi: SPI, @@ -160,7 +160,11 @@ pub struct SDCardInfo { } impl SDCard { - pub fn new(spi: X, spi_cs: u32, cs_gpionum: u8/*, dmac: &'a DMAC, channel: dma_channel*/) -> Self { + pub fn new( + spi: X, + spi_cs: u32, + cs_gpionum: u8, /*, dmac: &'a DMAC, channel: dma_channel*/ + ) -> Self { Self { spi, spi_cs, @@ -606,7 +610,7 @@ impl SDCard { } let mut error = false; //let mut dma_chunk = [0u32; SEC_LEN]; - let mut tmp_chunk= [0u8; SEC_LEN]; + let mut tmp_chunk = [0u8; SEC_LEN]; for chunk in data_buf.chunks_mut(SEC_LEN) { if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ { error = true; @@ -616,7 +620,7 @@ impl SDCard { //self.read_data_dma(&mut dma_chunk); self.read_data(&mut tmp_chunk); /* Place the data received as u32 units from DMA into the u8 target buffer */ - for (a, b) in chunk.iter_mut().zip(/*dma_chunk*/tmp_chunk.iter()) { + for (a, b) in chunk.iter_mut().zip(/*dma_chunk*/ tmp_chunk.iter()) { //*a = (b & 0xff) as u8; *a = *b; } @@ -675,7 +679,7 @@ impl SDCard { /* Send the data token to signify the start of the data */ self.write_data(&frame); /* Write the block data to SD : write count data by block */ - for (a, &b) in /*dma_chunk*/tmp_chunk.iter_mut().zip(chunk.iter()) { + for (a, &b) in /*dma_chunk*/ tmp_chunk.iter_mut().zip(chunk.iter()) { //*a = b.into(); *a = b; } @@ -711,9 +715,8 @@ fn io_init() { } lazy_static! { - static ref PERIPHERALS: UPSafeCell = unsafe { - UPSafeCell::new(Peripherals::take().unwrap()) - }; + static ref PERIPHERALS: UPSafeCell = + unsafe { UPSafeCell::new(Peripherals::take().unwrap()) }; } fn init_sdcard() -> SDCard> { @@ -747,9 +750,15 @@ impl SDCardWrapper { impl BlockDevice for SDCardWrapper { fn read_block(&self, block_id: usize, buf: &mut [u8]) { - self.0.exclusive_access().read_sector(buf,block_id as u32).unwrap(); + self.0 + .exclusive_access() + .read_sector(buf, block_id as u32) + .unwrap(); } fn write_block(&self, block_id: usize, buf: &[u8]) { - self.0.exclusive_access().write_sector(buf,block_id as u32).unwrap(); + self.0 + .exclusive_access() + .write_sector(buf, block_id as u32) + .unwrap(); } -} \ No newline at end of file +} diff --git a/os/src/drivers/block/virtio_blk.rs b/os/src/drivers/block/virtio_blk.rs index 6b386190..cca839da 100644 --- a/os/src/drivers/block/virtio_blk.rs +++ b/os/src/drivers/block/virtio_blk.rs @@ -1,20 +1,12 @@ - -use virtio_drivers::{VirtIOBlk, VirtIOHeader}; +use super::BlockDevice; use crate::mm::{ - PhysAddr, - VirtAddr, - frame_alloc, - frame_dealloc, - PhysPageNum, - FrameTracker, - StepByOne, - PageTable, - kernel_token, + frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum, + StepByOne, VirtAddr, }; -use super::BlockDevice; use crate::sync::UPSafeCell; use alloc::vec::Vec; use lazy_static::*; +use virtio_drivers::{VirtIOBlk, VirtIOHeader}; #[allow(unused)] const VIRTIO0: usize = 0x10001000; @@ -22,21 +14,21 @@ const VIRTIO0: usize = 0x10001000; pub struct VirtIOBlock(UPSafeCell>); lazy_static! { - static ref QUEUE_FRAMES: UPSafeCell> = unsafe { - UPSafeCell::new(Vec::new()) - }; + static ref QUEUE_FRAMES: UPSafeCell> = unsafe { UPSafeCell::new(Vec::new()) }; } impl BlockDevice for VirtIOBlock { fn read_block(&self, block_id: usize, buf: &mut [u8]) { - self.0.exclusive_access() - .read_block(block_id, buf) - .expect("Error when reading VirtIOBlk"); + self.0 + .exclusive_access() + .read_block(block_id, buf) + .expect("Error when reading VirtIOBlk"); } fn write_block(&self, block_id: usize, buf: &[u8]) { - self.0.exclusive_access() - .write_block(block_id, buf) - .expect("Error when writing VirtIOBlk"); + self.0 + .exclusive_access() + .write_block(block_id, buf) + .expect("Error when writing VirtIOBlk"); } } @@ -44,9 +36,9 @@ impl VirtIOBlock { #[allow(unused)] pub fn new() -> Self { unsafe { - Self(UPSafeCell::new(VirtIOBlk::new( - &mut *(VIRTIO0 as *mut VirtIOHeader) - ).unwrap())) + Self(UPSafeCell::new( + VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap(), + )) } } } @@ -56,7 +48,9 @@ pub extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr { let mut ppn_base = PhysPageNum(0); for i in 0..pages { let frame = frame_alloc().unwrap(); - if i == 0 { ppn_base = frame.ppn; } + if i == 0 { + ppn_base = frame.ppn; + } assert_eq!(frame.ppn.0, ppn_base.0 + i); QUEUE_FRAMES.exclusive_access().push(frame); } @@ -80,5 +74,7 @@ pub extern "C" fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr { #[no_mangle] pub extern "C" fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr { - PageTable::from_token(kernel_token()).translate_va(vaddr).unwrap() + PageTable::from_token(kernel_token()) + .translate_va(vaddr) + .unwrap() } diff --git a/os/src/drivers/mod.rs b/os/src/drivers/mod.rs index 54c0a2cb..43a6f54b 100644 --- a/os/src/drivers/mod.rs +++ b/os/src/drivers/mod.rs @@ -1,3 +1,3 @@ mod block; -pub use block::BLOCK_DEVICE; \ No newline at end of file +pub use block::BLOCK_DEVICE; diff --git a/os/src/fs/inode.rs b/os/src/fs/inode.rs index 8e644066..ad22ca58 100644 --- a/os/src/fs/inode.rs +++ b/os/src/fs/inode.rs @@ -1,15 +1,12 @@ -use easy_fs::{ - EasyFileSystem, - Inode, -}; +use super::File; use crate::drivers::BLOCK_DEVICE; +use crate::mm::UserBuffer; use crate::sync::UPSafeCell; use alloc::sync::Arc; -use lazy_static::*; -use bitflags::*; use alloc::vec::Vec; -use super::File; -use crate::mm::UserBuffer; +use bitflags::*; +use easy_fs::{EasyFileSystem, Inode}; +use lazy_static::*; pub struct OSInode { readable: bool, @@ -23,18 +20,11 @@ pub struct OSInodeInner { } impl OSInode { - pub fn new( - readable: bool, - writable: bool, - inode: Arc, - ) -> Self { + pub fn new(readable: bool, writable: bool, inode: Arc) -> Self { Self { readable, writable, - inner: unsafe { UPSafeCell::new(OSInodeInner { - offset: 0, - inode, - })}, + inner: unsafe { UPSafeCell::new(OSInodeInner { offset: 0, inode }) }, } } pub fn read_all(&self) -> Vec { @@ -98,40 +88,30 @@ pub fn open_file(name: &str, flags: OpenFlags) -> Option> { if let Some(inode) = ROOT_INODE.find(name) { // clear size inode.clear(); - Some(Arc::new(OSInode::new( - readable, - writable, - inode, - ))) + Some(Arc::new(OSInode::new(readable, writable, inode))) } else { // create file - ROOT_INODE.create(name) - .map(|inode| { - Arc::new(OSInode::new( - readable, - writable, - inode, - )) - }) + ROOT_INODE + .create(name) + .map(|inode| Arc::new(OSInode::new(readable, writable, inode))) } } else { - ROOT_INODE.find(name) - .map(|inode| { - if flags.contains(OpenFlags::TRUNC) { - inode.clear(); - } - Arc::new(OSInode::new( - readable, - writable, - inode - )) - }) + ROOT_INODE.find(name).map(|inode| { + if flags.contains(OpenFlags::TRUNC) { + inode.clear(); + } + Arc::new(OSInode::new(readable, writable, inode)) + }) } } impl File for OSInode { - fn readable(&self) -> bool { self.readable } - fn writable(&self) -> bool { self.writable } + fn readable(&self) -> bool { + self.readable + } + fn writable(&self) -> bool { + self.writable + } fn read(&self, mut buf: UserBuffer) -> usize { let mut inner = self.inner.exclusive_access(); let mut total_read_size = 0usize; diff --git a/os/src/fs/mod.rs b/os/src/fs/mod.rs index ecc0d155..ce88f287 100644 --- a/os/src/fs/mod.rs +++ b/os/src/fs/mod.rs @@ -1,14 +1,14 @@ -mod stdio; mod inode; +mod stdio; use crate::mm::UserBuffer; -pub trait File : Send + Sync { +pub trait File: Send + Sync { fn readable(&self) -> bool; fn writable(&self) -> bool; fn read(&self, buf: UserBuffer) -> usize; fn write(&self, buf: UserBuffer) -> usize; } +pub use inode::{list_apps, open_file, OSInode, OpenFlags}; pub use stdio::{Stdin, Stdout}; -pub use inode::{OSInode, open_file, OpenFlags, list_apps}; diff --git a/os/src/fs/stdio.rs b/os/src/fs/stdio.rs index e8df7950..7c74d3e1 100644 --- a/os/src/fs/stdio.rs +++ b/os/src/fs/stdio.rs @@ -1,5 +1,5 @@ use super::File; -use crate::mm::{UserBuffer}; +use crate::mm::UserBuffer; use crate::sbi::console_getchar; use crate::task::suspend_current_and_run_next; @@ -8,8 +8,12 @@ pub struct Stdin; pub struct Stdout; impl File for Stdin { - fn readable(&self) -> bool { true } - fn writable(&self) -> bool { false } + fn readable(&self) -> bool { + true + } + fn writable(&self) -> bool { + false + } fn read(&self, mut user_buf: UserBuffer) -> usize { assert_eq!(user_buf.len(), 1); // busy loop @@ -24,7 +28,9 @@ impl File for Stdin { } } let ch = c as u8; - unsafe { user_buf.buffers[0].as_mut_ptr().write_volatile(ch); } + unsafe { + user_buf.buffers[0].as_mut_ptr().write_volatile(ch); + } 1 } fn write(&self, _user_buf: UserBuffer) -> usize { @@ -33,9 +39,13 @@ impl File for Stdin { } impl File for Stdout { - fn readable(&self) -> bool { false } - fn writable(&self) -> bool { true } - fn read(&self, _user_buf: UserBuffer) -> usize{ + fn readable(&self) -> bool { + false + } + fn writable(&self) -> bool { + true + } + fn read(&self, _user_buf: UserBuffer) -> usize { panic!("Cannot read from stdout!"); } fn write(&self, user_buf: UserBuffer) -> usize { @@ -44,4 +54,4 @@ impl File for Stdout { } user_buf.len() } -} \ No newline at end of file +} 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/main.rs b/os/src/main.rs index 3a960a65..23b9725b 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -10,17 +10,17 @@ extern crate bitflags; #[macro_use] mod console; +mod config; +mod drivers; +mod fs; mod lang_items; +mod mm; mod sbi; +mod sync; mod syscall; -mod trap; -mod config; mod task; mod timer; -mod sync; -mod mm; -mod fs; -mod drivers; +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); } } diff --git a/os/src/mm/address.rs b/os/src/mm/address.rs index 107f35c6..7faceaa9 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; @@ -52,35 +52,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 { @@ -89,13 +113,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 { @@ -104,7 +138,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 { @@ -121,28 +157,20 @@ impl VirtPageNum { impl PhysAddr { pub fn get_ref(&self) -> &'static T { - unsafe { - (self.0 as *const T).as_ref().unwrap() - } + unsafe { (self.0 as *const T).as_ref().unwrap() } } 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(); @@ -165,41 +193,57 @@ impl StepByOne for PhysPageNum { } #[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 357db707..e0db1d40 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 { } pub 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 31092442..a6b2dc01 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -1,22 +1,15 @@ -use super::{PageTable, PageTableEntry, PTEFlags}; -use super::{VirtPageNum, VirtAddr, PhysPageNum, PhysAddr}; -use super::{FrameTracker, frame_alloc}; -use super::{VPNRange, StepByOne}; +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, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE}; +use crate::sync::UPSafeCell; use alloc::collections::BTreeMap; -use alloc::vec::Vec; -use riscv::register::satp; use alloc::sync::Arc; -use lazy_static::*; -use crate::sync::UPSafeCell; -use crate::config::{ - MEMORY_END, - PAGE_SIZE, - TRAMPOLINE, - TRAP_CONTEXT, - USER_STACK_SIZE, - MMIO, -}; +use alloc::vec::Vec; use core::arch::asm; +use lazy_static::*; +use riscv::register::satp; extern "C" { fn stext(); @@ -32,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 fn kernel_token() -> usize { @@ -57,17 +49,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); } @@ -96,50 +95,71 @@ 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); - println!("mapping memory-mapped registers"); - for pair in MMIO { - memory_set.push(MapArea::new( - (*pair).0.into(), - ((*pair).0 + (*pair).1).into(), + memory_set.push( + MapArea::new( + (ekernel as usize).into(), + MEMORY_END.into(), MapType::Identical, MapPermission::R | MapPermission::W, - ), None); + ), + None, + ); + println!("mapping memory-mapped registers"); + for pair in MMIO { + memory_set.push( + MapArea::new( + (*pair).0.into(), + ((*pair).0 + (*pair).1).into(), + MapType::Identical, + MapPermission::R | MapPermission::W, + ), + None, + ); } memory_set } @@ -163,19 +183,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]), ); } } @@ -185,20 +206,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(); @@ -212,7 +243,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 @@ -245,7 +278,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(); @@ -344,15 +377,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 85e8c16a..34220c4a 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -1,28 +1,22 @@ -mod heap_allocator; mod address; mod frame_allocator; -mod page_table; +mod heap_allocator; mod memory_set; +mod page_table; -use page_table::PTEFlags; use address::VPNRange; -pub use address::{PhysAddr, VirtAddr, PhysPageNum, VirtPageNum, StepByOne}; -pub use frame_allocator::{FrameTracker, frame_alloc, frame_dealloc,}; +pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; +pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker}; +pub use memory_set::remap_test; +pub use memory_set::{kernel_token, MapPermission, MemorySet, KERNEL_SPACE}; +use page_table::PTEFlags; pub use page_table::{ - PageTable, - PageTableEntry, - translated_byte_buffer, - translated_str, - translated_ref, - translated_refmut, - UserBuffer, - UserBufferIterator, + translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable, + PageTableEntry, UserBuffer, UserBufferIterator, }; -pub use memory_set::{MemorySet, KERNEL_SPACE, MapPermission, kernel_token}; -pub use memory_set::remap_test; pub fn init() { heap_allocator::init_heap(); frame_allocator::init_frame_allocator(); KERNEL_SPACE.exclusive_access().activate(); -} \ No newline at end of file +} diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index 1412c9fe..0400914a 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,17 +122,15 @@ 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| { - let aligned_pa: PhysAddr = pte.ppn().into(); - 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| { + let aligned_pa: PhysAddr = pte.ppn().into(); + 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 @@ -157,10 +145,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)); @@ -180,7 +165,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; } @@ -193,13 +181,19 @@ pub fn translated_str(token: usize, ptr: *const u8) -> String { #[allow(unused)] pub fn translated_ref(token: usize, ptr: *const T) -> &'static T { let page_table = PageTable::from_token(token); - page_table.translate_va(VirtAddr::from(ptr as usize)).unwrap().get_ref() + page_table + .translate_va(VirtAddr::from(ptr as usize)) + .unwrap() + .get_ref() } pub fn translated_refmut(token: usize, ptr: *mut T) -> &'static mut T { let page_table = PageTable::from_token(token); let va = ptr as usize; - page_table.translate_va(VirtAddr::from(va)).unwrap().get_mut() + page_table + .translate_va(VirtAddr::from(va)) + .unwrap() + .get_mut() } pub struct UserBuffer { 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 d1063e76..dbaa4eaf 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -1,10 +1,6 @@ -use crate::mm::{ - UserBuffer, - translated_byte_buffer, - translated_str, -}; -use crate::task::{current_user_token, current_task}; -use crate::fs::{OpenFlags, open_file}; +use crate::fs::{open_file, OpenFlags}; +use crate::mm::{translated_byte_buffer, translated_str, UserBuffer}; +use crate::task::{current_task, current_user_token}; pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { let token = current_user_token(); @@ -20,9 +16,7 @@ pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { let file = file.clone(); // release current task TCB manually to avoid multi-borrow drop(inner); - file.write( - UserBuffer::new(translated_byte_buffer(token, buf, len)) - ) as isize + file.write(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize } else { -1 } @@ -42,9 +36,7 @@ pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize { } // release current task TCB manually to avoid multi-borrow drop(inner); - file.read( - UserBuffer::new(translated_byte_buffer(token, buf, len)) - ) as isize + file.read(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize } else { -1 } @@ -54,10 +46,7 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize { let task = current_task().unwrap(); let token = current_user_token(); let path = translated_str(token, path); - if let Some(inode) = open_file( - path.as_str(), - OpenFlags::from_bits(flags).unwrap() - ) { + if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) { let mut inner = task.inner_exclusive_access(); let fd = inner.alloc_fd(); inner.fd_table[fd] = Some(inode); diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 817c0ea7..8c5f6e3f 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -32,4 +32,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 a43ccfaf..6010370b 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,19 +1,10 @@ +use crate::fs::{open_file, OpenFlags}; +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::fs::{ - open_file, - OpenFlags, -}; use alloc::sync::Arc; pub fn sys_exit(exit_code: i32) -> ! { @@ -69,21 +60,20 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { // ---- access current PCB 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 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 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 being removed from children list 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 81d6a09b..7dfcdbdc 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -1,28 +1,23 @@ mod context; -mod switch; -mod task; mod manager; -mod processor; mod pid; +mod processor; +mod switch; +mod task; use crate::fs::{open_file, OpenFlags}; -use switch::__switch; -use task::{TaskControlBlock, TaskStatus}; use alloc::sync::Arc; -use manager::fetch_task; -use lazy_static::*; pub use context::TaskContext; +use lazy_static::*; +use manager::fetch_task; +use switch::__switch; +use task::{TaskControlBlock, TaskStatus}; +pub use manager::add_task; +pub use pid::{pid_alloc, KernelStack, PidHandle}; pub use processor::{ - run_tasks, - current_task, - current_user_token, - current_trap_cx, - take_current_task, - schedule, + current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task, }; -pub use manager::add_task; -pub use pid::{PidHandle, pid_alloc, KernelStack}; pub fn suspend_current_and_run_next() { // There must be an application running. 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 f46db719..b5b917dd 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,19 +1,14 @@ -use crate::mm::{ - MemorySet, - PhysPageNum, - KERNEL_SPACE, - VirtAddr, -}; -use crate::trap::{TrapContext, trap_handler}; +use super::TaskContext; +use super::{pid_alloc, KernelStack, PidHandle}; use crate::config::TRAP_CONTEXT; +use crate::fs::{File, Stdin, Stdout}; +use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE}; use crate::sync::UPSafeCell; -use core::cell::RefMut; -use super::TaskContext; -use super::{PidHandle, pid_alloc, KernelStack}; -use alloc::sync::{Weak, Arc}; +use crate::trap::{trap_handler, TrapContext}; +use alloc::sync::{Arc, Weak}; use alloc::vec; use alloc::vec::Vec; -use crate::fs::{File, Stdin, Stdout}; +use core::cell::RefMut; pub struct TaskControlBlock { // immutable @@ -49,8 +44,7 @@ impl TaskControlBlockInner { self.get_status() == TaskStatus::Zombie } pub fn alloc_fd(&mut self) -> usize { - if let Some(fd) = (0..self.fd_table.len()) - .find(|fd| self.fd_table[*fd].is_none()) { + if let Some(fd) = (0..self.fd_table.len()).find(|fd| self.fd_table[*fd].is_none()) { fd } else { self.fd_table.push(None); @@ -77,24 +71,26 @@ 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, - fd_table: vec![ - // 0 -> stdin - Some(Arc::new(Stdin)), - // 1 -> stdout - Some(Arc::new(Stdout)), - // 2 -> stderr - Some(Arc::new(Stdout)), - ], - })}, + 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, + fd_table: vec![ + // 0 -> stdin + Some(Arc::new(Stdin)), + // 1 -> stdout + Some(Arc::new(Stdout)), + // 2 -> stderr + Some(Arc::new(Stdout)), + ], + }) + }, }; // prepare TrapContext in user space let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx(); @@ -136,9 +132,7 @@ impl TaskControlBlock { // ---- hold parent PCB lock 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() @@ -159,17 +153,19 @@ 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, - fd_table: new_fd_table, - })}, + 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, + fd_table: new_fd_table, + }) + }, }); // add child parent_inner.children.push(task_control_block.clone()); @@ -185,7 +181,6 @@ impl TaskControlBlock { pub fn getpid(&self) -> usize { self.pid.0 } - } #[derive(Copy, Clone, PartialEq)] 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 16f81415..011b7fb7 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)] #[derive(Debug)] @@ -12,7 +12,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 66d403f7..4c9a1128 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 + ); } } //println!("before trap_return"); 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/filetest_simple.rs b/user/src/bin/filetest_simple.rs index 60fda6aa..3406d551 100644 --- a/user/src/bin/filetest_simple.rs +++ b/user/src/bin/filetest_simple.rs @@ -4,13 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{ - open, - close, - read, - write, - OpenFlags, -}; +use user_lib::{close, open, read, write, OpenFlags}; #[no_mangle] pub fn main() -> i32 { @@ -29,10 +23,7 @@ pub fn main() -> i32 { let read_len = read(fd, &mut buffer) as usize; close(fd); - assert_eq!( - test_str, - core::str::from_utf8(&buffer[..read_len]).unwrap(), - ); + assert_eq!(test_str, core::str::from_utf8(&buffer[..read_len]).unwrap(),); println!("file_test passed!"); 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/huge_write.rs b/user/src/bin/huge_write.rs index b00ca17b..e93f8b8e 100644 --- a/user/src/bin/huge_write.rs +++ b/user/src/bin/huge_write.rs @@ -4,19 +4,13 @@ #[macro_use] extern crate user_lib; -use user_lib::{ - OpenFlags, - open, - close, - write, - get_time, -}; +use user_lib::{close, get_time, open, write, OpenFlags}; #[no_mangle] pub fn main() -> i32 { let mut buffer = [0u8; 1024]; // 1KiB - for i in 0..buffer.len() { - buffer[i] = i as u8; + for (i, ch) in buffer.iter_mut().enumerate() { + *ch = i as u8; } let f = open("testf\0", OpenFlags::CREATE | OpenFlags::WRONLY); if f < 0 { @@ -25,12 +19,15 @@ pub fn main() -> i32 { let f = f as usize; let start = get_time(); let size_mb = 1usize; - for _ in 0..1024*size_mb { + for _ in 0..1024 * size_mb { write(f, &buffer); } close(f); let time_ms = (get_time() - start) as usize; let speed_kbs = size_mb * 1000000 / time_ms; - println!("{}MiB written, time cost = {}ms, write speed = {}KiB/s", size_mb, time_ms, speed_kbs); + println!( + "{}MiB written, time cost = {}ms, write speed = {}KiB/s", + size_mb, time_ms, speed_kbs + ); 0 } diff --git a/user/src/bin/initproc.rs b/user/src/bin/initproc.rs index a201fffb..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,8 +20,7 @@ fn main() -> i32 { } println!( "[initproc] Released a zombie process, pid={}, exit_code={}", - pid, - exit_code, + pid, exit_code, ); } } diff --git a/user/src/bin/matrix.rs b/user/src/bin/matrix.rs index 8f1357ea..9ebf48f4 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; diff --git a/user/src/bin/run_pipe_test.rs b/user/src/bin/run_pipe_test.rs index a62a98b7..447eeea9 100644 --- a/user/src/bin/run_pipe_test.rs +++ b/user/src/bin/run_pipe_test.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -use user_lib::{fork, exec, wait}; +use user_lib::{exec, fork, wait}; #[no_mangle] pub fn main() -> i32 { diff --git a/user/src/bin/sleep.rs b/user/src/bin/sleep.rs index 65283970..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; 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 f0858234..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 { @@ -60,4 +61,3 @@ pub fn main() -> i32 { } } } - diff --git a/user/src/bin/usertests.rs b/user/src/bin/usertests.rs index cf77f15c..62bc8388 100644 --- a/user/src/bin/usertests.rs +++ b/user/src/bin/usertests.rs @@ -32,7 +32,10 @@ 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!"); 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 b5b98e08..c65aa421 100644 --- a/user/src/lang_items.rs +++ b/user/src/lang_items.rs @@ -4,9 +4,14 @@ use super::exit; 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); } exit(-1); -} \ No newline at end of file +} diff --git a/user/src/lib.rs b/user/src/lib.rs index 9f409728..c3b2cb90 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -5,15 +5,15 @@ #[macro_use] pub mod console; -mod syscall; mod lang_items; +mod syscall; extern crate alloc; #[macro_use] extern crate bitflags; -use syscall::*; use buddy_system_allocator::LockedHeap; +use syscall::*; const USER_HEAP_SIZE: usize = 32768; @@ -53,20 +53,42 @@ bitflags! { } } -pub fn open(path: &str, flags: OpenFlags) -> isize { sys_open(path, flags.bits) } -pub fn close(fd: usize) -> isize { sys_close(fd) } -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 open(path: &str, flags: OpenFlags) -> isize { + sys_open(path, flags.bits) +} +pub fn close(fd: usize) -> isize { + sys_close(fd) +} +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, } @@ -76,7 +98,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 7bdf57f2..5423cce9 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -35,7 +35,10 @@ pub fn sys_close(fd: usize) -> 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 {