Skip to content

uefi: Fix shell args when run from a script #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 6 additions & 34 deletions framework_lib/src/commandline/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use alloc::vec::Vec;
use log::{debug, error, info, trace};
use uefi::prelude::BootServices;
use uefi::proto::shell_params::*;
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams, SearchType};
use uefi::Identify;
use uefi::Handle;

use crate::chromium_ec::commands::SetGpuSerialMagic;
use crate::chromium_ec::{CrosEcDriverType, HardwareDeviceType};
Expand All @@ -16,40 +15,13 @@ use crate::commandline::Cli;
use super::{ConsoleArg, FpBrightnessArg, InputDeckModeArg, RebootEcArg, TabletModeArg};

/// Get commandline arguments from UEFI environment
pub fn get_args(boot_services: &BootServices) -> Vec<String> {
// TODO: I think i should open this from the ImageHandle?
let shell_params_h =
boot_services.locate_handle_buffer(SearchType::ByProtocol(&ShellParameters::GUID));
let shell_params_h = if let Ok(shell_params_h) = shell_params_h {
shell_params_h
pub fn get_args(bs: &BootServices, image_handle: Handle) -> Vec<String> {
if let Ok(shell_params) = bs.open_protocol_exclusive::<ShellParameters>(image_handle) {
shell_params.get_args()
} else {
error!("ShellParameters protocol not found");
return vec![];
};

for handle in &*shell_params_h {
let params_handle = unsafe {
boot_services
.open_protocol::<ShellParameters>(
OpenProtocolParams {
handle: *handle,
agent: boot_services.image_handle(),
controller: None,
},
OpenProtocolAttributes::GetProtocol,
)
.expect("Failed to open ShellParameters handle")
};

// Ehm why are there two and one has no args?
// Maybe one is the shell itself?
if params_handle.argc == 0 {
continue;
}

return params_handle.get_args();
// No protocol found if the application wasn't executed by the shell
vec![]
}
vec![]
}

pub fn parse(args: &[String]) -> Cli {
Expand Down
3 changes: 3 additions & 0 deletions framework_uefi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ $(BUILD)/efi.img: $(BUILD)/boot.efi
mkfs.vfat $@.tmp
mmd -i $@.tmp efi
mmd -i $@.tmp efi/boot
echo 'efi\boot\bootx64.efi --version' > startup.nsh
mcopy -i $@.tmp startup.nsh ::efi/boot/startup.nsh
rm -f startup.nsh
mcopy -i $@.tmp $< ::efi/boot/bootx64.efi
mv $@.tmp $@

Expand Down
4 changes: 2 additions & 2 deletions framework_uefi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ extern crate alloc;
use framework_lib::commandline;

#[entry]
fn main(_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi_services::init(&mut system_table).unwrap();
let bs = system_table.boot_services();

let args = commandline::uefi::get_args(bs);
let args = commandline::uefi::get_args(bs, image_handle);
let args = commandline::parse(&args);
if commandline::run_with_args(&args, false) == 0 {
return Status::SUCCESS;
Expand Down
Loading