Better virtual file system, keyboard through MMIO&VirtIO
This commit is contained in:
@@ -1,24 +1,116 @@
|
||||
use core::{cell::LazyCell, fmt::Debug};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use bffs::path::{Path, PathBuf};
|
||||
use bffs::{
|
||||
Fat32FileSystem,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use io::{IoBase, Read, Seek, Write};
|
||||
|
||||
pub trait VirtualNode {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, ()>;
|
||||
}
|
||||
|
||||
pub trait VirtualFileSystem {
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + Send>, ()>;
|
||||
use crate::{fs::Disk, tty::Tty, vga::Vga};
|
||||
|
||||
pub trait VirtualNode: IoBase<Error = ()> + Read + Write + Seek + Debug {}
|
||||
|
||||
pub trait VirtualFileSystem: Debug {
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + '_>, ()>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MainFileSystem {
|
||||
root: Box<dyn VirtualFileSystem>,
|
||||
mounts: HashMap<PathBuf, Box<dyn VirtualFileSystem>>,
|
||||
}
|
||||
|
||||
impl MainFileSystem {
|
||||
pub fn mount(&mut self, path: PathBuf, fs: Box<dyn VirtualFileSystem>) {
|
||||
self.mounts.insert(path, fs);
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualFileSystem for MainFileSystem {
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + Send>, ()> {
|
||||
for mount in self.mounts.iter() {
|
||||
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + '_>, ()> {
|
||||
let mut max = &mut self.root;
|
||||
let mut max_path = Path::new("/");
|
||||
let mut path_remaining = path;
|
||||
for (mount, fs) in self.mounts.iter_mut() {
|
||||
if path.starts_with(mount) && mount.starts_with(max_path) {
|
||||
max = fs;
|
||||
max_path = mount;
|
||||
path_remaining = path.without(mount);
|
||||
}
|
||||
}
|
||||
max.open(path_remaining)
|
||||
}
|
||||
}
|
||||
|
||||
pub static mut FILE_SYSTEM: LazyCell<MainFileSystem> = LazyCell::new(|| MainFileSystem {
|
||||
root: Box::new(Fat32FileSystem::new(Disk::new(1024 * 1024 * 16)).unwrap()),
|
||||
mounts: HashMap::new(),
|
||||
});
|
||||
|
||||
pub unsafe fn init_file_system() {
|
||||
unsafe {
|
||||
FILE_SYSTEM.mount("/dev/fb0".into(), Box::new(VGAFileSystem));
|
||||
FILE_SYSTEM.mount("/dev/tty0".into(), Box::new(Tty::new()));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VGAFileSystem;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VGAVirtualNode {
|
||||
position: u64,
|
||||
}
|
||||
|
||||
impl VirtualNode for VGAVirtualNode {}
|
||||
|
||||
impl IoBase for VGAVirtualNode {
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
impl Seek for VGAVirtualNode {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
||||
self.position = match pos {
|
||||
io::SeekFrom::Start(v) => v,
|
||||
io::SeekFrom::End(v) => {
|
||||
((crate::vga::WIDTH * crate::vga::HEIGHT * size_of::<crate::draw::Color>()) as i64
|
||||
+ v) as u64
|
||||
}
|
||||
io::SeekFrom::Current(v) => (self.position as i64 + v) as u64,
|
||||
};
|
||||
Ok(self.position)
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for VGAVirtualNode {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, ()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for VGAVirtualNode {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, ()> {
|
||||
let start = self.position;
|
||||
buf.iter().for_each(|val| {
|
||||
unsafe { Vga::write_u8_unsafe(self.position as usize, *val) };
|
||||
self.position += 1;
|
||||
});
|
||||
Ok((self.position - start) as usize)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualFileSystem for VGAFileSystem {
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + '_>, ()> {
|
||||
if !path.is_empty() {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(Box::new(VGAVirtualNode { position: 0 }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user