Skip to content

Commit 15ce0e4

Browse files
committed
Report UEFI/BIOS memory type IDs in memory map
Also: Reuse some UEFI regions that are no longer needed as `Usable` before switching to kernel.
1 parent 3dbe8d4 commit 15ce0e4

File tree

4 files changed

+63
-51
lines changed

4 files changed

+63
-51
lines changed

src/binary/bios/memory_descriptor.rs

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::binary::legacy_memory_region::LegacyMemoryRegion;
1+
use crate::{binary::legacy_memory_region::LegacyMemoryRegion, memory_map::MemoryRegionKind};
22
use x86_64::PhysAddr;
33

44
impl LegacyMemoryRegion for E820MemoryRegion {
@@ -10,8 +10,11 @@ impl LegacyMemoryRegion for E820MemoryRegion {
1010
self.len
1111
}
1212

13-
fn usable(&self) -> bool {
14-
self.region_type == 1
13+
fn kind(&self) -> MemoryRegionKind {
14+
match self.region_type {
15+
1 => MemoryRegionKind::Usable,
16+
other => MemoryRegionKind::UnknownBios(other),
17+
}
1518
}
1619

1720
fn set_start(&mut self, new_start: PhysAddr) {
@@ -28,22 +31,3 @@ pub struct E820MemoryRegion {
2831
pub region_type: u32,
2932
pub acpi_extended_attributes: u32,
3033
}
31-
32-
/*
33-
impl From<E820MemoryRegion> for MemoryRegion {
34-
fn from(region: E820MemoryRegion) -> MemoryRegion {
35-
let region_type = match region.region_type {
36-
1 => MemoryRegionType::Usable,
37-
2 => MemoryRegionType::Reserved,
38-
3 => MemoryRegionType::AcpiReclaimable,
39-
4 => MemoryRegionType::AcpiNvs,
40-
5 => MemoryRegionType::BadMemory,
41-
t => panic!("invalid region type {}", t),
42-
};
43-
MemoryRegion {
44-
range: FrameRange::new(region.start_addr, region.start_addr + region.len),
45-
region_type,
46-
}
47-
}
48-
}
49-
*/

src/binary/legacy_memory_region.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::memory_map::MemoryRegion;
1+
use crate::memory_map::{MemoryRegion, MemoryRegionKind};
22
use core::mem::MaybeUninit;
33
use x86_64::{
44
structures::paging::{FrameAllocator, PhysFrame, Size4KiB},
@@ -8,7 +8,7 @@ use x86_64::{
88
pub trait LegacyMemoryRegion: Copy + core::fmt::Debug {
99
fn start(&self) -> PhysAddr;
1010
fn len(&self) -> u64;
11-
fn usable(&self) -> bool;
11+
fn kind(&self) -> MemoryRegionKind;
1212

1313
fn set_start(&mut self, new_start: PhysAddr);
1414
}
@@ -76,34 +76,47 @@ where
7676
self,
7777
regions: &mut [MaybeUninit<MemoryRegion>],
7878
) -> &mut [MemoryRegion] {
79-
use crate::memory_map::MemoryRegionKind;
80-
8179
let mut next_index = 0;
8280

8381
for mut descriptor in self.original {
8482
let end = descriptor.start() + descriptor.len();
8583
let next_free = self.next_frame.start_address();
86-
let kind = if descriptor.usable() {
87-
if end <= next_free {
88-
MemoryRegionKind::Bootloader
89-
} else if descriptor.start() >= next_free {
90-
MemoryRegionKind::Usable
91-
} else {
92-
// part of the region is used -> add is separately
93-
let used_region = MemoryRegion {
94-
start: descriptor.start().as_u64(),
95-
end: next_free.as_u64(),
96-
kind: MemoryRegionKind::Bootloader,
97-
};
98-
Self::add_region(used_region, regions, &mut next_index)
99-
.expect("Failed to add memory region");
100-
101-
// add unused part normally
102-
descriptor.set_start(next_free);
103-
MemoryRegionKind::Usable
84+
let kind = match descriptor.kind() {
85+
MemoryRegionKind::Usable => {
86+
if end <= next_free {
87+
MemoryRegionKind::Bootloader
88+
} else if descriptor.start() >= next_free {
89+
MemoryRegionKind::Usable
90+
} else {
91+
// part of the region is used -> add is separately
92+
let used_region = MemoryRegion {
93+
start: descriptor.start().as_u64(),
94+
end: next_free.as_u64(),
95+
kind: MemoryRegionKind::Bootloader,
96+
};
97+
Self::add_region(used_region, regions, &mut next_index)
98+
.expect("Failed to add memory region");
99+
100+
// add unused part normally
101+
descriptor.set_start(next_free);
102+
MemoryRegionKind::Usable
103+
}
104+
}
105+
// some mappings created by the UEFI firmware become usable again at this point
106+
#[cfg(feature = "uefi_bin")]
107+
MemoryRegionKind::UnknownUefi(other) => {
108+
use uefi::table::boot::MemoryType as M;
109+
match M::custom(other) {
110+
M::LOADER_CODE
111+
| M::LOADER_DATA
112+
| M::BOOT_SERVICES_CODE
113+
| M::BOOT_SERVICES_DATA
114+
| M::RUNTIME_SERVICES_CODE
115+
| M::RUNTIME_SERVICES_DATA => MemoryRegionKind::Usable,
116+
other => MemoryRegionKind::UnknownUefi(other.0),
117+
}
104118
}
105-
} else {
106-
MemoryRegionKind::Reserved // FIXME more types
119+
other => other,
107120
};
108121

109122
let region = MemoryRegion {
@@ -152,7 +165,7 @@ where
152165

153166
// find next suitable descriptor
154167
while let Some(descriptor) = self.memory_map.next() {
155-
if !descriptor.usable() {
168+
if descriptor.kind() != MemoryRegionKind::Usable {
156169
continue;
157170
}
158171
if let Some(frame) = self.allocate_frame_from_descriptor(descriptor) {

src/binary/uefi/memory_descriptor.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::binary::legacy_memory_region::LegacyMemoryRegion;
1+
use crate::{binary::legacy_memory_region::LegacyMemoryRegion, memory_map::MemoryRegionKind};
22
use uefi::table::boot::{MemoryDescriptor, MemoryType};
33
use x86_64::PhysAddr;
44

@@ -13,8 +13,11 @@ impl<'a> LegacyMemoryRegion for MemoryDescriptor {
1313
self.page_count * PAGE_SIZE
1414
}
1515

16-
fn usable(&self) -> bool {
17-
self.ty == MemoryType::CONVENTIONAL
16+
fn kind(&self) -> MemoryRegionKind {
17+
match self.ty {
18+
MemoryType::CONVENTIONAL => MemoryRegionKind::Usable,
19+
other => MemoryRegionKind::UnknownUefi(other.0),
20+
}
1821
}
1922

2023
fn set_start(&mut self, new_start: PhysAddr) {

src/memory_map.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,20 @@ impl MemoryRegion {
1616
}
1717

1818
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
19+
#[non_exhaustive]
1920
pub enum MemoryRegionKind {
21+
/// Unused conventional memory, can be used by the kernel.
2022
Usable,
21-
Reserved,
23+
/// Memory mappings created by the bootloader, including the kernel and boot info mappings.
24+
///
25+
/// This memory should _not_ be used by the kernel.
2226
Bootloader,
27+
/// An unknown memory region reported by the UEFI firmware.
28+
///
29+
/// This should only be used if the UEFI memory type is known as usable.
30+
UnknownUefi(u32),
31+
/// An unknown memory region reported by the BIOS firmware.
32+
///
33+
/// This should only be used if the BIOS memory type is known as usable.
34+
UnknownBios(u32),
2335
}

0 commit comments

Comments
 (0)