diff --git a/src/driver/acpi/hpet.rs b/src/driver/acpi/hpet.rs index 5dbf8a050881589bb6605f8307b8e4af1eb75c68..79381ef92988919c8c705c8054218f9bd7f4dbb6 100644 --- a/src/driver/acpi/hpet.rs +++ b/src/driver/acpi/hpet.rs @@ -10,7 +10,8 @@ use spin::{Lazy, Mutex}; use crate::{ debug, trace, - vfs::{FileDevice, IoResult}, + util::slice_read::{self, slice_read, slice_write}, + vfs::{FileDevice, IoError, IoResult}, }; use super::{rsdt::RSDT, SdtError}; @@ -234,12 +235,11 @@ impl FileDevice for HpetDevice { fn read(&self, offset: usize, buf: &mut [u8]) -> IoResult<usize> { let bytes = &HPET.lock().now_bytes()[..]; - bytes.read(offset, buf) + slice_read(bytes, offset, buf) } - fn write(&mut self, offset: usize, buf: &[u8]) -> IoResult<usize> { - let mut bytes = &HPET.lock().now_bytes()[..]; - bytes.write(offset, buf) + fn write(&mut self, _: usize, _: &[u8]) -> IoResult<usize> { + Err(IoError::PermissionDenied) } } diff --git a/src/driver/rtc.rs b/src/driver/rtc.rs index 5bd0d562d79dcbe84255b3efaa3a50d31d60e4e2..becbb1a46b7767d5658c66fd0b6ed097ddf98389 100644 --- a/src/driver/rtc.rs +++ b/src/driver/rtc.rs @@ -1,6 +1,7 @@ use crate::{ debug, error, - vfs::{self, FileDevice}, + util::slice_read::slice_read, + vfs::{self, FileDevice, IoError, IoResult}, }; use chrono::{DateTime, TimeZone, Utc}; use core::{ @@ -110,14 +111,13 @@ impl FileDevice for RtcDevice { mem::size_of::<i64>() } - fn read(&self, offset: usize, buf: &mut [u8]) -> vfs::IoResult<usize> { + fn read(&self, offset: usize, buf: &mut [u8]) -> IoResult<usize> { let bytes = &RTC.now_bytes()[..]; - bytes.read(offset, buf) + slice_read(bytes, offset, buf) } - fn write(&mut self, offset: usize, buf: &[u8]) -> vfs::IoResult<usize> { - let mut bytes = &RTC.now_bytes()[..]; - bytes.write(offset, buf) + fn write(&mut self, _: usize, _: &[u8]) -> IoResult<usize> { + Err(IoError::PermissionDenied) } } diff --git a/src/main.rs b/src/main.rs index fd91494e5c7757770f1d6d9c95102ab164d9a8df..f5fa755137e3df4df4d672324e38f91479e8a1f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,14 +24,15 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use crate::{ - arch::cpu::idt::Irq, + arch::{cpu::idt::Irq, int}, driver::{ acpi::{apic::ApicId, ioapic::IoApic}, - rtc, + rtc::{self, RtcDevice, RTC}, }, scheduler::kshell::kshell, smp::CPU_COUNT, util::fmt::NumberPostfix, + vfs::FileDevice, }; extern crate alloc; diff --git a/src/mem/pmm.rs b/src/mem/pmm.rs index c1125ac1d57042bf729dea1a9aa0aa785d17cf7f..3b90688e488c85ec487327c4c3dc4153712fc830 100755 --- a/src/mem/pmm.rs +++ b/src/mem/pmm.rs @@ -131,8 +131,6 @@ impl PageFrameAllocator { self.used .fetch_add(count as u64 * PAGE_SIZE, Ordering::SeqCst); - // trace!("allocating pages first={first_page} count={}", count); - PageFrame { first: addr, count } } diff --git a/src/mem/slab.rs b/src/mem/slab.rs index 7620c48b520470544862b361a92744542332c3d4..6575917e90b9e1f4cab32fbd99b425be0fb68260 100644 --- a/src/mem/slab.rs +++ b/src/mem/slab.rs @@ -90,6 +90,7 @@ impl SlabAllocator { } pub fn alloc(&self, size: usize) -> VirtAddr { + // crate::println!("alloc {size}"); if let Some(slab) = self.get_slab(size) { slab.write().alloc(&self.stats) } else { diff --git a/src/scheduler/kshell/shell.rs b/src/scheduler/kshell/shell.rs index 34f8360443185f0888cccb93a566e50527bf0da9..c72b36d1bd57adb2be0a0d0992c34fac53cd142c 100644 --- a/src/scheduler/kshell/shell.rs +++ b/src/scheduler/kshell/shell.rs @@ -1,6 +1,6 @@ use crate::{ driver::acpi::hpet::HPET, - mem::pmm::PageFrameAllocator, + mem::{from_higher_half, pmm::PageFrameAllocator}, util::fmt::NumberPostfix, vfs::{ self, @@ -13,7 +13,8 @@ use alloc::{borrow::ToOwned, string::String, sync::Arc}; use chrono::{TimeZone, Utc}; use core::fmt::Write; use snafu::ResultExt; -use spin::Mutex; +use spin::{Mutex, MutexGuard}; +use x86_64::VirtAddr; use super::{term::Term, Error, IoSnafu, Result}; @@ -103,7 +104,7 @@ impl<'fbo> Shell<'fbo> { } fn splash_cmd(&mut self, _: Option<&str>) -> Result<()> { - _ = writeln!(self.term, "{KERNEL_SPLASH}"); + // _ = writeln!(self.term, "{KERNEL_SPLASH}"); _ = writeln!(self.term, "Welcome to {KERNEL_NAME} - {KERNEL_VERSION} (built {KERNEL_BUILD_TIME} build [{KERNEL_BUILD_REV}])"); Ok(()) } @@ -156,14 +157,16 @@ impl<'fbo> Shell<'fbo> { let file = vfs::get_file(resource, false, false).with_context(|_| IoSnafu { resource: resource.to_owned(), })?; - let mut file = file.lock(); + let file = file.lock(); let mut at = 0usize; let mut buf = [0u8; 16]; loop { + let addr = (&*file) as *const _ as *const () as u64; let read = file.read(at, &mut buf).with_context(|_| IoSnafu { resource: resource.to_owned(), })?; + if read == 0 { break; } diff --git a/src/util/slice_read.rs b/src/util/slice_read.rs index 64bfaef1ce86600a2300151acd2b92d4a2e00898..37d8a5f712cc3ee1437e5798bf6b8acfde7ea53d 100644 --- a/src/util/slice_read.rs +++ b/src/util/slice_read.rs @@ -2,46 +2,26 @@ use crate::vfs::{FileDevice, IoError, IoResult}; // -impl FileDevice for &'_ [u8] { - fn len(&self) -> usize { - self.len() - } +pub fn slice_read(this: &[u8], offset: usize, buf: &mut [u8]) -> IoResult<usize> { + let len = this + .len() + .checked_sub(offset) + .ok_or(IoError::UnexpectedEOF)? + .min(buf.len()); - fn read(&self, offset: usize, buf: &mut [u8]) -> IoResult<usize> { - let len = self - .len() - .checked_sub(offset) - .ok_or(IoError::UnexpectedEOF)? - .min(buf.len()); + buf[..len].copy_from_slice(&this[offset..offset + len]); - buf[..len].copy_from_slice(&self[offset..offset + len]); - - Ok(len) - } - - fn write(&mut self, offset: usize, buf: &[u8]) -> IoResult<usize> { - Err(IoError::PermissionDenied) - } + Ok(len) } -impl FileDevice for &'_ mut [u8] { - fn len(&self) -> usize { - self.len() - } - - fn read(&self, offset: usize, buf: &mut [u8]) -> IoResult<usize> { - self.as_ref().read(offset, buf) - } - - fn write(&mut self, offset: usize, buf: &[u8]) -> IoResult<usize> { - let len = self - .len() - .checked_sub(offset) - .ok_or(IoError::UnexpectedEOF)? - .min(buf.len()); +pub fn slice_write(this: &mut [u8], offset: usize, buf: &[u8]) -> IoResult<usize> { + let len = this + .len() + .checked_sub(offset) + .ok_or(IoError::UnexpectedEOF)? + .min(buf.len()); - self[offset..offset + len].copy_from_slice(&buf[..len]); + this[offset..offset + len].copy_from_slice(&buf[..len]); - Ok(len) - } + Ok(len) } diff --git a/src/vfs/devices.rs b/src/vfs/devices.rs index 7ea97988f3fd67cc107b419af2599fbc532f8c8e..5fb464e986f0971c075b10469a531bda309cf4f0 100644 --- a/src/vfs/devices.rs +++ b/src/vfs/devices.rs @@ -3,9 +3,11 @@ use crate::{ vfs, }; +use super::Node; + // -pub fn install() { - vfs::install_dev("/dev/rtc", RtcDevice); - vfs::install_dev("/dev/hpet", HpetDevice); +pub fn install(root: Node) { + vfs::install_dev_with(root.clone(), "/dev/rtc", RtcDevice); + vfs::install_dev_with(root, "/dev/hpet", HpetDevice); } diff --git a/src/vfs/mod.rs b/src/vfs/mod.rs index 55b6a0ca633586dbd27ba6e1cd466cf90cd7ad91..1ec71e3ddd7122c6687a231b9ad9c78c7a37971c 100644 --- a/src/vfs/mod.rs +++ b/src/vfs/mod.rs @@ -21,65 +21,35 @@ pub mod path; static _ROOT_NODE: Lazy<Root> = Lazy::new(|| Directory::from("")); pub static ROOT: Lazy<Root> = Lazy::new(|| { debug!("Initializing VFS"); - devices::install(); + devices::install(Node::Directory(_ROOT_NODE.clone())); _ROOT_NODE.clone() }); // -pub fn get_node(path: impl AsRef<Path>, make_dirs: bool) -> IoResult<Node> { - let mut node = Node::Directory(ROOT.clone()); - - for part in path.as_ref().iter() { - match node { - Node::File(_) => return Err(IoError::NotADirectory), - Node::Directory(_dir) => { - let mut dir = _dir.lock(); - // TODO: only Node::Directory should be cloned - - node = if let Ok(node) = dir.get_node(part) { - node - } else if make_dirs { - let node = Node::Directory(Directory::from(part)); - dir.create_node(part, node.clone())?; - node - } else { - return Err(IoError::NotFound); - }; - } - } - } +pub fn get_root() -> Node { + Node::Directory(ROOT.clone()) +} - Ok(node) +pub fn get_node(path: impl AsRef<Path>, make_dirs: bool) -> IoResult<Node> { + get_node_with(get_root(), path, make_dirs) } pub fn get_dir(path: impl AsRef<Path>, make_dirs: bool) -> IoResult<DirRef> { - let node = get_node(path, make_dirs)?; - match node { - Node::File(_) => Err(IoError::NotADirectory), - Node::Directory(dir) => Ok(dir), - } + get_dir_with(get_root(), path, make_dirs) } // TODO: create -pub fn get_file(path: impl AsRef<Path>, make_dirs: bool, _create: bool) -> IoResult<FileRef> { - let node = get_node(path, make_dirs)?; - match node { - Node::File(file) => Ok(file), - Node::Directory(_) => Err(IoError::IsADirectory), - } +pub fn get_file(path: impl AsRef<Path>, make_dirs: bool, create: bool) -> IoResult<FileRef> { + get_file_with(get_root(), path, make_dirs, create) } pub fn create_device(path: impl AsRef<Path>, make_dirs: bool, dev: FileRef) -> IoResult<()> { - create_node(path, make_dirs, Node::File(dev)) + create_device_with(get_root(), path, make_dirs, dev) } pub fn install_dev(path: impl AsRef<Path>, dev: impl FileDevice + Send + Sync + 'static) { - let path = path.as_ref(); - debug!("installing VFS device at {path:?}"); - if let Err(err) = create_device(path, true, Arc::new(Mutex::new(dev)) as _) { - error!("failed to install VFS device at {path:?} : {err:?}"); - } + install_dev_with(get_root(), path, dev) } pub use {get_dir as read_dir, get_file as open}; @@ -334,25 +304,20 @@ fn install_dev_with( } fn create_node_with( - node: Node, + root: Node, path: impl AsRef<Path>, make_dirs: bool, node: Node, ) -> IoResult<()> { let (parent_dir, file_name) = path.as_ref().split().ok_or(IoError::NotFound)?; - let parent_dir = get_dir(parent_dir, make_dirs)?; + let parent_dir = get_dir_with(root, parent_dir, make_dirs)?; let mut parent_dir = parent_dir.lock(); - parent_dir.create_node_with(node, file_name, node)?; + parent_dir.create_node(file_name, node)?; Ok(()) } -fn create_node(path: impl AsRef<Path>, make_dirs: bool, node: Node) -> IoResult<()> { - let (parent_dir, file_name) = path.as_ref().split().ok_or(IoError::NotFound)?; - let parent_dir = get_dir(parent_dir, make_dirs)?; - let mut parent_dir = parent_dir.lock(); - parent_dir.create_node(file_name, node)?; - - Ok(()) +fn create_node(path: impl AsRef<Path>, make_dirs: bool, node: Node) -> IoResult<()> { + create_node_with(Node::Directory(ROOT.clone()), path, make_dirs, node) }