Fix initrd loading
This commit is contained in:
parent
842fd84cc8
commit
f0fc10ed8a
@ -1,22 +1,10 @@
|
|||||||
use uefi::{
|
use uefi::{
|
||||||
|
prelude::BootServices,
|
||||||
proto::media::file::{Directory, File, FileAttribute, FileInfo, FileMode, RegularFile},
|
proto::media::file::{Directory, File, FileAttribute, FileInfo, FileMode, RegularFile},
|
||||||
table::boot::MemoryMap,
|
table::boot::{AllocateType, MemoryType},
|
||||||
CStr16, Error,
|
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> {
|
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) };
|
let buffer = unsafe { core::slice::from_raw_parts_mut(base as *mut u8, size as usize) };
|
||||||
file.read(buffer)?;
|
file.read(buffer)?;
|
||||||
@ -24,12 +12,10 @@ fn do_load(file: &mut RegularFile, base: u64, size: u64) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_somewhere(
|
pub fn load_somewhere(
|
||||||
|
bs: &BootServices,
|
||||||
root: &mut Directory,
|
root: &mut Directory,
|
||||||
filename: &CStr16,
|
filename: &CStr16,
|
||||||
mmap: &MemoryMap,
|
|
||||||
obj: &LoadedObject,
|
|
||||||
) -> Result<(u64, u64), Error> {
|
) -> Result<(u64, u64), Error> {
|
||||||
const IMAGE_END_GAP: u64 = 0x3000;
|
|
||||||
const MAXIMUM_ADDRESS: u64 = 0x100000000;
|
const MAXIMUM_ADDRESS: u64 = 0x100000000;
|
||||||
|
|
||||||
let mut info_buffer: [u8; 1024] = [0; 1024];
|
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 file_info: &FileInfo = file.get_info(&mut info_buffer).unwrap();
|
||||||
let size = file_info.file_size();
|
let size = file_info.file_size();
|
||||||
|
let page_count = (size + 0xFFF) / 0x1000;
|
||||||
|
|
||||||
// 1. Try loading below the kernel
|
let base = bs.allocate_pages(
|
||||||
if obj.image_start >= size {
|
AllocateType::MaxAddress(MAXIMUM_ADDRESS),
|
||||||
let start = (obj.image_start - size) & !0xFFF;
|
MemoryType::LOADER_DATA,
|
||||||
|
page_count as _,
|
||||||
|
)?;
|
||||||
|
|
||||||
if can_place(mmap, start, size) {
|
do_load(&mut file, base, size)?;
|
||||||
do_load(&mut file, start, size)?;
|
|
||||||
return Ok((start, size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Try any location above the kernel
|
Ok((base, size))
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,7 @@ fn load_kernel<'a, 'b>(
|
|||||||
debug!("Loaded object: {:#x?}", loaded_obj);
|
debug!("Loaded object: {:#x?}", loaded_obj);
|
||||||
|
|
||||||
// Load initrd
|
// Load initrd
|
||||||
let (initrd_start, initrd_size) =
|
let (initrd_start, initrd_size) = initrd::load_somewhere(bs, &mut root, cstr16!("initrd.img"))?;
|
||||||
initrd::load_somewhere(&mut root, cstr16!("initrd.img"), &mmap, &loaded_obj)?;
|
|
||||||
debug!(
|
debug!(
|
||||||
"Loaded initrd: {:#x?}",
|
"Loaded initrd: {:#x?}",
|
||||||
initrd_start..initrd_start + initrd_size
|
initrd_start..initrd_start + initrd_size
|
||||||
|
Loading…
x
Reference in New Issue
Block a user