diff --git a/scripts/README.md b/scripts/README.md
index a7f873a..b9c368e 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -1,11 +1,12 @@
# CappuccinOS/scripts
+
This folder is responsible for holding all the scripts that are necessary for building CappuccinOS
- **demangle-symbols.py**
- This file takes in a symbols file generated by the `nm` program and outputs a symbol file with the symbol names demangled, it uses my library, [rustc_demangle.py](https://github.com/juls0730/rustc_demangle.py) which is a python port of the Rust symbol demangling library [rustc-demangle](https://github.com/rust-lang/rustc-demangle).
+ This file takes in a symbols file generated by the `nm` program and outputs a symbol file with the symbol names demangled, it uses my library, [rustc_demangle.py](https://github.com/juls0730/rustc_demangle.py) which is a python port of the Rust symbol demangling library [rustc-demangle](https://github.com/rust-lang/rustc-demangle).
- **font.py**
- This file takes an array of u8 numbers and exports a PC Screen Font file (2.0)
+ This file takes an array of u8 numbers and exports a PC Screen Font file (2.0)
-- **initramfs-test.py**
- This file generates tons of files in the initramfs directory from huge to small files nested in directories, etc. It's intended to test the squashfs driver
\ No newline at end of file
+- **initramfs-test.py**
+ This file generates tons of files in the initramfs directory from huge to small files nested in directories, etc. It's intended to test the squashfs driver
diff --git a/src/arch/x86_64/linker.ld b/src/arch/x86_64/linker.ld
index 72e3a4d..f16abdb 100644
--- a/src/arch/x86_64/linker.ld
+++ b/src/arch/x86_64/linker.ld
@@ -1,59 +1,75 @@
+/* Tell the linker that we want an x86_64 ELF64 output file */
+OUTPUT_FORMAT(elf64-x86-64)
+OUTPUT_ARCH(i386:x86-64)
+
/* We want the symbol _start to be our entry point */
ENTRY(_start)
-
+
/* Define the program headers we want so the bootloader gives us the right */
/* MMU permissions */
PHDRS
{
- text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
- rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
- data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
- dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */
+ requests PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
+ text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
+ rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
+ data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
+ dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */
}
-
+
SECTIONS
{
- /* We wanna be placed in the topmost 2GiB of the address space, for optimizations */
+ /* We wanna be placed in the topmost 2GiB of the address space, for optimisations */
/* and because that is what the Limine spec mandates. */
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
/* that is the beginning of the region. */
. = 0xffffffff80000000;
-
+
+ /* Define a section to contain the Limine requests and assign it to its own PHDR */
+ .requests : {
+ KEEP(*(.requests_start_marker))
+ KEEP(*(.requests))
+ KEEP(*(.requests_end_marker))
+ } :requests
+
+ /* Move to the next memory page for .text */
+ . += CONSTANT(MAXPAGESIZE);
+
.text : {
*(.text .text.*)
} :text
-
+
/* Move to the next memory page for .rodata */
. += CONSTANT(MAXPAGESIZE);
-
+
.rodata : {
*(.rodata .rodata.*)
} :rodata
-
+
/* Move to the next memory page for .data */
. += CONSTANT(MAXPAGESIZE);
-
+
.data : {
*(.data .data.*)
} :data
-
+
/* Dynamic section for relocations, both in its own PHDR and inside data PHDR */
.dynamic : {
*(.dynamic)
} :data :dynamic
-
+
+
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
/* unnecessary zeros will be written to the binary. */
/* If you need, for example, .init_array and .fini_array, those should be placed */
/* above this. */
.bss : {
- *(COMMON)
*(.bss .bss.*)
+ *(COMMON)
} :data
-
+
/* Discard .note.* and .eh_frame since they may cause issues on some hosts. */
/DISCARD/ : {
*(.eh_frame)
*(.note .note.*)
}
-}
\ No newline at end of file
+}
diff --git a/src/arch/x86_64/stack_trace.rs b/src/arch/x86_64/stack_trace.rs
index de3e8c6..3ef7139 100644
--- a/src/arch/x86_64/stack_trace.rs
+++ b/src/arch/x86_64/stack_trace.rs
@@ -16,7 +16,7 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) {
crate::println!("Stack Trace:");
for _frame in 0..max_frames {
- if stackframe.is_null() || unsafe { (*stackframe).back.is_null() } {
+ if stackframe.is_null() || unsafe { core::ptr::read_unaligned(stackframe).back.is_null() } {
break;
}
diff --git a/src/arch/x86_64/x86_64-unknown-none.json b/src/arch/x86_64/x86_64-unknown-none.json
index 74308ba..df65cce 100644
--- a/src/arch/x86_64/x86_64-unknown-none.json
+++ b/src/arch/x86_64/x86_64-unknown-none.json
@@ -1,4 +1,5 @@
{
+ "arch": "x86_64",
"cpu": "x86-64",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"llvm-target": "x86_64-unknown-none",
@@ -7,7 +8,6 @@
"target-c-int-width": "32",
"features": "-mmx,-sse,+soft-float",
"os": "CappuccinOS",
- "arch": "x86_64",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"pre-link-args": {
diff --git a/src/drivers/fs/fat.rs b/src/drivers/fs/fat.rs
index daa3145..1b8effe 100755
--- a/src/drivers/fs/fat.rs
+++ b/src/drivers/fs/fat.rs
@@ -432,10 +432,6 @@ impl FatFs {
}
fn cluster_to_sector(&self, cluster: usize) -> usize {
- crate::println!("bytes per sector: {}", unsafe {
- core::ptr::read_unaligned(core::ptr::addr_of!(self.bpb.bytes_per_sector))
- });
-
let fat_size = self.sectors_per_fat;
let root_dir_sectors = ((self.bpb.root_directory_count * 32)
+ (self.bpb.bytes_per_sector - 1))
diff --git a/src/drivers/fs/vfs.rs b/src/drivers/fs/vfs.rs
index 26ee4d4..4b69d5f 100755
--- a/src/drivers/fs/vfs.rs
+++ b/src/drivers/fs/vfs.rs
@@ -1,22 +1,22 @@
-use core::fmt::Debug;
+use core::{fmt::Debug, ptr::NonNull};
use alloc::{
- // alloc::{alloc, dealloc},
+ alloc::{alloc, dealloc, handle_alloc_error},
boxed::Box,
string::{String, ToString},
sync::Arc,
vec::Vec,
};
-use crate::{log_info, log_ok, mem::PHYSICAL_MEMORY_MANAGER};
+use crate::{log_info, log_ok};
static mut ROOT_VFS: Vfs = Vfs::null();
#[allow(unused)]
pub struct Vfs {
mount_point: Option,
- next: Option<*mut Vfs>,
- ops: Option>,
+ next: Option>,
+ ops: Option>,
// vnode_covered: Option<*const VNode>,
flags: u32,
block_size: u32,
@@ -222,21 +222,31 @@ pub struct VAttr {
used_blocks: u32,
}
-unsafe fn find_mount_point(file_path: &str) -> Option<*mut Vfs> {
+unsafe fn find_mount_point(file_path: &str) -> Option> {
// TODO: refactor
- let mut mount_point = ROOT_VFS.next;
+ let mut mount_point: Option> = None;
let mut current = ROOT_VFS.next;
while let Some(node) = current {
+ if node
+ .as_ref()
+ .mount_point
+ .as_ref()
+ .expect("Null mount point")
+ == "/"
+ && mount_point.is_none()
+ {
+ mount_point = Some(node);
+ }
+
let mount_point_str = node
.as_ref()
- .unwrap()
.mount_point
.as_ref()
.expect("Null mount point");
if file_path.starts_with(mount_point_str)
&& mount_point_str.len()
- > (mount_point.unwrap().as_ref().unwrap())
+ > (mount_point.unwrap().as_ref())
.mount_point
.as_ref()
.unwrap()
@@ -244,7 +254,7 @@ unsafe fn find_mount_point(file_path: &str) -> Option<*mut Vfs> {
{
mount_point = Some(node);
}
- current = unsafe { (*node).next };
+ current = unsafe { (*node.as_ptr()).next };
}
mount_point
@@ -255,42 +265,66 @@ pub fn add_vfs(mut mount_point: &str, fs_ops: Box) -> Result<(), ()>
mount_point = mount_point.trim_end_matches('/');
}
- // let layout = alloc::alloc::Layout::new::();
+ /// # Safety
+ /// Consumes vfs
+ unsafe fn deallocate_vfs(vfs: NonNull) {
+ let fs_ops_box = Box::from_raw(vfs.as_ref().ops.unwrap().as_ptr());
+ drop(fs_ops_box);
+ dealloc(
+ vfs.as_ptr().cast::(),
+ alloc::alloc::Layout::new::(),
+ );
+ }
+
+ let layout = alloc::alloc::Layout::new::();
// TODO: its fucking broken again
- let vfs_ptr = PHYSICAL_MEMORY_MANAGER.alloc(1).cast::();
+ // let vfs_ptr = PHYSICAL_MEMORY_MANAGER.alloc(1).cast::();
+ let vfs_ptr = unsafe { alloc(layout).cast::() };
- let vfs = unsafe { &mut *vfs_ptr };
+ if vfs_ptr.is_null() {
+ handle_alloc_error(layout)
+ }
- (*vfs) = Vfs::null();
- (*vfs).ops = Some(fs_ops);
- (*vfs).mount_point = Some(mount_point.to_string());
+ // 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)));
+ vfs.mount_point = Some(mount_point.to_string());
+ *vfs_ptr = vfs;
+ };
- log_info!("Adding vfs at {mount_point} {vfs_ptr:p}");
+ // 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() };
+
+ log_info!("Adding vfs at {mount_point}");
// TODO: dont give / special treatment
if mount_point == "/" {
if unsafe { ROOT_VFS.next.is_some() } {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
+ unsafe {
+ deallocate_vfs(vfs_ptr);
+ };
+ // PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
return Err(());
}
- {
- let vfsp = vfs.as_ptr();
-
- (*vfs)
- .ops
- .as_mut()
+ unsafe {
+ vfs.ops
.unwrap()
- .mount(mount_point, &mut vfs.data, vfsp);
+ .as_mut()
+ .mount(mount_point, &mut vfs.data, vfs_ptr.as_ptr());
}
- unsafe { ROOT_VFS.next = Some(vfs.as_mut_ptr()) };
+ unsafe { ROOT_VFS.next = Some(vfs_ptr) };
} else {
// TODO: technically this allows you to mount file systems at nonexistent mount point
if unsafe { ROOT_VFS.next.is_none() } {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
+ unsafe {
+ deallocate_vfs(vfs_ptr);
+ };
+ // PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
return Err(());
}
@@ -299,71 +333,37 @@ pub fn add_vfs(mut mount_point: &str, fs_ops: Box) -> Result<(), ()>
let mut next_vfs = unsafe { ROOT_VFS.next };
while let Some(target_vfs) = next_vfs {
- if unsafe { target_vfs.as_ref().unwrap().mount_point.as_ref().unwrap() == mount_point }
- {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
+ if unsafe { target_vfs.as_ref().mount_point.as_ref().unwrap() == mount_point } {
+ unsafe {
+ deallocate_vfs(vfs_ptr);
+ };
+ // PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
return Err(());
}
- if unsafe { (*target_vfs).next }.is_none() {
+ if unsafe { target_vfs.as_ref().next }.is_none() {
break;
}
- next_vfs = unsafe { (*target_vfs).next };
+ next_vfs = unsafe { target_vfs.as_ref().next };
}
if next_vfs.is_none() {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
+ unsafe {
+ deallocate_vfs(vfs_ptr);
+ };
+ // PHYSICAL_MEMORY_MANAGER.dealloc(vfs_ptr.cast::(), 1);
return Err(());
}
- {
- let vfsp = vfs.as_ptr();
-
- (*vfs)
- .ops
- .as_mut()
+ unsafe {
+ vfs.ops
.unwrap()
- .mount(mount_point, &mut vfs.data, vfsp);
+ .as_mut()
+ .mount(mount_point, &mut vfs.data, vfs_ptr.as_ptr());
}
- unsafe { (*(next_vfs.unwrap())).next = Some(vfs) };
-
- // let mut cur_vnode = unsafe { (*target_vfs).ops.as_mut().unwrap().root(target_vfs) };
-
- // let parts = mount_point.split('/').collect::>();
-
- // for part in parts {
- // if part.is_empty() {
- // continue;
- // }
-
- // // TODO: dont just lookup everything as the root user
- // if let Ok(vnode) =
- // cur_vnode
- // .ops
- // .lookup(part, UserCred { uid: 0, gid: 0 }, cur_vnode.as_ptr())
- // {
- // cur_vnode = vnode;
- // } else {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- // return Err(());
- // }
- // }
-
- // if cur_vnode.vfs_mounted_here.is_some() {
- // unsafe { dealloc(vfs_ptr.cast::(), layout) };
- // return Err(());
- // }
-
- // {
- // let vfsp = vfs.as_ptr();
-
- // }
-
- // cur_vnode.vfs_mounted_here = Some(vfs.as_mut_ptr());
+ unsafe { (next_vfs.unwrap()).as_mut().next = Some(vfs_ptr) };
}
log_ok!("Added vfs at {mount_point}");
@@ -383,14 +383,16 @@ pub fn vfs_open(path: &str) -> Result {
}
let mut cur_vnode = unsafe {
- (*root_vfs.unwrap())
- .ops
- .as_mut()
+ root_vfs
.unwrap()
- .root(root_vfs.unwrap())
+ .as_mut()
+ .ops
+ .unwrap()
+ .as_mut()
+ .root(root_vfs.unwrap().as_ptr())
};
- let path = &path[unsafe { (*root_vfs.unwrap()).mount_point.as_ref().unwrap() }.len()..];
+ let path = &path[unsafe { root_vfs.unwrap().as_ref().mount_point.as_ref().unwrap() }.len()..];
let parts = path.split('/').collect::>();
diff --git a/src/main.rs b/src/main.rs
index eb2fceb..1378e6b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
-#![feature(abi_x86_interrupt, naked_functions, const_mut_refs)]
+#![feature(allocator_api, abi_x86_interrupt, naked_functions, const_mut_refs)]
#![allow(clippy::needless_return)]
#![no_std]
#![no_main]
@@ -7,6 +7,7 @@ use core::ffi::CStr;
use alloc::vec::Vec;
use limine::KernelFileRequest;
+use mem::HHDM_OFFSET;
use crate::drivers::fs::{
initramfs,
@@ -45,6 +46,14 @@ pub fn kmain() -> ! {
let mut file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap();
+ crate::println!(
+ "YEAH.TXT: {:X?}",
+ &file
+ .ops
+ .open(0, UserCred { uid: 0, gid: 0 }, file.as_ptr())
+ .unwrap()
+ );
+
drivers::storage::ide::init();
let mut nested_file = vfs_open("/mnt/boot/limine/limine.cfg").unwrap();
@@ -57,13 +66,6 @@ pub fn kmain() -> ! {
);
// let file = vfs_open("/example.txt").unwrap();
- crate::println!(
- "YEAH.TXT: {:X?}",
- &file
- .ops
- .open(0, UserCred { uid: 0, gid: 0 }, file.as_ptr())
- .unwrap()
- );
// as a sign that we didnt panic
draw_gradient();
diff --git a/src/mem/allocator.rs b/src/mem/allocator.rs
index ad3be1b..fafccdc 100644
--- a/src/mem/allocator.rs
+++ b/src/mem/allocator.rs
@@ -5,7 +5,7 @@ use core::{
use crate::{libs::sync::Mutex, mem::pmm::PAGE_SIZE};
-use super::align_up;
+use super::{align_up, HHDM_OFFSET};
#[derive(Debug)]
struct MemNode {
@@ -47,7 +47,9 @@ impl LinkedListAllocator {
pub fn init(&mut self, pages: usize) {
unsafe {
self.add_free_region(
- super::PHYSICAL_MEMORY_MANAGER.alloc(pages),
+ super::PHYSICAL_MEMORY_MANAGER
+ .alloc(pages)
+ .add(*HHDM_OFFSET),
PAGE_SIZE * pages,
);
}
diff --git a/src/mem/mod.rs b/src/mem/mod.rs
index b1cf709..5b7edd6 100755
--- a/src/mem/mod.rs
+++ b/src/mem/mod.rs
@@ -7,6 +7,7 @@ use self::{allocator::LinkedListAllocator, pmm::PhysicalMemoryManager};
static MEMMAP_REQUEST: limine::MemmapRequest = limine::MemmapRequest::new(0);
static HHDM_REQUEST: limine::HhdmRequest = limine::HhdmRequest::new(0);
+pub static HHDM_OFFSET: OnceCell = OnceCell::new();
pub static PHYSICAL_MEMORY_MANAGER: OnceCell = OnceCell::new();
@@ -15,7 +16,7 @@ pub fn align_up(addr: usize, align: usize) -> usize {
addr + offset
}
-const HEAP_PAGES: usize = 4096; // 8 MiB heap
+const HEAP_PAGES: usize = 1024; // 4 MiB heap
#[global_allocator]
pub static ALLOCATOR: Mutex = Mutex::new(LinkedListAllocator::new());
diff --git a/src/mem/pmm.rs b/src/mem/pmm.rs
index 7220f91..8c54904 100644
--- a/src/mem/pmm.rs
+++ b/src/mem/pmm.rs
@@ -2,7 +2,7 @@
use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
-use super::{HHDM_REQUEST, MEMMAP_REQUEST};
+use super::{HHDM_OFFSET, HHDM_REQUEST, MEMMAP_REQUEST};
pub const PAGE_SIZE: usize = 4096;
@@ -36,6 +36,8 @@ impl PhysicalMemoryManager {
let hhdm_offset = hhdm_req.offset as usize;
+ HHDM_OFFSET.set(hhdm_offset);
+
let memmap = MEMMAP_REQUEST
.get_response()
.get_mut()