@@ -26,6 +26,7 @@ use uefi::{
2626 CStr16 , CStr8 ,
2727} ;
2828use x86_64:: {
29+ align_up,
2930 structures:: paging:: { FrameAllocator , OffsetPageTable , PageTable , PhysFrame , Size4KiB } ,
3031 PhysAddr , VirtAddr ,
3132} ;
@@ -130,6 +131,7 @@ fn load_kernel(image: Handle, st: &SystemTable<Boot>) -> Kernel<'static> {
130131 Kernel :: parse ( kernel_slice)
131132}
132133
134+ /// Try to load a kernel file from the boot device.
133135fn load_kernel_file ( image : Handle , st : & SystemTable < Boot > ) -> Option < & ' static mut [ u8 ] > {
134136 load_kernel_file_from_disk ( image, st)
135137 . or_else ( || load_kernel_file_from_tftp_boot_server ( image, st) )
@@ -189,59 +191,62 @@ fn load_kernel_file_from_disk(image: Handle, st: &SystemTable<Boot>) -> Option<&
189191 Some ( kernel_slice)
190192}
191193
194+ /// Try to load a kernel from a TFTP boot server.
192195fn load_kernel_file_from_tftp_boot_server (
193196 image : Handle ,
194197 st : & SystemTable < Boot > ,
195198) -> Option < & ' static mut [ u8 ] > {
196- let ref this = st. boot_services ( ) ;
199+ let this = st. boot_services ( ) ;
197200
198- let file_system_raw = {
199- let ref this = st. boot_services ( ) ;
200- let loaded_image = this
201- . handle_protocol :: < LoadedImage > ( image)
202- . expect ( "Failed to retrieve `LoadedImage` protocol from handle" ) ;
203- let loaded_image = unsafe { & * loaded_image. get ( ) } ;
201+ // Try to locate a `BaseCode` protocol on the boot device.
204202
205- let device_handle = loaded_image. device ( ) ;
203+ let loaded_image = this
204+ . handle_protocol :: < LoadedImage > ( image)
205+ . expect ( "Failed to retrieve `LoadedImage` protocol from handle" ) ;
206+ let loaded_image = unsafe { & * loaded_image. get ( ) } ;
206207
207- let device_path = this
208- . handle_protocol :: < DevicePath > ( device_handle)
209- . expect ( "Failed to retrieve `DevicePath` protocol from image's device handle" ) ;
210- let mut device_path = unsafe { & * device_path. get ( ) } ;
208+ let device_handle = loaded_image. device ( ) ;
211209
212- let device_handle = this
213- . locate_device_path :: < BaseCode > ( & mut device_path)
214- . expect ( "Failed to locate `BaseCode` protocol on device path" ) ;
210+ let device_path = this
211+ . handle_protocol :: < DevicePath > ( device_handle)
212+ . expect ( "Failed to retrieve `DevicePath` protocol from image's device handle" ) ;
213+ let mut device_path = unsafe { & * device_path. get ( ) } ;
215214
216- this. handle_protocol :: < BaseCode > ( device_handle)
217- }
218- . unwrap ( ) ;
219- let base_code = unsafe { & mut * file_system_raw. get ( ) } ;
215+ let device_handle = this. locate_device_path :: < BaseCode > ( & mut device_path) . ok ( ) ?;
220216
217+ let base_code_raw = this. handle_protocol :: < BaseCode > ( device_handle) . unwrap ( ) ;
218+ let base_code = unsafe { & mut * base_code_raw. get ( ) } ;
219+
220+ // Find the TFTP boot server.
221221 let mode = base_code. mode ( ) ;
222222 assert ! ( mode. dhcp_ack_received) ;
223223 let dhcpv4: & DhcpV4Packet = mode. dhcp_ack . as_ref ( ) ;
224224 let server_ip = IpAddress :: new_v4 ( dhcpv4. bootp_si_addr ) ;
225225
226226 let filename = CStr8 :: from_bytes_with_nul ( b"kernel-x86_64\0 " ) . unwrap ( ) ;
227- let file_size = base_code. tftp_get_file_size ( & server_ip, filename) . unwrap ( ) ;
228227
229- let kernel_size = usize:: try_from ( file_size) . unwrap ( ) ;
228+ // Determine the kernel file size.
229+ let file_size = base_code
230+ . tftp_get_file_size ( & server_ip, filename)
231+ . expect ( "Failed to query the kernel file size" ) ;
232+ let kernel_size =
233+ usize:: try_from ( file_size) . expect ( "The kernel file size should fit into usize" ) ;
230234
235+ // Allocate some memory for the kernel file.
231236 let kernel_ptr = st
232237 . boot_services ( )
233238 . allocate_pages (
234239 AllocateType :: AnyPages ,
235240 MemoryType :: LOADER_DATA ,
236- ( ( kernel_size - 1 ) / 4096 ) + 1 ,
241+ align_up ( kernel_size, 4096 ) ,
237242 )
238- . unwrap ( ) as * mut u8 ;
239- unsafe { ptr:: write_bytes ( kernel_ptr, 0 , kernel_size) } ;
243+ . expect ( "Failed to allocate memory for the kernel file" ) as * mut u8 ;
240244 let kernel_slice = unsafe { slice:: from_raw_parts_mut ( kernel_ptr, kernel_size) } ;
241245
246+ // Load the kernel file.
242247 base_code
243248 . tftp_read_file ( & server_ip, filename, Some ( kernel_slice) )
244- . unwrap ( ) ;
249+ . expect ( "Failed to read kernel file from the TFTP boot server" ) ;
245250
246251 Some ( kernel_slice)
247252}
0 commit comments