Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e5b6b3e

Browse files
committed
test: add load_image integration test
1 parent e82de9d commit e5b6b3e

File tree

1 file changed

+79
-5
lines changed
  • uefi-test-runner/src/boot

1 file changed

+79
-5
lines changed

‎uefi-test-runner/src/boot/mod.rs

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1+
use alloc::string::ToString;
12
use uefi::proto::console::text::Output;
2-
use uefi::table::boot::{BootServices, SearchType};
3-
use uefi::Identify;
3+
use uefi::proto::device_path::{DevicePath, DeviceSubType, DeviceType, LoadedImageDevicePath};
4+
use uefi::table::boot::{BootServices, LoadImageSource, SearchType};
5+
use uefi::{CStr16, CString16, Identify};
6+
7+
mod memory;
8+
mod misc;
49

510
pub fn test(bt: &BootServices) {
611
info!("Testing boot services");
712
memory::test(bt);
813
misc::test(bt);
914
test_locate_handle_buffer(bt);
15+
test_load_image(bt);
1016
}
1117

12-
mod memory;
13-
mod misc;
14-
1518
fn test_locate_handle_buffer(bt: &BootServices) {
1619
info!("Testing the `locate_handle_buffer` function");
1720

@@ -34,3 +37,74 @@ fn test_locate_handle_buffer(bt: &BootServices) {
3437
);
3538
}
3639
}
40+
41+
/// This test loads the "self image" again into memory using the `load_image`
42+
/// boot service function. The image is not started but just loaded into memory.
43+
///
44+
/// It transitively tests the protocols [`LoadedImageDevicePath`] which is
45+
/// required as helper.
46+
fn test_load_image(bt: &BootServices) {
47+
info!("Testing the `load_image` function");
48+
49+
let image_device_path_protocol = bt
50+
.open_protocol_exclusive::<LoadedImageDevicePath>(bt.image_handle())
51+
.expect("should open LoadedImage protocol");
52+
53+
// Note: This is the full device path. The LoadedImage protocol would only
54+
// provide us with the file-path portion of the device path.
55+
let image_device_path: &DevicePath = &image_device_path_protocol;
56+
57+
// Get the file-path portion of the device path which is typically behind
58+
// device path node (0x4, 0x4).
59+
let image_device_path_file_path = image_device_path
60+
.node_iter()
61+
.filter(|node| {
62+
node.device_type() == DeviceType::MEDIA /* 0x4 */
63+
&& node.sub_type() == DeviceSubType::HARDWARE_VENDOR /* 0x4 */
64+
})
65+
.take(1)
66+
.map(|node| unsafe { CStr16::from_ptr(node.data().as_ptr().cast()) })
67+
.fold(CString16::new(), |mut acc, next| {
68+
acc.push_str(next);
69+
acc
70+
})
71+
// to Rust string
72+
.to_string()
73+
.to_uppercase();
74+
75+
// On x86_64, this will be `\EFI\BOOT\BOOTX64.EFI` for example.
76+
assert!(image_device_path_file_path
77+
.as_str()
78+
.starts_with(r"\EFI\BOOT\BOOT"));
79+
assert!(image_device_path_file_path.as_str().ends_with(".EFI"));
80+
81+
// Variant A: FromBuffer
82+
{
83+
let mut fs = bt
84+
.get_image_file_system(bt.image_handle())
85+
.expect("should open file system");
86+
let path = CString16::try_from(image_device_path_file_path.as_str()).unwrap();
87+
let image_data = fs.read(&*path).expect("should read file content");
88+
let load_source = LoadImageSource::FromBuffer {
89+
buffer: image_data.as_slice(),
90+
file_path: None,
91+
};
92+
let _ = bt
93+
.load_image(bt.image_handle(), load_source)
94+
.expect("should load image");
95+
96+
log::debug!("load_image with FromBuffer strategy works");
97+
}
98+
// Variant B: FromFilePath
99+
{
100+
let load_source = LoadImageSource::FromFilePath {
101+
file_path: image_device_path,
102+
from_boot_manager: false,
103+
};
104+
let _ = bt
105+
.load_image(bt.image_handle(), load_source)
106+
.expect("should load image");
107+
108+
log::debug!("load_image with FromFilePath strategy works");
109+
}
110+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /