Compare commits
No commits in common. "405cdf8f2682365db4d29dc24f7f1e191cf9887c" and "5a86c41d0746c1bde485f589285ef700440bc0d8" have entirely different histories.
405cdf8f26
...
5a86c41d07
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -20,38 +20,27 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "elf"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
|
||||
|
||||
[[package]]
|
||||
name = "freeloader"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"goblin",
|
||||
"elf",
|
||||
"log",
|
||||
"uefi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
|
@ -90,26 +79,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
|
|
|
@ -6,4 +6,4 @@ edition = "2021"
|
|||
[dependencies]
|
||||
uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] }
|
||||
log = { version = "0.4.22", default-features = false }
|
||||
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
||||
elf = { version = "0.7.4", default_features = false }
|
||||
|
|
169
notes.md
169
notes.md
|
@ -40,172 +40,3 @@ Tons of arch-specific restrictions
|
|||
* Pointers are passed as 32-bit, must be within the first 4G
|
||||
* First 4G of virtual memory must be identity mapped
|
||||
* Kernel virtual address must also be mapped to kernel (normally `0xffff_ffff_8000_0000`)
|
||||
|
||||
## Sample kernel
|
||||
modinfo:
|
||||
```
|
||||
0xffffffff8282b000:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 20
|
||||
value: /boot/kernel/kernel
|
||||
0xffffffff8282b020:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 11
|
||||
value: elf kernel
|
||||
0xffffffff8282b038:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff80200000
|
||||
0xffffffff8282b048:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 32731368
|
||||
0xffffffff8282b058:
|
||||
type: (0x9004) MODINFO_METADATA | MODINFOMD_EFI_MAP
|
||||
len: 6080
|
||||
value: buffer contents omitted
|
||||
0xffffffff8282c820:
|
||||
type: (0x9005) MODINFO_METADATA | MODINFOMD_EFI_FB
|
||||
len: 48
|
||||
value: 0x0000000084000000
|
||||
0xffffffff8282c858:
|
||||
type: (0x800d) MODINFO_METADATA | MODINFOMD_KEYBUF
|
||||
len: 33028
|
||||
value: buffer contents omitted
|
||||
0xffffffff82834968:
|
||||
type: (0x800c) MODINFO_METADATA | MODINFOMD_FW_HANDLE
|
||||
len: 8
|
||||
value: buffer contents omitted
|
||||
0xffffffff82834978:
|
||||
type: (0x9006) MODINFO_METADATA | MODINFOMD_MODULEP
|
||||
len: 8
|
||||
value:
|
||||
0xffffffff82834988:
|
||||
type: (0x8008) MODINFO_METADATA | MODINFOMD_KERNEND
|
||||
len: 8
|
||||
value: 0x0000000002837000
|
||||
0xffffffff82834998:
|
||||
type: (0x8006) MODINFO_METADATA | MODINFOMD_ENVP
|
||||
len: 8
|
||||
value: 0x000000000282a000
|
||||
0xffffffff828349a8:
|
||||
type: (0x8007) MODINFO_METADATA | MODINFOMD_HOWTO
|
||||
len: 4
|
||||
value: 0x20000000
|
||||
0xffffffff828349b8:
|
||||
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
|
||||
len: 64
|
||||
value: buffer contents omitted
|
||||
0xffffffff82834a00:
|
||||
type: (0x8005) MODINFO_METADATA | MODINFOMD_DYNAMIC
|
||||
len: 8
|
||||
value: 0xffffffff81600000
|
||||
0xffffffff82834a10:
|
||||
type: (0x8004) MODINFO_METADATA | MODINFOMD_ESYM
|
||||
len: 8
|
||||
value: 0xffffffff821370e8
|
||||
0xffffffff82834a20:
|
||||
type: (0x8003) MODINFO_METADATA | MODINFOMD_SSYM
|
||||
len: 8
|
||||
value: 0xffffffff81e00000
|
||||
0xffffffff82834a30:
|
||||
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
|
||||
len: 3904
|
||||
value: buffer contents omitted
|
||||
0xffffffff82835978:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 20
|
||||
value: /boot/kernel/zfs.ko
|
||||
0xffffffff82835998:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 15
|
||||
value: elf obj module
|
||||
0xffffffff828359b0:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff82138000
|
||||
0xffffffff828359c0:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 6084104
|
||||
0xffffffff828359d0:
|
||||
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
|
||||
len: 64
|
||||
value: buffer contents omitted
|
||||
0xffffffff82835a18:
|
||||
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
|
||||
len: 1984
|
||||
value: buffer contents omitted
|
||||
0xffffffff828361e0:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 26
|
||||
value: /boot/kernel/cryptodev.ko
|
||||
0xffffffff82836208:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 15
|
||||
value: elf obj module
|
||||
0xffffffff82836220:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff82706000
|
||||
0xffffffff82836230:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 30680
|
||||
0xffffffff82836240:
|
||||
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
|
||||
len: 64
|
||||
value: buffer contents omitted
|
||||
0xffffffff82836288:
|
||||
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
|
||||
len: 1856
|
||||
value: buffer contents omitted
|
||||
0xffffffff828369d0:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 12
|
||||
value: /etc/hostid
|
||||
0xffffffff828369e8:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 9
|
||||
value: hostuuid
|
||||
0xffffffff82836a00:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff8270d7d8
|
||||
0xffffffff82836a10:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 37
|
||||
0xffffffff82836a20:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 14
|
||||
value: /boot/entropy
|
||||
0xffffffff82836a38:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 19
|
||||
value: boot_entropy_cache
|
||||
0xffffffff82836a58:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff8270d7fd
|
||||
0xffffffff82836a68:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 4096
|
||||
0xffffffff82836a78:
|
||||
type: (0x01) MODINFO_NAME
|
||||
len: 6
|
||||
value: TSLOG
|
||||
0xffffffff82836a88:
|
||||
type: (0x02) MODINFO_TYPE
|
||||
len: 11
|
||||
value: TSLOG data
|
||||
0xffffffff82836aa0:
|
||||
type: (0x03) MODINFO_ADDR
|
||||
len: 8
|
||||
value: 0xffffffff8270e7fd
|
||||
0xffffffff82836ab0:
|
||||
type: (0x04) MODINFO_SIZE
|
||||
len: 8
|
||||
value: 1159497
|
||||
```
|
||||
|
|
|
@ -181,8 +181,8 @@ impl Serialize for ModuleInfoValue {
|
|||
/// TODO: figure out how to make this properly typesafe
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleInfoItem {
|
||||
pub tag: ModuleInfoType,
|
||||
pub value: ModuleInfoValue,
|
||||
tag: ModuleInfoType,
|
||||
value: ModuleInfoValue,
|
||||
}
|
||||
|
||||
impl Serialize for ModuleInfoItem {
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -2,11 +2,10 @@
|
|||
#![no_std]
|
||||
|
||||
mod abi;
|
||||
mod object;
|
||||
mod staging;
|
||||
|
||||
use elf::endian::NativeEndian;
|
||||
use log::info;
|
||||
use object::{Kernel, Module};
|
||||
use uefi::{fs::FileSystem, prelude::*};
|
||||
|
||||
#[entry]
|
||||
|
@ -15,6 +14,8 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
|||
|
||||
info!("Starting freeloader");
|
||||
|
||||
let staging_buf = staging::allocate_staging(system_table.boot_services());
|
||||
|
||||
let mut esp = FileSystem::new(
|
||||
system_table
|
||||
.boot_services()
|
||||
|
@ -22,18 +23,18 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
|||
.expect("Failed to get ESP handle"),
|
||||
);
|
||||
|
||||
let kernel_data = esp
|
||||
let kernel = esp
|
||||
.read(cstr16!("efi\\freebsd\\kernel"))
|
||||
.expect("Failed to read kernel");
|
||||
|
||||
info!("Read kernel");
|
||||
info!("Loaded kernel");
|
||||
|
||||
let kernel = Kernel::from_elf_bytes(&kernel_data);
|
||||
staging_buf[..kernel.len()].copy_from_slice(&kernel);
|
||||
|
||||
info!(
|
||||
"Kernel metadata is {:#?}",
|
||||
kernel.metadata(core::ptr::null::<u8>())
|
||||
);
|
||||
let header =
|
||||
elf::ElfBytes::<NativeEndian>::minimal_parse(staging_buf).expect("Failed to parse kernel");
|
||||
|
||||
info!("Kernel is {:?}", header.ehdr.class);
|
||||
|
||||
loop {
|
||||
system_table.boot_services().stall(10_000_000);
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
extern crate alloc;
|
||||
|
||||
use crate::abi::{ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize};
|
||||
use alloc::vec::Vec;
|
||||
use goblin::elf::Elf;
|
||||
use log::info;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const NATIVE_ELF_MACHINE: u16 = goblin::elf::header::EM_X86_64;
|
||||
|
||||
pub trait Module {
|
||||
/// Associated metadata for this module, including name and type
|
||||
fn metadata(&self, load_address: *const u8) -> Vec<ModuleInfoItem>;
|
||||
}
|
||||
|
||||
pub struct Kernel<'a> {
|
||||
/// Full ELF
|
||||
elf: &'a [u8],
|
||||
/// Parsed ELF
|
||||
parsed: Elf<'a>,
|
||||
/// Raw ELF header bytes
|
||||
elf_header: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> Kernel<'a> {
|
||||
pub fn from_elf_bytes(elf: &'a [u8]) -> Self {
|
||||
let parsed = Elf::parse(elf).expect("Failed to parse kernel");
|
||||
if parsed.header.e_machine != NATIVE_ELF_MACHINE {
|
||||
panic!("Kernel has wrong ELF machine");
|
||||
}
|
||||
|
||||
let header_size = if parsed.is_64 { 0x40 } else { 0x34 };
|
||||
let elf_header = &elf[..header_size];
|
||||
|
||||
Self {
|
||||
elf,
|
||||
parsed,
|
||||
elf_header,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Serialize for Kernel<'a> {
|
||||
fn alignment() -> usize {
|
||||
// On some platforms we need to be aligned to a level 2 page
|
||||
2 * 1024 * 1024
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize(&self, out: &mut [u8]) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Module for Kernel<'a> {
|
||||
fn metadata(&self, load_address: *const u8) -> Vec<ModuleInfoItem> {
|
||||
alloc::vec![
|
||||
ModuleInfoItem {
|
||||
tag: ModuleInfoType::Name,
|
||||
value: ModuleInfoValue::StaticString("/boot/kernel/kernel")
|
||||
},
|
||||
ModuleInfoItem {
|
||||
tag: ModuleInfoType::Type,
|
||||
value: ModuleInfoValue::StaticString("elf kernel")
|
||||
},
|
||||
ModuleInfoItem {
|
||||
tag: ModuleInfoType::ElfHeader,
|
||||
value: ModuleInfoValue::Buffer(self.elf_header.to_vec())
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue