Skip to content

Commit cd2761e

Browse files
committed
Limit BIOS bootloader's max_phys_addr to 4 GiB
When determining the maximum physical address for the BIOS bootloader's identity mapping, we currently use the highest address in the E380 memory map, no matter how high it is. However, the bootloader runs in protected mode, and therefore, it cannot address more than 4 GiB of memory. We can save some time by not identity mapping addresses over 4 GiB, as the bootloader cannot address them anyway. This commit changes the BIOS bootloader to skip addresses over 4 GiB when determining the maximum physical address. This is one of the changes described in issue rust-osdev#259.
1 parent ac46d04 commit cd2761e

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

src/bin/bios.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ fn bootloader_main(
7878
use bootloader::binary::{
7979
bios::memory_descriptor::E820MemoryRegion, legacy_memory_region::LegacyFrameAllocator,
8080
};
81+
const GIGABYTE: u64 = 4096 * 512 * 512;
8182

8283
let e820_memory_map = {
8384
let ptr = usize_from(memory_map_addr.as_u64()) as *const E820MemoryRegion;
@@ -86,6 +87,10 @@ fn bootloader_main(
8687
let max_phys_addr = e820_memory_map
8788
.iter()
8889
.map(|r| r.start_addr + r.len)
90+
// Don't consider addresses > 4GiB when determining the maximum
91+
// physical address for the bootloader, as we are in protected mode and
92+
// cannot address more than 4 GiB of memory anyway.
93+
.filter(|&addr| addr < GIGABYTE * 4)
8994
.max()
9095
.expect("no physical memory regions found");
9196

@@ -106,7 +111,7 @@ fn bootloader_main(
106111
// identity-map remaining physical memory (first gigabyte is already identity-mapped)
107112
{
108113
let start_frame: PhysFrame<Size2MiB> =
109-
PhysFrame::containing_address(PhysAddr::new(4096 * 512 * 512));
114+
PhysFrame::containing_address(PhysAddr::new(GIGABYTE));
110115
let end_frame = PhysFrame::containing_address(PhysAddr::new(max_phys_addr - 1));
111116
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
112117
unsafe {

0 commit comments

Comments
 (0)