the correctest way (mostly) to do vfs

This commit is contained in:
Zoe
2024-05-22 00:23:27 -05:00
parent fdacc74091
commit b9efc59e49
11 changed files with 424 additions and 358 deletions

View File

@@ -106,6 +106,8 @@ copy-iso-files:
mkdir -p ${ISO_PATH}/boot/limine
mkdir -p ${ISO_PATH}/EFI/BOOT
mkdir -p ${ISO_PATH}/mnt
cp -v limine.cfg limine/limine-bios.sys ${ISO_PATH}/boot/limine
cp -v limine/BOOT${LIMINE_BOOT_VARIATION}.EFI ${ISO_PATH}/EFI/BOOT/
@@ -158,8 +160,6 @@ compile-bootloader:
@if [ ! -d "limine" ]; then \
echo "Cloning Limine into limine/..."; \
git clone https://github.com/limine-bootloader/limine.git --branch=${LIMINE_BRANCH} --depth=1; \
else \
echo "Folder limine already exists. Skipping clone."; \
fi
make -C limine

View File

@@ -103,7 +103,6 @@ exception_function!(0x00, div_error);
exception_function!(0x06, invalid_opcode);
exception_function!(0x08, double_fault);
exception_function!(0x0D, general_protection_fault);
// TODO: fix the page fault then gracefully return.
exception_function!(0x0E, page_fault);
exception_function!(0xFF, generic_handler);

View File

@@ -95,7 +95,11 @@ pub fn idt_init() {
let mut idt_lock = IDT.lock();
IDT_PTR.base = idt_lock.as_ptr() as u64;
core::ptr::write_bytes(idt_lock.as_mut_ptr() as *mut core::ffi::c_void, 0, idt_size);
core::ptr::write_bytes(
idt_lock.as_mut_ptr().cast::<core::ffi::c_void>(),
0,
idt_size,
);
}
// Set every interrupt to the "null" interrupt handler (it does nothing)

View File

@@ -1,3 +1,5 @@
use core::ptr::NonNull;
use alloc::{
boxed::Box,
string::{String, ToString},
@@ -265,45 +267,6 @@ impl FatFs {
_ => bpb.sectors_per_fat as usize,
};
let bytes_per_fat = 512 * sectors_per_fat;
let mut fat: Option<Arc<[u32]>> = None;
if crate::KERNEL_FEATURES.fat_in_mem {
let cluster_bytes = match fat_type {
FatType::Fat32(_) => 4,
_ => 2,
};
let mut fat_vec: Vec<u32> = Vec::with_capacity(bytes_per_fat / cluster_bytes);
for i in 0..sectors_per_fat {
let sector = partition
.read(fat_start + i as u64, 1)
.expect("Failed to read FAT");
for j in 0..(512 / cluster_bytes) {
match fat_type {
FatType::Fat32(_) => fat_vec.push(u32::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
)),
_ => fat_vec.push(u16::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
) as u32),
}
}
}
fat = Some(Arc::from(fat_vec));
} else {
crate::log_info!(
"\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
)
}
crate::println!("Found {fat_type:?} FS");
let cluster_size = bpb.sectors_per_cluster as usize * 512;
@@ -311,7 +274,7 @@ impl FatFs {
return Ok(Self {
partition,
fs_info,
fat,
fat: None,
bpb,
fat_start,
fat_type,
@@ -511,17 +474,57 @@ impl FatFs {
}
impl FsOps for FatFs {
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: *const super::vfs::Vfs) {
// TODO: load the FAT into memory here
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: NonNull<super::vfs::Vfs>) {
let bytes_per_fat = 512 * self.sectors_per_fat;
let mut fat: Option<Arc<[u32]>> = None;
if crate::KERNEL_FEATURES.fat_in_mem {
let cluster_bytes = match self.fat_type {
FatType::Fat32(_) => 4,
_ => 2,
};
let mut fat_vec: Vec<u32> = Vec::with_capacity(bytes_per_fat / cluster_bytes);
for i in 0..self.sectors_per_fat {
let sector = self
.partition
.read(self.fat_start + i as u64, 1)
.expect("Failed to read FAT");
for j in 0..(512 / cluster_bytes) {
match self.fat_type {
FatType::Fat32(_) => fat_vec.push(u32::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
)),
_ => fat_vec.push(u16::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
) as u32),
}
}
}
fat = Some(Arc::from(fat_vec));
} else {
crate::log_info!(
"\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
)
}
self.fat = fat;
*data = core::ptr::addr_of!(*self) as *mut u8;
}
fn unmount(&mut self, _vfsp: *const super::vfs::Vfs) {
// TODO: unload the FAT form memory
fn unmount(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
self.fat = None;
}
fn root(&mut self, vfsp: *const super::vfs::Vfs) -> super::vfs::VNode {
fn root(&mut self, vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::VNode {
let root_cluster = match self.fat_type {
FatType::Fat32(ebpb) => ebpb.root_dir_cluster as usize,
_ => self.sector_to_cluster(
@@ -537,22 +540,22 @@ impl FsOps for FatFs {
return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp);
}
fn fid(&mut self, _path: &str, _vfsp: *const super::vfs::Vfs) -> Option<super::vfs::FileId> {
fn fid(&mut self, _path: &str, _vfsp: NonNull<super::vfs::Vfs>) -> Option<super::vfs::FileId> {
todo!("FAT FID");
}
fn statfs(&mut self, _vfsp: *const super::vfs::Vfs) -> super::vfs::StatFs {
fn statfs(&mut self, _vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::StatFs {
todo!("FAT STATFS");
}
fn sync(&mut self, _vfsp: *const super::vfs::Vfs) {
fn sync(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
todo!("FAT SYNC");
}
fn vget(
&mut self,
_fid: super::vfs::FileId,
_vfsp: *const super::vfs::Vfs,
_vfsp: NonNull<super::vfs::Vfs>,
) -> super::vfs::VNode {
todo!("FAT VGET");
}
@@ -564,19 +567,19 @@ enum File {
}
impl VNodeOperations for File {
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: *const VNode) {
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: *const VNode) -> super::vfs::VNode {
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode {
todo!("VNODE OPERATIONS");
}
fn bread(&mut self, _block_number: u32, _vp: *const VNode) -> Arc<[u8]> {
fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
todo!("VNODE OPERATIONS");
}
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: *const VNode) {
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
@@ -587,20 +590,20 @@ impl VNodeOperations for File {
_e: u32,
_m: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS");
}
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) {
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) -> super::vfs::VAttr {
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!("VNODE OPERATIONS");
}
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) {
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
@@ -610,7 +613,7 @@ impl VNodeOperations for File {
_d: *mut u8,
_f: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
@@ -620,7 +623,7 @@ impl VNodeOperations for File {
_target_dir: *mut super::vfs::VNode,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
@@ -629,9 +632,9 @@ impl VNodeOperations for File {
&mut self,
nm: &str,
_c: super::vfs::UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
let fat_fs = unsafe { (*(*vp).parent_vfs).data.cast::<FatFs>() };
let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<FatFs>() };
match self {
File::Dir(directory) => unsafe {
@@ -652,7 +655,7 @@ impl VNodeOperations for File {
File::Archive(FatFile { file_entry })
};
let vnode = VNode::new(Box::new(file), file_typ, (*vp).parent_vfs);
let vnode = VNode::new(Box::new(file), file_typ, (*vp.as_ptr()).parent_vfs);
Ok(vnode)
},
@@ -665,7 +668,7 @@ impl VNodeOperations for File {
_nm: &str,
_va: super::vfs::VAttr,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS");
}
@@ -674,11 +677,11 @@ impl VNodeOperations for File {
&mut self,
_f: u32,
_c: super::vfs::UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
match self {
File::Archive(archive) => {
let fat_fs = unsafe { (*(*vp).parent_vfs).data.cast::<FatFs>() };
let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<FatFs>() };
let mut file: Vec<u8> = Vec::with_capacity(archive.file_entry.file_size as usize);
let mut file_ptr_index = 0;
@@ -746,8 +749,8 @@ impl VNodeOperations for File {
_direction: super::vfs::IODirection,
_f: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
) {
_vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
todo!("VNODE OPERATIONS");
}
@@ -755,7 +758,7 @@ impl VNodeOperations for File {
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
@@ -764,7 +767,7 @@ impl VNodeOperations for File {
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
@@ -775,20 +778,25 @@ impl VNodeOperations for File {
_target_dir: *mut super::vfs::VNode,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
fn select(&mut self, _w: super::vfs::IODirection, _c: super::vfs::UserCred, _vp: *const VNode) {
fn select(
&mut self,
_w: super::vfs::IODirection,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: *const VNode) {
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn strategy(&mut self, _bp: (), _vp: *const VNode) {
fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
@@ -798,7 +806,7 @@ impl VNodeOperations for File {
_va: super::vfs::VAttr,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}

View File

@@ -1,7 +1,7 @@
mod chunk_reader;
mod superblock;
use core::{fmt::Debug, mem::MaybeUninit};
use core::{fmt::Debug, mem::MaybeUninit, ptr::NonNull};
use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
use limine::ModuleRequest;
@@ -82,7 +82,7 @@ impl Squashfs<'_> {
// crate::log_info!("Parsing initramfs at {:p}", ptr);
// 40 is the offset for bytes used by the archive in the superblock
let length = unsafe { u64::from_le(*(ptr.add(40) as *const u64)) as usize };
let length = unsafe { u64::from_le(*(ptr.add(40).cast::<u64>())) as usize };
let squashfs_data: &[u8] = unsafe { core::slice::from_raw_parts(ptr, length) };
@@ -345,39 +345,39 @@ impl Squashfs<'_> {
}
impl<'a> FsOps for Squashfs<'a> {
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfspp: *const super::vfs::Vfs) {
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: NonNull<super::vfs::Vfs>) {
// STUB
// not recommended:tm:
*data = core::ptr::addr_of!(*self) as *mut u8;
}
fn unmount(&mut self, _vfsp: *const super::vfs::Vfs) {
fn unmount(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
// STUB
}
fn root(&mut self, vfsp: *const super::vfs::Vfs) -> super::vfs::VNode {
fn root(&mut self, vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::VNode {
let root_dir = self.read_root_dir();
return VNode::new(Box::new(root_dir), VNodeType::Directory, vfsp);
}
fn fid(&mut self, _path: &str, _vfspp: *const super::vfs::Vfs) -> Option<super::vfs::FileId> {
fn fid(&mut self, _path: &str, _vfsp: NonNull<super::vfs::Vfs>) -> Option<super::vfs::FileId> {
todo!();
}
fn statfs(&mut self, _vfsp: *const super::vfs::Vfs) -> super::vfs::StatFs {
fn statfs(&mut self, _vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::StatFs {
todo!();
}
fn sync(&mut self, _vfsp: *const super::vfs::Vfs) {
fn sync(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
todo!();
}
fn vget(
&mut self,
_fid: super::vfs::FileId,
_vfsp: *const super::vfs::Vfs,
_vfsp: NonNull<super::vfs::Vfs>,
) -> super::vfs::VNode {
todo!();
}
@@ -412,9 +412,9 @@ impl VNodeOperations for Inode {
&mut self,
_f: u32,
_c: super::vfs::UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
let squashfs = unsafe { (*(*vp).parent_vfs).data.cast::<Squashfs>() };
let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<Squashfs>() };
match self {
Inode::BasicFile(file) => unsafe {
@@ -456,7 +456,7 @@ impl VNodeOperations for Inode {
// And since we are building the array due to unaligned pointer shenanigans we need to
// include the header bytes otherwise we are short by two bytes
let fragment_block_size =
(u16::from_le(core::ptr::read_unaligned(fragment_pointer as *mut u16))
(u16::from_le(core::ptr::read_unaligned(fragment_pointer.cast::<u16>()))
& 0x7FFF)
+ 2;
@@ -498,7 +498,7 @@ impl VNodeOperations for Inode {
}
}
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: *const VNode) {
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!()
}
@@ -508,8 +508,8 @@ impl VNodeOperations for Inode {
_direction: super::vfs::IODirection,
_f: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
) {
_vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
todo!()
}
@@ -519,24 +519,29 @@ impl VNodeOperations for Inode {
_d: *mut u8,
_f: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
fn select(&mut self, _w: super::vfs::IODirection, _c: super::vfs::UserCred, _vp: *const VNode) {
fn select(
&mut self,
_w: super::vfs::IODirection,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!()
}
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) -> super::vfs::VAttr {
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!()
}
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: *const VNode) {
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!()
}
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: *const VNode) {
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!()
}
@@ -544,9 +549,11 @@ impl VNodeOperations for Inode {
&mut self,
nm: &str,
_c: super::vfs::UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
let squashfs = unsafe { (*(*vp).parent_vfs).data.cast::<Squashfs>() };
let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<Squashfs>() };
crate::println!("wawawaw");
match self {
Inode::BasicDirectory(_) | Inode::ExtendedDirectory(_) => unsafe {
@@ -556,7 +563,7 @@ impl VNodeOperations for Inode {
Inode::BasicFile(_) => VNodeType::Regular,
};
let vnode = VNode::new(Box::new(inode), vnode_type, (*vp).parent_vfs);
let vnode = VNode::new(Box::new(inode), vnode_type, (*vp.as_ptr()).parent_vfs);
return Ok(vnode);
},
@@ -571,7 +578,7 @@ impl VNodeOperations for Inode {
_e: u32,
_m: u32,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
todo!()
}
@@ -581,7 +588,7 @@ impl VNodeOperations for Inode {
_target_dir: *mut super::vfs::VNode,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
@@ -592,7 +599,7 @@ impl VNodeOperations for Inode {
_target_dir: *mut super::vfs::VNode,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
@@ -602,7 +609,7 @@ impl VNodeOperations for Inode {
_nm: &str,
_va: super::vfs::VAttr,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
todo!()
}
@@ -611,7 +618,7 @@ impl VNodeOperations for Inode {
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
@@ -622,7 +629,7 @@ impl VNodeOperations for Inode {
_va: super::vfs::VAttr,
_target_name: &str,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
@@ -631,28 +638,28 @@ impl VNodeOperations for Inode {
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: *const VNode,
_vp: NonNull<VNode>,
) {
todo!()
}
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) {
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!()
}
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) {
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!()
}
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: *const VNode) -> super::vfs::VNode {
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode {
todo!()
}
fn strategy(&mut self, _bp: (), _vp: *const VNode) {
fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!()
}
fn bread(&mut self, _block_number: u32, _vp: *const VNode) -> Arc<[u8]> {
fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
todo!()
}
}

View File

@@ -1,10 +1,9 @@
// is this terrible? God yes, but it works
use core::{fmt::Debug, ptr::NonNull};
use alloc::{
alloc::{alloc, dealloc, handle_alloc_error},
boxed::Box,
collections::BTreeMap,
rc::Rc,
string::{String, ToString},
sync::Arc,
vec::Vec,
@@ -12,108 +11,196 @@ use alloc::{
use crate::{log_info, log_ok};
// TODO: probably keeps excess memory but whatever
struct TreeNode {
vnode: Rc<VNode>,
parent: Option<NonNull<Self>>,
children: BTreeMap<String, Self>,
}
impl TreeNode {
fn new(vnode: VNode) -> Self {
return Self {
vnode: Rc::new(vnode),
parent: None,
children: BTreeMap::new(),
};
}
fn as_ptr(&self) -> NonNull<Self> {
return NonNull::from(self);
}
fn get_vnode(&mut self) -> &mut VNode {
Rc::get_mut(&mut self.vnode).unwrap()
}
fn lookup(&mut self, name: &str) -> Result<&mut Self, ()> {
let parent = Some(self.as_ptr());
crate::println!("looking up {name} in node_tree");
if !self.children.contains_key(name) {
crate::println!("not found in node tree");
let vnode: VNode;
if let Some(mut vfs) = self.vnode.vfs_mounted_here {
crate::println!("using VFS root");
unsafe {
vnode = vfs
.as_mut()
.root()
.lookup(name, UserCred { uid: 0, gid: 0 })?
};
} else {
vnode = Rc::get_mut(&mut self.vnode)
.unwrap()
.lookup(name, UserCred { uid: 0, gid: 0 })?;
}
let child_node = TreeNode {
vnode: Rc::new(vnode),
parent,
children: BTreeMap::new(),
};
self.children.insert(name.to_string(), child_node);
let child = self.children.get_mut(name).unwrap();
return Ok(child);
}
return Ok(self.children.get_mut(name).unwrap());
}
}
static mut NODE_TREE: Option<TreeNode> = None;
static mut ROOT_VFS: Vfs = Vfs::null();
// TODO: everything being Option to accomodate the stupid null root vfs is getting annoying
#[allow(unused)]
pub struct Vfs {
mount_point: Option<String>,
next: Option<NonNull<Vfs>>,
ops: Option<NonNull<dyn FsOps>>,
// vnode_covered: Option<*const VNode>,
next: Option<Box<Vfs>>,
pub fs: Option<Box<dyn FsOps>>,
vnode_covered: Option<NonNull<VNode>>,
flags: u32,
block_size: u32,
pub data: *mut u8,
}
unsafe impl Sync for Vfs {}
impl !Sync for Vfs {}
impl Vfs {
const fn null() -> Self {
return Vfs {
mount_point: None,
next: None,
ops: None,
// vnode_covered: None,
fs: None,
vnode_covered: None,
flags: 0,
block_size: 0,
data: core::ptr::null_mut(),
};
}
fn as_ptr(&self) -> *const Self {
core::ptr::addr_of!(*self)
fn add_vfs(&mut self, vfs: Box<Self>) {
let mut current = self;
while let Some(ref mut next_vfs) = current.next {
current = next_vfs;
}
current.next = Some(vfs);
}
fn as_ptr(&self) -> NonNull<Self> {
unsafe { NonNull::new_unchecked(core::ptr::addr_of!(*self) as *mut Self) }
}
pub fn mount(&mut self, path: &str) {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
let vfsp = self.as_ptr();
unsafe { self.ops.unwrap().as_mut().mount(path, &mut self.data, vfsp) };
self.fs
.as_mut()
.unwrap()
.as_mut()
.mount(path, &mut self.data, vfsp);
}
pub fn unmount(&mut self) {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().unmount(self.as_ptr()) };
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().unmount(vfsp);
}
pub fn root(&mut self) -> VNode {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().root(self.as_ptr()) }
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().root(vfsp)
}
pub fn statfs(&mut self) -> StatFs {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().statfs(self.as_ptr()) }
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().statfs(vfsp)
}
pub fn sync(&mut self) {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().sync(self.as_ptr()) };
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().sync(vfsp);
}
pub fn fid(&mut self, path: &str) -> Option<FileId> {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().fid(path, self.as_ptr()) }
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().fid(path, vfsp)
}
pub fn vget(&mut self, fid: FileId) -> VNode {
if self.ops.is_none() {
if self.fs.is_none() {
panic!("FsOps is null");
}
unsafe { self.ops.unwrap().as_mut().vget(fid, self.as_ptr()) }
let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().vget(fid, vfsp)
}
}
pub trait FsOps {
// yes, the vfsp was the best solution I could come up with
fn mount(&mut self, path: &str, data: &mut *mut u8, vfsp: *const Vfs);
fn unmount(&mut self, vfsp: *const Vfs);
fn root(&mut self, vfsp: *const Vfs) -> VNode;
fn statfs(&mut self, vfsp: *const Vfs) -> StatFs;
fn sync(&mut self, vfsp: *const Vfs);
fn fid(&mut self, path: &str, vfsp: *const Vfs) -> Option<FileId>;
fn mount(&mut self, path: &str, data: &mut *mut u8, vfsp: NonNull<Vfs>);
fn unmount(&mut self, vfsp: NonNull<Vfs>);
fn root(&mut self, vfsp: NonNull<Vfs>) -> VNode;
fn statfs(&mut self, vfsp: NonNull<Vfs>) -> StatFs;
fn sync(&mut self, vfsp: NonNull<Vfs>);
fn fid(&mut self, path: &str, vfsp: NonNull<Vfs>) -> Option<FileId>;
// idk how the fuck you're supposed to accomplish this
// good luck I guess.
fn vget(&mut self, fid: FileId, vfsp: *const Vfs) -> VNode;
fn vget(&mut self, fid: FileId, vfsp: NonNull<Vfs>) -> VNode;
}
#[allow(unused)]
@@ -136,6 +223,7 @@ pub struct StatFs {
}
#[repr(u8)]
#[derive(PartialEq)]
pub enum VNodeType {
// Jury is out on this one
NON = 0,
@@ -149,87 +237,95 @@ pub enum VNodeType {
}
pub struct VNode {
// for internal use only
relative_path: String,
pub flags: u16,
pub ref_count: u16,
pub shared_lock_count: u16,
pub exclusive_lock_count: u16,
ops: NonNull<dyn VNodeOperations>,
inode: Box<dyn VNodeOperations>,
pub node_data: Option<NodeData>,
pub parent_vfs: *const Vfs,
pub typ: VNodeType,
pub vfs_mounted_here: Option<NonNull<Vfs>>,
pub parent_vfs: NonNull<Vfs>,
pub file_typ: VNodeType,
pub data: *mut u8,
}
impl VNode {
pub fn new(ops: Box<dyn VNodeOperations>, file_typ: VNodeType, parent_vfs: *const Vfs) -> Self {
pub fn new(
inode: Box<dyn VNodeOperations>,
file_typ: VNodeType,
parent_vfs: NonNull<Vfs>,
) -> Self {
return Self {
relative_path: "".to_string(),
flags: 0,
ref_count: 0,
shared_lock_count: 0,
exclusive_lock_count: 0,
ops: unsafe { NonNull::new_unchecked(Box::into_raw(ops)) },
inode,
node_data: None,
vfs_mounted_here: None,
parent_vfs,
typ: file_typ,
file_typ,
data: core::ptr::null_mut(),
};
}
pub fn as_ptr(&self) -> *const VNode {
core::ptr::addr_of!(*self)
pub fn as_ptr(&self) -> NonNull<VNode> {
unsafe { NonNull::new_unchecked(core::ptr::addr_of!(*self) as *mut Self) }
}
// Trait functions
pub fn open(&mut self, f: u32, c: UserCred) -> Result<Arc<[u8]>, ()> {
unsafe { self.ops.as_mut().open(f, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().open(f, c, vp)
}
pub fn close(&mut self, f: u32, c: UserCred) {
unsafe { self.ops.as_mut().close(f, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().close(f, c, vp)
}
pub fn rdwr(&mut self, uiop: *const UIO, direction: IODirection, f: u32, c: UserCred) {
unsafe { self.ops.as_mut().rdwr(uiop, direction, f, c, self.as_ptr()) }
pub fn rdwr(
&mut self,
uiop: *const UIO,
direction: IODirection,
f: u32,
c: UserCred,
) -> Result<Arc<[u8]>, ()> {
let vp = self.as_ptr();
self.inode.as_mut().rdwr(uiop, direction, f, c, vp)
}
pub fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred) {
unsafe { self.ops.as_mut().ioctl(com, d, f, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().ioctl(com, d, f, c, vp)
}
pub fn select(&mut self, w: IODirection, c: UserCred) {
unsafe { self.ops.as_mut().select(w, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().select(w, c, vp)
}
pub fn getattr(&mut self, c: UserCred) -> VAttr {
unsafe { self.ops.as_mut().getattr(c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().getattr(c, vp)
}
pub fn setattr(&mut self, va: VAttr, c: UserCred) {
unsafe { self.ops.as_mut().setattr(va, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().setattr(va, c, vp)
}
pub fn access(&mut self, m: u32, c: UserCred) {
unsafe { self.ops.as_mut().access(m, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().access(m, c, vp)
}
pub fn lookup(&mut self, nm: &str, c: UserCred) -> Result<VNode, ()> {
let mut vnode = unsafe { self.ops.as_mut().lookup(nm, c, self.as_ptr()) }?;
let vp = self.as_ptr();
// TODO: the memory cost of this is pretty bad
vnode.relative_path = self.relative_path.clone() + "/" + nm;
unsafe {
if let Some(mut new_vfs) = vfs_has_mount_point(
&((*self.parent_vfs).mount_point.clone().unwrap() + &vnode.relative_path),
) {
return Ok(new_vfs.as_mut().root());
}
}
return Ok(vnode);
self.inode.as_mut().lookup(nm, c, vp)
}
pub fn create(
@@ -240,70 +336,79 @@ impl VNode {
m: u32,
c: UserCred,
) -> Result<VNode, ()> {
unsafe { self.ops.as_mut().create(nm, va, e, m, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().create(nm, va, e, m, c, vp)
}
pub fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred) {
unsafe {
self.ops
.as_mut()
.link(target_dir, target_name, c, self.as_ptr())
}
let vp = self.as_ptr();
self.inode.as_mut().link(target_dir, target_name, c, vp)
}
pub fn rename(&mut self, nm: &str, target_dir: *mut VNode, target_name: &str, c: UserCred) {
unsafe {
self.ops
let vp = self.as_ptr();
self.inode
.as_mut()
.rename(nm, target_dir, target_name, c, self.as_ptr())
}
.rename(nm, target_dir, target_name, c, vp)
}
pub fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred) -> Result<VNode, ()> {
unsafe { self.ops.as_mut().mkdir(nm, va, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().mkdir(nm, va, c, vp)
}
pub fn readdir(&mut self, uiop: *const UIO, c: UserCred) {
unsafe { self.ops.as_mut().readdir(uiop, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().readdir(uiop, c, vp)
}
pub fn symlink(&mut self, link_name: &str, va: VAttr, target_name: &str, c: UserCred) {
unsafe {
self.ops
let vp = self.as_ptr();
self.inode
.as_mut()
.symlink(link_name, va, target_name, c, self.as_ptr())
}
.symlink(link_name, va, target_name, c, vp)
}
pub fn readlink(&mut self, uiop: *const UIO, c: UserCred) {
unsafe { self.ops.as_mut().readlink(uiop, c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().readlink(uiop, c, vp)
}
pub fn fsync(&mut self, c: UserCred) {
unsafe { self.ops.as_mut().fsync(c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().fsync(c, vp)
}
pub fn inactive(&mut self, c: UserCred) {
unsafe { self.ops.as_mut().inactive(c, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().inactive(c, vp)
}
pub fn bmap(&mut self, block_number: u32, bnp: ()) -> VNode {
unsafe { self.ops.as_mut().bmap(block_number, bnp, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().bmap(block_number, bnp, vp)
}
pub fn strategy(&mut self, bp: ()) {
unsafe { self.ops.as_mut().strategy(bp, self.as_ptr()) }
let vp = self.as_ptr();
self.inode.as_mut().strategy(bp, vp)
}
pub fn bread(&mut self, block_number: u32) -> Arc<[u8]> {
unsafe { self.ops.as_mut().bread(block_number, self.as_ptr()) }
}
}
let vp = self.as_ptr();
impl Drop for VNode {
fn drop(&mut self) {
let vnode_ops = unsafe { Box::from_raw(self.ops.as_ptr()) };
drop(vnode_ops)
self.inode.as_mut().bread(block_number, vp)
}
}
@@ -347,22 +452,22 @@ pub struct UIO {
}
pub trait VNodeOperations {
fn open(&mut self, f: u32, c: UserCred, vp: *const VNode) -> Result<Arc<[u8]>, ()>;
fn close(&mut self, f: u32, c: UserCred, vp: *const VNode);
fn open(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>) -> Result<Arc<[u8]>, ()>;
fn close(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>);
fn rdwr(
&mut self,
uiop: *const UIO,
direction: IODirection,
f: u32,
c: UserCred,
vp: *const VNode,
);
fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: *const VNode);
fn select(&mut self, w: IODirection, c: UserCred, vp: *const VNode);
fn getattr(&mut self, c: UserCred, vp: *const VNode) -> VAttr;
fn setattr(&mut self, va: VAttr, c: UserCred, vp: *const VNode);
fn access(&mut self, m: u32, c: UserCred, vp: *const VNode);
fn lookup(&mut self, nm: &str, c: UserCred, vp: *const VNode) -> Result<VNode, ()>;
vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()>;
fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: NonNull<VNode>);
fn select(&mut self, w: IODirection, c: UserCred, vp: NonNull<VNode>);
fn getattr(&mut self, c: UserCred, vp: NonNull<VNode>) -> VAttr;
fn setattr(&mut self, va: VAttr, c: UserCred, vp: NonNull<VNode>);
fn access(&mut self, m: u32, c: UserCred, vp: NonNull<VNode>);
fn lookup(&mut self, nm: &str, c: UserCred, vp: NonNull<VNode>) -> Result<VNode, ()>;
fn create(
&mut self,
nm: &str,
@@ -370,33 +475,33 @@ pub trait VNodeOperations {
e: u32,
m: u32,
c: UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
) -> Result<VNode, ()>;
fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred, vp: *const VNode);
fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred, vp: NonNull<VNode>);
fn rename(
&mut self,
nm: &str,
target_dir: *mut VNode,
target_name: &str,
c: UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
);
fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred, vp: *const VNode) -> Result<VNode, ()>;
fn readdir(&mut self, uiop: *const UIO, c: UserCred, vp: *const VNode);
fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred, vp: NonNull<VNode>) -> Result<VNode, ()>;
fn readdir(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>);
fn symlink(
&mut self,
link_name: &str,
va: VAttr,
target_name: &str,
c: UserCred,
vp: *const VNode,
vp: NonNull<VNode>,
);
fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: *const VNode);
fn fsync(&mut self, c: UserCred, vp: *const VNode);
fn inactive(&mut self, c: UserCred, vp: *const VNode);
fn bmap(&mut self, block_number: u32, bnp: (), vp: *const VNode) -> VNode;
fn strategy(&mut self, bp: (), vp: *const VNode);
fn bread(&mut self, block_number: u32, vp: *const VNode) -> Arc<[u8]>;
fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>);
fn fsync(&mut self, c: UserCred, vp: NonNull<VNode>);
fn inactive(&mut self, c: UserCred, vp: NonNull<VNode>);
fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull<VNode>) -> VNode;
fn strategy(&mut self, bp: (), vp: NonNull<VNode>);
fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
}
#[allow(unused)]
@@ -419,72 +524,24 @@ pub struct VAttr {
used_blocks: u32,
}
unsafe fn vfs_has_mount_point(mount_point: &str) -> Option<NonNull<Vfs>> {
let mut current = ROOT_VFS.next;
while let Some(node) = current {
if node.as_ref().mount_point.as_ref().unwrap() == mount_point {
return Some(node);
}
current = unsafe { (*node.as_ptr()).next };
}
None
}
pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
/// # Safety
/// Consumes vfs
unsafe fn deallocate_vfs(vfs: NonNull<Vfs>) {
let fs_ops_box = Box::from_raw(vfs.as_ref().ops.unwrap().as_ptr());
drop(fs_ops_box);
dealloc(
vfs.as_ptr().cast::<u8>(),
alloc::alloc::Layout::new::<Vfs>(),
);
}
let layout = alloc::alloc::Layout::new::<Vfs>();
let vfs_ptr = unsafe { alloc(layout).cast::<Vfs>() };
if vfs_ptr.is_null() {
handle_alloc_error(layout)
}
// Initialize the data so we can use the nonnull helpers
unsafe {
let mut vfs = Vfs::null();
vfs.ops = Some(NonNull::new_unchecked(Box::into_raw(fs_ops)));
// 'normalize' the path (yes, making "/" == "" is intentional)
vfs.mount_point = Some(mount_point.trim_end_matches('/').to_string());
vfs_ptr.write(vfs);
};
let mut new_vfs = Vfs::null();
new_vfs.fs = Some(fs_ops);
let mut vfs = Box::new(new_vfs);
// Safety: We know vfs_ptr is not null
let mut vfs_ptr = unsafe { NonNull::new_unchecked(vfs_ptr) };
let vfs = unsafe { vfs_ptr.as_mut() };
let vfsp = vfs.as_ptr();
log_info!("Adding vfs at {mount_point}");
if mount_point == "/" {
if unsafe { ROOT_VFS.next.is_some() } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
}
vfs.mount(mount_point);
unsafe { ROOT_VFS.next = Some(vfs_ptr) };
unsafe { NODE_TREE = Some(TreeNode::new(vfs.fs.as_mut().unwrap().as_mut().root(vfsp))) }
} else {
if unsafe { ROOT_VFS.next.is_none() } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
}
@@ -492,46 +549,26 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
return Err(());
}
let mut next_vfs = unsafe { ROOT_VFS.next };
let vnode = vfs_open(mount_point)?;
while let Some(target_vfs) = next_vfs {
if unsafe { target_vfs.as_ref().mount_point.as_ref().unwrap() == mount_point } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
}
if unsafe { target_vfs.as_ref().next }.is_none() {
break;
}
next_vfs = unsafe { target_vfs.as_ref().next };
}
if next_vfs.is_none() {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
vnode.vfs_mounted_here = Some(vfsp);
}
vfs.mount(mount_point);
unsafe { (next_vfs.unwrap()).as_mut().next = Some(vfs_ptr) };
}
unsafe { ROOT_VFS.add_vfs(vfs) };
log_ok!("Added vfs at {mount_point}");
return Ok(());
}
pub fn vfs_open(path: &str) -> Result<VNode, ()> {
if unsafe { ROOT_VFS.next.is_none() } {
pub fn vfs_open(path: &str) -> Result<&mut VNode, ()> {
if unsafe { ROOT_VFS.next.is_none() || NODE_TREE.is_none() } {
return Err(());
}
let mut cur_vnode = unsafe { ROOT_VFS.next.unwrap().as_mut().root() };
let mut cur_node = unsafe { NODE_TREE.as_mut().unwrap() };
let parts = path.split('/').collect::<Vec<&str>>();
@@ -540,12 +577,12 @@ pub fn vfs_open(path: &str) -> Result<VNode, ()> {
continue;
}
if let Ok(vnode) = cur_vnode.lookup(part, UserCred { uid: 0, gid: 0 }) {
cur_vnode = vnode;
if let Ok(new_node) = cur_node.lookup(part) {
cur_node = new_node;
} else {
return Err(());
}
}
return Ok(cur_vnode);
return Ok(cur_node.get_vnode());
}

View File

@@ -100,7 +100,7 @@ pub fn is_transmit_empty() -> bool {
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
pub fn write_serial(character: u8) {
unsafe {
*UART = character;
UART.write(character);
};
}

View File

@@ -432,14 +432,14 @@ impl ATABus {
ATADriveDirection::Read => unsafe {
insw(
self.io_bar + ATADriveDataRegister::Data as u16,
(buffer.as_mut_ptr() as *mut u16).add(buffer_offset),
(buffer.as_mut_ptr().cast::<u16>()).add(buffer_offset),
ATA_SECTOR_SIZE / size_of::<u16>(),
);
},
ATADriveDirection::Write => unsafe {
outsw(
self.io_bar + ATADriveDataRegister::Data as u16,
(buffer.as_mut_ptr() as *mut u16).add(buffer_offset),
(buffer.as_mut_ptr().cast::<u16>()).add(buffer_offset),
ATA_SECTOR_SIZE / size_of::<u16>(),
)
},
@@ -502,7 +502,7 @@ impl ATADrive {
fn sector_count(&self) -> u64 {
let sectors = self.identify_data[120..].as_ptr();
return unsafe { *(sectors as *const u32) } as u64;
return unsafe { *(sectors.cast::<u32>()) } as u64;
}
pub fn as_ptr(&self) -> *const ATADrive {
@@ -524,7 +524,7 @@ impl BlockDevice for ATADrive {
fn sector_count(&self) -> u64 {
let sectors = self.identify_data[120..].as_ptr();
return unsafe { *(sectors as *const u32) } as u64;
return unsafe { *(sectors.cast::<u32>()) } as u64;
}
fn write(&self, sector: u64, buffer: &[u8]) -> Result<(), ()> {
@@ -542,7 +542,6 @@ static DRIVES: Mutex<Vec<ATADrive>> = Mutex::new(Vec::new());
// TODO: This code is pretty much just the C from @Moldytzu's mOS
// This code could probably be made better and more device agnostic
// But that's TODO obviously
fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
let mut drives_lock = DRIVES.lock();
let io_port_base = bar0 as u16;

View File

@@ -32,7 +32,7 @@ impl Framebuffer {
let pixel_offset = (y * self.pitch as u32 + (x * (self.bpp / 8) as u32)) as isize;
unsafe {
*(self.pointer.offset(pixel_offset) as *mut u32) = color;
*(self.pointer.offset(pixel_offset).cast::<u32>()) = color;
}
}
@@ -43,21 +43,25 @@ impl Framebuffer {
unsafe {
if let Some(mirror_buffer) = mirror_buffer {
crate::mem::memset32(mirror_buffer.pointer as *mut u32, color, buffer_size);
crate::mem::memset32(mirror_buffer.pointer.cast::<u32>(), color, buffer_size);
}
crate::mem::memset32(self.pointer as *mut u32, color, buffer_size);
crate::mem::memset32(self.pointer.cast::<u32>(), color, buffer_size);
}
}
pub fn blit_screen(&self, buffer: &mut [u32], mirror_buffer: Option<Self>) {
unsafe {
core::ptr::copy_nonoverlapping(buffer.as_ptr(), self.pointer as *mut u32, buffer.len());
core::ptr::copy_nonoverlapping(
buffer.as_ptr(),
self.pointer.cast::<u32>(),
buffer.len(),
);
if let Some(mirror_buffer) = mirror_buffer {
core::ptr::copy_nonoverlapping(
buffer.as_ptr(),
mirror_buffer.pointer as *mut u32,
mirror_buffer.pointer.cast::<u32>(),
buffer.len(),
);
}

View File

@@ -10,6 +10,8 @@ pub struct Cell<T: ?Sized> {
value: UnsafeCell<T>,
}
impl<T: ?Sized> !Sync for Cell<T> {}
impl<T> Cell<T> {
pub const fn new(value: T) -> Cell<T> {
return Self {

View File

@@ -1,4 +1,10 @@
#![feature(allocator_api, abi_x86_interrupt, naked_functions, const_mut_refs)]
#![feature(
allocator_api,
abi_x86_interrupt,
naked_functions,
const_mut_refs,
negative_impls
)]
#![allow(clippy::needless_return)]
#![no_std]
#![no_main]
@@ -45,13 +51,12 @@ pub fn kmain() -> ! {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
drivers::pci::enumerate_pci_bus();
let mut file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap();
let file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap();
crate::println!("YEAH.TXT: {:X?}", file.open(0, UserCred { uid: 0, gid: 0 }));
drivers::storage::ide::init();
let mut limine_dir = vfs_open("/mnt/boot/limine").unwrap();
let limine_dir = vfs_open("/mnt/boot/limine").unwrap();
crate::println!(
"LIMINE BOOT: {:X?}",
@@ -61,21 +66,22 @@ pub fn kmain() -> ! {
.open(0, UserCred { uid: 0, gid: 0 })
);
let mut root_dir = vfs_open("/").unwrap();
// TODO: figure out whether this should or shouldnt work in the first place
// let root_dir = vfs_open("/").unwrap();
crate::println!(
"LIMINE BOOT THROUGH LOOKUP: {:X?}",
root_dir
.lookup("mnt", UserCred { uid: 0, gid: 0 })
.unwrap()
.lookup("boot", UserCred { uid: 0, gid: 0 })
.unwrap()
.lookup("limine", UserCred { uid: 0, gid: 0 })
.unwrap()
.lookup("limine.cfg", UserCred { uid: 0, gid: 0 })
.unwrap()
.open(0, UserCred { uid: 0, gid: 0 })
);
// crate::println!(
// "LIMINE BOOT THROUGH LOOKUP: {:X?}",
// root_dir
// .lookup("mnt", UserCred { uid: 0, gid: 0 })
// .unwrap()
// .lookup("boot", UserCred { uid: 0, gid: 0 })
// .unwrap()
// .lookup("limine", UserCred { uid: 0, gid: 0 })
// .unwrap()
// .lookup("limine.cfg", UserCred { uid: 0, gid: 0 })
// .unwrap()
// .open(0, UserCred { uid: 0, gid: 0 })
// );
// let file = vfs_open("/example.txt").unwrap();
@@ -83,20 +89,20 @@ pub fn kmain() -> ! {
draw_gradient();
// loop {
// let ch = read_serial();
// let ch = crate::drivers::serial::read_serial();
// if ch == b'\x00' {
// continue;
// }
// if ch == b'\x08' {
// write_serial(b'\x08');
// write_serial(b' ');
// write_serial(b'\x08');
// crate::drivers::serial::write_serial(b'\x08');
// crate::drivers::serial::write_serial(b' ');
// crate::drivers::serial::write_serial(b'\x08');
// }
// if ch > 0x20 && ch < 0x7F {
// write_serial(ch);
// if ch > 0x1F && ch < 0x7F {
// crate::drivers::serial::write_serial(ch);
// }
// }