load kernel

This commit is contained in:
mii443
2025-07-01 20:04:03 +09:00
parent 830b95bad4
commit 8509a1bed6
2 changed files with 60 additions and 6 deletions

View File

@ -4,11 +4,11 @@
extern crate alloc; extern crate alloc;
use alloc::{boxed::Box, vec}; use alloc::{boxed::Box, vec};
use core::arch::asm; use core::{arch::asm, slice};
use goblin::elf; use goblin::elf::{self, Elf};
use uefi::{ use uefi::{
allocator::Allocator, allocator::Allocator,
boot::{MemoryType, ScopedProtocol}, boot::{AllocateType, MemoryType, ScopedProtocol},
mem::memory_map::MemoryMap, mem::memory_map::MemoryMap,
prelude::*, prelude::*,
println, println,
@ -56,6 +56,48 @@ fn read_kernel(name: &CStr16) -> Box<[u8]> {
buf.into_boxed_slice() 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] #[entry]
fn main() -> Status { fn main() -> Status {
uefi::helpers::init().unwrap(); uefi::helpers::init().unwrap();
@ -78,13 +120,17 @@ fn main() -> Status {
let kernel = read_kernel(cstr16!("nel_os_kernel.elf")); 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 { unsafe {
let _ = uefi::boot::exit_boot_services(Some(MemoryType::LOADER_DATA)); let _ = uefi::boot::exit_boot_services(Some(MemoryType::LOADER_DATA));
} }
entry();
hlt_loop(); hlt_loop();
} }

View File

@ -15,5 +15,13 @@
"features": "-mmx,-sse,+soft-float", "features": "-mmx,-sse,+soft-float",
"rustc-abi": "x86-softfloat", "rustc-abi": "x86-softfloat",
"code-model": "kernel", "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"
]
}
} }