Properly reserve the kernel image

This commit is contained in:
Mark Poliakov 2023-11-06 10:39:45 +02:00
parent 7e1770e591
commit 842fd84cc8
3 changed files with 22 additions and 8 deletions

View File

@ -4,8 +4,9 @@ use bytemuck::Zeroable;
use log::{debug, error, info}; use log::{debug, error, info};
// TODO use 'elf' crate // TODO use 'elf' crate
use uefi::{ use uefi::{
prelude::BootServices,
proto::media::file::{File, FileAttribute, FileMode, RegularFile}, proto::media::file::{File, FileAttribute, FileMode, RegularFile},
table::boot::MemoryMap, table::boot::{AllocateType, MemoryMap, MemoryType},
CStr16, Error, Status, CStr16, Error, Status,
}; };
use yboot_proto::LoadProtocolV1; use yboot_proto::LoadProtocolV1;
@ -152,7 +153,7 @@ impl Object {
} }
// Returns the image entry point // Returns the image entry point
pub fn load(&mut self, mmap: &MemoryMap) -> Result<LoadedObject, Error> { pub fn load(&mut self, bs: &BootServices, mmap: &MemoryMap) -> Result<LoadedObject, Error> {
// 1. Locate the protocol data structure // 1. Locate the protocol data structure
let Some(loc_proto) = self.locate_protocol_data()? else { let Some(loc_proto) = self.locate_protocol_data()? else {
error!("The image does not have a valid protocol structure"); error!("The image does not have a valid protocol structure");
@ -218,7 +219,19 @@ impl Object {
} }
} }
// TODO maybe reserve the kernel memory in the boot services? assert!(image_end > image_start);
assert_eq!(image_start & 0xFFF, 0);
assert_eq!(image_end & 0xFFF, 0);
info!("Image start: {:#x}, end: {:#x}", image_start, image_end);
// Reserve the kernel memory
let reserved_addr = bs.allocate_pages(
AllocateType::Address(image_start),
MemoryType::RUNTIME_SERVICES_DATA,
(image_end - image_start) as usize / 0x1000,
)?;
assert_eq!(reserved_addr, image_start);
// 3. Load the segments // 3. Load the segments
for i in 0..self.ehdr.phnum { for i in 0..self.ehdr.phnum {
let phdr = self.read_phdr(i as _)?; let phdr = self.read_phdr(i as _)?;
@ -248,7 +261,7 @@ impl Object {
self.file.read_exact(dst)?; self.file.read_exact(dst)?;
} }
if phdr.memsz > 0 { if phdr.memsz > phdr.filesz {
let dst = unsafe { let dst = unsafe {
core::slice::from_raw_parts_mut( core::slice::from_raw_parts_mut(
(phdr.paddr + phdr.filesz) as *mut u8, (phdr.paddr + phdr.filesz) as *mut u8,

View File

@ -98,7 +98,7 @@ fn load_kernel<'a, 'b>(
let mut root = fs.open_volume()?; let mut root = fs.open_volume()?;
let mut kernel_obj = Object::open(&mut root, cstr16!("kernel.elf"))?; let mut kernel_obj = Object::open(&mut root, cstr16!("kernel.elf"))?;
let loaded_obj = kernel_obj.load(&mmap)?; let loaded_obj = kernel_obj.load(bs, &mmap)?;
debug!("Loaded object: {:#x?}", loaded_obj); debug!("Loaded object: {:#x?}", loaded_obj);
@ -157,7 +157,6 @@ unsafe fn map_and_enter_kernel(
entry: u64, entry: u64,
) -> ! { ) -> ! {
let (_, mmap) = st.exit_boot_services(); let (_, mmap) = st.exit_boot_services();
let mut index = 0; let mut index = 0;
let mmap_data = core::slice::from_raw_parts_mut( let mmap_data = core::slice::from_raw_parts_mut(
@ -179,7 +178,7 @@ unsafe fn map_and_enter_kernel(
proto_data.memory_map.len = index as _; proto_data.memory_map.len = index as _;
let cr3 = mem::map_image(); let cr3 = mem::map_image();
asm!("mov {0}, %cr3", in(reg) cr3, options(att_syntax)); asm!("cli; wbinvd; mov {0}, %cr3", in(reg) cr3, options(att_syntax));
asm!("jmp *{0}", in(reg) entry, in("eax") LOADER_MAGIC, options(noreturn, att_syntax)); asm!("jmp *{0}", in(reg) entry, in("eax") LOADER_MAGIC, options(noreturn, att_syntax));
} }
@ -189,6 +188,7 @@ fn efi_main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status
uefi_services::init(&mut system_table).unwrap(); uefi_services::init(&mut system_table).unwrap();
let (entry, mmap_memory, proto_data) = load_kernel(image_handle, &system_table).unwrap(); let (entry, mmap_memory, proto_data) = load_kernel(image_handle, &system_table).unwrap();
unsafe { unsafe {
map_and_enter_kernel(system_table, proto_data, mmap_memory, entry); map_and_enter_kernel(system_table, proto_data, mmap_memory, entry);
} }

View File

@ -25,9 +25,10 @@ static mut MMAP_BUFFER: MmapBuffer = MmapBuffer {
data: [0; MMAP_BUFFER_SIZE], data: [0; MMAP_BUFFER_SIZE],
}; };
const PD_COUNT: usize = 32;
static mut PML4: Table = Table { data: [0; 512] }; static mut PML4: Table = Table { data: [0; 512] };
static mut PDPT: Table = Table { data: [0; 512] }; static mut PDPT: Table = Table { data: [0; 512] };
static mut PDS: [Table; 4] = [Table { data: [0; 512] }; 4]; static mut PDS: [Table; PD_COUNT] = [Table { data: [0; 512] }; PD_COUNT];
pub trait MemoryMapExt { pub trait MemoryMapExt {
fn is_usable(&self, page: u64) -> bool; fn is_usable(&self, page: u64) -> bool;