Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Commit

Permalink
feat(bootx64): jump to the kernel (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
toku-sa-n authored Jun 26, 2021
1 parent 0688584 commit 0673ef9
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
9 changes: 7 additions & 2 deletions bootloader/bootx64/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) })
}
Expand All @@ -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
Expand All @@ -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> {
Expand Down
13 changes: 8 additions & 5 deletions bootloader/bootx64/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)()
}
5 changes: 3 additions & 2 deletions bootloader/bootx64/src/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(f: impl FnOnce() -> T) -> T {
disable_write_protect();
f();
let r = f();
enable_write_protect();
r
}

/// # Safety
Expand Down
4 changes: 3 additions & 1 deletion kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}

0 comments on commit 0673ef9

Please sign in to comment.