@@ -11,7 +11,6 @@ use bootloader_x86_64_common::{
11
11
use core:: {
12
12
cell:: UnsafeCell ,
13
13
fmt:: Write ,
14
- mem,
15
14
ops:: { Deref , DerefMut } ,
16
15
ptr, slice,
17
16
} ;
@@ -32,7 +31,7 @@ use uefi::{
32
31
ProtocolPointer ,
33
32
} ,
34
33
table:: boot:: {
35
- AllocateType , MemoryDescriptor , MemoryType , OpenProtocolAttributes , OpenProtocolParams ,
34
+ AllocateType , MemoryType , OpenProtocolAttributes , OpenProtocolParams ,
36
35
ScopedProtocol ,
37
36
} ,
38
37
CStr16 , CStr8 ,
@@ -73,6 +72,7 @@ fn efi_main(image: Handle, st: SystemTable<Boot>) -> Status {
73
72
74
73
fn main_inner ( image : Handle , mut st : SystemTable < Boot > ) -> Status {
75
74
// temporarily clone the y table for printing panics
75
+
76
76
unsafe {
77
77
* SYSTEM_TABLE . get ( ) = Some ( st. unsafe_clone ( ) ) ;
78
78
}
@@ -111,28 +111,52 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
111
111
. unwrap ( ) ;
112
112
113
113
let framebuffer = init_logger ( & st, kernel. config ) ;
114
-
115
- // we no longer need the system table for printing panics
116
- unsafe {
117
- * SYSTEM_TABLE . get ( ) = None ;
114
+ if let Some ( _) = framebuffer {
115
+ // we no longer need the system table for printing panics
116
+ unsafe {
117
+ * SYSTEM_TABLE . get ( ) = None ;
118
+ }
119
+ } else {
120
+ writeln ! (
121
+ stdout,
122
+ "Framebuffer not found, keeping stdout and SYSTEM_TABLE"
123
+ )
124
+ . unwrap ( ) ;
118
125
}
119
126
120
127
log:: info!( "UEFI bootloader started" ) ;
121
128
log:: info!( "Reading kernel and configuration from disk was successful" ) ;
122
129
if let Some ( framebuffer) = framebuffer {
123
130
log:: info!( "Using framebuffer at {:#x}" , framebuffer. addr) ;
124
131
}
125
-
132
+ writeln ! ( stdout , "Creating memory map storage" ) . unwrap ( ) ;
126
133
let mmap_storage = {
127
- let max_mmap_size =
128
- st. boot_services ( ) . memory_map_size ( ) . map_size + 8 * mem:: size_of :: < MemoryDescriptor > ( ) ;
129
- let ptr = st
130
- . boot_services ( )
131
- . allocate_pool ( MemoryType :: LOADER_DATA , max_mmap_size)
132
- . expect ( "Failed to allocate memory for mmap storage" ) ;
133
- unsafe { slice:: from_raw_parts_mut ( ptr, max_mmap_size) }
134
+ let mut memory_map_size = st. boot_services ( ) . memory_map_size ( ) ;
135
+ let mut target_size = memory_map_size. map_size + ( 64 * memory_map_size. entry_size ) ;
136
+ let mut storage: & mut [ u8 ] ;
137
+ loop {
138
+ let ptr = st
139
+ . boot_services ( )
140
+ . allocate_pool ( MemoryType :: LOADER_DATA , target_size)
141
+ . expect ( "Failed to allocate memory for mmap storage" ) ;
142
+ storage = unsafe { slice:: from_raw_parts_mut ( ptr, target_size) } ;
143
+ if let Err ( _) = st. boot_services ( ) . memory_map ( storage) {
144
+ memory_map_size = st. boot_services ( ) . memory_map_size ( ) ;
145
+ // By measuring the size here, we can find out exactly how much we need.
146
+ // We may hit this code twice, if the map allocation ends up spanning more pages.
147
+ let next_target_size = memory_map_size. map_size + ( 64 * memory_map_size. entry_size ) ;
148
+ writeln ! ( stdout, "Allocated {} bytes for the memory map, but we need {}, trying again." , target_size, next_target_size) . unwrap ( ) ;
149
+ target_size = next_target_size;
150
+ st. boot_services ( ) . free_pool ( ptr) . expect ( "Failed to free temporary memory for memory map!" ) ;
151
+ continue ;
152
+ }
153
+ writeln ! ( stdout, "Allocated {} bytes for memory map storage, reported required is {}" , target_size, memory_map_size. map_size) . unwrap ( ) ;
154
+ break ;
155
+ }
156
+ storage
134
157
} ;
135
158
159
+ writeln ! ( stdout, "Exiting boot services" ) . unwrap ( ) ;
136
160
log:: trace!( "exiting boot services" ) ;
137
161
let ( system_table, memory_map) = st
138
162
. exit_boot_services ( image, mmap_storage)
@@ -443,12 +467,20 @@ fn create_page_tables(
443
467
}
444
468
445
469
fn init_logger ( st : & SystemTable < Boot > , config : BootloaderConfig ) -> Option < RawFrameBufferInfo > {
446
- let gop = unsafe {
470
+ let stdout = unsafe { ( & mut * SYSTEM_TABLE . get ( ) ) . as_mut ( ) . unwrap ( ) . stdout ( ) } ;
471
+ writeln ! ( stdout, "Attempting to open GOP" ) . unwrap ( ) ;
472
+ let gop_handle = st
473
+ . boot_services ( )
474
+ . get_handle_for_protocol :: < GraphicsOutput > ( )
475
+ . ok ( ) ?;
476
+ writeln ! ( stdout, "Opened GOP handle: {:?}" , gop_handle) . unwrap ( ) ;
477
+ let mut gop = unsafe {
478
+
447
479
st. boot_services ( )
448
- . locate_protocol :: < GraphicsOutput > ( )
480
+ . open_protocol :: < GraphicsOutput > ( OpenProtocolParams { handle : gop_handle , agent : st . boot_services ( ) . image_handle ( ) , controller : None } , OpenProtocolAttributes :: Exclusive )
449
481
. ok ( ) ?
450
482
} ;
451
- let gop = unsafe { & mut * gop . get ( ) } ;
483
+ writeln ! ( stdout , "Opened GOP, getting framebuffer info" ) . unwrap ( ) ;
452
484
453
485
let mode = {
454
486
let modes = gop. modes ( ) ;
@@ -474,6 +506,7 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr
474
506
}
475
507
} ;
476
508
if let Some ( mode) = mode {
509
+ writeln ! ( stdout, "Setting graphics mode to {:?}" , mode. info( ) ) . unwrap ( ) ;
477
510
gop. set_mode ( & mode)
478
511
. expect ( "Failed to apply the desired display mode" ) ;
479
512
}
@@ -495,10 +528,9 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr
495
528
bytes_per_pixel : 4 ,
496
529
stride : mode_info. stride ( ) ,
497
530
} ;
498
-
499
- log:: info!( "UEFI boot" ) ;
500
-
531
+ writeln ! ( stdout, "Switching to framebuffer logging." ) . unwrap ( ) ;
501
532
bootloader_x86_64_common:: init_logger ( slice, info) ;
533
+ log:: info!( "UEFI boot" ) ;
502
534
503
535
Some ( RawFrameBufferInfo {
504
536
addr : PhysAddr :: new ( framebuffer. as_mut_ptr ( ) as u64 ) ,
0 commit comments