diff --git a/crate/memory/src/memory_set/handler/mod.rs b/crate/memory/src/memory_set/handler/mod.rs index 6154e96..9a17732 100644 --- a/crate/memory/src/memory_set/handler/mod.rs +++ b/crate/memory/src/memory_set/handler/mod.rs @@ -41,11 +41,11 @@ pub trait FrameAllocator: Debug + Clone + Send + Sync + 'static { mod byframe; mod delay; -mod linear; mod file; +mod linear; //mod swap; pub use self::byframe::ByFrame; pub use self::delay::Delay; -pub use self::linear::Linear; pub use self::file::{File, Read}; +pub use self::linear::Linear; diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 24ac173..e7232ad 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -85,7 +85,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitvec" version = "0.11.0" -source = "git+https://github.com/myrrlyn/bitvec.git#ed2aec38bfb5b1116e3585b1574c50655b9c85ec" +source = "git+https://github.com/myrrlyn/bitvec.git#8ab20a3e33fe068fc3a4a05eda1211d5fcc1237b" [[package]] name = "bootloader" @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "buddy_system_allocator" -version = "0.1.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -248,11 +248,6 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "once" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "os_bootinfo" version = "0.2.1" @@ -372,7 +367,7 @@ dependencies = [ "bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)", "bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)", "bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)", - "buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)", @@ -381,7 +376,6 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "pc-keyboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "pci 0.0.1 (git+https://github.com/rcore-os/pci-rs)", @@ -402,12 +396,15 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221" +source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707" +dependencies = [ + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221" +source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -667,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)" = "" "checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b" "checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)" = "" -"checksum buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed828f1e227d6e32b998d6375b67fd63ac5389d50b23f258ce151d22b6cc595" +"checksum buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "94a6c0143a07fea0db2f4b43cb9540dcc7c17af8a7beafdf2184e5e4e35aae91" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" @@ -689,7 +686,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6" "checksum mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4cbf449a63e4db77af9f662d6b42068c0925e779a3a7c70ad02f191cf1e6c802" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "931fb7a4cf34610cf6cbe58d52a8ca5ef4c726d4e2e178abd0dc13a6551c6d73" "checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a" "checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" "checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 32855b1..8ef38d7 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -50,7 +50,6 @@ opt-level = 2 [dependencies] log = "0.4" spin = "0.5" -once = "0.3" xmas-elf = "0.6" bitflags = "1.0" bit_field = "0.9" @@ -58,7 +57,7 @@ volatile = "0.2" heapless = "0.4" bitvec = { git = "https://github.com/myrrlyn/bitvec.git", default-features = false, features = ["alloc"] } console-traits = "0.3" -buddy_system_allocator = "0.1" +buddy_system_allocator = "0.3" pci = { git = "https://github.com/rcore-os/pci-rs" } device_tree = { git = "https://github.com/rcore-os/device_tree-rs" } isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers" } diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 1cc6696..0480e35 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -2,7 +2,6 @@ use alloc::string::String; use bcm2837::atags::Atags; -use once::*; #[path = "../../../../drivers/gpu/fb.rs"] pub mod fb; @@ -18,10 +17,7 @@ pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000; /// Initialize serial port before other initializations. pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); - serial::init(); - println!("Hello Raspberry Pi!"); } diff --git a/kernel/src/arch/aarch64/board/raspi3/serial.rs b/kernel/src/arch/aarch64/board/raspi3/serial.rs index b7796d3..b2a1577 100644 --- a/kernel/src/arch/aarch64/board/raspi3/serial.rs +++ b/kernel/src/arch/aarch64/board/raspi3/serial.rs @@ -1,7 +1,6 @@ use bcm2837::mini_uart::{MiniUart, MiniUartInterruptId}; use core::fmt; use lazy_static::lazy_static; -use once::*; use spin::Mutex; /// Struct to get a global SerialPort interface @@ -23,8 +22,6 @@ impl SerialPort { /// Init a newly created SerialPort, can only be called once. fn init(&mut self) { - assert_has_not_been_called!("SerialPort::init must be called only once"); - self.mu.init(); super::irq::register_irq(super::irq::Interrupt::Aux, handle_serial_irq); } diff --git a/kernel/src/arch/aarch64/driver/mod.rs b/kernel/src/arch/aarch64/driver/mod.rs index a100c2b..d80ab0c 100644 --- a/kernel/src/arch/aarch64/driver/mod.rs +++ b/kernel/src/arch/aarch64/driver/mod.rs @@ -1,7 +1,6 @@ //! ARM64 drivers use super::board; -use once::*; pub use self::board::fb; pub use self::board::serial; @@ -10,8 +9,6 @@ pub mod console; /// Initialize ARM64 common drivers pub fn init() { - assert_has_not_been_called!("driver::init must be called only once"); - board::init_driver(); console::init(); } diff --git a/kernel/src/arch/mipsel/board/malta/mod.rs b/kernel/src/arch/mipsel/board/malta/mod.rs index 0fbaa33..7b54808 100644 --- a/kernel/src/arch/mipsel/board/malta/mod.rs +++ b/kernel/src/arch/mipsel/board/malta/mod.rs @@ -1,7 +1,6 @@ use crate::drivers::bus::pci; use alloc::string::String; use mips::registers::cp0; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -17,7 +16,6 @@ use fb::FramebufferInfo; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); // initialize serial driver serial::init(0xbf000900); // Enable serial interrupt diff --git a/kernel/src/arch/mipsel/board/mipssim/mod.rs b/kernel/src/arch/mipsel/board/mipssim/mod.rs index 97eb465..be68708 100644 --- a/kernel/src/arch/mipsel/board/mipssim/mod.rs +++ b/kernel/src/arch/mipsel/board/mipssim/mod.rs @@ -1,5 +1,4 @@ use alloc::string::String; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -11,7 +10,6 @@ pub mod serial; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); serial::init(0xbfd003f8); println!("Hello QEMU MIPSSIM!"); } diff --git a/kernel/src/arch/mipsel/board/thinpad/mod.rs b/kernel/src/arch/mipsel/board/thinpad/mod.rs index dae1f92..2afb19f 100644 --- a/kernel/src/arch/mipsel/board/thinpad/mod.rs +++ b/kernel/src/arch/mipsel/board/thinpad/mod.rs @@ -1,5 +1,4 @@ use alloc::string::String; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -14,7 +13,6 @@ use fb::FramebufferResult; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); serial::init(0xa3000000); println!("Hello ThinPad!"); } diff --git a/kernel/src/arch/mipsel/driver/mod.rs b/kernel/src/arch/mipsel/driver/mod.rs index 0cf6ad0..7fb6fd0 100644 --- a/kernel/src/arch/mipsel/driver/mod.rs +++ b/kernel/src/arch/mipsel/driver/mod.rs @@ -1,7 +1,6 @@ //! mipsel drivers use super::board; -use once::*; pub use self::board::fb; pub use self::board::serial; @@ -10,7 +9,6 @@ pub mod console; /// Initialize common drivers pub fn init() { - assert_has_not_been_called!("driver::init must be called only once"); board::init_driver(); console::init(); } diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index 02158ed..cbc4d67 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -1,5 +1,3 @@ -use once::*; - pub mod ide; pub mod keyboard; pub mod pic; @@ -9,8 +7,6 @@ pub mod serial; pub mod vga; pub fn init() { - assert_has_not_been_called!(); - // Use IOAPIC instead of PIC pic::disable(); diff --git a/kernel/src/arch/x86_64/driver/pic.rs b/kernel/src/arch/x86_64/driver/pic.rs index 7a67a3c..d35ca5c 100644 --- a/kernel/src/arch/x86_64/driver/pic.rs +++ b/kernel/src/arch/x86_64/driver/pic.rs @@ -1,7 +1,6 @@ // Copy from Redox use log::*; -use once::*; use spin::Mutex; use x86_64::instructions::port::Port; @@ -18,8 +17,6 @@ pub fn disable() { } pub unsafe fn init() { - assert_has_not_been_called!("pic::init must be called only once"); - let mut master = MASTER.lock(); let mut slave = SLAVE.lock(); diff --git a/kernel/src/arch/x86_64/driver/pit.rs b/kernel/src/arch/x86_64/driver/pit.rs index 655ce8a..2b88280 100644 --- a/kernel/src/arch/x86_64/driver/pit.rs +++ b/kernel/src/arch/x86_64/driver/pit.rs @@ -1,9 +1,7 @@ use log::*; -use once::*; use x86_64::instructions::port::Port; pub fn init() { - assert_has_not_been_called!("pit::init must be called only once"); Pit::new(0x40).init(100); info!("pit: init end"); } diff --git a/kernel/src/arch/x86_64/driver/serial.rs b/kernel/src/arch/x86_64/driver/serial.rs index 68655e2..8242fdb 100644 --- a/kernel/src/arch/x86_64/driver/serial.rs +++ b/kernel/src/arch/x86_64/driver/serial.rs @@ -1,4 +1,3 @@ -use once::*; use spin::Mutex; use uart_16550::SerialPort; use x86_64::instructions::port::Port; @@ -9,8 +8,6 @@ pub static COM1: Mutex = Mutex::new(unsafe { SerialPort::new(0x3F8) pub static COM2: Mutex = Mutex::new(unsafe { SerialPort::new(0x2F8) }); pub fn init() { - assert_has_not_been_called!("serial::init must be called only once"); - COM1.lock().init(); COM2.lock().init(); enable_irq(consts::COM1); diff --git a/kernel/src/arch/x86_64/memory.rs b/kernel/src/arch/x86_64/memory.rs index 092dc9e..c5afb85 100644 --- a/kernel/src/arch/x86_64/memory.rs +++ b/kernel/src/arch/x86_64/memory.rs @@ -4,12 +4,10 @@ use bitmap_allocator::BitAlloc; use super::{BootInfo, MemoryRegionType}; use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR}; use log::*; -use once::*; use rcore_memory::paging::*; use rcore_memory::PAGE_SIZE; pub fn init(boot_info: &BootInfo) { - assert_has_not_been_called!("memory::init must be called only once"); init_frame_allocator(boot_info); init_device_vm_map(); init_heap(); diff --git a/kernel/src/drivers/block/ahci.rs b/kernel/src/drivers/block/ahci.rs index 189c6e4..f86b909 100644 --- a/kernel/src/drivers/block/ahci.rs +++ b/kernel/src/drivers/block/ahci.rs @@ -48,8 +48,6 @@ pub fn init(_irq: Option, header: usize, size: usize) -> Arc { let ahci = AHCI::new(header, size); let driver = Arc::new(AHCIDriver(Mutex::new(ahci))); DRIVERS.write().push(driver.clone()); - BLK_DRIVERS - .write() - .push(Arc::new(BlockDriver(driver.clone()))); + BLK_DRIVERS.write().push(driver.clone()); driver } diff --git a/kernel/src/drivers/block/virtio_blk.rs b/kernel/src/drivers/block/virtio_blk.rs index fd38b64..3a561f4 100644 --- a/kernel/src/drivers/block/virtio_blk.rs +++ b/kernel/src/drivers/block/virtio_blk.rs @@ -222,5 +222,5 @@ pub fn virtio_blk_init(node: &Node) { let driver = Arc::new(driver); DRIVERS.write().push(driver.clone()); - BLK_DRIVERS.write().push(Arc::new(BlockDriver(driver))); + BLK_DRIVERS.write().push(driver); } diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 2744b2b..b2c86e7 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -5,7 +5,6 @@ use crate::drivers::{Driver, DRIVERS, NET_DRIVERS}; use crate::memory::active_table; use alloc::collections::BTreeMap; use alloc::sync::Arc; -use core::cmp::Ordering; use pci::*; use rcore_memory::{paging::PageTable, PAGE_SIZE}; use spin::Mutex; diff --git a/kernel/src/drivers/gpu/fb.rs b/kernel/src/drivers/gpu/fb.rs index 54d7e10..01fbe6a 100644 --- a/kernel/src/drivers/gpu/fb.rs +++ b/kernel/src/drivers/gpu/fb.rs @@ -4,7 +4,6 @@ use alloc::string::String; use core::fmt; use lazy_static::lazy_static; use log::*; -use once::*; use spin::Mutex; /// Framebuffer information @@ -134,8 +133,6 @@ impl fmt::Debug for Framebuffer { impl Framebuffer { fn new(width: u32, height: u32, depth: u32) -> Result { - assert_has_not_been_called!("Framebuffer::new must be called only once"); - let probed_info = super::probe_fb_info(width, height, depth); match probed_info { diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index de559ce..bc9bba8 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -7,7 +7,7 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address}; use spin::RwLock; use crate::sync::Condvar; -use rcore_fs::dev::BlockDevice; +use rcore_fs::dev::{self, BlockDevice, DevError}; #[allow(dead_code)] pub mod block; @@ -95,19 +95,29 @@ lazy_static! { // NOTE: RwLock only write when initializing drivers pub static ref DRIVERS: RwLock>> = RwLock::new(Vec::new()); pub static ref NET_DRIVERS: RwLock>> = RwLock::new(Vec::new()); - pub static ref BLK_DRIVERS: RwLock>> = RwLock::new(Vec::new()); + pub static ref BLK_DRIVERS: RwLock>> = RwLock::new(Vec::new()); } -pub struct BlockDriver(Arc); +pub struct BlockDriver(pub Arc); impl BlockDevice for BlockDriver { const BLOCK_SIZE_LOG2: u8 = 9; // 512 - fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { - self.0.read_block(block_id, buf) + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> dev::Result<()> { + match self.0.read_block(block_id, buf) { + true => Ok(()), + false => Err(DevError), + } } - fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { - self.0.write_block(block_id, buf) + fn write_at(&self, block_id: usize, buf: &[u8]) -> dev::Result<()> { + match self.0.write_block(block_id, buf) { + true => Ok(()), + false => Err(DevError), + } + } + + fn sync(&self) -> dev::Result<()> { + Ok(()) } } diff --git a/kernel/src/fs/device.rs b/kernel/src/fs/device.rs index dc33ed8..dfe2cc4 100644 --- a/kernel/src/fs/device.rs +++ b/kernel/src/fs/device.rs @@ -19,34 +19,42 @@ impl MemBuf { } impl Device for MemBuf { - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { let slice = self.0.read(); let len = buf.len().min(slice.len() - offset); buf[..len].copy_from_slice(&slice[offset..offset + len]); - Some(len) + Ok(len) } - fn write_at(&self, offset: usize, buf: &[u8]) -> Option { + fn write_at(&self, offset: usize, buf: &[u8]) -> Result { let mut slice = self.0.write(); let len = buf.len().min(slice.len() - offset); slice[offset..offset + len].copy_from_slice(&buf[..len]); - Some(len) + Ok(len) + } + fn sync(&self) -> Result<()> { + Ok(()) } } #[cfg(target_arch = "x86_64")] impl BlockDevice for ide::IDE { const BLOCK_SIZE_LOG2: u8 = 9; - fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> Result<()> { use core::slice; assert!(buf.len() >= ide::BLOCK_SIZE); let buf = unsafe { slice::from_raw_parts_mut(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; - self.read(block_id as u64, 1, buf).is_ok() + self.read(block_id as u64, 1, buf).map_err(|_| DevError)?; + Ok(()) } - fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { + fn write_at(&self, block_id: usize, buf: &[u8]) -> Result<()> { use core::slice; assert!(buf.len() >= ide::BLOCK_SIZE); let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; - self.write(block_id as u64, 1, buf).is_ok() + self.write(block_id as u64, 1, buf).map_err(|_| DevError)?; + Ok(()) + } + fn sync(&self) -> Result<()> { + Ok(()) } } diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 3979c4d..9fd8119 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -1,6 +1,7 @@ //! File handle for process use alloc::{string::String, sync::Arc}; +use core::fmt; use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result}; @@ -9,6 +10,7 @@ pub struct FileHandle { inode: Arc, offset: u64, options: OpenOptions, + path: String, } #[derive(Debug, Clone)] @@ -27,12 +29,13 @@ pub enum SeekFrom { } impl FileHandle { - pub fn new(inode: Arc, options: OpenOptions) -> Self { - FileHandle { + pub fn new(inode: Arc, options: OpenOptions, path: String) -> Self { + return FileHandle { inode, offset: 0, options, - } + path, + }; } pub fn read(&mut self, buf: &mut [u8]) -> Result { @@ -121,3 +124,14 @@ impl FileHandle { self.inode.clone() } } + +impl fmt::Debug for FileHandle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + return f + .debug_struct("FileHandle") + .field("offset", &self.offset) + .field("options", &self.options) + .field("path", &self.path) + .finish(); + } +} diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 32c5cdc..dbbdbe4 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -5,6 +5,7 @@ use crate::net::Socket; use crate::syscall::{SysError, SysResult}; use alloc::boxed::Box; use rcore_fs::vfs::PollStatus; +use super::ioctl::*; // TODO: merge FileLike to FileHandle ? // TODO: fix dup and remove Clone @@ -30,13 +31,19 @@ impl FileLike { Ok(len) } pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { - match self { - FileLike::File(file) => file.io_control(request as u32, arg1)?, - FileLike::Socket(socket) => { - socket.ioctl(request, arg1, arg2, arg3)?; + match request { + // TODO: place flags & path in FileLike in stead of FileHandle/Socket + FIOCLEX => Ok(0), + _ => { + match self { + FileLike::File(file) => file.io_control(request as u32, arg1)?, + FileLike::Socket(socket) => { + socket.ioctl(request, arg1, arg2, arg3)?; + } + } + Ok(0) } } - Ok(0) } pub fn poll(&self) -> Result { let status = match self { @@ -53,8 +60,8 @@ impl FileLike { impl fmt::Debug for FileLike { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - FileLike::File(_) => write!(f, "File"), - FileLike::Socket(_) => write!(f, "Socket"), + FileLike::File(file) => write!(f, "File({:?})", file), + FileLike::Socket(socket) => write!(f, "Socket({:?})", socket), } } } diff --git a/kernel/src/fs/ioctl.rs b/kernel/src/fs/ioctl.rs new file mode 100644 index 0000000..e9fa9ca --- /dev/null +++ b/kernel/src/fs/ioctl.rs @@ -0,0 +1,36 @@ +// for IOR and IOW: +// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits +// higher 2 bits: 01 = write, 10 = read + +#[cfg(not(target_arch = "mips"))] +pub const TCGETS: usize = 0x5401; +#[cfg(target_arch = "mips")] +pub const TCGETS: usize = 0x540D; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCGPGRP: usize = 0x540F; +// _IOR('t', 119, int) +#[cfg(target_arch = "mips")] +pub const TIOCGPGRP: usize = 0x4_004_74_77; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCSPGRP: usize = 0x5410; +// _IOW('t', 118, int) +#[cfg(target_arch = "mips")] +pub const TIOCSPGRP: usize = 0x8_004_74_76; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCGWINSZ: usize = 0x5413; +// _IOR('t', 104, struct winsize) +#[cfg(target_arch = "mips")] +pub const TIOCGWINSZ: usize = 0x4_008_74_68; + +#[cfg(not(target_arch = "mips"))] +pub const FIONCLEX: usize = 0x5450; +#[cfg(target_arch = "mips")] +pub const FIOCLEX: usize = 0x6602; + +#[cfg(not(target_arch = "mips"))] +pub const FIOCLEX: usize = 0x5451; +#[cfg(target_arch = "mips")] +pub const FIOCLEX: usize = 0x6601; \ No newline at end of file diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 256ce5e..a5e56a1 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -1,23 +1,24 @@ use alloc::{sync::Arc, vec::Vec}; use rcore_fs::vfs::*; +use rcore_fs::dev::block_cache::BlockCache; use rcore_fs_sfs::SimpleFileSystem; -#[cfg(target_arch = "x86_64")] -use crate::arch::driver::ide; +use crate::drivers::BlockDriver; pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; -pub use self::stdio::{STDIN, STDOUT}; pub use self::pseudo::*; +pub use self::stdio::{STDIN, STDOUT}; mod device; mod file; mod file_like; mod pipe; -mod stdio; mod pseudo; +mod stdio; +mod ioctl; /// Hard link user programs #[cfg(feature = "link_user")] @@ -41,9 +42,15 @@ lazy_static! { let device = { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "x86_64"))] { - crate::drivers::BLK_DRIVERS.read().iter() - .next().expect("Block device not found") - .clone() + let driver = BlockDriver( + crate::drivers::BLK_DRIVERS + .read().iter() + .next().expect("Block device not found") + .clone() + ); + // enable block cache + Arc::new(BlockCache::new(driver, 0x100)) + // Arc::new(driver) } #[cfg(target_arch = "aarch64")] { diff --git a/kernel/src/fs/pipe.rs b/kernel/src/fs/pipe.rs index 8807380..6059e1a 100644 --- a/kernel/src/fs/pipe.rs +++ b/kernel/src/fs/pipe.rs @@ -57,7 +57,6 @@ impl Pipe { // TODO: better way to provide default impl? macro_rules! impl_inode { () => { - fn poll(&self) -> Result { Err(FsError::NotSupported) } fn metadata(&self) -> Result { Err(FsError::NotSupported) } fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) } fn sync_all(&self) -> Result<()> { Ok(()) } @@ -104,5 +103,41 @@ impl INode for Pipe { Ok(0) } } + + fn poll(&self) -> Result { + let data = self.data.lock(); + match self.direction { + PipeEnd::Read => { + if data.buf.len() > 0 { + Ok(PollStatus { + read: true, + write: false, + error: false, + }) + } else { + Ok(PollStatus { + read: false, + write: false, + error: false, + }) + } + } + PipeEnd::Write => { + if data.buf.len() > 0 { + Ok(PollStatus { + read: false, + write: true, + error: false, + }) + } else { + Ok(PollStatus { + read: false, + write: false, + error: false, + }) + } + } + } + } impl_inode!(); } diff --git a/kernel/src/fs/pseudo.rs b/kernel/src/fs/pseudo.rs index 6da58c0..fdcc535 100644 --- a/kernel/src/fs/pseudo.rs +++ b/kernel/src/fs/pseudo.rs @@ -14,7 +14,7 @@ impl Pseudo { pub fn new(s: &str, type_: FileType) -> Self { Pseudo { content: Vec::from(s.as_bytes()), - type_ + type_, } } } diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index 429b80c..6a73c28 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -7,6 +7,7 @@ use rcore_fs::vfs::*; use crate::sync::Condvar; use crate::sync::SpinNoIrqLock as Mutex; +use super::ioctl::*; #[derive(Default)] pub struct Stdin { @@ -37,10 +38,12 @@ impl Stdin { } #[cfg(not(any(feature = "board_k210", feature = "board_rocket_chip")))] loop { - let ret = self.buf.lock().pop_front(); - match ret { + let mut buf_lock = self.buf.lock(); + match buf_lock.pop_front() { Some(c) => return c, - None => self.pushed._wait(), + None => { + self.pushed.wait(buf_lock); + } } } } @@ -62,32 +65,6 @@ lazy_static! { pub static ref STDOUT: Arc = Arc::new(Stdout::default()); } -// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits -// higher 2 bits: 01 = write, 10 = read - -#[cfg(not(target_arch = "mips"))] -const TCGETS: u32 = 0x5401; -#[cfg(target_arch = "mips")] -const TCGETS: u32 = 0x540D; - -#[cfg(not(target_arch = "mips"))] -const TIOCGPGRP: u32 = 0x540F; -// _IOR('t', 119, int) -#[cfg(target_arch = "mips")] -const TIOCGPGRP: u32 = 0x4_004_74_77; - -#[cfg(not(target_arch = "mips"))] -const TIOCSPGRP: u32 = 0x5410; -// _IOW('t', 118, int) -#[cfg(target_arch = "mips")] -const TIOCSPGRP: u32 = 0x8_004_74_76; - -#[cfg(not(target_arch = "mips"))] -const TIOCGWINSZ: u32 = 0x5413; -// _IOR('t', 104, struct winsize) -#[cfg(target_arch = "mips")] -const TIOCGWINSZ: u32 = 0x4_008_74_68; - // TODO: better way to provide default impl? macro_rules! impl_inode { () => { @@ -103,7 +80,7 @@ macro_rules! impl_inode { fn find(&self, _name: &str) -> Result> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result { Err(FsError::NotDir) } fn io_control(&self, cmd: u32, data: usize) -> Result<()> { - match cmd { + match cmd as usize { TCGETS | TIOCGWINSZ | TIOCSPGRP => { // pretend to be tty Ok(()) diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index fa5f0a6..b6c482c 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -18,7 +18,7 @@ extern crate log; extern crate lazy_static; pub use crate::process::{new_kernel_context, processor}; -use buddy_system_allocator::LockedHeap; +use buddy_system_allocator::LockedHeapWithRescue; use rcore_thread::std_thread as thread; #[macro_use] // print! @@ -65,4 +65,5 @@ pub fn kmain() -> ! { /// /// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod. #[global_allocator] -static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); +static HEAP_ALLOCATOR: LockedHeapWithRescue = + LockedHeapWithRescue::new(crate::memory::enlarge_heap); diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 8367cbc..b3b013a 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -14,14 +14,16 @@ use super::HEAP_ALLOCATOR; pub use crate::arch::paging::*; -use crate::consts::MEMORY_OFFSET; +use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; use crate::process::process_unsafe; use crate::sync::SpinNoIrqLock; +use alloc::boxed::Box; use bitmap_allocator::BitAlloc; -use buddy_system_allocator::LockedHeap; +use buddy_system_allocator::Heap; use lazy_static::*; use log::*; pub use rcore_memory::memory_set::{handler::*, MemoryArea, MemoryAttr}; +use rcore_memory::paging::PageTable; use rcore_memory::*; pub type MemorySet = rcore_memory::memory_set::MemorySet; @@ -145,5 +147,37 @@ pub fn init_heap() { info!("heap init end"); } -/// Allocator for the rest memory space on NO-MMU case. -pub static MEMORY_ALLOCATOR: LockedHeap = LockedHeap::empty(); +pub fn enlarge_heap(heap: &mut Heap) { + info!("Enlarging heap to avoid oom"); + + let mut page_table = active_table(); + let mut addrs = [(0, 0); 32]; + let mut addr_len = 0; + #[cfg(target_arch = "x86_64")] + let va_offset = KERNEL_OFFSET + 0xe0000000; + #[cfg(not(target_arch = "x86_64"))] + let va_offset = KERNEL_OFFSET + 0x00e00000; + for i in 0..16384 { + let page = alloc_frame().unwrap(); + let va = va_offset + page; + if addr_len > 0 { + let (ref mut addr, ref mut len) = addrs[addr_len - 1]; + if *addr - PAGE_SIZE == va { + *len += PAGE_SIZE; + *addr -= PAGE_SIZE; + continue; + } + } + addrs[addr_len] = (va, PAGE_SIZE); + addr_len += 1; + } + for (addr, len) in addrs[..addr_len].into_iter() { + for va in (*addr..(*addr + *len)).step_by(PAGE_SIZE) { + page_table.map(va, va - va_offset).update(); + } + info!("Adding {:#X} {:#X} to heap", addr, len); + unsafe { + heap.init(*addr, *len); + } + } +} diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index b905fde..1892fc3 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -4,6 +4,7 @@ use crate::sync::SpinNoIrqLock as Mutex; use crate::syscall::*; use crate::util; use alloc::boxed::Box; +use alloc::fmt::Debug; use alloc::sync::Arc; use alloc::vec::Vec; use bitflags::*; @@ -50,7 +51,7 @@ pub enum Endpoint { } /// Common methods that a socket must have -pub trait Socket: Send + Sync { +pub trait Socket: Send + Sync + Debug { fn read(&self, data: &mut [u8]) -> (SysResult, Endpoint); fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult; fn poll(&self) -> (bool, bool, bool); // (in, out, err) @@ -265,9 +266,8 @@ impl Socket for TcpSocketState { TcpState::SynSent => { // still connecting drop(socket); - drop(sockets); debug!("poll for connection wait"); - SOCKET_ACTIVITY._wait(); + SOCKET_ACTIVITY.wait(sockets); } TcpState::Established => { break Ok(0); @@ -357,10 +357,8 @@ impl Socket for TcpSocketState { return Ok((new_socket, Endpoint::Ip(remote_endpoint))); } - // avoid deadlock drop(socket); - drop(sockets); - SOCKET_ACTIVITY._wait(); + SOCKET_ACTIVITY.wait(sockets); } } @@ -447,9 +445,8 @@ impl Socket for UdpSocketState { ); } - // avoid deadlock drop(socket); - SOCKET_ACTIVITY._wait() + SOCKET_ACTIVITY.wait(sockets); } } @@ -626,10 +623,8 @@ impl Socket for RawSocketState { ); } - // avoid deadlock drop(socket); - drop(sockets); - SOCKET_ACTIVITY._wait() + SOCKET_ACTIVITY.wait(sockets); } } diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 2ec8dcf..d5942ba 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -13,7 +13,7 @@ use xmas_elf::{ }; use crate::arch::interrupt::{Context, TrapFrame}; -use crate::fs::{FileHandle, FileLike, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH}; +use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH}; use crate::memory::{ ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read, }; @@ -255,6 +255,7 @@ impl Thread { write: false, append: false, }, + String::from("stdin"), )), ); files.insert( @@ -266,6 +267,7 @@ impl Thread { write: true, append: false, }, + String::from("stdout"), )), ); files.insert( @@ -277,6 +279,7 @@ impl Thread { write: true, append: false, }, + String::from("stderr"), )), ); diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 816be57..1375b14 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -1,7 +1,6 @@ //! Kernel shell -use crate::drivers::CMDLINE; -use crate::fs::{INodeExt, ROOT_INODE}; +use crate::fs::ROOT_INODE; use crate::process::*; use alloc::string::String; use alloc::vec::Vec; @@ -44,6 +43,7 @@ pub fn add_user_shell() { #[cfg(feature = "run_cmdline")] pub fn add_user_shell() { + use crate::drivers::CMDLINE; let cmdline = CMDLINE.read(); let inode = ROOT_INODE.lookup(&cmdline).unwrap(); println!("not use the fucking up busybox"); diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index a03f107..61db073 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -15,6 +15,7 @@ impl Condvar { } /// Park current thread and wait for this condvar to be notified. + #[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")] pub fn _wait(&self) { // The condvar might be notified between adding to queue and thread parking. // So park current thread before wait queue lock is freed. @@ -25,6 +26,7 @@ impl Condvar { }); } + #[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")] pub fn wait_any(condvars: &[&Condvar]) { let token = Arc::new(thread::current()); // Avoid racing in the same way as the function above @@ -40,19 +42,23 @@ impl Condvar { }); } - pub fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { + fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { let mut lock = self.wait_queue.lock(); lock.push_back(Arc::new(thread::current())); return lock; } + /// Park current thread and wait for this condvar to be notified. pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S> where S: MutexSupport, { let mutex = guard.mutex; - drop(guard); - self._wait(); + let lock = self.add_to_wait_queue(); + thread::park_action(move || { + drop(lock); + drop(guard); + }); mutex.lock() } @@ -80,7 +86,4 @@ impl Condvar { } count } - pub fn _clear(&self) { - self.wait_queue.lock().clear(); - } } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index efa0852..49aebe5 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -156,6 +156,11 @@ pub fn sys_select( // infinity 1 << 31 }; + + // for debugging + if cfg!(debug_assertions) { + debug!("files before select {:#?}", proc.files); + } drop(proc); let begin_time_ms = crate::trap::uptime_msec(); @@ -273,7 +278,13 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> proc.lookup_inode_at(dir_fd, &path, true)? }; - let file = FileHandle::new(inode, flags.to_options()); + let mut file = FileHandle::new(inode, flags.to_options(), String::from(path)); + + // for debugging + if cfg!(debug_assertions) { + debug!("files before open {:#?}", proc.files); + } + let fd = proc.add_file(FileLike::File(file)); Ok(fd) } @@ -281,6 +292,12 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> pub fn sys_close(fd: usize) -> SysResult { info!("close: fd: {:?}", fd); let mut proc = process(); + + // for debugging + if cfg!(debug_assertions) { + debug!("files before close {:#?}", proc.files); + } + proc.files.remove(&fd).ok_or(SysError::EBADF)?; Ok(0) } @@ -635,6 +652,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: false, append: false, }, + String::from("pipe_r:[]"), ))); let write_fd = proc.add_file(FileLike::File(FileHandle::new( @@ -644,6 +662,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: true, append: false, }, + String::from("pipe_w:[]"), ))); fds[0] = read_fd as u32; diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index d108a7c..1a241ac 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,4 +1,4 @@ -use rcore_memory::memory_set::handler::{ByFrame, Delay, File}; +use rcore_memory::memory_set::handler::{Delay, File}; use rcore_memory::memory_set::MemoryAttr; use rcore_memory::paging::PageTable; use rcore_memory::Page; diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index e7f867c..54c7925 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -91,6 +91,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S return Err(SysError::EAGAIN); } // FIXME: support timeout + // FIXME: fix racing queue._wait(); Ok(0) } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 066d0a6..3f183d8 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -31,8 +31,8 @@ mod net; mod proc; mod time; -use spin::Mutex; use alloc::collections::BTreeMap; +use spin::Mutex; #[cfg(feature = "profile")] lazy_static! { @@ -45,9 +45,7 @@ lazy_static! { #[deny(unreachable_patterns)] pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { #[cfg(feature = "profile")] - let begin_time = unsafe { - core::arch::x86_64::_rdtsc() - }; + let begin_time = unsafe { core::arch::x86_64::_rdtsc() }; let cid = cpu::id(); let pid = process().pid.clone(); let tid = processor().tid(); @@ -268,9 +266,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } #[cfg(feature = "profile")] { - let end_time = unsafe { - core::arch::x86_64::_rdtsc() - }; + let end_time = unsafe { core::arch::x86_64::_rdtsc() }; *SYSCALL_TIMING.lock().entry(id).or_insert(0) += end_time - begin_time; if end_time % 1000 == 0 { let timing = SYSCALL_TIMING.lock(); diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index af28065..e7c3318 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -2,7 +2,6 @@ use super::fs::IoVecs; use super::*; -use crate::drivers::SOCKET_ACTIVITY; use crate::fs::FileLike; use crate::net::{ Endpoint, LinkLevelEndpoint, NetlinkEndpoint, NetlinkSocketState, PacketSocketState, diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 9fcb97e..b24c960 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -120,8 +120,7 @@ pub fn sys_wait4(pid: isize, wstatus: *mut i32) -> SysResult { target ); let condvar = proc.child_exit.clone(); - drop(proc); // must release lock of current process - condvar._wait(); + condvar.wait(proc); } } diff --git a/user b/user index 8dbc0ed..b6a3477 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit 8dbc0edb935a62d748aaac39258d4a985de0ae17 +Subproject commit b6a347750531be125583107b6d0fc307366fdcc9