Skip to content

Commit

Permalink
Only perform a single TLB flush after identity mapping
Browse files Browse the repository at this point in the history
This commit changes the BIOS bootloader to only flush the TLB once,
after it has identity-mapped every physical memory frame. This should be
a bit more efficient, as we don't perform a separate `invlpg` for every
page table entry we create, and instead only flush the entire thing by
reloading `CR3` when we're actually ready to use it.

This is based on a suggestion by @phil-opp, here:
rust-osdev#260 (comment)

This change doesn't actually seem to make all that big an impact in boot
times on QEMU v7.1 on its own, relative to PR rust-osdev#260, but it might make an
additional improvement on top of that PR.
  • Loading branch information
hawkw committed Sep 23, 2022
1 parent ac46d04 commit 14c63aa
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/bin/bios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,28 @@ fn bootloader_main(
PhysFrame::containing_address(PhysAddr::new(4096 * 512 * 512));
let end_frame = PhysFrame::containing_address(PhysAddr::new(max_phys_addr - 1));
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
unsafe {
let flusher = unsafe {
bootloader_page_table
.identity_map(
frame,
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
&mut frame_allocator,
)
.unwrap()
.flush()
};
// skip flushing the entry from the TLB for now, as we will
// flush the entire TLB at the end of the loop.
flusher.ignore();
}
}

// once all the physical memory is mapped, flush the TLB by reloading the
// CR3 register.
//
// we perform a single flush here rather than flushing each individual entry as
// it's mapped using `invlpg`, for efficiency.
x86_64::instructions::tlb::flush_all();

let framebuffer_addr = PhysAddr::new(unsafe { VBEModeInfo_physbaseptr }.into());
let mut error = None;
let framebuffer_info = unsafe {
Expand Down

0 comments on commit 14c63aa

Please sign in to comment.