Pass on command line from UKI to Linux kernel

This commit is contained in:
Julian Stecklina 2022-11-23 12:11:20 +01:00
parent 8f2f11aa1b
commit 5a6c05cf11
3 changed files with 51 additions and 16 deletions

View File

@ -72,7 +72,7 @@
VERSION="${lanzaboote.version}" VERSION="${lanzaboote.version}"
''; '';
cmdline = pkgs.writeText "lanzaboote-cmdline" ""; cmdline = pkgs.writeText "lanzaboote-cmdline" "console=ttyS0";
lanzaboote-uki = pkgs.runCommand "lanzboote-uki" { lanzaboote-uki = pkgs.runCommand "lanzboote-uki" {
nativeBuildInputs = [ nativeBuildInputs = [

View File

@ -14,18 +14,15 @@ use uefi::{
prelude::*, prelude::*,
proto::{ proto::{
console::text::Output, console::text::Output,
device_path::text::{AllowShortcuts, DevicePathToText, DisplayOnly},
loaded_image::LoadedImage, loaded_image::LoadedImage,
media::file::{File, FileAttribute, FileMode, RegularFile}, media::file::{File, FileAttribute, FileMode},
}, },
table::boot::{OpenProtocolAttributes, OpenProtocolParams},
Result,
}; };
use crate::{ use crate::{
linux_loader::InitrdLoader, linux_loader::InitrdLoader,
pe_section::pe_section, pe_section::pe_section,
uefi_helpers::{booted_image_file, read_all}, uefi_helpers::{booted_image_cmdline, booted_image_file, read_all},
}; };
fn print_logo(output: &mut Output) { fn print_logo(output: &mut Output) {
@ -52,17 +49,19 @@ fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
print_logo(system_table.stdout()); print_logo(system_table.stdout());
let boot_services = system_table.boot_services();
{ {
let image_data = read_all(&mut booted_image_file(boot_services).unwrap()).unwrap(); let image_data =
read_all(&mut booted_image_file(system_table.boot_services()).unwrap()).unwrap();
if let Some(data) = pe_section(&image_data, ".osrel") { if let Some(data) = pe_section(&image_data, ".osrel") {
info!("osrel = {}", core::str::from_utf8(data).unwrap_or("???")) info!("osrel = {}", core::str::from_utf8(data).unwrap_or("???"))
} }
} }
let mut file_system = boot_services.get_image_file_system(handle).unwrap(); let mut file_system = system_table
.boot_services()
.get_image_file_system(handle)
.unwrap();
let mut root = file_system.open_volume().unwrap(); let mut root = file_system.open_volume().unwrap();
let mut file = root let mut file = root
@ -77,23 +76,47 @@ fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
.into_regular_file() .into_regular_file()
.unwrap(); .unwrap();
// We need to manually drop those to be able to touch the system_table again.
drop(root);
drop(file_system);
debug!("Opened file"); debug!("Opened file");
let kernel = read_all(&mut file).unwrap(); let kernel_cmdline = booted_image_cmdline(system_table.boot_services()).unwrap();
let kernel_image = boot_services let kernel_data = read_all(&mut file).unwrap();
let kernel_handle = system_table
.boot_services()
.load_image( .load_image(
handle, handle,
uefi::table::boot::LoadImageSource::FromBuffer { uefi::table::boot::LoadImageSource::FromBuffer {
buffer: &kernel, buffer: &kernel_data,
file_path: None, file_path: None,
}, },
) )
.unwrap(); .unwrap();
let mut initrd_loader = InitrdLoader::new(&boot_services, handle, initrd).unwrap(); let mut kernel_image = system_table
let status = boot_services.start_image(kernel_image).status(); .boot_services()
.open_protocol_exclusive::<LoadedImage>(kernel_handle)
.unwrap();
initrd_loader.uninstall(&boot_services).unwrap(); unsafe {
kernel_image.set_load_options(
kernel_cmdline.as_ptr() as *const u8,
u32::try_from(kernel_cmdline.len()).unwrap(),
);
}
let mut initrd_loader =
InitrdLoader::new(&system_table.boot_services(), handle, initrd).unwrap();
let status = system_table
.boot_services()
.start_image(kernel_handle)
.status();
initrd_loader
.uninstall(&system_table.boot_services())
.unwrap();
status status
} }

View File

@ -56,3 +56,15 @@ pub fn booted_image_file(boot_services: &BootServices) -> Result<RegularFile> {
.into_regular_file() .into_regular_file()
.ok_or(Status::INVALID_PARAMETER)?) .ok_or(Status::INVALID_PARAMETER)?)
} }
/// Return the command line of the currently executing image.
pub fn booted_image_cmdline(boot_services: &BootServices) -> Result<Vec<u8>> {
let loaded_image =
boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())?;
Ok(loaded_image
// If this fails, we have no load options and we return an empty string.
.load_options_as_bytes()
.map(|b| b.to_vec())
.unwrap_or_else(|| Vec::new()))
}