Add more ABI types

This commit is contained in:
Artemis Tosini 2024-08-04 20:10:09 +00:00
parent a5da22da18
commit 9e36a39444
Signed by: artemist
GPG key ID: EE5227935FE3FF18
3 changed files with 128 additions and 6 deletions

1
Cargo.lock generated
View file

@ -24,6 +24,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
name = "freeloader"
version = "0.1.0"
dependencies = [
"bitflags",
"goblin",
"log",
"uefi",

View file

@ -8,3 +8,4 @@ uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "gl
log = { version = "0.4.22", default-features = false }
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
x86_64 = { version = "0.15.1", default-features = false }
bitflags = "2.6.0"

View file

@ -1,6 +1,9 @@
extern crate alloc;
use alloc::vec::Vec;
use alloc::{collections::BTreeMap, string::String};
use bitflags::bitflags;
use uefi::prelude::BootServices;
use uefi::table::boot::MemoryType;
use uefi::{
proto::console::gop::{GraphicsOutput, PixelFormat},
table::boot::PAGE_SIZE,
@ -112,6 +115,110 @@ impl Serialize for EFIFramebufferParams {
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct EFIMemoryMapHeader {
memory_size: usize,
descriptor_size: usize,
descriptor_version: u32,
}
#[derive(Debug, Clone)]
pub struct EFIMemoryMapParams {
header: EFIMemoryMapHeader,
map: Vec<u8>,
}
impl EFIMemoryMapParams {
pub fn from_boot_services(bs: &BootServices) -> Self {
let map = bs
.memory_map(MemoryType::LOADER_DATA)
.expect("Failed to get EFI memory map");
let (raw, meta) = map.as_raw();
let header = EFIMemoryMapHeader {
memory_size: meta.map_size,
descriptor_size: meta.desc_size,
descriptor_version: meta.desc_version,
};
Self {
header,
map: raw.to_vec(),
}
}
}
impl Serialize for EFIMemoryMapParams {
fn alignment() -> usize {
4
}
fn size(&self) -> usize {
core::mem::size_of::<EFIMemoryMapHeader>() + self.map.len()
}
fn serialize_raw(&self, out: &mut [u8]) {
let header_size = core::mem::size_of_val(&self.header);
let header_bytes = unsafe {
core::slice::from_raw_parts(
&self.header as *const EFIMemoryMapHeader as *const u8,
header_size,
)
};
out[..header_size].copy_from_slice(header_bytes);
out[header_size..].copy_from_slice(&self.map);
}
}
bitflags! {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Howto: u32 {
/// Don't set flags, system should figure it out
const AUTOBOOT = 0;
/// Prompt for root filesystem
const ASKNAME = 1 << 0;
/// Enter single user mode
const SINGLE = 1 << 1;
/// Use default rootdev from kernel buidl time
const DFLTROOT = 1 << 5;
/// Enable kernel debugger
const KDB = 1 << 6;
/// Make console more verbose
const VERBOSE = 1 << 11;
/// Set serial port as primary console
const SERIAL = 1 << 12;
/// Boot from CD rootfs
const CDROM = 1 << 13;
/// Use gdb for kernel debugger
const GDB = 1 << 15;
/// Disable console output
const MUTE = 1 << 16;
/// Wait for input after every console line
const PAUSE = 1 << 20;
///Make console quieter
const QUIET = 1 << 21;
/// Set console to both serial and display
const DUAL = 1 << 29;
}
}
impl Serialize for Howto {
fn alignment() -> usize {
core::mem::size_of::<u32>()
}
fn size(&self) -> usize {
core::mem::size_of::<u32>()
}
fn serialize_raw(&self, out: &mut [u8]) {
out.copy_from_slice(&u32::to_ne_bytes(self.bits()))
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
#[allow(dead_code)]
@ -176,10 +283,12 @@ pub enum ModuleInfoType {
pub enum ModuleInfoValue {
StaticString(&'static str),
String(String),
// TODO: figure out how to make this pointer safer
Pointer(*const u8),
Size(usize),
Buffer(Vec<u8>),
Howto(Howto),
EFIFrameBuffer(EFIFramebufferParams),
EFIMemoryMap(EFIMemoryMapParams),
}
impl ModuleInfoValue {
@ -201,6 +310,9 @@ impl Serialize for ModuleInfoValue {
ModuleInfoValue::Pointer(obj) => core::mem::size_of_val(obj),
ModuleInfoValue::Size(obj) => core::mem::size_of_val(obj),
ModuleInfoValue::Buffer(buf) => buf.len(),
ModuleInfoValue::Howto(obj) => obj.size(),
ModuleInfoValue::EFIFrameBuffer(obj) => obj.size(),
ModuleInfoValue::EFIMemoryMap(obj) => obj.size(),
}
}
@ -211,6 +323,9 @@ impl Serialize for ModuleInfoValue {
ModuleInfoValue::Pointer(p) => out.copy_from_slice(&usize::to_ne_bytes(*p as usize)),
ModuleInfoValue::Size(p) => out.copy_from_slice(&usize::to_ne_bytes(*p)),
ModuleInfoValue::Buffer(buf) => out.copy_from_slice(buf),
ModuleInfoValue::Howto(obj) => obj.serialize_raw(out),
ModuleInfoValue::EFIFrameBuffer(obj) => obj.serialize_raw(out),
ModuleInfoValue::EFIMemoryMap(obj) => obj.serialize_raw(out),
}
}
}
@ -218,11 +333,16 @@ impl Serialize for ModuleInfoValue {
impl core::fmt::Debug for ModuleInfoValue {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::StaticString(arg0) => f.debug_tuple("StaticString").field(arg0).finish(),
Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
Self::Pointer(arg0) => f.debug_tuple("Pointer").field(arg0).finish(),
Self::Size(arg0) => f.debug_tuple("Size").field(arg0).finish(),
Self::Buffer(arg0) => write!(f, "Buffer(len={})", arg0.len()),
ModuleInfoValue::StaticString(arg0) => {
f.debug_tuple("StaticString").field(arg0).finish()
}
ModuleInfoValue::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
ModuleInfoValue::Pointer(arg0) => f.debug_tuple("Pointer").field(arg0).finish(),
ModuleInfoValue::Size(arg0) => f.debug_tuple("Size").field(arg0).finish(),
ModuleInfoValue::Buffer(arg0) => write!(f, "Buffer(len={})", arg0.len()),
ModuleInfoValue::Howto(arg0) => f.debug_tuple("Howto").field(arg0).finish(),
ModuleInfoValue::EFIFrameBuffer(_) => write!(f, "EFIFrameBuffer(elided)"),
ModuleInfoValue::EFIMemoryMap(_) => write!(f, "EFIMemoryMap(elided)"),
}
}
}