From 8fcc70bee1078046c404b433ae7a174198b15c48 Mon Sep 17 00:00:00 2001 From: fekhesk Date: Thu, 27 Oct 2022 14:29:40 -0700 Subject: [PATCH] make it boot on my macbook --- Makefile | 14 ++++++++++---- serial.log | 26 +++----------------------- src/boot/mod.rs | 13 +++++++------ src/lib.rs | 7 ++++--- src/memory/allocator.rs | 7 ++++--- src/memory/mod.rs | 17 +++++++++-------- 6 files changed, 37 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index bd74e82..5a53afc 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,10 @@ iso := build/arch/$(arch)/wukkOS.iso target ?= $(arch)-custom final := build/arch/$(arch)/wukkOS.bin efi_bios := build/arch/$(arch)/OVMF-pure-efi.fd +gcc := x86_64-elf-gcc +ld := x86_64-elf-ld +# set grub-mkrescue to either $GRUB_MKRESCUE or /usr/bin/grub-mkrescue +grub-mkrescue ?= $(shell which grub-mkrescue) linker_script := arch/$(arch)/linker.ld grub_cfg := arch/$(arch)/grub.cfg @@ -11,10 +15,12 @@ assembly_source_files := $(wildcard arch/$(arch)/*.asm) assembly_object_files := $(patsubst arch/$(arch)/%.asm, \ build/arch/$(arch)/%.o, $(assembly_source_files)) -.PHONY: all clean run iso quick_invalidate +.PHONY: all clean run iso quick_invalidate build_no_iso all: $(final) $(iso) +build_no_iso: $(final) + clean: @xargo clean @rm -rf build @@ -36,12 +42,12 @@ $(iso): $(final) $(grub_cfg) @mkdir -p isodir/boot/grub @cp $(final) isodir/boot/wukkOS.bin @cp $(grub_cfg) isodir/boot/grub/grub.cfg - @grub-mkrescue -o $(iso) isodir + @$(grub-mkrescue) -o $(iso) isodir @rm -rf isodir $(final): $(kernel) $(linker_script) $(assembly_object_files) - @ld -n -T $(linker_script) -o $(final) $(assembly_object_files) $(kernel) \ - --gc-sections + @$(ld) -n -T $(linker_script) -o $(final) $(assembly_object_files) $(kernel) \ + --gc-sections -z noexecstack $(kernel): @RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) -Zbuild-std=core,alloc --features "f_multiboot2" diff --git a/serial.log b/serial.log index c5b92ba..3b30c1c 100644 --- a/serial.log +++ b/serial.log @@ -1,8 +1,6 @@ -[=3h[=3h[=3h[=3hBdsDxe: loading Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0) +[=3hBdsDxe: loading Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0) BdsDxe: starting Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0) -Welcome to GRUB! - -  Booting `wukkOS basic kernel' + Booting `wukkOS basic kernel' WARNING: no console will be available to OS error: no suitable video mode found. @@ -29,22 +27,4 @@ initialising apic...[debug] read_phys_memory32: addr fee000f0 not mapped [debug] mapped page: Page[4KiB](0xfee00000) [debug] map_to_result: Ok(MapperFlush(Page[4KiB](0xfee00000))) [OK] -setting up apic interrupts...[debug] write_phys_memory32: addr fec00000 not mapped -[debug] allocated frame: PhysFrame[4KiB](0x1f000) -[debug] mapped page: Page[4KiB](0xfec00000) -[debug] map_to_result: Ok(MapperFlush(Page[4KiB](0xfec00000))) -[OK] -[debug] keyboard interrupt ----KERNEL FUCKY WUKKY UWU--- -double fault! -stack frame: InterruptStackFrame { - instruction_pointer: VirtAddr( - 0x120ef1, - ), - code_segment: 8, - cpu_flags: 0x200002, - stack_pointer: VirtAddr( - 0x140c00, - ), - stack_segment: 16, -} +setting up apic interrupts...[debug] read_phys_memory32: addr 1fb7d000 not mapped diff --git a/src/boot/mod.rs b/src/boot/mod.rs index 3b2bf39..9d65346 100644 --- a/src/boot/mod.rs +++ b/src/boot/mod.rs @@ -6,8 +6,9 @@ use crate::{debug, KernelArgs, println}; #[cfg(feature = "f_multiboot2")] use multiboot2::{load, MemoryMapTag, BootInformation}; -use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, Translate}; -use crate::memory::{BootInfoFrameAllocator, FRAME_ALLOC, MEM_MAPPER}; +use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, Page, Translate}; +use x86_64::VirtAddr; +use crate::memory::{BootInfoFrameAllocator, FRAME_ALLOC, MEM_MAPPER, PageSize}; pub struct KernelInfo { kernel_start: u64, @@ -27,14 +28,14 @@ impl AcpiHandler for Handler { let frame = FRAME_ALLOC.lock().as_mut().unwrap().allocate_frame().unwrap(); debug!("allocated frame: {:?}", frame); let flags = x86_64::structures::paging::PageTableFlags::PRESENT | x86_64::structures::paging::PageTableFlags::WRITABLE; - let page = x86_64::structures::paging::Page::containing_address(initaladdr); + let page: Page = Page::containing_address(VirtAddr::new(physical_address as u64)); debug!("mapped page: {:?}", page); let map_to_result = unsafe { MEM_MAPPER.lock().as_mut().unwrap().map_to(page, frame, flags, FRAME_ALLOC.lock().as_mut().unwrap()) }; debug!("map_to_result: {:?}", map_to_result); if map_to_result.is_err() { panic!("Failed to map page"); } - let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(initaladdr) }; + let addr = unsafe { MEM_MAPPER.lock().as_mut().unwrap().translate_addr(VirtAddr::new(physical_address as u64)) }; if let Some(addr) = addr { // physical start, virtual start, region length, mapped length, Self PhysicalMapping::new( @@ -49,7 +50,7 @@ impl AcpiHandler for Handler { fn unmap_physical_region(region: &PhysicalMapping) { // get page - let page = x86_64::structures::paging::Page::containing_address(region.start_address()); + let page: Page = Page::containing_address(VirtAddr::new(region.physical_start() as u64)); // unmap page let res = unsafe { MEM_MAPPER.lock().as_mut().unwrap().unmap(page) }; // it isn't *that* important if we don't unmap successfully at the moment, so just write a warning if we fail @@ -108,7 +109,7 @@ impl KernelInfo { let rsdt = rsdp.rsdt_address(); let rsdt = unsafe { acpi::AcpiTables::from_rsdt( - AcpiHandler, 0, + Handler, 0, rsdt) .expect("failed to get acpi tables") }; diff --git a/src/lib.rs b/src/lib.rs index b87a25d..caeb948 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ mod memory; mod macros; lazy_static! { + pub static ref KERN_INFO: Mutex> = Mutex::new(None); static ref GDT: Mutex = { let mut gdt = GlobalDescriptorTable::new(); Mutex::new(gdt) @@ -163,7 +164,7 @@ pub extern fn kernel_main(args: KernelArgs) -> ! { println!(); println!("welcome to wukkOS!"); println!("(c) 2022 Real Microsoft, LLC"); - let kern_info = Mutex::new(KernelInfo::init_from_kernel_args(args)); + KERN_INFO.lock().replace(KernelInfo::init_from_kernel_args(args)); // memory stuff { @@ -171,7 +172,7 @@ pub extern fn kernel_main(args: KernelArgs) -> ! { MEM_MAPPER.lock().replace(unsafe { memory::init(VirtAddr::new(0)) }); println!("[OK]"); print!("initialising frame allocator..."); - FRAME_ALLOC.lock().replace(unsafe { memory::BootInfoFrameAllocator::init(kern_info) }); + FRAME_ALLOC.lock().replace(unsafe { memory::BootInfoFrameAllocator::init() }); println!("[OK]"); print!("initialising heap..."); memory::allocator::init_heap(MEM_MAPPER.lock().as_mut().unwrap(), FRAME_ALLOC.lock().as_mut().unwrap()).expect("heap init failed"); @@ -208,7 +209,7 @@ pub extern fn kernel_main(args: KernelArgs) -> ! { unsafe { internals::cpu::enable_apic() }; println!("[OK]"); print!("setting up apic interrupts..."); - unsafe { internals::cpu::setup_apic_interrupts(kern_info.lock().acpi_get_ioapic_addr()) }; + unsafe { internals::cpu::setup_apic_interrupts(KERN_INFO.lock().as_ref().unwrap().acpi_get_ioapic_addr()) }; println!("[OK]"); // enable interrupts x86_64::instructions::interrupts::enable(); diff --git a/src/memory/allocator.rs b/src/memory/allocator.rs index 229b2a3..7430d06 100644 --- a/src/memory/allocator.rs +++ b/src/memory/allocator.rs @@ -4,6 +4,7 @@ use core::ptr::NonNull; use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB}; use x86_64::structures::paging::mapper::MapToError; use x86_64::VirtAddr; +use crate::memory::PageSize; use super::Locked; pub const HEAP_START: u64 = 0x_4444_4444_0000; @@ -99,9 +100,9 @@ fn list_index(layout: &core::alloc::Layout) -> Option { } pub fn init_heap( - mapper: &mut impl Mapper, - frame_allocator: &mut impl FrameAllocator, -) -> Result<(), MapToError> { + mapper: &mut impl Mapper, + frame_allocator: &mut impl FrameAllocator, +) -> Result<(), MapToError> { let page_range = { let heap_start = VirtAddr::new(HEAP_START as u64); let heap_end = heap_start + HEAP_SIZE - 1u64; diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 1755dec..7bead8e 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -7,10 +7,12 @@ use x86_64::structures::paging::{FrameAllocator, Mapper, OffsetPageTable, PageTa use x86_64::{PhysAddr, VirtAddr}; lazy_static!{ - pub static ref MEM_MAPPER: Mutex> = Mutex::new(None); + pub static ref MEM_MAPPER: Mutex>> = Mutex::new(None); pub static ref FRAME_ALLOC: Mutex> = Mutex::new(None); } +pub type PageSize = Size4KiB; + pub struct Locked { inner: spin::Mutex, } @@ -48,18 +50,16 @@ unsafe fn active_level_4_table(phys_mem_offset: VirtAddr) -> &'static mut PageTa use multiboot2::{MemoryMapTag, BootInformation}; use spin::Mutex; use crate::boot::KernelInfo; -use crate::{debug, print, println}; +use crate::{debug, KERN_INFO, print, println}; pub struct BootInfoFrameAllocator { - kern_info: Mutex, next: usize, } impl BootInfoFrameAllocator { #[cfg(feature = "f_multiboot2")] - pub unsafe fn init(kern_info: Mutex) -> Self { + pub unsafe fn init() -> Self { Self { - kern_info, next: 0, } } @@ -68,8 +68,9 @@ impl BootInfoFrameAllocator { unsafe impl FrameAllocator for BootInfoFrameAllocator { fn allocate_frame(&mut self) -> Option { #[cfg(feature = "f_multiboot2")] { - let mut kern_lock = self.kern_info.lock(); - let mut usable_frames = kern_lock + let mut kern_lock = KERN_INFO.lock(); + let mut kern_info = kern_lock.as_mut().unwrap(); + let mut usable_frames = kern_info .memory_areas(); let mut usable_frames = usable_frames .map(|area| { @@ -85,7 +86,7 @@ unsafe impl FrameAllocator for BootInfoFrameAllocator { self.next += 1; // ensure unlock - unsafe { self.kern_info.force_unlock() }; + unsafe { KERN_INFO.force_unlock() }; frame }