Skip to content

Commit

Permalink
AArch64: pass kernel cmdline through image handle
Browse files Browse the repository at this point in the history
cmdline is essential for direct kernel boot. To pass cmdline:
1. get original cmdline from FDT;
2. allocate memory for it;
3. convert raw cmdline from utf-8 to utf-16;
4. put cmdline info into image handle;

Signed-off-by: Jianyong Wu <[email protected]>
  • Loading branch information
jongwu committed Nov 23, 2023
1 parent 924690d commit 3e1374e
Showing 1 changed file with 44 additions and 2 deletions.
46 changes: 44 additions & 2 deletions src/efi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@ pub extern "efiapi" fn load_image(
path,
parent_image_handle,
wrapped_fs_ref as *const _ as Handle,
null_mut(),
0,
load_addr,
load_size,
entry_addr,
Expand Down Expand Up @@ -1033,10 +1035,13 @@ struct LoadedImageWrapper {

type DevicePaths = [file::FileDevicePathProtocol; 2];

#[allow(clippy::too_many_arguments)]
fn new_image_handle(
path: &str,
parent_handle: Handle,
device_handle: Handle,
load_options: *mut core::ffi::c_void,
load_options_size: u32,
load_addr: u64,
load_size: u64,
entry_addr: u64,
Expand Down Expand Up @@ -1088,8 +1093,8 @@ fn new_image_handle(
system_table: unsafe { &mut ST },
device_handle,
file_path: &mut file_paths[0].device_path, // Pointer to first path entry
load_options_size: 0,
load_options: null_mut(),
load_options_size,
load_options,
image_base: load_addr as *mut _,
image_size: load_size,
image_code_type: efi::LOADER_CODE,
Expand All @@ -1102,6 +1107,39 @@ fn new_image_handle(
image
}

#[cfg(target_arch = "aarch64")]
fn prepare_cmdline(info: &dyn bootinfo::Info) -> (*mut c_void, u32) {
let cmdline = info.cmdline();
let mut cmdline_size = cmdline.len();
let mut cmd_addr = null_mut();
// Allocate memory for cmdline
// cmdline will be converted to [u16], so size must be double
let status = allocate_pool(
efi::LOADER_DATA,
cmdline_size * 2,
&mut cmd_addr as *mut *mut c_void,
);

assert!(status == Status::SUCCESS);

let cmd_addr = cmd_addr as *mut u16;
// Linux asks for cmdline to be in format of utf-16.
for (i, p) in cmdline.iter().enumerate().take(cmdline_size) {
unsafe {
let tmp_addr = cmd_addr.add(i);
*tmp_addr = *p as u16;
}
}
cmdline_size *= 2;

(cmd_addr as *mut c_void, cmdline_size as u32)
}

#[cfg(not(target_arch = "aarch64"))]
fn prepare_cmdline(_info: &dyn bootinfo::Info) -> (*mut c_void, u32) {
(null_mut(), 0)
}

pub fn efi_exec(
address: u64,
loaded_address: u64,
Expand Down Expand Up @@ -1190,10 +1228,14 @@ pub fn efi_exec(
core::ptr::null::<u8>() as Handle
};

let (cmd_addr, cmdline_size) = prepare_cmdline(info);

let image = new_image_handle(
crate::efi::EFI_BOOT_PATH,
0 as Handle,
wrapped_fs,
cmd_addr,
cmdline_size,
loaded_address,
loaded_size,
address,
Expand Down

0 comments on commit 3e1374e

Please sign in to comment.