@@ -11,7 +11,6 @@ use bootloader_x86_64_common::{
1111use core:: {
1212 cell:: UnsafeCell ,
1313 fmt:: Write ,
14- mem,
1514 ops:: { Deref , DerefMut } ,
1615 ptr, slice,
1716} ;
@@ -32,7 +31,7 @@ use uefi::{
3231 ProtocolPointer ,
3332 } ,
3433 table:: boot:: {
35- AllocateType , MemoryDescriptor , MemoryType , OpenProtocolAttributes , OpenProtocolParams ,
34+ AllocateType , MemoryType , OpenProtocolAttributes , OpenProtocolParams ,
3635 ScopedProtocol ,
3736 } ,
3837 CStr16 , CStr8 ,
@@ -73,6 +72,7 @@ fn efi_main(image: Handle, st: SystemTable<Boot>) -> Status {
7372
7473fn main_inner ( image : Handle , mut st : SystemTable < Boot > ) -> Status {
7574 // temporarily clone the y table for printing panics
75+
7676 unsafe {
7777 * SYSTEM_TABLE . get ( ) = Some ( st. unsafe_clone ( ) ) ;
7878 }
@@ -111,28 +111,52 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
111111 . unwrap ( ) ;
112112
113113 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 ( ) ;
118125 }
119126
120127 log:: info!( "UEFI bootloader started" ) ;
121128 log:: info!( "Reading kernel and configuration from disk was successful" ) ;
122129 if let Some ( framebuffer) = framebuffer {
123130 log:: info!( "Using framebuffer at {:#x}" , framebuffer. addr) ;
124131 }
125-
132+ writeln ! ( stdout , "Creating memory map storage" ) . unwrap ( ) ;
126133 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
134157 } ;
135158
159+ writeln ! ( stdout, "Exiting boot services" ) . unwrap ( ) ;
136160 log:: trace!( "exiting boot services" ) ;
137161 let ( system_table, memory_map) = st
138162 . exit_boot_services ( image, mmap_storage)
@@ -443,12 +467,20 @@ fn create_page_tables(
443467}
444468
445469fn 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+
447479 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 )
449481 . ok ( ) ?
450482 } ;
451- let gop = unsafe { & mut * gop . get ( ) } ;
483+ writeln ! ( stdout , "Opened GOP, getting framebuffer info" ) . unwrap ( ) ;
452484
453485 let mode = {
454486 let modes = gop. modes ( ) ;
@@ -474,6 +506,7 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr
474506 }
475507 } ;
476508 if let Some ( mode) = mode {
509+ writeln ! ( stdout, "Setting graphics mode to {:?}" , mode. info( ) ) . unwrap ( ) ;
477510 gop. set_mode ( & mode)
478511 . expect ( "Failed to apply the desired display mode" ) ;
479512 }
@@ -495,10 +528,9 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr
495528 bytes_per_pixel : 4 ,
496529 stride : mode_info. stride ( ) ,
497530 } ;
498-
499- log:: info!( "UEFI boot" ) ;
500-
531+ writeln ! ( stdout, "Switching to framebuffer logging." ) . unwrap ( ) ;
501532 bootloader_x86_64_common:: init_logger ( slice, info) ;
533+ log:: info!( "UEFI boot" ) ;
502534
503535 Some ( RawFrameBufferInfo {
504536 addr : PhysAddr :: new ( framebuffer. as_mut_ptr ( ) as u64 ) ,
0 commit comments