Fix initrd loading
This commit is contained in:
parent
842fd84cc8
commit
f0fc10ed8a
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user