update to limine v8 and other various stuff

This commit is contained in:
Zoe
2024-08-13 10:35:06 -05:00
parent 992863a112
commit 119e27129c
23 changed files with 346 additions and 316 deletions

15
Cargo.lock generated
View File

@@ -10,7 +10,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "limine" name = "bitflags"
version = "0.1.11" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f45c67c512034e8eb0064556e1db5da671b3ef50791cd6ac6376e7aefc0ef27e" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "limine"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "846c87e24d089e8717a61098cba72b378e3525c46a87cf75b71352dcf668e68c"
dependencies = [
"bitflags",
]

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
limine = "0.1.10" limine = "0.2.0"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3

View File

@@ -20,7 +20,7 @@ IMAGE_PATH = ${ARTIFACTS_PATH}/${IMAGE_NAME}
CARGO_OPTS = --target=src/arch/${ARCH}/${ARCH}-unknown-none.json CARGO_OPTS = --target=src/arch/${ARCH}/${ARCH}-unknown-none.json
QEMU_OPTS += -m ${MEMORY} -drive id=hd0,format=raw,file=${IMAGE_PATH} QEMU_OPTS += -m ${MEMORY} -drive id=hd0,format=raw,file=${IMAGE_PATH}
LIMINE_BOOT_VARIATION = X64 LIMINE_BOOT_VARIATION = X64
LIMINE_BRANCH = v7.x-binary LIMINE_BRANCH = v8.x-binary
ifeq (${MODE},release) ifeq (${MODE},release)
CARGO_OPTS += --release CARGO_OPTS += --release
@@ -108,7 +108,7 @@ copy-iso-files:
mkdir -p ${ISO_PATH}/mnt mkdir -p ${ISO_PATH}/mnt
cp -v limine.cfg limine/limine-bios.sys ${ISO_PATH}/boot/limine cp -v limine.conf limine/limine-bios.sys ${ISO_PATH}/boot/limine
cp -v limine/BOOT${LIMINE_BOOT_VARIATION}.EFI ${ISO_PATH}/EFI/BOOT/ cp -v limine/BOOT${LIMINE_BOOT_VARIATION}.EFI ${ISO_PATH}/EFI/BOOT/
# OS files # OS files

View File

@@ -49,7 +49,7 @@ Before building CappuccinOS, make sure you have the following installed on your
- rust - rust
- python - python
- sgdisk - sgdisk
- mtools - dosfstools
- squashfs-tools - squashfs-tools
- qemu (optional) - qemu (optional)
@@ -71,7 +71,7 @@ Install the dependencies:
<details> <details>
<summary>Arch</summary> <summary>Arch</summary>
sudo pacman -S gptfdisk mtools squashfs-tools python sudo pacman -S gptfdisk dosfstools squashfs-tools python
# Optionally # Optionally
sudo pacman -S qemu-system-x86 sudo pacman -S qemu-system-x86
@@ -81,7 +81,7 @@ Install the dependencies:
<summary>Ubuntu</summary> <summary>Ubuntu</summary>
Python should be installed by default, and if it's not, make an issue or a PR and I'll fix it Python should be installed by default, and if it's not, make an issue or a PR and I'll fix it
sudo apt install gdisk mtools squashfs-tools sudo apt install gdisk dosfstools squashfs-tools
# Optionally # Optionally
sudo apt install qemu sudo apt install qemu

View File

@@ -1,10 +0,0 @@
# Timeout in seconds that Limine will use before automatically booting.
TIMEOUT=3
:CappuccinOS
PROTOCOL=limine
KERNEL_PATH=boot:///boot/CappuccinOS.elf
KERNEL_CMDLINE=fat_in_mem=false big_fat_phony
MODULE_PATH=boot:///boot/initramfs.img

View File

@@ -6,42 +6,52 @@ OUTPUT_ARCH(aarch64)
ENTRY(_start) ENTRY(_start)
/* Define the program headers we want so the bootloader gives us the right */ /* Define the program headers we want so the bootloader gives us the right */
/* MMU permissions */ /* MMU permissions; this also allows us to exert more control over the linking */
/* process. */
PHDRS PHDRS
{ {
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ headers PT_PHDR PHDRS;
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ text PT_LOAD FILEHDR PHDRS;
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ rodata PT_LOAD;
dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */ data PT_LOAD;
dynamic PT_DYNAMIC;
} }
SECTIONS SECTIONS
{ {
/* We wanna be placed in the topmost 2GiB of the address space, for optimisations */ /* We want to be placed in the topmost 2GiB of the address space, for optimisations */
/* and because that is what the Limine spec mandates. */ /* and because that is what the Limine spec mandates. */
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
/* that is the beginning of the region. */ /* that is the beginning of the region. */
. = 0xffffffff80000000; /* Additionally, leave space for the ELF headers by adding SIZEOF_HEADERS to the */
/* base load address. */
. = 0xffffffff80000000 + SIZEOF_HEADERS;
.text : { .text : {
*(.text .text.*) *(.text .text.*)
} :text } :text
/* Move to the next memory page for .rodata */ /* Move to the next memory page for .rodata */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.rodata : { .rodata : {
*(.rodata .rodata.*) *(.rodata .rodata.*)
} :rodata } :rodata
/* Move to the next memory page for .data */ /* Move to the next memory page for .data */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.data : { .data : {
*(.data .data.*) *(.data .data.*)
/* Place the sections that contain the Limine requests as part of the .data */
/* output section. */
KEEP(*(.requests_start_marker))
KEEP(*(.requests))
KEEP(*(.requests_end_marker))
} :data } :data
/* Dynamic section for relocations, both in its own PHDR and inside data PHDR */ /* Dynamic section for relocations, both in its own PHDR and inside data PHDR. */
.dynamic : { .dynamic : {
*(.dynamic) *(.dynamic)
} :data :dynamic } :data :dynamic
@@ -55,9 +65,13 @@ SECTIONS
*(COMMON) *(COMMON)
} :data } :data
/* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
/* Also discard the program interpreter section since we do not need one. This is */
/* more or less equivalent to the --no-dynamic-linker linker flag, except that it */
/* works with ld.gold. */
/DISCARD/ : { /DISCARD/ : {
*(.eh_frame) *(.eh_frame*)
*(.note .note.*) *(.note .note.*)
*(.interp)
} }
} }

View File

@@ -6,43 +6,54 @@ OUTPUT_ARCH(riscv:rv64)
ENTRY(_start) ENTRY(_start)
/* Define the program headers we want so the bootloader gives us the right */ /* Define the program headers we want so the bootloader gives us the right */
/* MMU permissions */ /* MMU permissions; this also allows us to exert more control over the linking */
/* process. */
PHDRS PHDRS
{ {
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ headers PT_PHDR PHDRS;
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ text PT_LOAD FILEHDR PHDRS;
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ rodata PT_LOAD;
dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */ data PT_LOAD;
dynamic PT_DYNAMIC;
} }
SECTIONS SECTIONS
{ {
/* We wanna be placed in the topmost 2GiB of the address space, for optimisations */ /* We want to be placed in the topmost 2GiB of the address space, for optimisations */
/* and because that is what the Limine spec mandates. */ /* and because that is what the Limine spec mandates. */
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
/* that is the beginning of the region. */ /* that is the beginning of the region. */
. = 0xffffffff80000000; /* Additionally, leave space for the ELF headers by adding SIZEOF_HEADERS to the */
/* base load address. */
. = 0xffffffff80000000 + SIZEOF_HEADERS;
.text : { .text : {
*(.text .text.*) *(.text .text.*)
} :text } :text
/* Move to the next memory page for .rodata */ /* Move to the next memory page for .rodata */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.rodata : { .rodata : {
*(.rodata .rodata.*) *(.rodata .rodata.*)
} :rodata } :rodata
/* Move to the next memory page for .data */ /* Move to the next memory page for .data */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.data : { .data : {
*(.data .data.*) *(.data .data.*)
/* Place the sections that contain the Limine requests as part of the .data */
/* output section. */
KEEP(*(.requests_start_marker))
KEEP(*(.requests))
KEEP(*(.requests_end_marker))
*(.sdata .sdata.*) *(.sdata .sdata.*)
} :data } :data
/* Dynamic section for relocations, both in its own PHDR and inside data PHDR */ /* Dynamic section for relocations, both in its own PHDR and inside data PHDR. */
.dynamic : { .dynamic : {
*(.dynamic) *(.dynamic)
} :data :dynamic } :data :dynamic
@@ -57,9 +68,13 @@ SECTIONS
*(COMMON) *(COMMON)
} :data } :data
/* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
/* Also discard the program interpreter section since we do not need one. This is */
/* more or less equivalent to the --no-dynamic-linker linker flag, except that it */
/* works with ld.gold. */
/DISCARD/ : { /DISCARD/ : {
*(.eh_frame) *(.eh_frame*)
*(.note .note.*) *(.note .note.*)
*(.interp)
} }
} }

View File

@@ -66,8 +66,8 @@ pub struct APIC {
pub cpus: Arc<[LAPIC]>, pub cpus: Arc<[LAPIC]>,
} }
extern "C" fn test(info: *const limine::SmpInfo) -> ! { unsafe extern "C" fn test<'a>(cpu: &'a limine::smp::Cpu) -> ! {
crate::log_ok!("hey from CPU {:<02}", unsafe { (*info).processor_id }); crate::log_ok!("hey from CPU {:<02}", cpu.id);
hcf(); hcf();
} }
@@ -175,21 +175,21 @@ impl APIC {
crate::println!("{number_of_inputs}"); crate::println!("{number_of_inputs}");
let smp_request = SMP_REQUEST.get_response().get_mut(); let smp_request = unsafe { SMP_REQUEST.get_response_mut() };
if smp_request.is_none() { if smp_request.is_none() {
panic!("Failed to get smp from limine!"); panic!("Failed to get smp from limine!");
} }
let smp_request = smp_request.unwrap(); let smp_request = smp_request.unwrap();
let bsp_lapic_id = smp_request.bsp_lapic_id; let bsp_lapic_id = smp_request.bsp_lapic_id();
for cpu in smp_request.cpus() { for cpu in smp_request.cpus() {
if cpu.processor_id == bsp_lapic_id { if cpu.id == bsp_lapic_id {
continue; continue;
} }
cpu.goto_address = test; cpu.goto_address.write(test);
} }
// Set and enable keyboard interrupt // Set and enable keyboard interrupt
@@ -220,7 +220,7 @@ impl APIC {
pub fn write_lapic(&self, reg: u32, value: u32) { pub fn write_lapic(&self, reg: u32, value: u32) {
unsafe { unsafe {
*self.local_apic.add(reg as usize).cast::<u32>() = value; core::ptr::write_volatile(self.local_apic.add(reg as usize).cast::<u32>(), value);
} }
} }

View File

@@ -36,43 +36,43 @@ struct Registers {
extern "C" fn exception_handler(registers: u64) { extern "C" fn exception_handler(registers: u64) {
let registers = unsafe { *(registers as *const Registers) }; let registers = unsafe { *(registers as *const Registers) };
crate::println!("{:X?}", registers); // crate::println!("{:X?}", registers);
let int = registers.int; let int = registers.int;
match int { match int {
0x00 => { 0x00 => {
log_error!("DIVISION ERROR!"); crate::drivers::serial::write_string("DIVISION ERROR!");
} }
0x06 => { 0x06 => {
log_error!("INVALID OPCODE!"); crate::drivers::serial::write_string("INVALID OPCODE!");
} }
0x08 => { 0x08 => {
log_error!("DOUBLE FAULT!"); crate::drivers::serial::write_string("DOUBLE FAULT!");
} }
0x0D => { 0x0D => {
log_error!("GENERAL PROTECTION FAULT!"); crate::drivers::serial::write_string("GENERAL PROTECTION FAULT!");
} }
0x0E => { 0x0E => {
log_error!("PAGE FAULT!"); crate::drivers::serial::write_string("PAGE FAULT!");
} }
0xFF => { 0xFF => {
log_error!("EXCEPTION!"); crate::drivers::serial::write_string("EXCEPTION!");
} }
_ => { _ => {
log_error!("EXCEPTION!"); crate::drivers::serial::write_string("EXCEPTION!");
} }
} }
log_info!( // log_info!(
"INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}", // "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}",
int, // int,
registers.rip, // registers.rip,
registers.cs, // registers.cs,
registers.rflags // registers.rflags
); // );
crate::arch::stack_trace::print_stack_trace(6, registers.rbp as u64); // crate::arch::stack_trace::print_stack_trace(6, registers.rbp as u64);
} }
// *macro intensifies* // *macro intensifies*

View File

@@ -1,11 +1,6 @@
pub mod apic; pub mod apic;
pub mod exceptions; pub mod exceptions;
use crate::{
// arch::{apic, x86_common::pic::ChainedPics},
libs::sync::Mutex,
};
use self::apic::APIC; use self::apic::APIC;
#[repr(C, packed)] #[repr(C, packed)]
@@ -34,13 +29,15 @@ impl IdtEntry {
} }
} }
impl !Sync for IdtEntry {}
#[repr(C, packed)] #[repr(C, packed)]
struct IdtPtr { struct IdtPtr {
limit: u16, limit: u16,
base: u64, base: u64,
} }
static IDT: Mutex<[IdtEntry; 256]> = Mutex::new([IdtEntry::new(); 256]); static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256];
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[repr(u8)] #[repr(u8)]
@@ -62,7 +59,8 @@ static mut IDT_PTR: IdtPtr = IdtPtr {
pub fn idt_set_gate(num: u8, function_ptr: usize) { pub fn idt_set_gate(num: u8, function_ptr: usize) {
let base = function_ptr; let base = function_ptr;
IDT.lock()[num as usize] = IdtEntry { unsafe {
IDT[num as usize] = IdtEntry {
base_lo: (base & 0xFFFF) as u16, base_lo: (base & 0xFFFF) as u16,
base_mid: ((base >> 16) & 0xFFFF) as u16, base_mid: ((base >> 16) & 0xFFFF) as u16,
base_hi: ((base >> 32) & 0xFFFFFFFF) as u32, base_hi: ((base >> 32) & 0xFFFFFFFF) as u32,
@@ -71,6 +69,7 @@ pub fn idt_set_gate(num: u8, function_ptr: usize) {
always0: 0, always0: 0,
flags: 0xEE, flags: 0xEE,
}; };
}
// If the interrupt with this number occurred with the "null" interrupt handler // If the interrupt with this number occurred with the "null" interrupt handler
// We will need to tell the PIC that interrupt is over, this stops new interrupts // We will need to tell the PIC that interrupt is over, this stops new interrupts
@@ -83,31 +82,18 @@ extern "x86-interrupt" fn null_interrupt_handler() {
signal_end_of_interrupt(); signal_end_of_interrupt();
} }
extern "x86-interrupt" fn timer_handler() {
// crate::usr::tty::puts(".");
signal_end_of_interrupt();
}
pub fn idt_init() { pub fn idt_init() {
unsafe { unsafe {
let idt_size = core::mem::size_of::<IdtEntry>() * 256; let idt_size = core::mem::size_of::<IdtEntry>() * 256;
{ IDT_PTR.base = IDT.as_ptr() as u64;
let mut idt_lock = IDT.lock();
IDT_PTR.base = idt_lock.as_ptr() as u64;
core::ptr::write_bytes( core::ptr::write_bytes(IDT.as_mut_ptr().cast::<core::ffi::c_void>(), 0, idt_size);
idt_lock.as_mut_ptr().cast::<core::ffi::c_void>(),
0,
idt_size,
);
}
// Set every interrupt to the "null" interrupt handler (it does nothing) // Set every interrupt to the "null" interrupt handler (it does nothing)
for num in 0..=255 { for num in 0..=255 {
idt_set_gate(num, null_interrupt_handler as usize); idt_set_gate(num, null_interrupt_handler as usize);
} }
idt_set_gate(InterruptIndex::Timer.as_u8(), timer_handler as usize);
idt_set_gate(0x80, syscall as usize); idt_set_gate(0x80, syscall as usize);
core::arch::asm!( core::arch::asm!(

View File

@@ -6,58 +6,56 @@ OUTPUT_ARCH(i386:x86-64)
ENTRY(_start) ENTRY(_start)
/* Define the program headers we want so the bootloader gives us the right */ /* Define the program headers we want so the bootloader gives us the right */
/* MMU permissions */ /* MMU permissions; this also allows us to exert more control over the linking */
/* process. */
PHDRS PHDRS
{ {
requests PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ headers PT_PHDR PHDRS;
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ text PT_LOAD FILEHDR PHDRS;
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ rodata PT_LOAD;
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ data PT_LOAD;
dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */ dynamic PT_DYNAMIC;
} }
SECTIONS SECTIONS
{ {
/* We wanna be placed in the topmost 2GiB of the address space, for optimisations */ /* We want to be placed in the topmost 2GiB of the address space, for optimisations */
/* and because that is what the Limine spec mandates. */ /* and because that is what the Limine spec mandates. */
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
/* that is the beginning of the region. */ /* that is the beginning of the region. */
. = 0xffffffff80000000; /* Additionally, leave space for the ELF headers by adding SIZEOF_HEADERS to the */
/* base load address. */
/* Define a section to contain the Limine requests and assign it to its own PHDR */ . = 0xffffffff80000000 + SIZEOF_HEADERS;
.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.*) *(.text .text.*)
} :text } :text
/* Move to the next memory page for .rodata */ /* Move to the next memory page for .rodata */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.rodata : { .rodata : {
*(.rodata .rodata.*) *(.rodata .rodata.*)
} :rodata } :rodata
/* Move to the next memory page for .data */ /* Move to the next memory page for .data */
. += CONSTANT(MAXPAGESIZE); . = ALIGN(CONSTANT(MAXPAGESIZE));
.data : { .data : {
*(.data .data.*) *(.data .data.*)
/* Place the sections that contain the Limine requests as part of the .data */
/* output section. */
KEEP(*(.requests_start_marker))
KEEP(*(.requests))
KEEP(*(.requests_end_marker))
} :data } :data
/* Dynamic section for relocations, both in its own PHDR and inside data PHDR */ /* Dynamic section for relocations, both in its own PHDR and inside data PHDR. */
.dynamic : { .dynamic : {
*(.dynamic) *(.dynamic)
} :data :dynamic } :data :dynamic
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
/* unnecessary zeros will be written to the binary. */ /* unnecessary zeros will be written to the binary. */
/* If you need, for example, .init_array and .fini_array, those should be placed */ /* If you need, for example, .init_array and .fini_array, those should be placed */
@@ -67,9 +65,13 @@ SECTIONS
*(COMMON) *(COMMON)
} :data } :data
/* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
/* Also discard the program interpreter section since we do not need one. This is */
/* more or less equivalent to the --no-dynamic-linker linker flag, except that it */
/* works with ld.gold. */
/DISCARD/ : { /DISCARD/ : {
*(.eh_frame) *(.eh_frame*)
*(.note .note.*) *(.note .note.*)
*(.interp)
} }
} }

View File

@@ -1,5 +1,8 @@
use core::ops::Add;
use alloc::vec::Vec; use alloc::vec::Vec;
use limine::SmpRequest; use limine::request::RsdpRequest;
use limine::request::SmpRequest;
use crate::{ use crate::{
arch::io::{inw, outb}, arch::io::{inw, outb},
@@ -7,7 +10,9 @@ use crate::{
mem::HHDM_OFFSET, mem::HHDM_OFFSET,
}; };
pub static SMP_REQUEST: SmpRequest = SmpRequest::new(0); #[used]
#[link_section = ".requests"]
pub static mut SMP_REQUEST: SmpRequest = SmpRequest::new();
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -33,7 +38,9 @@ pub struct SDT<'a, T> {
impl<'a, T> SDT<'a, T> { impl<'a, T> SDT<'a, T> {
unsafe fn new(mut ptr: *const u8) -> Self { unsafe fn new(mut ptr: *const u8) -> Self {
if (ptr as usize) < *HHDM_OFFSET {
ptr = ptr.add(*HHDM_OFFSET); ptr = ptr.add(*HHDM_OFFSET);
}
let length = core::ptr::read_unaligned(ptr.add(4).cast::<u32>()); let length = core::ptr::read_unaligned(ptr.add(4).cast::<u32>());
let data = core::slice::from_raw_parts(ptr, length as usize); let data = core::slice::from_raw_parts(ptr, length as usize);
@@ -121,12 +128,12 @@ impl<'a> RootSDT<'a> {
let root_ptr = match self { let root_ptr = match self {
RootSDT::RSDT(rsdt) => { RootSDT::RSDT(rsdt) => {
let ptrs = rsdt.inner.pointers as *const u8; let ptrs = (rsdt.inner.pointers as usize).add(*HHDM_OFFSET) as *const u8;
assert!(!ptrs.is_null()); assert!(!ptrs.is_null());
ptrs.add(offset) ptrs.add(offset)
} }
RootSDT::XSDT(xsdt) => { RootSDT::XSDT(xsdt) => {
let ptrs = xsdt.inner.pointers as *const u8; let ptrs = (xsdt.inner.pointers as usize).add(*HHDM_OFFSET) as *const u8;
assert!(!ptrs.is_null()); assert!(!ptrs.is_null());
ptrs.add(offset) ptrs.add(offset)
} }
@@ -149,22 +156,22 @@ struct ACPI<'a> {
static ACPI: OnceCell<ACPI> = OnceCell::new(); static ACPI: OnceCell<ACPI> = OnceCell::new();
static RSDP_REQ: limine::RsdpRequest = limine::RsdpRequest::new(0); static RSDP_REQ: RsdpRequest = RsdpRequest::new();
fn resolve_acpi() { fn resolve_acpi() {
let rsdp_ptr = RSDP_REQ.get_response().get(); let rsdp_ptr = RSDP_REQ.get_response();
if rsdp_ptr.is_none() { if rsdp_ptr.is_none() {
panic!("RSDP not found!"); panic!("RSDP not found!");
} }
let rsdp = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::<RSDP>() }; let rsdp = unsafe { &*rsdp_ptr.unwrap().address().cast::<RSDP>() };
// TODO: validate RSDT // TODO: validate RSDT
let root_sdt = { let root_sdt = {
if rsdp.revision == 0 { if rsdp.revision == 0 {
RootSDT::RSDT(unsafe { SDT::new(rsdp.rsdt_addr as *mut u8) }) RootSDT::RSDT(unsafe { SDT::new(rsdp.rsdt_addr as *mut u8) })
} else { } else {
let xsdt = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::<XSDP>() }; let xsdt = unsafe { &*rsdp_ptr.unwrap().address().cast::<XSDP>() };
RootSDT::XSDT(unsafe { SDT::new(xsdt.xsdt_addr as *mut u8) }) RootSDT::XSDT(unsafe { SDT::new(xsdt.xsdt_addr as *mut u8) })
} }
}; };
@@ -256,6 +263,7 @@ struct FADT {
x_gpe1_block: GenericAddressStructure, x_gpe1_block: GenericAddressStructure,
} }
#[no_mangle]
pub fn init_acpi() { pub fn init_acpi() {
resolve_acpi(); resolve_acpi();

View File

@@ -39,20 +39,20 @@ enum FatType {
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct BIOSParameterBlock { pub struct BIOSParameterBlock {
_jmp_instruction: [u8; 3], // EB 58 90 _jmp_instruction: [u8; 3],
pub oem_identifier: [u8; 8], // MTOO4043 (hey, mtools) pub oem_identifier: [u8; 8],
pub bytes_per_sector: u16, // 00 02 (little endian so 512) pub bytes_per_sector: u16,
pub sectors_per_cluster: u8, // 01 pub sectors_per_cluster: u8,
pub reserved_sectors: u16, // 20 00 (32) pub reserved_sectors: u16,
pub fat_count: u8, // 02 pub fat_count: u8,
pub root_directory_count: u16, // 00 00 (what) pub root_directory_count: u16,
pub total_sectors: u16, // equal to zero when sector count is more than 65535 pub total_sectors: u16,
pub media_descriptor_type: u8, // F0 pub media_descriptor_type: u8,
pub sectors_per_fat: u16, // Fat12/Fat16 only pub sectors_per_fat: u16,
pub sectors_per_track: u16, // 3F 00 (63) pub sectors_per_track: u16,
pub head_count: u16, // 10 00 (16) pub head_count: u16,
pub hidden_sectors: u32, // 00 00 00 00 pub hidden_sectors: u32,
pub large_sector_count: u32, // 00 F8 01 00 (129024) pub large_sector_count: u32,
pub ebpb_bytes: [u8; 54], pub ebpb_bytes: [u8; 54],
} }
@@ -71,19 +71,19 @@ pub struct Fat16EBPB {
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Fat32EBPB { pub struct Fat32EBPB {
pub sectors_per_fat_ext: u32, // E1 03 00 00 (993, wtf) pub sectors_per_fat_ext: u32,
pub flags: [u8; 2], // 00 00 pub flags: [u8; 2],
pub fat_version: u16, // 00 00 pub fat_version: u16,
pub root_dir_cluster: u32, // 2C 00 00 00 (2) pub root_dir_cluster: u32,
pub fsinfo_sector: u16, // 01 00 (1) pub fsinfo_sector: u16,
pub backup_bootsector: u16, // 06 00 (6) pub backup_bootsector: u16,
_reserved: [u8; 12], // all zero _reserved: [u8; 12],
pub drive_number: u8, // 00 pub drive_number: u8,
_reserved2: u8, // 00 _reserved2: u8,
pub signature: u8, // either 0x28 of 0x29: 29 pub signature: u8,
pub volume_id: u32, // Varies pub volume_id: u32,
pub volume_label: [u8; 11], // "NO NAME " pub volume_label: [u8; 11],
pub system_identifier_string: [u8; 8], // Always "FAT32 " but never trust the contents of this string (for some reason) pub system_identifier_string: [u8; 8],
} }
#[repr(C, packed)] #[repr(C, packed)]
@@ -358,31 +358,29 @@ impl FatFs {
} }
} }
if name.replacen('.', "", 1).len() <= 11 { let raw_short_filename = core::str::from_utf8(&file_entry.file_name)
let search_parts: Vec<&str> = name.split('.').collect(); .unwrap()
.trim_end();
let raw_short_extension = core::str::from_utf8(&file_entry.extension)
.unwrap()
.trim_end();
let formatted_short_filename = match raw_short_extension.is_empty() {
true => raw_short_filename.to_string(),
false => alloc::format!("{}.{}", raw_short_filename, raw_short_extension),
};
let filename = core::str::from_utf8(&file_entry.file_name).unwrap(); if let Some(ref filename) = long_filename_string {
let extension = core::str::from_utf8(&file_entry.extension).unwrap(); if filename != name {
if (search_parts.len() == 1
&& !filename.contains(&search_parts[0].to_ascii_uppercase()))
|| (search_parts.len() > 1
&& (!filename.contains(&search_parts[0].to_ascii_uppercase())
|| !extension.contains(&search_parts[1].to_ascii_uppercase())))
{
continue; continue;
} }
return Ok(file_entry);
} else { } else {
// Long file name if name.to_uppercase() != formatted_short_filename {
if long_filename_string != Some(name.to_string()) {
continue; continue;
} }
}
return Ok(file_entry); return Ok(file_entry);
} }
}
return Err(()); return Err(());
} }
@@ -533,9 +531,7 @@ impl FsOps for FatFs {
), ),
}; };
let file = File::Dir(FatDirectory { let file = File::Dir(root_cluster);
directory_cluster: root_cluster,
});
return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp); return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp);
} }
@@ -562,8 +558,9 @@ impl FsOps for FatFs {
} }
enum File { enum File {
Archive(FatFile), Archive(FileEntry),
Dir(FatDirectory), // directory cluster
Dir(usize),
} }
impl VNodeOperations for File { impl VNodeOperations for File {
@@ -585,8 +582,8 @@ impl VNodeOperations for File {
let mut file: Vec<u8> = Vec::with_capacity(count); let mut file: Vec<u8> = Vec::with_capacity(count);
let mut cluster = ((archive.file_entry.high_first_cluster_number as u32) << 16) let mut cluster = ((archive.high_first_cluster_number as u32) << 16)
| archive.file_entry.low_first_cluster_number as u32; | archive.low_first_cluster_number as u32;
let cluster_size = unsafe { (*fat_fs).cluster_size }; let cluster_size = unsafe { (*fat_fs).cluster_size };
@@ -685,8 +682,7 @@ impl VNodeOperations for File {
match self { match self {
File::Dir(directory) => unsafe { File::Dir(directory) => unsafe {
let file_entry = let file_entry = (*fat_fs).find_entry_in_directory(*directory, nm)?;
(*fat_fs).find_entry_in_directory(directory.directory_cluster, nm)?;
let file_typ = if file_entry.attributes == FileEntryAttributes::Directory as u8 { let file_typ = if file_entry.attributes == FileEntryAttributes::Directory as u8 {
crate::drivers::fs::vfs::VNodeType::Directory crate::drivers::fs::vfs::VNodeType::Directory
@@ -695,11 +691,9 @@ impl VNodeOperations for File {
}; };
let file = if file_entry.attributes == FileEntryAttributes::Directory as u8 { let file = if file_entry.attributes == FileEntryAttributes::Directory as u8 {
File::Dir(FatDirectory { File::Dir(file_entry.cluster() as usize)
directory_cluster: file_entry.cluster() as usize,
})
} else { } else {
File::Archive(FatFile { file_entry }) File::Archive(file_entry)
}; };
let vnode = VNode::new(Box::new(file), file_typ, (*vp.as_ptr()).parent_vfs); let vnode = VNode::new(Box::new(file), file_typ, (*vp.as_ptr()).parent_vfs);
@@ -788,16 +782,8 @@ impl VNodeOperations for File {
fn len(&self, _vp: NonNull<VNode>) -> usize { fn len(&self, _vp: NonNull<VNode>) -> usize {
match self { match self {
File::Archive(archive) => archive.file_entry.file_size as usize, File::Archive(archive) => archive.file_size as usize,
_ => panic!("idk"), _ => panic!("idk"),
} }
} }
} }
struct FatFile {
file_entry: FileEntry,
}
struct FatDirectory {
directory_cluster: usize,
}

View File

@@ -64,7 +64,10 @@ pub struct ChunkReader<'a, F> {
decompressor: F, decompressor: F,
} }
impl<'a, F: Fn(&[u8]) -> Result<Vec<u8>, ()>> ChunkReader<'a, F> { impl<'a, F> ChunkReader<'a, F>
where
F: Fn(&[u8]) -> Result<Vec<u8>, ()>,
{
pub fn new(data: &'a [u8], decompressor: F) -> Self { pub fn new(data: &'a [u8], decompressor: F) -> Self {
let mut chunks: Vec<Chunk<'_>> = Vec::new(); let mut chunks: Vec<Chunk<'_>> = Vec::new();

View File

@@ -4,30 +4,32 @@ mod superblock;
use core::{fmt::Debug, mem::MaybeUninit, ptr::NonNull}; use core::{fmt::Debug, mem::MaybeUninit, ptr::NonNull};
use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
use limine::ModuleRequest; use limine::request::ModuleRequest;
use super::vfs::{FsOps, VNode, VNodeOperations, VNodeType}; use super::vfs::{FsOps, VNode, VNodeOperations, VNodeType};
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new(0); #[used]
#[link_section = ".requests"]
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new();
pub fn init() -> Squashfs<'static> { pub fn init() -> Squashfs<'static> {
// TODO: Put the module request stuff in another file? // TODO: Put the module request stuff in another file?
if MODULE_REQUEST.get_response().get().is_none() { if MODULE_REQUEST.get_response().is_none() {
panic!("Module request in none!"); panic!("Module request in none!");
} }
let module_response = MODULE_REQUEST.get_response().get().unwrap(); let module_response = MODULE_REQUEST.get_response().unwrap();
let mut initramfs = None; let mut initramfs = None;
let module_name = "initramfs.img"; let module_name = "initramfs.img";
for module in module_response.modules() { for module in module_response.modules() {
let c_path = module.path.to_str(); let path = core::str::from_utf8(module.path());
if c_path.is_none() { if path.is_err() {
continue; continue;
} }
if !c_path.unwrap().to_str().unwrap().contains(module_name) { if !path.unwrap().contains(module_name) {
continue; continue;
} }
@@ -40,7 +42,7 @@ pub fn init() -> Squashfs<'static> {
} }
let initramfs = initramfs.unwrap(); let initramfs = initramfs.unwrap();
let squashfs = Squashfs::new(initramfs.base.as_ptr().unwrap()); let squashfs = Squashfs::new(initramfs.addr());
if squashfs.is_err() { if squashfs.is_err() {
panic!("Initramfs in corrupt!"); panic!("Initramfs in corrupt!");
@@ -173,6 +175,7 @@ impl Squashfs<'_> {
}); });
} }
#[inline(always)]
fn get_inode_block_offset(&self, inode: u64) -> (u64, u16) { fn get_inode_block_offset(&self, inode: u64) -> (u64, u16) {
let inode_block = (inode >> 16) & 0x0000FFFFFFFFFFFF; let inode_block = (inode >> 16) & 0x0000FFFFFFFFFFFF;
let inode_offset = (inode & 0xFFFF) as u16; let inode_offset = (inode & 0xFFFF) as u16;

View File

@@ -632,6 +632,22 @@ pub trait VNodeOperations {
// fn strategy(&mut self, bp: (), vp: NonNull<VNode>); // fn strategy(&mut self, bp: (), vp: NonNull<VNode>);
// fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>; // fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
fn len(&self, vp: NonNull<VNode>) -> usize; fn len(&self, vp: NonNull<VNode>) -> usize;
// TODO: not object safe
// fn get_fs<'a, T>(&self, vp: NonNull<VNode>) -> &'a mut T
// where
// T: FsOps,
// {
// unsafe {
// let vfs = (*vp.as_ptr()).parent_vfs.as_mut();
// let fs = vfs
// .fs
// .as_mut()
// .expect("Tried to call get_fs on root VFS")
// .as_mut() as *mut dyn FsOps;
// &mut *fs.cast::<T>()
// }
// }
} }
#[allow(unused)] #[allow(unused)]
@@ -667,7 +683,10 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
return Err(()); return Err(());
} }
unsafe { NODE_TREE = Some(TreeNode::new(vfs.fs.as_mut().unwrap().as_mut().root(vfsp))) } crate::println!("reading the root");
let root = vfs.fs.as_mut().unwrap().as_mut().root(vfsp);
crate::println!("successfully read the root");
unsafe { NODE_TREE = Some(TreeNode::new(root)) }
} else { } else {
if unsafe { ROOT_VFS.next.is_none() } { if unsafe { ROOT_VFS.next.is_none() } {
return Err(()); return Err(());

View File

@@ -30,8 +30,14 @@ pub extern "x86-interrupt" fn keyboard_interrupt_handler() {
let key = parse_key(scancode); let key = parse_key(scancode);
if let Some(key) = key { if let Some(key) = key {
if !key.pressed {
return;
}
if let Some(character) = key.character {
// crate::usr::shell::handle_key(key) // crate::usr::shell::handle_key(key)
write_serial(key.character.unwrap() as u8); write_serial(character as u8);
}
} }
} }

View File

@@ -1,4 +1,4 @@
use limine::FramebufferRequest; use limine::{framebuffer, request::FramebufferRequest};
use crate::libs::cell::OnceCell; use crate::libs::cell::OnceCell;
@@ -69,27 +69,28 @@ impl Framebuffer {
} }
} }
pub static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(0); #[used]
#[link_section = ".requests"]
pub static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
pub static FRAMEBUFFER: OnceCell<Option<Framebuffer>> = OnceCell::new(); pub static FRAMEBUFFER: OnceCell<Option<Framebuffer>> = OnceCell::new();
pub fn get_framebuffer() -> Option<Framebuffer> { pub fn get_framebuffer() -> Option<Framebuffer> {
*FRAMEBUFFER.get_or_set(|| { *FRAMEBUFFER.get_or_set(|| {
let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST.get_response()?;
.get_response() let framebuffer = framebuffer_response.framebuffers().next();
.get()?;
if framebuffer_response.framebuffer_count < 1 { if framebuffer.is_none() {
return None; return None;
} }
let framebuffer_response = &framebuffer_response.framebuffers()[0]; let framebuffer_response = framebuffer.as_ref().unwrap();
let framebuffer = Framebuffer::new( let framebuffer = Framebuffer::new(
framebuffer_response.bpp as usize, framebuffer_response.bpp() as usize,
framebuffer_response.pitch as usize, framebuffer_response.pitch() as usize,
framebuffer_response.address.as_ptr().unwrap(), framebuffer_response.addr(),
framebuffer_response.width as usize, framebuffer_response.width() as usize,
framebuffer_response.height as usize, framebuffer_response.height() as usize,
); );
return Some(framebuffer); return Some(framebuffer);

View File

@@ -1,7 +1,5 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::libs::sync::Mutex;
#[derive(Debug)] #[derive(Debug)]
#[repr(u8)] #[repr(u8)]
enum ZlibCompressionLevel { enum ZlibCompressionLevel {
@@ -109,15 +107,6 @@ struct Huff {
symbols: [u16; 288], symbols: [u16; 288],
} }
static FIXED_LENGTHS: Mutex<Huff> = Mutex::new(Huff {
counts: [0_u16; 16],
symbols: [0_u16; 288],
});
static FIXED_DISTS: Mutex<Huff> = Mutex::new(Huff {
counts: [0_u16; 16],
symbols: [0_u16; 288],
});
struct HuffRing { struct HuffRing {
pointer: usize, pointer: usize,
data: Vec<u8>, data: Vec<u8>,
@@ -183,7 +172,16 @@ impl InflateContext {
} }
pub fn decompress(&mut self) -> Result<Vec<u8>, ()> { pub fn decompress(&mut self) -> Result<Vec<u8>, ()> {
build_fixed(); let mut lengths = Huff {
counts: [0_u16; 16],
symbols: [0_u16; 288],
};
let mut dists = Huff {
counts: [0_u16; 16],
symbols: [0_u16; 288],
};
build_fixed(&mut lengths, &mut dists);
loop { loop {
let is_final = self.get_bit(); let is_final = self.get_bit();
@@ -194,7 +192,7 @@ impl InflateContext {
self.uncompressed()?; self.uncompressed()?;
} }
0x01 => { 0x01 => {
self.inflate(&mut FIXED_LENGTHS.lock(), &mut FIXED_DISTS.lock())?; self.inflate(&mut lengths, &mut dists)?;
} }
0x02 => { 0x02 => {
self.decode_huffman()?; self.decode_huffman()?;
@@ -418,7 +416,7 @@ fn build_huffman(lengths: &[u8], size: usize, out: &mut Huff) {
} }
} }
fn build_fixed() { fn build_fixed(out_length: &mut Huff, out_dist: &mut Huff) {
let mut lengths = [0_u8; 288]; let mut lengths = [0_u8; 288];
lengths[0..144].fill(8); lengths[0..144].fill(8);
@@ -426,9 +424,9 @@ fn build_fixed() {
lengths[256..280].fill(7); lengths[256..280].fill(7);
lengths[280..288].fill(8); lengths[280..288].fill(8);
build_huffman(&lengths, 288, &mut FIXED_LENGTHS.lock()); build_huffman(&lengths, 288, out_length);
lengths[0..30].fill(5); lengths[0..30].fill(5);
build_huffman(&lengths, 30, &mut FIXED_DISTS.lock()); build_huffman(&lengths, 30, out_dist);
} }

View File

@@ -27,6 +27,7 @@ impl<T> Mutex<T> {
.is_err() .is_err()
{ {
// spin lock // spin lock
core::hint::spin_loop()
} }
return MutexGuard { mutex: self }; return MutexGuard { mutex: self };
} }

View File

@@ -1,18 +1,11 @@
#![feature( #![feature(abi_x86_interrupt, naked_functions, negative_impls)]
allocator_api,
abi_x86_interrupt,
naked_functions,
const_mut_refs,
negative_impls
)]
#![allow(clippy::needless_return)] #![allow(clippy::needless_return)]
#![no_std] #![no_std]
#![no_main] #![no_main]
use core::ffi::CStr;
use alloc::vec::Vec; use alloc::vec::Vec;
use limine::KernelFileRequest; use limine::{request::KernelFileRequest, BaseRevision};
use mem::HHDM_OFFSET;
use crate::drivers::fs::{ use crate::drivers::fs::{
initramfs, initramfs,
@@ -26,7 +19,15 @@ pub mod drivers;
pub mod libs; pub mod libs;
pub mod mem; pub mod mem;
pub static KERNEL_REQUEST: KernelFileRequest = KernelFileRequest::new(0); // Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
#[used]
// The .requests section allows limine to find the requests faster and more safely.
#[link_section = ".requests"]
static BASE_REVISION: BaseRevision = BaseRevision::new();
#[used]
#[link_section = ".requests"]
pub static KERNEL_REQUEST: KernelFileRequest = KernelFileRequest::new();
#[no_mangle] #[no_mangle]
pub extern "C" fn _start() -> ! { pub extern "C" fn _start() -> ! {
@@ -65,7 +66,7 @@ pub fn kmain() -> ! {
crate::println!( crate::println!(
"LIMINE BOOT: {:X?}", "LIMINE BOOT: {:X?}",
limine_dir limine_dir
.lookup("limine.cfg") .lookup("limine.conf")
.unwrap() .unwrap()
.open(0, UserCred { uid: 0, gid: 0 }) .open(0, UserCred { uid: 0, gid: 0 })
.read(0, 0, 0) .read(0, 0, 0)
@@ -82,7 +83,7 @@ pub fn kmain() -> ! {
.unwrap() .unwrap()
.lookup("limine") .lookup("limine")
.unwrap() .unwrap()
.lookup("limine.cfg") .lookup("limine.conf")
.unwrap() .unwrap()
.open(0, UserCred { uid: 0, gid: 0 }) .open(0, UserCred { uid: 0, gid: 0 })
.read(0, 10, 0) .read(0, 10, 0)
@@ -95,7 +96,7 @@ pub fn kmain() -> ! {
crate::println!( crate::println!(
"LIMINE BOOT: {:X?}", "LIMINE BOOT: {:X?}",
limine_dir limine_dir
.lookup("limine.cfg") .lookup("limine.conf")
.unwrap() .unwrap()
.open(0, UserCred { uid: 0, gid: 0 }) .open(0, UserCred { uid: 0, gid: 0 })
.read(0, 0, 0) .read(0, 0, 0)
@@ -132,20 +133,14 @@ fn draw_gradient() {
let length = (fb.height * fb.width) * (fb.bpp / 8); let length = (fb.height * fb.width) * (fb.bpp / 8);
let pages = length / crate::mem::pmm::PAGE_SIZE; let pages = length / crate::mem::pmm::PAGE_SIZE;
let buffer_ptr = crate::mem::PHYSICAL_MEMORY_MANAGER.alloc(pages); let buffer_ptr =
(crate::mem::PHYSICAL_MEMORY_MANAGER.alloc(pages) as usize + *HHDM_OFFSET) as *mut u8;
if buffer_ptr.is_null() { if buffer_ptr.is_null() {
panic!("Failed to allocate screen buffer") panic!("Failed to allocate screen buffer")
} }
let buffer = unsafe { let buffer = unsafe { core::slice::from_raw_parts_mut(buffer_ptr.cast::<u32>(), length) };
core::slice::from_raw_parts_mut(
crate::mem::PHYSICAL_MEMORY_MANAGER
.alloc(pages)
.cast::<u32>(),
length,
)
};
for y in 0..fb.height { for y in 0..fb.height {
for x in 0..fb.width { for x in 0..fb.width {
@@ -160,7 +155,8 @@ fn draw_gradient() {
fb.blit_screen(buffer, None); fb.blit_screen(buffer, None);
crate::mem::PHYSICAL_MEMORY_MANAGER.dealloc(buffer_ptr, pages); crate::mem::PHYSICAL_MEMORY_MANAGER
.dealloc((buffer_ptr as usize - *HHDM_OFFSET) as *mut u8, pages);
} }
#[macro_export] #[macro_export]
@@ -219,31 +215,15 @@ pub static KERNEL_FEATURES: libs::cell::OnceCell<KernelFeatures> = libs::cell::O
fn parse_kernel_cmdline() { fn parse_kernel_cmdline() {
let mut kernel_features: KernelFeatures = KernelFeatures { fat_in_mem: true }; let mut kernel_features: KernelFeatures = KernelFeatures { fat_in_mem: true };
let kernel_file_response = KERNEL_REQUEST.get_response().get(); let kernel_file_response = KERNEL_REQUEST.get_response();
if kernel_file_response.is_none() { if kernel_file_response.is_none() {
KERNEL_FEATURES.set(kernel_features); KERNEL_FEATURES.set(kernel_features);
return; return;
} }
let cmdline_ptr = kernel_file_response let cmdline = core::str::from_utf8(kernel_file_response.unwrap().file().cmdline());
.unwrap()
.kernel_file
.get()
.unwrap()
.cmdline
.as_ptr();
if cmdline_ptr.is_none() { let kernel_arguments = cmdline.unwrap().split_whitespace().collect::<Vec<&str>>();
KERNEL_FEATURES.set(kernel_features);
return;
}
let cmdline = unsafe { CStr::from_ptr(cmdline_ptr.unwrap()) };
let kernel_arguments = cmdline
.to_str()
.unwrap()
.split_whitespace()
.collect::<Vec<&str>>();
crate::println!("{kernel_arguments:?}"); crate::println!("{kernel_arguments:?}");

View File

@@ -5,8 +5,14 @@ use crate::libs::{cell::OnceCell, sync::Mutex};
use self::{allocator::LinkedListAllocator, pmm::PhysicalMemoryManager}; use self::{allocator::LinkedListAllocator, pmm::PhysicalMemoryManager};
static MEMMAP_REQUEST: limine::MemmapRequest = limine::MemmapRequest::new(0); #[used]
static HHDM_REQUEST: limine::HhdmRequest = limine::HhdmRequest::new(0); #[link_section = ".requests"]
static mut MEMMAP_REQUEST: limine::request::MemoryMapRequest =
limine::request::MemoryMapRequest::new();
#[used]
#[link_section = ".requests"]
static HHDM_REQUEST: limine::request::HhdmRequest = limine::request::HhdmRequest::new();
pub static HHDM_OFFSET: OnceCell<usize> = OnceCell::new(); pub static HHDM_OFFSET: OnceCell<usize> = OnceCell::new();
pub static PHYSICAL_MEMORY_MANAGER: OnceCell<PhysicalMemoryManager> = OnceCell::new(); pub static PHYSICAL_MEMORY_MANAGER: OnceCell<PhysicalMemoryManager> = OnceCell::new();
@@ -21,26 +27,27 @@ const HEAP_PAGES: usize = 1024; // 4 MiB heap
#[global_allocator] #[global_allocator]
pub static ALLOCATOR: Mutex<LinkedListAllocator> = Mutex::new(LinkedListAllocator::new()); pub static ALLOCATOR: Mutex<LinkedListAllocator> = Mutex::new(LinkedListAllocator::new());
pub fn log_memory_map() { // TODO: Limine-rs 0.2.0 does NOT have debug implemented for a lot of it's types, so until that is fixed, either go without Type, or hack limine-rs locally
let memmap_request = MEMMAP_REQUEST.get_response().get_mut(); // pub fn log_memory_map() {
if memmap_request.is_none() { // let memmap_request = unsafe { MEMMAP_REQUEST.get_response_mut() };
panic!("Memory map was None!"); // if memmap_request.is_none() {
} // panic!("Memory map was None!");
// }
let memmap = memmap_request.unwrap().memmap(); // let memmap = memmap_request.unwrap().entries();
crate::log_serial!("====== MEMORY MAP ======\n"); // crate::log_serial!("====== MEMORY MAP ======\n");
for entry in memmap.iter() { // for entry in memmap.iter() {
let label = (entry.len as usize).label_bytes(); // let label = (entry.length as usize).label_bytes();
crate::log_serial!( // crate::log_serial!(
"[ {:#018X?} ] Type: {:?} Size: {}\n", // "[ {:#018X?} ] Type: {:?} Size: {}\n",
entry.base..entry.base + entry.len, // entry.base..entry.base + entry.length,
entry.typ, // entry.entry_type,
label // label
) // )
} // }
} // }
pub fn init_allocator() { pub fn init_allocator() {
let mut allocator_lock = ALLOCATOR.lock(); let mut allocator_lock = ALLOCATOR.lock();
@@ -51,7 +58,9 @@ pub fn init_allocator() {
crate::println!( crate::println!(
"{} of memory available", "{} of memory available",
PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes() PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes()
) );
// log_memory_map();
} }
pub enum Label { pub enum Label {

View File

@@ -31,27 +31,27 @@ impl PhysicalMemoryManager {
let hhdm_req = HHDM_REQUEST let hhdm_req = HHDM_REQUEST
.get_response() .get_response()
.get()
.expect("Failed to get Higher Half Direct Map!"); .expect("Failed to get Higher Half Direct Map!");
let hhdm_offset = hhdm_req.offset as usize; let hhdm_offset = hhdm_req.offset() as usize;
HHDM_OFFSET.set(hhdm_offset); HHDM_OFFSET.set(hhdm_offset);
let memmap = MEMMAP_REQUEST let memmap = unsafe {
.get_response() MEMMAP_REQUEST
.get_mut() .get_response_mut()
.expect("Failed to get Memory map!") .expect("Failed to get Memory map!")
.memmap_mut(); .entries_mut()
};
let mut highest_addr: usize = 0; let mut highest_addr: usize = 0;
for entry in memmap.iter() { for entry in memmap.iter() {
if entry.typ == limine::MemoryMapEntryType::Usable { if entry.entry_type == limine::memory_map::EntryType::USABLE {
pmm.usable_pages pmm.usable_pages
.fetch_add(entry.len as usize / PAGE_SIZE, Ordering::SeqCst); .fetch_add(entry.length as usize / PAGE_SIZE, Ordering::SeqCst);
if highest_addr < (entry.base + entry.len) as usize { if highest_addr < (entry.base + entry.length) as usize {
highest_addr = (entry.base + entry.len) as usize; highest_addr = (entry.base + entry.length) as usize;
} }
} }
} }
@@ -62,11 +62,11 @@ impl PhysicalMemoryManager {
((pmm.highest_page_idx.load(Ordering::SeqCst) / 8) + PAGE_SIZE - 1) & !(PAGE_SIZE - 1); ((pmm.highest_page_idx.load(Ordering::SeqCst) / 8) + PAGE_SIZE - 1) & !(PAGE_SIZE - 1);
for entry in memmap.iter_mut() { for entry in memmap.iter_mut() {
if entry.typ != limine::MemoryMapEntryType::Usable { if entry.entry_type != limine::memory_map::EntryType::USABLE {
continue; continue;
} }
if entry.len as usize >= bitmap_size { if entry.length as usize >= bitmap_size {
let ptr = (entry.base as usize + hhdm_offset) as *mut u8; let ptr = (entry.base as usize + hhdm_offset) as *mut u8;
pmm.bitmap.store(ptr, Ordering::SeqCst); pmm.bitmap.store(ptr, Ordering::SeqCst);
@@ -75,7 +75,7 @@ impl PhysicalMemoryManager {
core::ptr::write_bytes(ptr, 0xFF, bitmap_size); core::ptr::write_bytes(ptr, 0xFF, bitmap_size);
}; };
entry.len -= bitmap_size as u64; entry.length -= bitmap_size as u64;
entry.base += bitmap_size as u64; entry.base += bitmap_size as u64;
break; break;
@@ -83,11 +83,11 @@ impl PhysicalMemoryManager {
} }
for entry in memmap.iter() { for entry in memmap.iter() {
if entry.typ != limine::MemoryMapEntryType::Usable { if entry.entry_type != limine::memory_map::EntryType::USABLE {
continue; continue;
} }
for i in 0..(entry.len as usize / PAGE_SIZE) { for i in 0..(entry.length as usize / PAGE_SIZE) {
pmm.bitmap_reset((entry.base as usize + (i * PAGE_SIZE)) / PAGE_SIZE); pmm.bitmap_reset((entry.base as usize + (i * PAGE_SIZE)) / PAGE_SIZE);
} }
} }
@@ -147,7 +147,7 @@ impl PhysicalMemoryManager {
} }
unsafe { unsafe {
core::ptr::write_bytes(ret, 0x00, pages * PAGE_SIZE); core::ptr::write_bytes(ret.add(*HHDM_OFFSET), 0x00, pages * PAGE_SIZE);
}; };
return ret; return ret;