Fix initrd loading

This commit is contained in:
Mark Poliakov 2023-12-08 17:53:50 +02:00
parent 842fd84cc8
commit f0fc10ed8a
2 changed files with 12 additions and 37 deletions

View File

@ -1,22 +1,10 @@
use uefi::{
prelude::BootServices,
proto::media::file::{Directory, File, FileAttribute, FileInfo, FileMode, RegularFile},
table::boot::MemoryMap,
table::boot::{AllocateType, MemoryType},
CStr16, Error,
};
use crate::{elf::LoadedObject, mem::MemoryMapExt};
fn can_place(mmap: &MemoryMap, base: u64, size: u64) -> bool {
let start_aligned = base & !0xFFF;
let end_aligned = (base + size + 0xFFF) & !0xFFF;
for page in (start_aligned..end_aligned).step_by(0x1000) {
if !mmap.is_usable(page) {
return false;
}
}
true
}
fn do_load(file: &mut RegularFile, base: u64, size: u64) -> Result<(), Error> {
let buffer = unsafe { core::slice::from_raw_parts_mut(base as *mut u8, size as usize) };
file.read(buffer)?;
@ -24,12 +12,10 @@ fn do_load(file: &mut RegularFile, base: u64, size: u64) -> Result<(), Error> {
}
pub fn load_somewhere(
bs: &BootServices,
root: &mut Directory,
filename: &CStr16,
mmap: &MemoryMap,
obj: &LoadedObject,
) -> Result<(u64, u64), Error> {
const IMAGE_END_GAP: u64 = 0x3000;
const MAXIMUM_ADDRESS: u64 = 0x100000000;
let mut info_buffer: [u8; 1024] = [0; 1024];
@ -39,25 +25,15 @@ pub fn load_somewhere(
let file_info: &FileInfo = file.get_info(&mut info_buffer).unwrap();
let size = file_info.file_size();
let page_count = (size + 0xFFF) / 0x1000;
// 1. Try loading below the kernel
if obj.image_start >= size {
let start = (obj.image_start - size) & !0xFFF;
let base = bs.allocate_pages(
AllocateType::MaxAddress(MAXIMUM_ADDRESS),
MemoryType::LOADER_DATA,
page_count as _,
)?;
if can_place(mmap, start, size) {
do_load(&mut file, start, size)?;
return Ok((start, size));
}
}
do_load(&mut file, base, size)?;
// 2. Try any location above the kernel
let start = ((obj.image_end + 0xFFF) & !0xFFF) + IMAGE_END_GAP;
for base in (start..MAXIMUM_ADDRESS).step_by(0x1000) {
if can_place(mmap, base, size) {
do_load(&mut file, base, size)?;
return Ok((base, size));
}
}
panic!("Could not place initrd");
Ok((base, size))
}

View File

@ -103,8 +103,7 @@ fn load_kernel<'a, 'b>(
debug!("Loaded object: {:#x?}", loaded_obj);
// Load initrd
let (initrd_start, initrd_size) =
initrd::load_somewhere(&mut root, cstr16!("initrd.img"), &mmap, &loaded_obj)?;
let (initrd_start, initrd_size) = initrd::load_somewhere(bs, &mut root, cstr16!("initrd.img"))?;
debug!(
"Loaded initrd: {:#x?}",
initrd_start..initrd_start + initrd_size