Skip to content

Commit bcd2900

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 07d04b5 commit bcd2900

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
@@ -694,6 +694,8 @@ pub extern "efiapi" fn load_image(
694694
path,
695695
parent_image_handle,
696696
wrapped_fs_ref as *const _ as Handle,
697+
null_mut(),
698+
0,
697699
load_addr,
698700
load_size,
699701
entry_addr,
@@ -1034,10 +1036,13 @@ struct LoadedImageWrapper {
10341036

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

1039+
#[allow(clippy::too_many_arguments)]
10371040
fn new_image_handle(
10381041
path: &str,
10391042
parent_handle: Handle,
10401043
device_handle: Handle,
1044+
load_options: *mut core::ffi::c_void,
1045+
load_options_size: u32,
10411046
load_addr: u64,
10421047
load_size: u64,
10431048
entry_addr: u64,
@@ -1089,8 +1094,8 @@ fn new_image_handle(
10891094
system_table: unsafe { &mut ST },
10901095
device_handle,
10911096
file_path: &mut file_paths[0].device_path, // Pointer to first path entry
1092-
load_options_size: 0,
1093-
load_options: null_mut(),
1097+
load_options_size,
1098+
load_options,
10941099
image_base: load_addr as *mut _,
10951100
image_size: load_size,
10961101
image_code_type: efi::LOADER_CODE,
@@ -1103,6 +1108,39 @@ fn new_image_handle(
11031108
image
11041109
}
11051110

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

1233+
let (cmd_addr, cmdline_size) = prepare_cmdline(info);
1234+
11951235
let image = new_image_handle(
11961236
crate::efi::EFI_BOOT_PATH,
11971237
0 as Handle,
11981238
wrapped_fs,
1239+
cmd_addr,
1240+
cmdline_size,
11991241
loaded_address,
12001242
loaded_size,
12011243
address,

0 commit comments

Comments
 (0)