Skip to content

Commit e09e68a

Browse files
committed
Rework: LegacyFrameAllocator::construct_memory_map
The new implementation takes in a list of slices that are used by the bootloader. It then goes through all regions and checks if they overlap any of those slices. If so, the region is split and this process is started recursively until none of the usable regions overlap the memory used by the bootloader.
1 parent 2555127 commit e09e68a

File tree

5 files changed

+238
-155
lines changed

5 files changed

+238
-155
lines changed

bios/common/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod racy_cell;
55
#[cfg_attr(feature = "debug", derive(Debug))]
66
#[repr(C)]
77
pub struct BiosInfo {
8+
pub stage_3: Region,
89
pub stage_4: Region,
910
pub kernel: Region,
1011
pub ramdisk: Region,

bios/stage-2/src/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
145145
vesa_mode.enable().unwrap();
146146

147147
let mut info = BiosInfo {
148+
stage_3: Region {
149+
start: STAGE_3_DST as u64,
150+
len: stage_3_len,
151+
},
148152
stage_4: Region {
149153
start: stage_4_dst as u64,
150154
len: stage_4_len,

bios/stage-4/src/main.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
use crate::memory_descriptor::MemoryRegion;
55
use bootloader_api::info::{FrameBufferInfo, PixelFormat};
66
use bootloader_boot_config::{BootConfig, LevelFilter};
7-
use bootloader_x86_64_bios_common::{BiosFramebufferInfo, BiosInfo, E820MemoryRegion};
7+
use bootloader_x86_64_bios_common::{BiosFramebufferInfo, BiosInfo, E820MemoryRegion, Region};
8+
use bootloader_x86_64_common::legacy_memory_region::UsedMemorySlice;
89
use bootloader_x86_64_common::RawFrameBufferInfo;
910
use bootloader_x86_64_common::{
1011
legacy_memory_region::LegacyFrameAllocator, load_and_switch_to_kernel, Kernel, PageTables,
@@ -55,9 +56,10 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
5556
};
5657
let kernel_size = info.kernel.len;
5758
let next_free_frame = PhysFrame::containing_address(PhysAddr::new(info.last_used_addr)) + 1;
58-
let mut frame_allocator = LegacyFrameAllocator::new_starting_at(
59+
let mut frame_allocator = LegacyFrameAllocator::new_with_used_slices(
5960
next_free_frame,
6061
memory_map.iter().copied().map(MemoryRegion),
62+
used_memory_slices(info),
6163
);
6264

6365
// We identity-mapped all memory, so the offset between physical and virtual addresses is 0
@@ -216,6 +218,17 @@ fn init_logger(
216218
framebuffer_info
217219
}
218220

221+
fn used_memory_slices(info: &BiosInfo) -> impl Iterator<Item = UsedMemorySlice> + Clone {
222+
// skip kernel and ramdisk because they are handled individually by the
223+
// uefi/bios common code
224+
[info.stage_3, info.stage_4, info.config_file]
225+
.into_iter()
226+
.map(|region| UsedMemorySlice {
227+
start: PhysAddr::new(region.start).as_u64(),
228+
len: region.len,
229+
})
230+
}
231+
219232
/// Creates page table abstraction types for both the bootloader and kernel page tables.
220233
fn create_page_tables(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> PageTables {
221234
// We identity-mapped all memory, so the offset between physical and virtual addresses is 0

0 commit comments

Comments
 (0)