Compare commits
2 commits
5a86c41d07
...
405cdf8f26
Author | SHA1 | Date | |
---|---|---|---|
Artemis Tosini | 405cdf8f26 | ||
Artemis Tosini | 0f2fa36333 |
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -20,27 +20,38 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "elf"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "freeloader"
|
name = "freeloader"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"elf",
|
"goblin",
|
||||||
"log",
|
"log",
|
||||||
"uefi",
|
"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]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.22"
|
version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plain"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.86"
|
version = "1.0.86"
|
||||||
|
@ -79,6 +90,26 @@ dependencies = [
|
||||||
"proc-macro2",
|
"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]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
|
|
@ -6,4 +6,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] }
|
uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] }
|
||||||
log = { version = "0.4.22", default-features = false }
|
log = { version = "0.4.22", default-features = false }
|
||||||
elf = { version = "0.7.4", default_features = false }
|
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
||||||
|
|
169
notes.md
169
notes.md
|
@ -40,3 +40,172 @@ Tons of arch-specific restrictions
|
||||||
* Pointers are passed as 32-bit, must be within the first 4G
|
* Pointers are passed as 32-bit, must be within the first 4G
|
||||||
* First 4G of virtual memory must be identity mapped
|
* First 4G of virtual memory must be identity mapped
|
||||||
* Kernel virtual address must also be mapped to kernel (normally `0xffff_ffff_8000_0000`)
|
* 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
|
/// TODO: figure out how to make this properly typesafe
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ModuleInfoItem {
|
pub struct ModuleInfoItem {
|
||||||
tag: ModuleInfoType,
|
pub tag: ModuleInfoType,
|
||||||
value: ModuleInfoValue,
|
pub value: ModuleInfoValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for ModuleInfoItem {
|
impl Serialize for ModuleInfoItem {
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -2,10 +2,11 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
mod abi;
|
mod abi;
|
||||||
|
mod object;
|
||||||
mod staging;
|
mod staging;
|
||||||
|
|
||||||
use elf::endian::NativeEndian;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use object::{Kernel, Module};
|
||||||
use uefi::{fs::FileSystem, prelude::*};
|
use uefi::{fs::FileSystem, prelude::*};
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
|
@ -14,8 +15,6 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
||||||
|
|
||||||
info!("Starting freeloader");
|
info!("Starting freeloader");
|
||||||
|
|
||||||
let staging_buf = staging::allocate_staging(system_table.boot_services());
|
|
||||||
|
|
||||||
let mut esp = FileSystem::new(
|
let mut esp = FileSystem::new(
|
||||||
system_table
|
system_table
|
||||||
.boot_services()
|
.boot_services()
|
||||||
|
@ -23,18 +22,18 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
||||||
.expect("Failed to get ESP handle"),
|
.expect("Failed to get ESP handle"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let kernel = esp
|
let kernel_data = esp
|
||||||
.read(cstr16!("efi\\freebsd\\kernel"))
|
.read(cstr16!("efi\\freebsd\\kernel"))
|
||||||
.expect("Failed to read kernel");
|
.expect("Failed to read kernel");
|
||||||
|
|
||||||
info!("Loaded kernel");
|
info!("Read kernel");
|
||||||
|
|
||||||
staging_buf[..kernel.len()].copy_from_slice(&kernel);
|
let kernel = Kernel::from_elf_bytes(&kernel_data);
|
||||||
|
|
||||||
let header =
|
info!(
|
||||||
elf::ElfBytes::<NativeEndian>::minimal_parse(staging_buf).expect("Failed to parse kernel");
|
"Kernel metadata is {:#?}",
|
||||||
|
kernel.metadata(core::ptr::null::<u8>())
|
||||||
info!("Kernel is {:?}", header.ehdr.class);
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
system_table.boot_services().stall(10_000_000);
|
system_table.boot_services().stall(10_000_000);
|
||||||
|
|
75
src/object.rs
Normal file
75
src/object.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
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