load kernel
This commit is contained in:
@ -4,11 +4,11 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{boxed::Box, vec};
|
||||
use core::arch::asm;
|
||||
use goblin::elf;
|
||||
use core::{arch::asm, slice};
|
||||
use goblin::elf::{self, Elf};
|
||||
use uefi::{
|
||||
allocator::Allocator,
|
||||
boot::{MemoryType, ScopedProtocol},
|
||||
boot::{AllocateType, MemoryType, ScopedProtocol},
|
||||
mem::memory_map::MemoryMap,
|
||||
prelude::*,
|
||||
println,
|
||||
@ -56,6 +56,48 @@ fn read_kernel(name: &CStr16) -> Box<[u8]> {
|
||||
buf.into_boxed_slice()
|
||||
}
|
||||
|
||||
fn load_elf(bin: Box<[u8]>) -> u64 {
|
||||
let elf = elf::Elf::parse(&bin).expect("Failed to parse elf");
|
||||
let mut dest_start = u64::MAX;
|
||||
let mut dest_end = 0u64;
|
||||
|
||||
elf.program_headers
|
||||
.iter()
|
||||
.filter(|header| header.p_type == elf::program_header::PT_LOAD)
|
||||
.for_each(|header| {
|
||||
dest_start = dest_start.min(header.p_vaddr);
|
||||
dest_end = dest_end.max(header.p_vaddr + header.p_memsz);
|
||||
});
|
||||
|
||||
uefi::boot::allocate_pages(
|
||||
AllocateType::Address(dest_start),
|
||||
MemoryType::LOADER_DATA,
|
||||
dest_end
|
||||
.checked_sub(dest_start)
|
||||
.and_then(|size| size.checked_add(4095))
|
||||
.map(|size| size / 4096)
|
||||
.unwrap_or(0) as usize,
|
||||
)
|
||||
.expect("Failed to allocate pages");
|
||||
|
||||
elf.program_headers
|
||||
.iter()
|
||||
.filter(|header| header.p_type == elf::program_header::PT_LOAD)
|
||||
.for_each(|header| {
|
||||
let dest = unsafe {
|
||||
slice::from_raw_parts_mut(header.p_vaddr as *mut u8, header.p_memsz as usize)
|
||||
};
|
||||
|
||||
let file_size = header.p_filesz as usize;
|
||||
let offset = header.p_offset as usize;
|
||||
|
||||
dest[..file_size].copy_from_slice(&bin[offset..offset + file_size]);
|
||||
dest[file_size..].fill(0);
|
||||
});
|
||||
|
||||
elf.entry
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn main() -> Status {
|
||||
uefi::helpers::init().unwrap();
|
||||
@ -78,13 +120,17 @@ fn main() -> Status {
|
||||
|
||||
let kernel = read_kernel(cstr16!("nel_os_kernel.elf"));
|
||||
|
||||
let elf = elf::Elf::parse(&kernel).expect("Failed to parse kernel");
|
||||
let entry_point = load_elf(kernel);
|
||||
|
||||
println!("Entry point: {}", elf.entry);
|
||||
println!("Entry point: {:#x}", entry_point);
|
||||
|
||||
let entry: extern "sysv64" fn() = unsafe { core::mem::transmute(entry_point) };
|
||||
|
||||
unsafe {
|
||||
let _ = uefi::boot::exit_boot_services(Some(MemoryType::LOADER_DATA));
|
||||
}
|
||||
|
||||
entry();
|
||||
|
||||
hlt_loop();
|
||||
}
|
||||
|
@ -15,5 +15,13 @@
|
||||
"features": "-mmx,-sse,+soft-float",
|
||||
"rustc-abi": "x86-softfloat",
|
||||
"code-model": "kernel",
|
||||
"max-atomic-width": 64
|
||||
"max-atomic-width": 64,
|
||||
"position-independent-executables": false,
|
||||
"post-link-args": {
|
||||
"ld.lld": [
|
||||
"--entry=asm_main",
|
||||
"--image-base=0x100000",
|
||||
"--static"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user