Skip to content

Commit 3e1374e

Browse files
committed
AArch64: pass kernel cmdline through image handle
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]>
1 parent 924690d commit 3e1374e

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

src/efi/mod.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ pub extern "efiapi" fn load_image(
693693
path,
694694
parent_image_handle,
695695
wrapped_fs_ref as *const _ as Handle,
696+
null_mut(),
697+
0,
696698
load_addr,
697699
load_size,
698700
entry_addr,
@@ -1033,10 +1035,13 @@ struct LoadedImageWrapper {
10331035

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

1038+
#[allow(clippy::too_many_arguments)]
10361039
fn new_image_handle(
10371040
path: &str,
10381041
parent_handle: Handle,
10391042
device_handle: Handle,
1043+
load_options: *mut core::ffi::c_void,
1044+
load_options_size: u32,
10401045
load_addr: u64,
10411046
load_size: u64,
10421047
entry_addr: u64,
@@ -1088,8 +1093,8 @@ fn new_image_handle(
10881093
system_table: unsafe { &mut ST },
10891094
device_handle,
10901095
file_path: &mut file_paths[0].device_path, // Pointer to first path entry
1091-
load_options_size: 0,
1092-
load_options: null_mut(),
1096+
load_options_size,
1097+
load_options,
10931098
image_base: load_addr as *mut _,
10941099
image_size: load_size,
10951100
image_code_type: efi::LOADER_CODE,
@@ -1102,6 +1107,39 @@ fn new_image_handle(
11021107
image
11031108
}
11041109

1110+
#[cfg(target_arch = "aarch64")]
1111+
fn prepare_cmdline(info: &dyn bootinfo::Info) -> (*mut c_void, u32) {
1112+
let cmdline = info.cmdline();
1113+
let mut cmdline_size = cmdline.len();
1114+
let mut cmd_addr = null_mut();
1115+
// Allocate memory for cmdline
1116+
// cmdline will be converted to [u16], so size must be double
1117+
let status = allocate_pool(
1118+
efi::LOADER_DATA,
1119+
cmdline_size * 2,
1120+
&mut cmd_addr as *mut *mut c_void,
1121+
);
1122+
1123+
assert!(status == Status::SUCCESS);
1124+
1125+
let cmd_addr = cmd_addr as *mut u16;
1126+
// Linux asks for cmdline to be in format of utf-16.
1127+
for (i, p) in cmdline.iter().enumerate().take(cmdline_size) {
1128+
unsafe {
1129+
let tmp_addr = cmd_addr.add(i);
1130+
*tmp_addr = *p as u16;
1131+
}
1132+
}
1133+
cmdline_size *= 2;
1134+
1135+
(cmd_addr as *mut c_void, cmdline_size as u32)
1136+
}
1137+
1138+
#[cfg(not(target_arch = "aarch64"))]
1139+
fn prepare_cmdline(_info: &dyn bootinfo::Info) -> (*mut c_void, u32) {
1140+
(null_mut(), 0)
1141+
}
1142+
11051143
pub fn efi_exec(
11061144
address: u64,
11071145
loaded_address: u64,
@@ -1190,10 +1228,14 @@ pub fn efi_exec(
11901228
core::ptr::null::<u8>() as Handle
11911229
};
11921230

1231+
let (cmd_addr, cmdline_size) = prepare_cmdline(info);
1232+
11931233
let image = new_image_handle(
11941234
crate::efi::EFI_BOOT_PATH,
11951235
0 as Handle,
11961236
wrapped_fs,
1237+
cmd_addr,
1238+
cmdline_size,
11971239
loaded_address,
11981240
loaded_size,
11991241
address,

0 commit comments

Comments
 (0)