@@ -59,18 +59,18 @@ impl LoadedKernel {
59
59
/// Load a kernel from a vector.
60
60
/// This requires that the Multiboot header has already been parsed.
61
61
fn new (
62
- kernel_vec : Vec < u8 > , header : & Header , quirks : & BTreeSet < Quirk > ,
62
+ kernel_bytes : & [ u8 ] , header : & Header , quirks : & BTreeSet < Quirk > ,
63
63
) -> Result < Self , Status > {
64
64
if header. get_load_addresses ( ) . is_some ( ) && !quirks. contains ( & Quirk :: ForceElf ) {
65
- LoadedKernel :: new_multiboot ( kernel_vec , header, quirks)
65
+ Self :: new_multiboot ( kernel_bytes , header, quirks)
66
66
} else {
67
- LoadedKernel :: new_elf ( header, kernel_vec , quirks)
67
+ Self :: new_elf ( header, kernel_bytes , quirks)
68
68
}
69
69
}
70
70
71
71
/// Load a kernel which has its addresses specified inside the Multiboot header.
72
72
fn new_multiboot (
73
- kernel_vec : Vec < u8 > , header : & Header , quirks : & BTreeSet < Quirk > ,
73
+ kernel_bytes : & [ u8 ] , header : & Header , quirks : & BTreeSet < Quirk > ,
74
74
) -> Result < Self , Status > {
75
75
// TODO: Add support for AOut symbols? Do we really know this binary is AOut at this point?
76
76
let addresses = header. get_load_addresses ( ) . unwrap ( ) ;
@@ -82,7 +82,7 @@ impl LoadedKernel {
82
82
let load_offset = addresses. compute_load_offset ( header. header_start ( ) ) ;
83
83
// allocate
84
84
let kernel_length: usize = addresses. compute_kernel_length (
85
- kernel_vec . len ( ) . try_into ( ) . unwrap ( )
85
+ kernel_bytes . len ( ) . try_into ( ) . unwrap ( )
86
86
) . try_into ( ) . unwrap ( ) ;
87
87
let mut allocation = Allocation :: new_at (
88
88
addresses. load_addr ( ) . try_into ( ) . unwrap ( ) ,
@@ -92,14 +92,12 @@ impl LoadedKernel {
92
92
let kernel_buf = allocation. as_mut_slice ( ) ;
93
93
// copy from beginning of text to end of data segment and fill the rest with zeroes
94
94
kernel_buf. iter_mut ( ) . zip (
95
- kernel_vec . iter ( )
95
+ kernel_bytes . iter ( )
96
96
. skip ( load_offset. try_into ( ) . unwrap ( ) )
97
97
. take ( kernel_length)
98
98
. chain ( core:: iter:: repeat ( & 0 ) )
99
99
)
100
100
. for_each ( |( dst, src) | * dst = * src) ;
101
- // drop the old vector
102
- core:: mem:: drop ( kernel_vec) ;
103
101
104
102
let entry_point = get_kernel_uefi_entry ( header, quirks)
105
103
. or ( header. get_entry_address ( ) . map (
@@ -119,20 +117,20 @@ impl LoadedKernel {
119
117
120
118
/// Load a kernel which uses ELF semantics.
121
119
fn new_elf (
122
- header : & Header , kernel_vec : Vec < u8 > , quirks : & BTreeSet < Quirk > ,
120
+ header : & Header , kernel_bytes : & [ u8 ] , quirks : & BTreeSet < Quirk > ,
123
121
) -> Result < Self , Status > {
124
- let mut binary = Elf :: parse ( kernel_vec . as_slice ( ) ) . map_err ( |msg| {
122
+ let mut binary = Elf :: parse ( kernel_bytes ) . map_err ( |msg| {
125
123
error ! ( "failed to parse ELF structure of kernel: {msg}" ) ;
126
124
Status :: LOAD_ERROR
127
125
} ) ?;
128
126
let mut loader = OurElfLoader :: new ( binary. entry ) ;
129
127
loader
130
- . load_elf ( & binary, kernel_vec . as_slice ( ) , quirks)
128
+ . load_elf ( & binary, kernel_bytes , quirks)
131
129
. map_err ( |msg| {
132
130
error ! ( "failed to load kernel: {msg}" ) ;
133
131
Status :: LOAD_ERROR
134
132
} ) ?;
135
- let symbols = Some ( elf:: symbols ( header, & mut binary, kernel_vec . as_slice ( ) ) ) ;
133
+ let symbols = Some ( elf:: symbols ( header, & mut binary, kernel_bytes ) ) ;
136
134
let entry_point = get_kernel_uefi_entry ( header, quirks)
137
135
. or ( header. get_entry_address ( ) . map (
138
136
|e| EntryPoint :: Multiboot ( e as usize )
@@ -206,7 +204,7 @@ fn get_kernel_uefi_entry(
206
204
207
205
/// Prepare information for the kernel.
208
206
fn prepare_multiboot_information (
209
- entry : & Entry , header : Header , load_base_address : Option < u32 > ,
207
+ entry : & Entry , header : & Header , load_base_address : Option < u32 > ,
210
208
modules : & [ Allocation ] , symbols : Option < Symbols > ,
211
209
graphics_output : Option < ScopedProtocol < GraphicsOutput > > ,
212
210
boot_services_exited : bool ,
@@ -316,14 +314,15 @@ impl<'a> PreparedEntry<'a> {
316
314
/// This is non-destructive and will always return.
317
315
pub ( crate ) fn new (
318
316
entry : & ' a Entry , image_fs_handle : Handle ,
319
- ) -> Result < PreparedEntry < ' a > , Status > {
317
+ ) -> Result < Self , Status > {
320
318
let kernel_vec: Vec < u8 > = File :: open ( & entry. image , image_fs_handle) ?. try_into ( ) ?;
321
319
let header = Header :: from_slice ( kernel_vec. as_slice ( ) ) . ok_or_else ( || {
322
320
error ! ( "invalid Multiboot header" ) ;
323
321
Status :: LOAD_ERROR
324
322
} ) ?;
325
323
debug ! ( "loaded kernel {:?} to {:?}" , header, kernel_vec. as_ptr( ) ) ;
326
- let mut loaded_kernel = LoadedKernel :: new ( kernel_vec, & header, & entry. quirks ) ?;
324
+ let mut loaded_kernel = LoadedKernel :: new ( & kernel_vec, & header, & entry. quirks ) ?;
325
+ core:: mem:: drop ( kernel_vec) ;
327
326
info ! ( "kernel is loaded and bootable" ) ;
328
327
329
328
// Load all modules, fail completely if one fails to load.
@@ -340,7 +339,7 @@ impl<'a> PreparedEntry<'a> {
340
339
let graphics_output = video:: setup_video ( & header, & entry. quirks ) ;
341
340
342
341
let multiboot_information = prepare_multiboot_information (
343
- entry, header, loaded_kernel. load_base_address , & modules_vec,
342
+ entry, & header, loaded_kernel. load_base_address , & modules_vec,
344
343
loaded_kernel. symbols_struct ( ) , graphics_output,
345
344
!entry. quirks . contains ( & Quirk :: DontExitBootServices ) ,
346
345
) ;
@@ -414,7 +413,7 @@ impl<'a> PreparedEntry<'a> {
414
413
// The kernel is going to need the section headers and symbols.
415
414
core:: mem:: forget ( self . loaded_kernel . symbols ) ;
416
415
417
- self . loaded_kernel . entry_point . jump ( signature, info)
416
+ self . loaded_kernel . entry_point . jump ( signature, & info)
418
417
}
419
418
}
420
419
@@ -435,19 +434,19 @@ enum EntryPoint {
435
434
impl EntryPoint {
436
435
/// Jump to the loaded kernel.
437
436
/// This requires everything else to be ready and won't return.
438
- fn jump ( self , signature : u32 , info : Vec < u8 > ) -> ! {
437
+ fn jump ( self , signature : u32 , info : & [ u8 ] ) -> ! {
439
438
if let Self :: Uefi ( entry_address) = self {
440
- self . jump_uefi ( entry_address, signature, info)
439
+ Self :: jump_uefi ( entry_address, signature, info)
441
440
} else if let Self :: Multiboot ( entry_address) = self {
442
- self . jump_multiboot ( entry_address, signature, info)
441
+ Self :: jump_multiboot ( entry_address, signature, info)
443
442
} else {
444
443
panic ! ( "invalid entry point" )
445
444
}
446
445
}
447
446
448
447
/// Jump to the loaded kernel, UEFI-style, eg. just passing the information.
449
448
/// This requires everything else to be ready and won't return.
450
- fn jump_uefi ( self , entry_address : usize , signature : u32 , info : Vec < u8 > ) -> ! {
449
+ fn jump_uefi ( entry_address : usize , signature : u32 , info : & [ u8 ] ) -> ! {
451
450
debug ! ( "jumping to 0x{entry_address:x}" ) ;
452
451
unsafe {
453
452
// TODO: The spec mentions 32 bit registers, even on 64 bit.
@@ -459,15 +458,15 @@ impl EntryPoint {
459
458
"jmp {}" ,
460
459
in( reg) entry_address,
461
460
in( "eax" ) signature,
462
- in( "ecx" ) & info. as_slice ( ) [ 0 ] ,
461
+ in( "ecx" ) & raw const info[ 0 ] ,
463
462
options( noreturn) ,
464
463
) ;
465
464
}
466
465
}
467
466
468
467
/// i686-specific part of the Multiboot machine state.
469
468
#[ cfg( target_arch = "x86" ) ]
470
- fn jump_multiboot ( self , entry_address : usize , signature : u32 , info : Vec < u8 > ) -> ! {
469
+ fn jump_multiboot ( entry_address : usize , signature : u32 , info : & [ u8 ] ) -> ! {
471
470
debug ! ( "preparing machine state and jumping to 0x{entry_address:x}" ) ;
472
471
473
472
// 3.2 Machine state says:
@@ -497,7 +496,7 @@ impl EntryPoint {
497
496
sym Self :: jump_multiboot_common,
498
497
// LLVM needs some registers (https://github.com/rust-lang/rust/blob/1.67.1/compiler/rustc_target/src/asm/x86.rs#L206)
499
498
in( "eax" ) signature,
500
- in( "ecx" ) & info. as_slice ( ) [ 0 ] ,
499
+ in( "ecx" ) & raw const info[ 0 ] ,
501
500
in( "edi" ) entry_address,
502
501
options( noreturn) ,
503
502
) ;
@@ -506,7 +505,7 @@ impl EntryPoint {
506
505
507
506
/// x86_64-specific part of the Multiboot machine state.
508
507
#[ cfg( target_arch = "x86_64" ) ]
509
- fn jump_multiboot ( self , entry_address : usize , signature : u32 , info : Vec < u8 > ) -> ! {
508
+ fn jump_multiboot ( entry_address : usize , signature : u32 , info : & [ u8 ] ) -> ! {
510
509
debug ! ( "preparing machine state and jumping to 0x{entry_address:x}" ) ;
511
510
512
511
// 3.2 Machine state says:
@@ -576,7 +575,7 @@ impl EntryPoint {
576
575
sym Self :: jump_multiboot_common,
577
576
// LLVM needs some registers (https://github.com/rust-lang/rust/blob/1.67.1/compiler/rustc_target/src/asm/x86.rs#L206)
578
577
in( "eax" ) signature,
579
- in( "ecx" ) & info. as_slice ( ) [ 0 ] ,
578
+ in( "ecx" ) & raw const info[ 0 ] ,
580
579
in( "edi" ) entry_address,
581
580
options( noreturn) ,
582
581
) ;
0 commit comments