@@ -144,7 +144,8 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
144144 let mut frame_allocator =
145145 LegacyFrameAllocator :: new ( memory_map. entries ( ) . copied ( ) . map ( UefiMemoryDescriptor ) ) ;
146146
147- let page_tables = create_page_tables ( & mut frame_allocator) ;
147+ let max_phys_addr = frame_allocator. max_phys_addr ( ) ;
148+ let page_tables = create_page_tables ( & mut frame_allocator, max_phys_addr, framebuffer. as_ref ( ) ) ;
148149 let mut ramdisk_len = 0u64 ;
149150 let ramdisk_addr = if let Some ( rd) = ramdisk {
150151 ramdisk_len = rd. len ( ) as u64 ;
@@ -385,6 +386,8 @@ fn load_file_from_tftp_boot_server(
385386/// Creates page table abstraction types for both the bootloader and kernel page tables.
386387fn create_page_tables (
387388 frame_allocator : & mut impl FrameAllocator < Size4KiB > ,
389+ max_phys_addr : PhysAddr ,
390+ frame_buffer : Option < & RawFrameBufferInfo > ,
388391) -> bootloader_x86_64_common:: PageTables {
389392 // UEFI identity-maps all memory, so the offset between physical and virtual addresses is 0
390393 let phys_offset = VirtAddr :: new ( 0 ) ;
@@ -410,9 +413,21 @@ fn create_page_tables(
410413 }
411414 } ;
412415
413- // copy the first entry (we don't need to access more than 512 GiB; also, some UEFI
414- // implementations seem to create an level 4 table entry 0 in all slots)
415- new_table[ 0 ] = old_table[ 0 ] . clone ( ) ;
416+ // copy the pml4 entries for all identity mapped memory.
417+ let end_addr = VirtAddr :: new ( max_phys_addr. as_u64 ( ) - 1 ) ;
418+ for p4 in 0 ..=usize:: from ( end_addr. p4_index ( ) ) {
419+ new_table[ p4] = old_table[ p4] . clone ( ) ;
420+ }
421+
422+ // copy the pml4 entry for the frame buffer (the frame buffer is not
423+ // necessarily part of the identity mapping).
424+ if let Some ( frame_buffer) = frame_buffer {
425+ let start_addr = VirtAddr :: new ( frame_buffer. addr . as_u64 ( ) ) ;
426+ let end_addr = start_addr + frame_buffer. info . byte_len ;
427+ for p4 in usize:: from ( start_addr. p4_index ( ) ) ..=usize:: from ( end_addr. p4_index ( ) ) {
428+ new_table[ p4] = old_table[ p4] . clone ( ) ;
429+ }
430+ }
416431
417432 // the first level 4 table entry is now identical, so we can just load the new one
418433 unsafe {
0 commit comments