diff --git a/Cargo.lock b/Cargo.lock index ed2ef17..04846d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,16 @@ dependencies = [ ] [[package]] -name = "limine" -version = "0.1.11" +name = "bitflags" +version = "2.6.0" 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", +] diff --git a/Cargo.toml b/Cargo.toml index fa6078a..400da10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -limine = "0.1.10" +limine = "0.2.0" [profile.release] opt-level = 3 diff --git a/Makefile b/Makefile index 39a0423..a8b4dbd 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ IMAGE_PATH = ${ARTIFACTS_PATH}/${IMAGE_NAME} CARGO_OPTS = --target=src/arch/${ARCH}/${ARCH}-unknown-none.json QEMU_OPTS += -m ${MEMORY} -drive id=hd0,format=raw,file=${IMAGE_PATH} LIMINE_BOOT_VARIATION = X64 -LIMINE_BRANCH = v7.x-binary +LIMINE_BRANCH = v8.x-binary ifeq (${MODE},release) CARGO_OPTS += --release @@ -108,7 +108,7 @@ copy-iso-files: 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/ # OS files diff --git a/README.md b/README.md index d1dd868..c8446b6 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Before building CappuccinOS, make sure you have the following installed on your - rust - python - sgdisk -- mtools +- dosfstools - squashfs-tools - qemu (optional) @@ -71,7 +71,7 @@ Install the dependencies:
Arch - sudo pacman -S gptfdisk mtools squashfs-tools python + sudo pacman -S gptfdisk dosfstools squashfs-tools python # Optionally sudo pacman -S qemu-system-x86 @@ -81,7 +81,7 @@ Install the dependencies: Ubuntu 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 sudo apt install qemu diff --git a/limine.cfg b/limine.cfg deleted file mode 100644 index 37bfe9c..0000000 --- a/limine.cfg +++ /dev/null @@ -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 diff --git a/src/arch/aarch64/linker.ld b/src/arch/aarch64/linker.ld index f8dd817..a4c230a 100644 --- a/src/arch/aarch64/linker.ld +++ b/src/arch/aarch64/linker.ld @@ -6,42 +6,52 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) /* 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 { - 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 */ + headers PT_PHDR PHDRS; + text PT_LOAD FILEHDR PHDRS; + rodata PT_LOAD; + data PT_LOAD; + dynamic PT_DYNAMIC; } 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. */ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ /* 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 /* Move to the next memory page for .rodata */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { *(.rodata .rodata.*) } :rodata /* Move to the next memory page for .data */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .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 - /* 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) } :data :dynamic @@ -55,9 +65,13 @@ SECTIONS *(COMMON) } :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/ : { - *(.eh_frame) + *(.eh_frame*) *(.note .note.*) + *(.interp) } } \ No newline at end of file diff --git a/src/arch/riscv64/linker.ld b/src/arch/riscv64/linker.ld index 9261578..105ac1b 100644 --- a/src/arch/riscv64/linker.ld +++ b/src/arch/riscv64/linker.ld @@ -6,43 +6,54 @@ OUTPUT_ARCH(riscv:rv64) ENTRY(_start) /* 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 { - 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 */ + headers PT_PHDR PHDRS; + text PT_LOAD FILEHDR PHDRS; + rodata PT_LOAD; + data PT_LOAD; + dynamic PT_DYNAMIC; } 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. */ /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ /* 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 /* Move to the next memory page for .rodata */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { *(.rodata .rodata.*) } :rodata /* Move to the next memory page for .data */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .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.*) } :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) } :data :dynamic @@ -57,9 +68,13 @@ SECTIONS *(COMMON) } :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/ : { - *(.eh_frame) + *(.eh_frame*) *(.note .note.*) + *(.interp) } } \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/apic.rs b/src/arch/x86_64/interrupts/apic.rs index a9a23a1..1d4fdad 100644 --- a/src/arch/x86_64/interrupts/apic.rs +++ b/src/arch/x86_64/interrupts/apic.rs @@ -66,8 +66,8 @@ pub struct APIC { pub cpus: Arc<[LAPIC]>, } -extern "C" fn test(info: *const limine::SmpInfo) -> ! { - crate::log_ok!("hey from CPU {:<02}", unsafe { (*info).processor_id }); +unsafe extern "C" fn test<'a>(cpu: &'a limine::smp::Cpu) -> ! { + crate::log_ok!("hey from CPU {:<02}", cpu.id); hcf(); } @@ -175,21 +175,21 @@ impl APIC { 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() { panic!("Failed to get smp from limine!"); } 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() { - if cpu.processor_id == bsp_lapic_id { + if cpu.id == bsp_lapic_id { continue; } - cpu.goto_address = test; + cpu.goto_address.write(test); } // Set and enable keyboard interrupt @@ -220,7 +220,7 @@ impl APIC { pub fn write_lapic(&self, reg: u32, value: u32) { unsafe { - *self.local_apic.add(reg as usize).cast::() = value; + core::ptr::write_volatile(self.local_apic.add(reg as usize).cast::(), value); } } diff --git a/src/arch/x86_64/interrupts/exceptions.rs b/src/arch/x86_64/interrupts/exceptions.rs index 5352498..6398e60 100644 --- a/src/arch/x86_64/interrupts/exceptions.rs +++ b/src/arch/x86_64/interrupts/exceptions.rs @@ -36,43 +36,43 @@ struct Registers { extern "C" fn exception_handler(registers: u64) { let registers = unsafe { *(registers as *const Registers) }; - crate::println!("{:X?}", registers); + // crate::println!("{:X?}", registers); let int = registers.int; match int { 0x00 => { - log_error!("DIVISION ERROR!"); + crate::drivers::serial::write_string("DIVISION ERROR!"); } 0x06 => { - log_error!("INVALID OPCODE!"); + crate::drivers::serial::write_string("INVALID OPCODE!"); } 0x08 => { - log_error!("DOUBLE FAULT!"); + crate::drivers::serial::write_string("DOUBLE FAULT!"); } 0x0D => { - log_error!("GENERAL PROTECTION FAULT!"); + crate::drivers::serial::write_string("GENERAL PROTECTION FAULT!"); } 0x0E => { - log_error!("PAGE FAULT!"); + crate::drivers::serial::write_string("PAGE FAULT!"); } 0xFF => { - log_error!("EXCEPTION!"); + crate::drivers::serial::write_string("EXCEPTION!"); } _ => { - log_error!("EXCEPTION!"); + crate::drivers::serial::write_string("EXCEPTION!"); } } - log_info!( - "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}", - int, - registers.rip, - registers.cs, - registers.rflags - ); + // log_info!( + // "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}", + // int, + // registers.rip, + // registers.cs, + // 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* diff --git a/src/arch/x86_64/interrupts/mod.rs b/src/arch/x86_64/interrupts/mod.rs index 5408885..58fbd52 100755 --- a/src/arch/x86_64/interrupts/mod.rs +++ b/src/arch/x86_64/interrupts/mod.rs @@ -1,11 +1,6 @@ pub mod apic; pub mod exceptions; -use crate::{ - // arch::{apic, x86_common::pic::ChainedPics}, - libs::sync::Mutex, -}; - use self::apic::APIC; #[repr(C, packed)] @@ -34,13 +29,15 @@ impl IdtEntry { } } +impl !Sync for IdtEntry {} + #[repr(C, packed)] struct IdtPtr { limit: u16, base: u64, } -static IDT: Mutex<[IdtEntry; 256]> = Mutex::new([IdtEntry::new(); 256]); +static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256]; #[derive(Clone, Copy)] #[repr(u8)] @@ -62,15 +59,17 @@ static mut IDT_PTR: IdtPtr = IdtPtr { pub fn idt_set_gate(num: u8, function_ptr: usize) { let base = function_ptr; - IDT.lock()[num as usize] = IdtEntry { - base_lo: (base & 0xFFFF) as u16, - base_mid: ((base >> 16) & 0xFFFF) as u16, - base_hi: ((base >> 32) & 0xFFFFFFFF) as u32, - sel: 0x28, - ist: 0, - always0: 0, - flags: 0xEE, - }; + unsafe { + IDT[num as usize] = IdtEntry { + base_lo: (base & 0xFFFF) as u16, + base_mid: ((base >> 16) & 0xFFFF) as u16, + base_hi: ((base >> 32) & 0xFFFFFFFF) as u32, + sel: 0x28, + ist: 0, + always0: 0, + flags: 0xEE, + }; + } // 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 @@ -83,31 +82,18 @@ extern "x86-interrupt" fn null_interrupt_handler() { signal_end_of_interrupt(); } -extern "x86-interrupt" fn timer_handler() { - // crate::usr::tty::puts("."); - signal_end_of_interrupt(); -} - pub fn idt_init() { unsafe { let idt_size = core::mem::size_of::() * 256; - { - let mut idt_lock = IDT.lock(); - IDT_PTR.base = idt_lock.as_ptr() as u64; + IDT_PTR.base = IDT.as_ptr() as u64; - core::ptr::write_bytes( - idt_lock.as_mut_ptr().cast::(), - 0, - idt_size, - ); - } + core::ptr::write_bytes(IDT.as_mut_ptr().cast::(), 0, idt_size); // Set every interrupt to the "null" interrupt handler (it does nothing) for num in 0..=255 { 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); core::arch::asm!( diff --git a/src/arch/x86_64/linker.ld b/src/arch/x86_64/linker.ld index f16abdb..6857755 100644 --- a/src/arch/x86_64/linker.ld +++ b/src/arch/x86_64/linker.ld @@ -6,58 +6,56 @@ OUTPUT_ARCH(i386:x86-64) ENTRY(_start) /* 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 { - 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 */ + headers PT_PHDR PHDRS; + text PT_LOAD FILEHDR PHDRS; + rodata PT_LOAD; + data PT_LOAD; + dynamic PT_DYNAMIC; } 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. */ /* 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); + /* Additionally, leave space for the ELF headers by adding SIZEOF_HEADERS to the */ + /* base load address. */ + . = 0xffffffff80000000 + SIZEOF_HEADERS; .text : { *(.text .text.*) } :text /* Move to the next memory page for .rodata */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { *(.rodata .rodata.*) } :rodata /* Move to the next memory page for .data */ - . += CONSTANT(MAXPAGESIZE); + . = ALIGN(CONSTANT(MAXPAGESIZE)); .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 - /* 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) } :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 */ @@ -67,9 +65,13 @@ SECTIONS *(COMMON) } :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/ : { - *(.eh_frame) + *(.eh_frame*) *(.note .note.*) + *(.interp) } -} +} \ No newline at end of file diff --git a/src/drivers/acpi.rs b/src/drivers/acpi.rs index 6d6b9a1..af415af 100644 --- a/src/drivers/acpi.rs +++ b/src/drivers/acpi.rs @@ -1,5 +1,8 @@ +use core::ops::Add; + use alloc::vec::Vec; -use limine::SmpRequest; +use limine::request::RsdpRequest; +use limine::request::SmpRequest; use crate::{ arch::io::{inw, outb}, @@ -7,7 +10,9 @@ use crate::{ 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)] #[derive(Clone, Copy, Debug)] @@ -33,7 +38,9 @@ pub struct SDT<'a, T> { impl<'a, T> SDT<'a, T> { unsafe fn new(mut ptr: *const u8) -> Self { - ptr = ptr.add(*HHDM_OFFSET); + if (ptr as usize) < *HHDM_OFFSET { + ptr = ptr.add(*HHDM_OFFSET); + } let length = core::ptr::read_unaligned(ptr.add(4).cast::()); let data = core::slice::from_raw_parts(ptr, length as usize); @@ -121,12 +128,12 @@ impl<'a> RootSDT<'a> { let root_ptr = match self { 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()); ptrs.add(offset) } 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()); ptrs.add(offset) } @@ -149,22 +156,22 @@ struct ACPI<'a> { static ACPI: OnceCell = OnceCell::new(); -static RSDP_REQ: limine::RsdpRequest = limine::RsdpRequest::new(0); +static RSDP_REQ: RsdpRequest = RsdpRequest::new(); fn resolve_acpi() { - let rsdp_ptr = RSDP_REQ.get_response().get(); + let rsdp_ptr = RSDP_REQ.get_response(); if rsdp_ptr.is_none() { panic!("RSDP not found!"); } - let rsdp = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::() }; + let rsdp = unsafe { &*rsdp_ptr.unwrap().address().cast::() }; // TODO: validate RSDT let root_sdt = { if rsdp.revision == 0 { RootSDT::RSDT(unsafe { SDT::new(rsdp.rsdt_addr as *mut u8) }) } else { - let xsdt = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::() }; + let xsdt = unsafe { &*rsdp_ptr.unwrap().address().cast::() }; RootSDT::XSDT(unsafe { SDT::new(xsdt.xsdt_addr as *mut u8) }) } }; @@ -256,6 +263,7 @@ struct FADT { x_gpe1_block: GenericAddressStructure, } +#[no_mangle] pub fn init_acpi() { resolve_acpi(); diff --git a/src/drivers/fs/fat.rs b/src/drivers/fs/fat.rs index cb99967..56b889e 100755 --- a/src/drivers/fs/fat.rs +++ b/src/drivers/fs/fat.rs @@ -39,20 +39,20 @@ enum FatType { #[repr(C, packed)] #[derive(Clone, Copy, Debug)] pub struct BIOSParameterBlock { - _jmp_instruction: [u8; 3], // EB 58 90 - pub oem_identifier: [u8; 8], // MTOO4043 (hey, mtools) - pub bytes_per_sector: u16, // 00 02 (little endian so 512) - pub sectors_per_cluster: u8, // 01 - pub reserved_sectors: u16, // 20 00 (32) - pub fat_count: u8, // 02 - pub root_directory_count: u16, // 00 00 (what) - pub total_sectors: u16, // equal to zero when sector count is more than 65535 - pub media_descriptor_type: u8, // F0 - pub sectors_per_fat: u16, // Fat12/Fat16 only - pub sectors_per_track: u16, // 3F 00 (63) - pub head_count: u16, // 10 00 (16) - pub hidden_sectors: u32, // 00 00 00 00 - pub large_sector_count: u32, // 00 F8 01 00 (129024) + _jmp_instruction: [u8; 3], + pub oem_identifier: [u8; 8], + pub bytes_per_sector: u16, + pub sectors_per_cluster: u8, + pub reserved_sectors: u16, + pub fat_count: u8, + pub root_directory_count: u16, + pub total_sectors: u16, + pub media_descriptor_type: u8, + pub sectors_per_fat: u16, + pub sectors_per_track: u16, + pub head_count: u16, + pub hidden_sectors: u32, + pub large_sector_count: u32, pub ebpb_bytes: [u8; 54], } @@ -71,19 +71,19 @@ pub struct Fat16EBPB { #[repr(C, packed)] #[derive(Clone, Copy, Debug)] pub struct Fat32EBPB { - pub sectors_per_fat_ext: u32, // E1 03 00 00 (993, wtf) - pub flags: [u8; 2], // 00 00 - pub fat_version: u16, // 00 00 - pub root_dir_cluster: u32, // 2C 00 00 00 (2) - pub fsinfo_sector: u16, // 01 00 (1) - pub backup_bootsector: u16, // 06 00 (6) - _reserved: [u8; 12], // all zero - pub drive_number: u8, // 00 - _reserved2: u8, // 00 - pub signature: u8, // either 0x28 of 0x29: 29 - pub volume_id: u32, // Varies - pub volume_label: [u8; 11], // "NO NAME " - pub system_identifier_string: [u8; 8], // Always "FAT32 " but never trust the contents of this string (for some reason) + pub sectors_per_fat_ext: u32, + pub flags: [u8; 2], + pub fat_version: u16, + pub root_dir_cluster: u32, + pub fsinfo_sector: u16, + pub backup_bootsector: u16, + _reserved: [u8; 12], + pub drive_number: u8, + _reserved2: u8, + pub signature: u8, + pub volume_id: u32, + pub volume_label: [u8; 11], + pub system_identifier_string: [u8; 8], } #[repr(C, packed)] @@ -358,30 +358,28 @@ impl FatFs { } } - if name.replacen('.', "", 1).len() <= 11 { - let search_parts: Vec<&str> = name.split('.').collect(); + let raw_short_filename = core::str::from_utf8(&file_entry.file_name) + .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(); - let extension = core::str::from_utf8(&file_entry.extension).unwrap(); - - 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()))) - { + if let Some(ref filename) = long_filename_string { + if filename != name { continue; } - - return Ok(file_entry); } else { - // Long file name - if long_filename_string != Some(name.to_string()) { + if name.to_uppercase() != formatted_short_filename { continue; } - - return Ok(file_entry); } + + return Ok(file_entry); } return Err(()); @@ -533,9 +531,7 @@ impl FsOps for FatFs { ), }; - let file = File::Dir(FatDirectory { - directory_cluster: root_cluster, - }); + let file = File::Dir(root_cluster); return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp); } @@ -562,8 +558,9 @@ impl FsOps for FatFs { } enum File { - Archive(FatFile), - Dir(FatDirectory), + Archive(FileEntry), + // directory cluster + Dir(usize), } impl VNodeOperations for File { @@ -585,8 +582,8 @@ impl VNodeOperations for File { let mut file: Vec = Vec::with_capacity(count); - let mut cluster = ((archive.file_entry.high_first_cluster_number as u32) << 16) - | archive.file_entry.low_first_cluster_number as u32; + let mut cluster = ((archive.high_first_cluster_number as u32) << 16) + | archive.low_first_cluster_number as u32; let cluster_size = unsafe { (*fat_fs).cluster_size }; @@ -685,8 +682,7 @@ impl VNodeOperations for File { match self { File::Dir(directory) => unsafe { - let file_entry = - (*fat_fs).find_entry_in_directory(directory.directory_cluster, nm)?; + let file_entry = (*fat_fs).find_entry_in_directory(*directory, nm)?; let file_typ = if file_entry.attributes == FileEntryAttributes::Directory as u8 { crate::drivers::fs::vfs::VNodeType::Directory @@ -695,11 +691,9 @@ impl VNodeOperations for File { }; let file = if file_entry.attributes == FileEntryAttributes::Directory as u8 { - File::Dir(FatDirectory { - directory_cluster: file_entry.cluster() as usize, - }) + File::Dir(file_entry.cluster() as usize) } else { - File::Archive(FatFile { file_entry }) + File::Archive(file_entry) }; 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) -> usize { match self { - File::Archive(archive) => archive.file_entry.file_size as usize, + File::Archive(archive) => archive.file_size as usize, _ => panic!("idk"), } } } - -struct FatFile { - file_entry: FileEntry, -} - -struct FatDirectory { - directory_cluster: usize, -} diff --git a/src/drivers/fs/initramfs/chunk_reader.rs b/src/drivers/fs/initramfs/chunk_reader.rs index 91ed4d8..072c2a5 100644 --- a/src/drivers/fs/initramfs/chunk_reader.rs +++ b/src/drivers/fs/initramfs/chunk_reader.rs @@ -64,7 +64,10 @@ pub struct ChunkReader<'a, F> { decompressor: F, } -impl<'a, F: Fn(&[u8]) -> Result, ()>> ChunkReader<'a, F> { +impl<'a, F> ChunkReader<'a, F> +where + F: Fn(&[u8]) -> Result, ()>, +{ pub fn new(data: &'a [u8], decompressor: F) -> Self { let mut chunks: Vec> = Vec::new(); diff --git a/src/drivers/fs/initramfs/mod.rs b/src/drivers/fs/initramfs/mod.rs index db18f85..0cee6a9 100755 --- a/src/drivers/fs/initramfs/mod.rs +++ b/src/drivers/fs/initramfs/mod.rs @@ -4,30 +4,32 @@ mod superblock; use core::{fmt::Debug, mem::MaybeUninit, ptr::NonNull}; use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; -use limine::ModuleRequest; +use limine::request::ModuleRequest; 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> { // 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!"); } - let module_response = MODULE_REQUEST.get_response().get().unwrap(); + let module_response = MODULE_REQUEST.get_response().unwrap(); let mut initramfs = None; let module_name = "initramfs.img"; for module in module_response.modules() { - let c_path = module.path.to_str(); - if c_path.is_none() { + let path = core::str::from_utf8(module.path()); + if path.is_err() { continue; } - if !c_path.unwrap().to_str().unwrap().contains(module_name) { + if !path.unwrap().contains(module_name) { continue; } @@ -40,7 +42,7 @@ pub fn init() -> Squashfs<'static> { } let initramfs = initramfs.unwrap(); - let squashfs = Squashfs::new(initramfs.base.as_ptr().unwrap()); + let squashfs = Squashfs::new(initramfs.addr()); if squashfs.is_err() { panic!("Initramfs in corrupt!"); @@ -173,6 +175,7 @@ impl Squashfs<'_> { }); } + #[inline(always)] fn get_inode_block_offset(&self, inode: u64) -> (u64, u16) { let inode_block = (inode >> 16) & 0x0000FFFFFFFFFFFF; let inode_offset = (inode & 0xFFFF) as u16; diff --git a/src/drivers/fs/vfs.rs b/src/drivers/fs/vfs.rs index 5db85b1..4e426d4 100755 --- a/src/drivers/fs/vfs.rs +++ b/src/drivers/fs/vfs.rs @@ -632,6 +632,22 @@ pub trait VNodeOperations { // fn strategy(&mut self, bp: (), vp: NonNull); // fn bread(&mut self, block_number: u32, vp: NonNull) -> Arc<[u8]>; fn len(&self, vp: NonNull) -> usize; + + // TODO: not object safe + // fn get_fs<'a, T>(&self, vp: NonNull) -> &'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::() + // } + // } } #[allow(unused)] @@ -667,7 +683,10 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box) -> Result<(), ()> { 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 { if unsafe { ROOT_VFS.next.is_none() } { return Err(()); diff --git a/src/drivers/keyboard.rs b/src/drivers/keyboard.rs index 06335b3..262fc68 100755 --- a/src/drivers/keyboard.rs +++ b/src/drivers/keyboard.rs @@ -30,8 +30,14 @@ pub extern "x86-interrupt" fn keyboard_interrupt_handler() { let key = parse_key(scancode); if let Some(key) = key { - // crate::usr::shell::handle_key(key) - write_serial(key.character.unwrap() as u8); + if !key.pressed { + return; + } + + if let Some(character) = key.character { + // crate::usr::shell::handle_key(key) + write_serial(character as u8); + } } } diff --git a/src/drivers/video.rs b/src/drivers/video.rs index 8877af6..1e15f06 100644 --- a/src/drivers/video.rs +++ b/src/drivers/video.rs @@ -1,4 +1,4 @@ -use limine::FramebufferRequest; +use limine::{framebuffer, request::FramebufferRequest}; 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> = OnceCell::new(); pub fn get_framebuffer() -> Option { *FRAMEBUFFER.get_or_set(|| { - let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST - .get_response() - .get()?; + let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST.get_response()?; + let framebuffer = framebuffer_response.framebuffers().next(); - if framebuffer_response.framebuffer_count < 1 { + if framebuffer.is_none() { return None; } - let framebuffer_response = &framebuffer_response.framebuffers()[0]; + let framebuffer_response = framebuffer.as_ref().unwrap(); let framebuffer = Framebuffer::new( - framebuffer_response.bpp as usize, - framebuffer_response.pitch as usize, - framebuffer_response.address.as_ptr().unwrap(), - framebuffer_response.width as usize, - framebuffer_response.height as usize, + framebuffer_response.bpp() as usize, + framebuffer_response.pitch() as usize, + framebuffer_response.addr(), + framebuffer_response.width() as usize, + framebuffer_response.height() as usize, ); return Some(framebuffer); diff --git a/src/libs/gzip.rs b/src/libs/gzip.rs index 8edaa96..f39cb26 100644 --- a/src/libs/gzip.rs +++ b/src/libs/gzip.rs @@ -1,7 +1,5 @@ use alloc::vec::Vec; -use crate::libs::sync::Mutex; - #[derive(Debug)] #[repr(u8)] enum ZlibCompressionLevel { @@ -109,15 +107,6 @@ struct Huff { symbols: [u16; 288], } -static FIXED_LENGTHS: Mutex = Mutex::new(Huff { - counts: [0_u16; 16], - symbols: [0_u16; 288], -}); -static FIXED_DISTS: Mutex = Mutex::new(Huff { - counts: [0_u16; 16], - symbols: [0_u16; 288], -}); - struct HuffRing { pointer: usize, data: Vec, @@ -183,7 +172,16 @@ impl InflateContext { } pub fn decompress(&mut self) -> Result, ()> { - 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 { let is_final = self.get_bit(); @@ -194,7 +192,7 @@ impl InflateContext { self.uncompressed()?; } 0x01 => { - self.inflate(&mut FIXED_LENGTHS.lock(), &mut FIXED_DISTS.lock())?; + self.inflate(&mut lengths, &mut dists)?; } 0x02 => { 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]; lengths[0..144].fill(8); @@ -426,9 +424,9 @@ fn build_fixed() { lengths[256..280].fill(7); lengths[280..288].fill(8); - build_huffman(&lengths, 288, &mut FIXED_LENGTHS.lock()); + build_huffman(&lengths, 288, out_length); lengths[0..30].fill(5); - build_huffman(&lengths, 30, &mut FIXED_DISTS.lock()); + build_huffman(&lengths, 30, out_dist); } diff --git a/src/libs/sync/mutex.rs b/src/libs/sync/mutex.rs index 5284b8d..8b9b26e 100755 --- a/src/libs/sync/mutex.rs +++ b/src/libs/sync/mutex.rs @@ -27,6 +27,7 @@ impl Mutex { .is_err() { // spin lock + core::hint::spin_loop() } return MutexGuard { mutex: self }; } diff --git a/src/main.rs b/src/main.rs index c4dd831..8020b4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,11 @@ -#![feature( - allocator_api, - abi_x86_interrupt, - naked_functions, - const_mut_refs, - negative_impls -)] +#![feature(abi_x86_interrupt, naked_functions, negative_impls)] #![allow(clippy::needless_return)] #![no_std] #![no_main] -use core::ffi::CStr; - use alloc::vec::Vec; -use limine::KernelFileRequest; +use limine::{request::KernelFileRequest, BaseRevision}; +use mem::HHDM_OFFSET; use crate::drivers::fs::{ initramfs, @@ -26,7 +19,15 @@ pub mod drivers; pub mod libs; 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] pub extern "C" fn _start() -> ! { @@ -65,7 +66,7 @@ pub fn kmain() -> ! { crate::println!( "LIMINE BOOT: {:X?}", limine_dir - .lookup("limine.cfg") + .lookup("limine.conf") .unwrap() .open(0, UserCred { uid: 0, gid: 0 }) .read(0, 0, 0) @@ -82,7 +83,7 @@ pub fn kmain() -> ! { .unwrap() .lookup("limine") .unwrap() - .lookup("limine.cfg") + .lookup("limine.conf") .unwrap() .open(0, UserCred { uid: 0, gid: 0 }) .read(0, 10, 0) @@ -95,7 +96,7 @@ pub fn kmain() -> ! { crate::println!( "LIMINE BOOT: {:X?}", limine_dir - .lookup("limine.cfg") + .lookup("limine.conf") .unwrap() .open(0, UserCred { uid: 0, gid: 0 }) .read(0, 0, 0) @@ -132,20 +133,14 @@ fn draw_gradient() { let length = (fb.height * fb.width) * (fb.bpp / 8); 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() { panic!("Failed to allocate screen buffer") } - let buffer = unsafe { - core::slice::from_raw_parts_mut( - crate::mem::PHYSICAL_MEMORY_MANAGER - .alloc(pages) - .cast::(), - length, - ) - }; + let buffer = unsafe { core::slice::from_raw_parts_mut(buffer_ptr.cast::(), length) }; for y in 0..fb.height { for x in 0..fb.width { @@ -160,7 +155,8 @@ fn draw_gradient() { 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] @@ -219,31 +215,15 @@ pub static KERNEL_FEATURES: libs::cell::OnceCell = libs::cell::O fn parse_kernel_cmdline() { 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() { KERNEL_FEATURES.set(kernel_features); return; } - let cmdline_ptr = kernel_file_response - .unwrap() - .kernel_file - .get() - .unwrap() - .cmdline - .as_ptr(); + let cmdline = core::str::from_utf8(kernel_file_response.unwrap().file().cmdline()); - if cmdline_ptr.is_none() { - 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::>(); + let kernel_arguments = cmdline.unwrap().split_whitespace().collect::>(); crate::println!("{kernel_arguments:?}"); diff --git a/src/mem/mod.rs b/src/mem/mod.rs index 5b7edd6..57f7d80 100755 --- a/src/mem/mod.rs +++ b/src/mem/mod.rs @@ -5,8 +5,14 @@ use crate::libs::{cell::OnceCell, sync::Mutex}; use self::{allocator::LinkedListAllocator, pmm::PhysicalMemoryManager}; -static MEMMAP_REQUEST: limine::MemmapRequest = limine::MemmapRequest::new(0); -static HHDM_REQUEST: limine::HhdmRequest = limine::HhdmRequest::new(0); +#[used] +#[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 = OnceCell::new(); pub static PHYSICAL_MEMORY_MANAGER: OnceCell = OnceCell::new(); @@ -21,26 +27,27 @@ const HEAP_PAGES: usize = 1024; // 4 MiB heap #[global_allocator] pub static ALLOCATOR: Mutex = Mutex::new(LinkedListAllocator::new()); -pub fn log_memory_map() { - let memmap_request = MEMMAP_REQUEST.get_response().get_mut(); - if memmap_request.is_none() { - panic!("Memory map was None!"); - } +// 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 +// pub fn log_memory_map() { +// let memmap_request = unsafe { MEMMAP_REQUEST.get_response_mut() }; +// 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"); - for entry in memmap.iter() { - let label = (entry.len as usize).label_bytes(); +// crate::log_serial!("====== MEMORY MAP ======\n"); +// for entry in memmap.iter() { +// let label = (entry.length as usize).label_bytes(); - crate::log_serial!( - "[ {:#018X?} ] Type: {:?} Size: {}\n", - entry.base..entry.base + entry.len, - entry.typ, - label - ) - } -} +// crate::log_serial!( +// "[ {:#018X?} ] Type: {:?} Size: {}\n", +// entry.base..entry.base + entry.length, +// entry.entry_type, +// label +// ) +// } +// } pub fn init_allocator() { let mut allocator_lock = ALLOCATOR.lock(); @@ -51,7 +58,9 @@ pub fn init_allocator() { crate::println!( "{} of memory available", PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes() - ) + ); + + // log_memory_map(); } pub enum Label { diff --git a/src/mem/pmm.rs b/src/mem/pmm.rs index 8c54904..d4da104 100644 --- a/src/mem/pmm.rs +++ b/src/mem/pmm.rs @@ -31,27 +31,27 @@ impl PhysicalMemoryManager { let hhdm_req = HHDM_REQUEST .get_response() - .get() .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); - let memmap = MEMMAP_REQUEST - .get_response() - .get_mut() - .expect("Failed to get Memory map!") - .memmap_mut(); + let memmap = unsafe { + MEMMAP_REQUEST + .get_response_mut() + .expect("Failed to get Memory map!") + .entries_mut() + }; let mut highest_addr: usize = 0; for entry in memmap.iter() { - if entry.typ == limine::MemoryMapEntryType::Usable { + if entry.entry_type == limine::memory_map::EntryType::USABLE { pmm.usable_pages - .fetch_add(entry.len as usize / PAGE_SIZE, Ordering::SeqCst); - if highest_addr < (entry.base + entry.len) as usize { - highest_addr = (entry.base + entry.len) as usize; + .fetch_add(entry.length as usize / PAGE_SIZE, Ordering::SeqCst); + if highest_addr < (entry.base + entry.length) 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); for entry in memmap.iter_mut() { - if entry.typ != limine::MemoryMapEntryType::Usable { + if entry.entry_type != limine::memory_map::EntryType::USABLE { 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; pmm.bitmap.store(ptr, Ordering::SeqCst); @@ -75,7 +75,7 @@ impl PhysicalMemoryManager { 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; break; @@ -83,11 +83,11 @@ impl PhysicalMemoryManager { } for entry in memmap.iter() { - if entry.typ != limine::MemoryMapEntryType::Usable { + if entry.entry_type != limine::memory_map::EntryType::USABLE { 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); } } @@ -147,7 +147,7 @@ impl PhysicalMemoryManager { } unsafe { - core::ptr::write_bytes(ret, 0x00, pages * PAGE_SIZE); + core::ptr::write_bytes(ret.add(*HHDM_OFFSET), 0x00, pages * PAGE_SIZE); }; return ret;