11use crate :: platform:: timer:: PlatformTimer ;
22use crate :: utils:: device_path_subpath;
3+ use crate :: utils:: variables:: { VariableClass , VariableController } ;
34use anyhow:: { Context , Result } ;
45use uefi:: proto:: device_path:: DevicePath ;
5- use uefi:: { CString16 , Guid , guid} ;
6- use uefi_raw:: table:: runtime:: { VariableAttributes , VariableVendor } ;
6+ use uefi:: { Guid , guid} ;
7+ use uefi_raw:: table:: runtime:: VariableVendor ;
78
89/// The name of the bootloader to tell the system.
910const LOADER_NAME : & str = "Sprout" ;
@@ -13,7 +14,9 @@ pub struct BootloaderInterface;
1314
1415impl BootloaderInterface {
1516 /// Bootloader Interface GUID from https://systemd.io/BOOT_LOADER_INTERFACE
16- const VENDOR : VariableVendor = VariableVendor ( guid ! ( "4a67b082-0a4c-41cf-b6c7-440b29bb8c4f" ) ) ;
17+ const VENDOR : VariableController = VariableController :: new ( VariableVendor ( guid ! (
18+ "4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
19+ ) ) ) ;
1720
1821 /// Tell the system that Sprout was initialized at the current time.
1922 pub fn mark_init ( timer : & PlatformTimer ) -> Result < ( ) > {
@@ -35,23 +38,39 @@ impl BootloaderInterface {
3538 fn mark_time ( key : & str , timer : & PlatformTimer ) -> Result < ( ) > {
3639 // Measure the elapsed time since the hardware timer was started.
3740 let elapsed = timer. elapsed_since_lifetime ( ) ;
38- Self :: set_cstr16 ( key, & elapsed. as_micros ( ) . to_string ( ) )
41+ Self :: VENDOR . set_cstr16 (
42+ key,
43+ & elapsed. as_micros ( ) . to_string ( ) ,
44+ VariableClass :: BootAndRuntimeTemporary ,
45+ )
3946 }
4047
4148 /// Tell the system what loader is being used.
4249 pub fn set_loader_info ( ) -> Result < ( ) > {
43- Self :: set_cstr16 ( "LoaderInfo" , LOADER_NAME )
50+ Self :: VENDOR . set_cstr16 (
51+ "LoaderInfo" ,
52+ LOADER_NAME ,
53+ VariableClass :: BootAndRuntimeTemporary ,
54+ )
4455 }
4556
4657 /// Tell the system the relative path to the partition root of the current bootloader.
4758 pub fn set_loader_path ( path : & DevicePath ) -> Result < ( ) > {
4859 let subpath = device_path_subpath ( path) . context ( "unable to get loader path subpath" ) ?;
49- Self :: set_cstr16 ( "LoaderImageIdentifier" , & subpath)
60+ Self :: VENDOR . set_cstr16 (
61+ "LoaderImageIdentifier" ,
62+ & subpath,
63+ VariableClass :: BootAndRuntimeTemporary ,
64+ )
5065 }
5166
5267 /// Tell the system what the partition GUID of the ESP Sprout was booted from is.
5368 pub fn set_partition_guid ( guid : & Guid ) -> Result < ( ) > {
54- Self :: set_cstr16 ( "LoaderDevicePartUUID" , & guid. to_string ( ) )
69+ Self :: VENDOR . set_cstr16 (
70+ "LoaderDevicePartUUID" ,
71+ & guid. to_string ( ) ,
72+ VariableClass :: BootAndRuntimeTemporary ,
73+ )
5574 }
5675
5776 /// Tell the system what boot entries are available.
@@ -69,17 +88,29 @@ impl BootloaderInterface {
6988 // Write the bytes (including the null terminator) into the data buffer.
7089 data. extend_from_slice ( & encoded) ;
7190 }
72- Self :: set ( "LoaderEntries" , & data)
91+ Self :: VENDOR . set (
92+ "LoaderEntries" ,
93+ & data,
94+ VariableClass :: BootAndRuntimeTemporary ,
95+ )
7396 }
7497
7598 /// Tell the system what the default boot entry is.
7699 pub fn set_default_entry ( entry : String ) -> Result < ( ) > {
77- Self :: set_cstr16 ( "LoaderEntryDefault" , & entry)
100+ Self :: VENDOR . set_cstr16 (
101+ "LoaderEntryDefault" ,
102+ & entry,
103+ VariableClass :: BootAndRuntimeTemporary ,
104+ )
78105 }
79106
80107 /// Tell the system what the selected boot entry is.
81108 pub fn set_selected_entry ( entry : String ) -> Result < ( ) > {
82- Self :: set_cstr16 ( "LoaderEntrySelected" , & entry)
109+ Self :: VENDOR . set_cstr16 (
110+ "LoaderEntrySelected" ,
111+ & entry,
112+ VariableClass :: BootAndRuntimeTemporary ,
113+ )
83114 }
84115
85116 /// Tell the system about the UEFI firmware we are running on.
@@ -91,35 +122,18 @@ impl BootloaderInterface {
91122 uefi:: system:: firmware_revision( ) >> 16 ,
92123 uefi:: system:: firmware_revision( ) & 0xFFFFF ,
93124 ) ;
94- Self :: set_cstr16 ( "LoaderFirmwareInfo" , & firmware_info) ?;
125+ Self :: VENDOR . set_cstr16 (
126+ "LoaderFirmwareInfo" ,
127+ & firmware_info,
128+ VariableClass :: BootAndRuntimeTemporary ,
129+ ) ?;
95130
96131 // Format the firmware revision into something human-readable.
97132 let firmware_type = format ! ( "UEFI {:02}" , uefi:: system:: firmware_revision( ) ) ;
98- Self :: set_cstr16 ( "LoaderFirmwareType" , & firmware_type)
99- }
100-
101- /// The [VariableAttributes] for bootloader interface variables.
102- fn attributes ( ) -> VariableAttributes {
103- VariableAttributes :: BOOTSERVICE_ACCESS | VariableAttributes :: RUNTIME_ACCESS
104- }
105-
106- /// Set a bootloader interface variable specified by `key` to `value`.
107- fn set ( key : & str , value : & [ u8 ] ) -> Result < ( ) > {
108- let name =
109- CString16 :: try_from ( key) . context ( "unable to convert variable name to CString16" ) ?;
110- uefi:: runtime:: set_variable ( & name, & Self :: VENDOR , Self :: attributes ( ) , value)
111- . with_context ( || format ! ( "unable to set efi variable {}" , key) ) ?;
112- Ok ( ( ) )
113- }
114-
115- /// Set a bootloader interface variable specified by `key` to `value`, converting the value to
116- /// a [CString16].
117- fn set_cstr16 ( key : & str , value : & str ) -> Result < ( ) > {
118- // Encode the value as a CString16 little endian.
119- let encoded = value
120- . encode_utf16 ( )
121- . flat_map ( |c| c. to_le_bytes ( ) )
122- . collect :: < Vec < u8 > > ( ) ;
123- Self :: set ( key, & encoded)
133+ Self :: VENDOR . set_cstr16 (
134+ "LoaderFirmwareType" ,
135+ & firmware_type,
136+ VariableClass :: BootAndRuntimeTemporary ,
137+ )
124138 }
125139}
0 commit comments