set pagetable, doesn't work
This commit is contained in:
parent
08291808c7
commit
a5da22da18
25
Cargo.lock
generated
25
Cargo.lock
generated
|
@ -27,6 +27,7 @@ dependencies = [
|
||||||
"goblin",
|
"goblin",
|
||||||
"log",
|
"log",
|
||||||
"uefi",
|
"uefi",
|
||||||
|
"x86_64",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -90,6 +91,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scroll"
|
name = "scroll"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
@ -190,3 +197,21 @@ name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "volatile"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x86_64"
|
||||||
|
version = "0.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bc79523af8abf92fb1a970c3e086c5a343f6bcc1a0eb890f575cbb3b45743df"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field",
|
||||||
|
"bitflags",
|
||||||
|
"rustversion",
|
||||||
|
"volatile",
|
||||||
|
]
|
||||||
|
|
|
@ -7,3 +7,4 @@ edition = "2021"
|
||||||
uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] }
|
uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] }
|
||||||
log = { version = "0.4.22", default-features = false }
|
log = { version = "0.4.22", default-features = false }
|
||||||
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
||||||
|
x86_64 = { version = "0.15.1", default-features = false }
|
||||||
|
|
74
src/boot.rs
74
src/boot.rs
|
@ -3,10 +3,13 @@ pub use x86_64::boot_kernel;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
mod x86_64 {
|
mod x86_64 {
|
||||||
use core::{arch::global_asm, ptr::null, slice};
|
use core::{arch::global_asm, slice};
|
||||||
|
|
||||||
|
use uefi::table::{boot::PAGE_SIZE, Boot, SystemTable};
|
||||||
use uefi::table::{Boot, SystemTable};
|
use x86_64::{
|
||||||
|
structures::paging::{PageTable, PageTableFlags},
|
||||||
|
PhysAddr,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{object::Kernel, staging::allocate_code};
|
use crate::{object::Kernel, staging::allocate_code};
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ trampoline_size:
|
||||||
|
|
||||||
fn trampoline_code(
|
fn trampoline_code(
|
||||||
stack: *const u8,
|
stack: *const u8,
|
||||||
pagetable: *const u8,
|
pagetable: *const PageTable,
|
||||||
modinfo_base: *const u8,
|
modinfo_base: *const u8,
|
||||||
free_ptr: *const u8,
|
free_ptr: *const u8,
|
||||||
entry: *const u8,
|
entry: *const u8,
|
||||||
|
@ -46,7 +49,17 @@ trampoline_size:
|
||||||
}
|
}
|
||||||
|
|
||||||
type TrampolineFunction =
|
type TrampolineFunction =
|
||||||
extern "sysv64" fn(*const u8, *const u8, *const u8, *const u8, *const u8);
|
extern "sysv64" fn(*const u8, *const PageTable, *const u8, *const u8, *const u8);
|
||||||
|
|
||||||
|
#[repr(C, align(4096))]
|
||||||
|
struct MiscBuf {
|
||||||
|
stack: [u8; PAGE_SIZE],
|
||||||
|
trampoline: [u8; PAGE_SIZE],
|
||||||
|
pt4: PageTable,
|
||||||
|
pt3_lower: PageTable,
|
||||||
|
pt3_upper: PageTable,
|
||||||
|
pt2_upper: PageTable,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn boot_kernel(
|
pub fn boot_kernel(
|
||||||
system_table: SystemTable<Boot>,
|
system_table: SystemTable<Boot>,
|
||||||
|
@ -55,19 +68,56 @@ trampoline_size:
|
||||||
modinfo_base: *const u8,
|
modinfo_base: *const u8,
|
||||||
free_ptr: *const u8,
|
free_ptr: *const u8,
|
||||||
) {
|
) {
|
||||||
let trampoline_code_size = unsafe { trampoline_size } as usize;
|
let misc_alloc = allocate_code(
|
||||||
let misc_buf = allocate_code(system_table.boot_services(), trampoline_code_size + 64);
|
system_table.boot_services(),
|
||||||
|
core::mem::size_of::<MiscBuf>(),
|
||||||
|
);
|
||||||
|
// allocate_code is always page aligned, so we'll always meet 4096 alignment for MiscBuf
|
||||||
|
let misc_buf = unsafe { (misc_alloc.as_mut_ptr() as *mut MiscBuf).as_mut().unwrap() };
|
||||||
|
|
||||||
let (stack_buf, trampoline_buf) = misc_buf.split_at_mut(64);
|
let trampoline_code_size = unsafe { trampoline_size } as usize;
|
||||||
trampoline_buf[..trampoline_code_size].copy_from_slice(unsafe {
|
misc_buf.trampoline[..trampoline_code_size].copy_from_slice(unsafe {
|
||||||
slice::from_raw_parts(trampoline_code as *const u8, trampoline_code_size)
|
slice::from_raw_parts(trampoline_code as *const u8, trampoline_code_size)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Map the lower 512G of RAM identity-mapped with 1GiB pages
|
||||||
|
for (idx, pte) in misc_buf.pt3_lower.iter_mut().enumerate() {
|
||||||
|
pte.set_addr(
|
||||||
|
PhysAddr::new((idx as u64) << 30),
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::HUGE_PAGE | PageTableFlags::WRITABLE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
misc_buf.pt4[0].set_addr(
|
||||||
|
PhysAddr::new(&misc_buf.pt3_lower as *const PageTable as usize as u64),
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Map the kernel to 2GiB from the top of RAM with 2MiB pages
|
||||||
|
for (idx, pte) in misc_buf.pt2_upper.iter_mut().enumerate() {
|
||||||
|
let addr = kernel_base as usize + (idx << 21);
|
||||||
|
pte.set_addr(
|
||||||
|
PhysAddr::new(addr as u64),
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::HUGE_PAGE | PageTableFlags::WRITABLE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// 512 entries, each pt3 entry represents 1GiB
|
||||||
|
misc_buf.pt3_upper[510].set_addr(
|
||||||
|
PhysAddr::new(&misc_buf.pt2_upper as *const PageTable as usize as u64),
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
|
||||||
|
);
|
||||||
|
// 512 entries, each pt4 entry represents 512GiB
|
||||||
|
misc_buf.pt4[511].set_addr(
|
||||||
|
PhysAddr::new(&misc_buf.pt3_upper as *const PageTable as usize as u64),
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
|
||||||
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let trampoline_func: TrampolineFunction = core::mem::transmute(trampoline_buf.as_ptr());
|
let trampoline_func: TrampolineFunction =
|
||||||
|
core::mem::transmute(misc_buf.trampoline.as_ptr());
|
||||||
trampoline_func(
|
trampoline_func(
|
||||||
stack_buf.as_ptr(),
|
&misc_buf.stack[PAGE_SIZE - 8] as *const u8,
|
||||||
null(),
|
&misc_buf.pt4 as *const PageTable,
|
||||||
modinfo_base,
|
modinfo_base,
|
||||||
free_ptr,
|
free_ptr,
|
||||||
kernel.entry_addr(kernel_base),
|
kernel.entry_addr(kernel_base),
|
||||||
|
|
Loading…
Reference in a new issue