11use crate :: platform:: timer:: PlatformTimer ;
2+ use crate :: utils:: device_path_subpath;
23use anyhow:: { Context , Result } ;
4+ use uefi:: proto:: device_path:: DevicePath ;
35use uefi:: { CString16 , Guid , guid} ;
46use uefi_raw:: table:: runtime:: { VariableAttributes , VariableVendor } ;
57
@@ -28,6 +30,12 @@ impl BootloaderInterface {
2830 Self :: set_cstr16 ( key, & elapsed. as_micros ( ) . to_string ( ) )
2931 }
3032
33+ /// Tell the system the relative path to the partition root of the current bootloader.
34+ pub fn set_loader_path ( path : & DevicePath ) -> Result < ( ) > {
35+ let subpath = device_path_subpath ( path) . context ( "unable to get loader path subpath" ) ?;
36+ Self :: set_cstr16 ( "LoaderImageIdentifier" , & subpath)
37+ }
38+
3139 /// Tell the system what the partition GUID of the ESP Sprout was booted from is.
3240 pub fn set_partition_guid ( guid : & Guid ) -> Result < ( ) > {
3341 Self :: set_cstr16 ( "LoaderDevicePartUUID" , & guid. to_string ( ) )
@@ -39,11 +47,14 @@ impl BootloaderInterface {
3947 // Iterate over the entries and convert them to CString16 placing them into data.
4048 let mut data = Vec :: new ( ) ;
4149 for entry in entries {
42- // Convert the entry to a CString16.
43- let entry = CString16 :: try_from ( entry. as_ref ( ) )
44- . context ( "unable to convert entry to CString16" ) ?;
50+ // Convert the entry to CString16 little endian.
51+ let encoded = entry
52+ . as_ref ( )
53+ . encode_utf16 ( )
54+ . flat_map ( |c| c. to_le_bytes ( ) )
55+ . collect :: < Vec < u8 > > ( ) ;
4556 // Write the bytes (including the null terminator) into the data buffer.
46- data. extend_from_slice ( entry . as_bytes ( ) ) ;
57+ data. extend_from_slice ( & encoded ) ;
4758 }
4859 Self :: set ( "LoaderEntries" , & data)
4960 }
@@ -91,8 +102,11 @@ impl BootloaderInterface {
91102 /// Set a bootloader interface variable specified by `key` to `value`, converting the value to
92103 /// a [CString16].
93104 fn set_cstr16 ( key : & str , value : & str ) -> Result < ( ) > {
94- let value =
95- CString16 :: try_from ( value) . context ( "unable to convert variable value to CString16" ) ?;
96- Self :: set ( key, value. as_bytes ( ) )
105+ // Encode the value as a CString16 little endian.
106+ let encoded = value
107+ . encode_utf16 ( )
108+ . flat_map ( |c| c. to_le_bytes ( ) )
109+ . collect :: < Vec < u8 > > ( ) ;
110+ Self :: set ( key, & encoded)
97111 }
98112}
0 commit comments