From 0673ef9b42c189b25b93da7d543950290faf4146 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Sat, 26 Jun 2021 16:58:19 +0900 Subject: [PATCH] feat(bootx64): jump to the kernel (#81) --- bootloader/bootx64/src/elf.rs | 9 +++++++-- bootloader/bootx64/src/main.rs | 13 ++++++++----- bootloader/bootx64/src/paging.rs | 5 +++-- kernel/src/main.rs | 4 +++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/bootloader/bootx64/src/elf.rs b/bootloader/bootx64/src/elf.rs index 97492fee..9a798ecd 100644 --- a/bootloader/bootx64/src/elf.rs +++ b/bootloader/bootx64/src/elf.rs @@ -19,7 +19,7 @@ use x86_64::VirtAddr; /// The caller must ensure that /// - The recursive paging address `0xff7f_bfdf_e000` is accessible. /// - There is no reference to one of the all working page tables. -pub unsafe fn load(binary: &[u8], mmap: &mut [MemoryDescriptor]) { +pub unsafe fn load(binary: &[u8], mmap: &mut [MemoryDescriptor]) -> VirtAddr { // SAFETY: The all rules are satisfied. paging::edit_page_tables(|| unsafe { load_without_disabling_page_table_protects(binary, mmap) }) } @@ -29,7 +29,10 @@ pub unsafe fn load(binary: &[u8], mmap: &mut [MemoryDescriptor]) { /// The caller must ensure that /// - The recursive paging address `0xff7f_bfdf_e000` is accessible. /// - There is no reference to one of the all working page tables. -unsafe fn load_without_disabling_page_table_protects(binary: &[u8], mmap: &mut [MemoryDescriptor]) { +unsafe fn load_without_disabling_page_table_protects( + binary: &[u8], + mmap: &mut [MemoryDescriptor], +) -> VirtAddr { let mut allocator = Allocator::new(mmap); // SAFETY: The caller ensures that the recursive paging is enabled and there is no reference to @@ -43,6 +46,8 @@ unsafe fn load_without_disabling_page_table_protects(binary: &[u8], mmap: &mut [ let r = elf.load(&mut loader); r.expect("Failed to load a ELF file."); + + VirtAddr::new(elf.entry_point()) } struct Loader<'a> { diff --git a/bootloader/bootx64/src/main.rs b/bootloader/bootx64/src/main.rs index bcabf288..8bf92470 100644 --- a/bootloader/bootx64/src/main.rs +++ b/bootloader/bootx64/src/main.rs @@ -11,7 +11,7 @@ use bootx64::paging; use bootx64::{fs, uefi_println}; #[no_mangle] -pub extern "win64" fn efi_main(h: uefi_wrapper::Handle, mut st: bootx64::SystemTable) -> ! { +extern "win64" fn efi_main(h: uefi_wrapper::Handle, mut st: bootx64::SystemTable) -> ! { let resolution = gop::set_preferred_resolution(&mut st); uefi_println!(&mut st, "GOP info: {:?}", resolution); @@ -24,9 +24,12 @@ pub extern "win64" fn efi_main(h: uefi_wrapper::Handle, mut st: bootx64::SystemT unsafe { paging::enable_recursive_paging() }; // SAFETY: Yes, the recursive paging is enabled and there are no references to the PML4. - unsafe { elf::load(bytes, mmap) }; + let entry = unsafe { elf::load(bytes, mmap) }; + assert!(!entry.is_null(), "The entry address is null."); - loop { - x86_64::instructions::hlt(); - } + // SAFETY: Safe as described in + // https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html#representation. + let entry: fn() -> ! = unsafe { core::mem::transmute(entry) }; + + (entry)() } diff --git a/bootloader/bootx64/src/paging.rs b/bootloader/bootx64/src/paging.rs index 1fa1726b..0dfff039 100644 --- a/bootloader/bootx64/src/paging.rs +++ b/bootloader/bootx64/src/paging.rs @@ -5,10 +5,11 @@ use x86_64::structures::paging::PageTableFlags; use x86_64::PhysAddr; use x86_64::VirtAddr; -pub(crate) fn edit_page_tables(f: impl FnOnce()) { +pub(crate) fn edit_page_tables(f: impl FnOnce() -> T) -> T { disable_write_protect(); - f(); + let r = f(); enable_write_protect(); + r } /// # Safety diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 365a8dbc..5849fd5c 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -7,6 +7,8 @@ extern crate kernel as _; #[no_mangle] fn main() { unsafe { - *(0x334 as *mut u8) = 3_u8; + loop { + *(0x334 as *mut u8) = 3_u8; + } } }