Add more ABI types
This commit is contained in:
parent
a5da22da18
commit
9e36a39444
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -24,6 +24,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
name = "freeloader"
|
name = "freeloader"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
"goblin",
|
"goblin",
|
||||||
"log",
|
"log",
|
||||||
"uefi",
|
"uefi",
|
||||||
|
|
|
@ -8,3 +8,4 @@ uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "gl
|
||||||
log = { version = "0.4.22", default-features = false }
|
log = { version = "0.4.22", default-features = false }
|
||||||
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
goblin = { version = "0.8.2", default-features = false, features = [ "elf64", "elf32", "endian_fd" ] }
|
||||||
x86_64 = { version = "0.15.1", default-features = false }
|
x86_64 = { version = "0.15.1", default-features = false }
|
||||||
|
bitflags = "2.6.0"
|
||||||
|
|
132
src/abi.rs
132
src/abi.rs
|
@ -1,6 +1,9 @@
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use alloc::{collections::BTreeMap, string::String};
|
use alloc::{collections::BTreeMap, string::String};
|
||||||
|
use bitflags::bitflags;
|
||||||
|
use uefi::prelude::BootServices;
|
||||||
|
use uefi::table::boot::MemoryType;
|
||||||
use uefi::{
|
use uefi::{
|
||||||
proto::console::gop::{GraphicsOutput, PixelFormat},
|
proto::console::gop::{GraphicsOutput, PixelFormat},
|
||||||
table::boot::PAGE_SIZE,
|
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)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -176,10 +283,12 @@ pub enum ModuleInfoType {
|
||||||
pub enum ModuleInfoValue {
|
pub enum ModuleInfoValue {
|
||||||
StaticString(&'static str),
|
StaticString(&'static str),
|
||||||
String(String),
|
String(String),
|
||||||
// TODO: figure out how to make this pointer safer
|
|
||||||
Pointer(*const u8),
|
Pointer(*const u8),
|
||||||
Size(usize),
|
Size(usize),
|
||||||
Buffer(Vec<u8>),
|
Buffer(Vec<u8>),
|
||||||
|
Howto(Howto),
|
||||||
|
EFIFrameBuffer(EFIFramebufferParams),
|
||||||
|
EFIMemoryMap(EFIMemoryMapParams),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInfoValue {
|
impl ModuleInfoValue {
|
||||||
|
@ -201,6 +310,9 @@ impl Serialize for ModuleInfoValue {
|
||||||
ModuleInfoValue::Pointer(obj) => core::mem::size_of_val(obj),
|
ModuleInfoValue::Pointer(obj) => core::mem::size_of_val(obj),
|
||||||
ModuleInfoValue::Size(obj) => core::mem::size_of_val(obj),
|
ModuleInfoValue::Size(obj) => core::mem::size_of_val(obj),
|
||||||
ModuleInfoValue::Buffer(buf) => buf.len(),
|
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::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::Size(p) => out.copy_from_slice(&usize::to_ne_bytes(*p)),
|
||||||
ModuleInfoValue::Buffer(buf) => out.copy_from_slice(buf),
|
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 {
|
impl core::fmt::Debug for ModuleInfoValue {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::StaticString(arg0) => f.debug_tuple("StaticString").field(arg0).finish(),
|
ModuleInfoValue::StaticString(arg0) => {
|
||||||
Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
|
f.debug_tuple("StaticString").field(arg0).finish()
|
||||||
Self::Pointer(arg0) => f.debug_tuple("Pointer").field(arg0).finish(),
|
}
|
||||||
Self::Size(arg0) => f.debug_tuple("Size").field(arg0).finish(),
|
ModuleInfoValue::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
|
||||||
Self::Buffer(arg0) => write!(f, "Buffer(len={})", arg0.len()),
|
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)"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue