@@ -26,6 +26,7 @@ use uefi::{
26
26
CStr16 , CStr8 ,
27
27
} ;
28
28
use x86_64:: {
29
+ align_up,
29
30
structures:: paging:: { FrameAllocator , OffsetPageTable , PageTable , PhysFrame , Size4KiB } ,
30
31
PhysAddr , VirtAddr ,
31
32
} ;
@@ -130,6 +131,7 @@ fn load_kernel(image: Handle, st: &SystemTable<Boot>) -> Kernel<'static> {
130
131
Kernel :: parse ( kernel_slice)
131
132
}
132
133
134
+ /// Try to load a kernel file from the boot device.
133
135
fn load_kernel_file ( image : Handle , st : & SystemTable < Boot > ) -> Option < & ' static mut [ u8 ] > {
134
136
load_kernel_file_from_disk ( image, st)
135
137
. 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<&
189
191
Some ( kernel_slice)
190
192
}
191
193
194
+ /// Try to load a kernel from a TFTP boot server.
192
195
fn load_kernel_file_from_tftp_boot_server (
193
196
image : Handle ,
194
197
st : & SystemTable < Boot > ,
195
198
) -> Option < & ' static mut [ u8 ] > {
196
- let ref this = st. boot_services ( ) ;
199
+ let this = st. boot_services ( ) ;
197
200
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.
204
202
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 ( ) } ;
206
207
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 ( ) ;
211
209
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 ( ) } ;
215
214
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 ( ) ?;
220
216
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.
221
221
let mode = base_code. mode ( ) ;
222
222
assert ! ( mode. dhcp_ack_received) ;
223
223
let dhcpv4: & DhcpV4Packet = mode. dhcp_ack . as_ref ( ) ;
224
224
let server_ip = IpAddress :: new_v4 ( dhcpv4. bootp_si_addr ) ;
225
225
226
226
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 ( ) ;
228
227
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" ) ;
230
234
235
+ // Allocate some memory for the kernel file.
231
236
let kernel_ptr = st
232
237
. boot_services ( )
233
238
. allocate_pages (
234
239
AllocateType :: AnyPages ,
235
240
MemoryType :: LOADER_DATA ,
236
- ( ( kernel_size - 1 ) / 4096 ) + 1 ,
241
+ align_up ( kernel_size, 4096 ) ,
237
242
)
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 ;
240
244
let kernel_slice = unsafe { slice:: from_raw_parts_mut ( kernel_ptr, kernel_size) } ;
241
245
246
+ // Load the kernel file.
242
247
base_code
243
248
. tftp_read_file ( & server_ip, filename, Some ( kernel_slice) )
244
- . unwrap ( ) ;
249
+ . expect ( "Failed to read kernel file from the TFTP boot server" ) ;
245
250
246
251
Some ( kernel_slice)
247
252
}
0 commit comments