Better virtual file system, keyboard through MMIO&VirtIO

This commit is contained in:
2026-03-05 14:41:28 +01:00
parent 041e544330
commit 9b6aec28f5
37 changed files with 1191 additions and 355 deletions

View File

@@ -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 }))
}
}
}