major cleanup

This commit is contained in:
2025-07-02 00:27:56 +02:00
parent 7655b589d6
commit a59b723f4b
7 changed files with 62 additions and 80 deletions

17
Cargo.lock generated
View File

@ -1,12 +1,11 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "barnacle" name = "barnacle"
version = "0.2.0" version = "0.3.0"
dependencies = [ dependencies = [
"log",
"uefi", "uefi",
"uefi-services", "uefi-services",
] ]
@ -97,9 +96,9 @@ dependencies = [
[[package]] [[package]]
name = "ucs2" name = "ucs2"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad643914094137d475641b6bab89462505316ec2ce70907ad20102d28a79ab8" checksum = "df79298e11f316400c57ec268f3c2c29ac3c4d4777687955cd3d4f3a35ce7eba"
dependencies = [ dependencies = [
"bit_field", "bit_field",
] ]
@ -132,9 +131,9 @@ dependencies = [
[[package]] [[package]]
name = "uefi-raw" name = "uefi-raw"
version = "0.5.0" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864ac69eadd877bfb34e7814be1928122ed0057d9f975169a56ee496aa7bdfd7" checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"ptr_meta", "ptr_meta",
@ -154,9 +153,9 @@ dependencies = [
[[package]] [[package]]
name = "uguid" name = "uguid"
version = "2.1.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ef516f0806c5f61da6aa95125d0eb2d91cc95b2df426c06bde8be657282aee5" checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"

View File

@ -1,20 +1,10 @@
[package] [package]
name = "barnacle" name = "barnacle"
version = "0.2.0" version = "0.3.0"
edition = "2021" edition = "2021"
[[bin]]
name = "barnacle"
test = false
bench = false
[lib]
test = false
bench = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4.20"
uefi = "0.26.0" uefi = "0.26.0"
uefi-services = "0.23.0" uefi-services = "0.23.0"

View File

@ -20,8 +20,8 @@ pub struct Loader {
pub fn make_loader(pointer: *const c_void, size: usize) -> Loader { pub fn make_loader(pointer: *const c_void, size: usize) -> Loader {
Loader { Loader {
_handler: initrd_loadfile2 as *const c_void, _handler: initrd_loadfile2 as *const c_void,
buf: pointer as *const c_void, buf: pointer,
size: size as usize, size,
} }
} }
@ -54,8 +54,8 @@ pub fn install_initrd(
} }
/// Creates a device path for a virtual device with the Linux initrd vendor GUID /// Creates a device path for a virtual device with the Linux initrd vendor GUID
pub fn make_initrd_device_path<'a>(buf: &'a mut [MaybeUninit<u8>; 256]) -> &'a DevicePath { pub fn make_initrd_device_path(buf: &mut [MaybeUninit<u8>; 256]) -> &DevicePath {
&build::DevicePathBuilder::with_buf(buf) build::DevicePathBuilder::with_buf(buf)
.push(&build::media::Vendor { .push(&build::media::Vendor {
vendor_guid: LINUX_INITRD_DEVICE_GUID, vendor_guid: LINUX_INITRD_DEVICE_GUID,
vendor_defined_data: &[], vendor_defined_data: &[],
@ -77,7 +77,7 @@ fn initrd_loadfile2(
) -> Status { ) -> Status {
unsafe { unsafe {
// Invalid buffer or insufficient size // Invalid buffer or insufficient size
if (*this).size > *size || buf == core::ptr::null_mut() { if (*this).size > *size || buf.is_null() {
// Update size parameter to specify expected space // Update size parameter to specify expected space
*size = (*this).size; *size = (*this).size;
return Status::BUFFER_TOO_SMALL; return Status::BUFFER_TOO_SMALL;

View File

@ -11,8 +11,13 @@ mod pe;
mod secureboot; mod secureboot;
mod unicode; mod unicode;
pub fn bootloader(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { #[cfg(not(test))]
uefi_services::init(&mut system_table).unwrap(); #[panic_handler]
pub fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
pub fn bootloader(image_handle: Handle, system_table: SystemTable<Boot>) -> Status {
let boot_services = system_table.boot_services(); let boot_services = system_table.boot_services();
let sections = get_loader_sections(boot_services).unwrap(); let sections = get_loader_sections(boot_services).unwrap();
start_linux(image_handle, boot_services, sections).unwrap(); start_linux(image_handle, boot_services, sections).unwrap();

View File

@ -22,22 +22,22 @@ pub fn start_linux(
) -> Result { ) -> Result {
// Load kernel as image from memory ignoring secure boot // Load kernel as image from memory ignoring secure boot
// Image is already trusted (signed) by being part of this EFI program // Image is already trusted (signed) by being part of this EFI program
let handle = unsafe { let handle = run_in_security_override(boot_services, || {
run_in_security_override(boot_services, || { boot_services
boot_services .load_image(
.load_image( image_handle,
image_handle, LoadImageSource::FromBuffer {
LoadImageSource::FromBuffer { buffer: unsafe {
buffer: &*slice_from_raw_parts::<u8>( &*slice_from_raw_parts::<u8>(
sections.linux.pointer, sections.linux.pointer,
sections.linux.size as usize, sections.linux.size as usize,
), )
file_path: None,
}, },
) file_path: None,
.unwrap() },
}) )
}; .unwrap()
})?;
let mut linux_image = boot_services let mut linux_image = boot_services
.open_protocol_exclusive::<LoadedImage>(handle) .open_protocol_exclusive::<LoadedImage>(handle)

View File

@ -2,9 +2,9 @@ use uefi::prelude::BootServices;
use uefi::proto::loaded_image::LoadedImage; use uefi::proto::loaded_image::LoadedImage;
use uefi::{Error, Result, Status}; use uefi::{Error, Result, Status};
const LINUX_SNAME: [u8; 8] = [0x2e, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0, 0]; const LINUX_SNAME: [u8; 8] = *b".linux\0\0";
const CMDLINE_SNAME: [u8; 8] = [0x2e, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65]; const CMDLINE_SNAME: [u8; 8] = *b".cmdline";
const INITRD_SNAME: [u8; 8] = [0x2e, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, 0]; const INITRD_SNAME: [u8; 8] = *b".initrd\0";
pub struct PESection { pub struct PESection {
pub name: [u8; 8], pub name: [u8; 8],
@ -52,8 +52,8 @@ pub fn get_loader_sections(boot_services: &BootServices) -> Result<BootSections>
// Section name at 0 bytes offset, 8 bytes long // Section name at 0 bytes offset, 8 bytes long
let mut name = [0; 8]; let mut name = [0; 8];
for j in 0..8 { for (j, char) in name.iter_mut().enumerate() {
name[j] = *section_row_ptr.add(j); *char = *section_row_ptr.add(j);
} }
// Section VMA at 12 bytes offset, 4 bytes long // Section VMA at 12 bytes offset, 4 bytes long
@ -68,12 +68,11 @@ pub fn get_loader_sections(boot_services: &BootServices) -> Result<BootSections>
}; };
// Section identification // Section identification
if section.name == LINUX_SNAME { match section.name {
tmp_sections.linux = Some(section); LINUX_SNAME => tmp_sections.linux = Some(section),
} else if section.name == CMDLINE_SNAME { CMDLINE_SNAME => tmp_sections.cmdline = Some(section),
tmp_sections.cmdline = Some(section); INITRD_SNAME => tmp_sections.initrd = Some(section),
} else if section.name == INITRD_SNAME { _ => {}
tmp_sections.initrd = Some(section);
} }
} }

View File

@ -1,7 +1,6 @@
use core::ffi::c_void; use core::ffi::c_void;
use log::info; use uefi::{prelude::BootServices, proto::unsafe_protocol, Result};
use uefi::{prelude::BootServices, proto::unsafe_protocol};
#[unsafe_protocol("A46423E3-4617-49F1-B9FF-D1BFA9115839")] #[unsafe_protocol("A46423E3-4617-49F1-B9FF-D1BFA9115839")]
struct SecurityArch { struct SecurityArch {
@ -22,60 +21,50 @@ fn security_handler() -> bool {
/// Runs a function with a blind secure boot validator /// Runs a function with a blind secure boot validator
/// Plagiarized from systemd-stub's "hack" /// Plagiarized from systemd-stub's "hack"
/// There must be a better way /// There must be a better way
pub fn run_in_security_override<R, T: Fn() -> R>(boot_services: &BootServices, function: T) -> R { pub fn run_in_security_override<R, T: Fn() -> R>(
// Backup storage boot_services: &BootServices,
function: T,
) -> Result<R> {
// Temporary storage for restoration later
let mut df_security1 = None; let mut df_security1 = None;
let mut df_security1_handler = None; let mut df_security1_handler = None;
let mut df_security2 = None; let mut df_security2 = None;
let mut df_security2_handler = None; let mut df_security2_handler = None;
// Obtain SecurityArch protocol and replace handler // Obtain SecurityArch protocol and replace handler
boot_services boot_services
.get_handle_for_protocol::<SecurityArch>() .get_handle_for_protocol::<SecurityArch>()
.and_then(|h| { .map(|h| {
boot_services boot_services
.open_protocol_exclusive::<SecurityArch>(h) .open_protocol_exclusive::<SecurityArch>(h)
.and_then(|mut security| { .map(|mut security| {
df_security1 = Some(core::ptr::addr_of_mut!(security.handler)); df_security1 = Some(core::ptr::addr_of_mut!(security.handler));
df_security1_handler = Some(security.handler); df_security1_handler = Some(security.handler);
security.handler = security_handler as *const c_void; security.handler = security_handler as *const c_void;
Ok(())
}) })
.unwrap_or_else(|_| { })??;
info!("security1 unsupported");
});
Ok(())
})
.unwrap_or_else(|_| {
info!("security1 not found");
});
// Obtain Security2Arch protocol and replace handler // Obtain Security2Arch protocol and replace handler
boot_services boot_services
.get_handle_for_protocol::<Security2Arch>() .get_handle_for_protocol::<Security2Arch>()
.and_then(|h| { .map(|h| {
boot_services boot_services
.open_protocol_exclusive::<Security2Arch>(h) .open_protocol_exclusive::<Security2Arch>(h)
.and_then(|mut security| { .map(|mut security| {
df_security2 = Some(core::ptr::addr_of_mut!(security.handler)); df_security2 = Some(core::ptr::addr_of_mut!(security.handler));
df_security2_handler = Some(security.handler); df_security2_handler = Some(security.handler);
security.handler = security_handler as *const c_void; security.handler = security_handler as *const c_void;
Ok(())
}) })
.unwrap_or_else(|_| { })??;
info!("security2 unsupported");
});
Ok(())
})
.unwrap_or_else(|_| {
info!("security2 not found");
});
// Run the parameter function
let x = function(); let x = function();
// Restore default SecurityArch handler // Restore default SecurityArch handler
df_security1.and_then(|s1| df_security1_handler.and_then(|s1h| Some(unsafe { *s1 = s1h }))); df_security1.and_then(|s1| df_security1_handler.map(|s1h| unsafe { *s1 = s1h }));
// Restore default SecurityArch2 handler // Restore default SecurityArch2 handler
df_security2.and_then(|s2| df_security2_handler.and_then(|s2h| Some(unsafe { *s2 = s2h }))); df_security2.and_then(|s2| df_security2_handler.map(|s2h| unsafe { *s2 = s2h }));
x Ok(x)
} }