stage1: return sorted memory map

This commit is contained in:
anna 2023-05-31 20:55:08 +02:00
parent 21d33b6047
commit 326997330b
Signed by: fef
GPG key ID: 2585C2DC6D79B485

View file

@ -1,6 +1,7 @@
use crate::asm::{do_bios_int, BiosIntRegs}; use crate::asm::{do_bios_int, BiosIntRegs};
use core::cmp::Ordering; use core::cmp::Ordering;
use core::mem::size_of; use core::mem::size_of;
use core::ptr::slice_from_raw_parts_mut;
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq)]
#[repr(C)] #[repr(C)]
@ -14,26 +15,28 @@ pub struct MemMapEntry {
const SMAP: u32 = 0x534d4150; const SMAP: u32 = 0x534d4150;
/// Use int15/e820 to detect the entire installed system memory. /// Use int15/e820 to detect the entire installed system memory.
/// The entries are sorted by ascending start address.
/// ///
/// ## Safety /// ## Safety
/// ///
/// `dest` must be aligned to at least 8 bytes, accessible from real mode, /// `dest` must be aligned to at least 8 bytes, accessible from real mode,
/// and have enough capacity to store the entire memory map. In practice, /// and have enough capacity to store the entire memory map. In practice,
/// we use a 64 K segment, which should be way more than sufficient. /// we use a 64 K segment, which should be way more than sufficient.
pub unsafe fn read_bios_mmap(mut dest: *mut MemMapEntry) -> usize { pub unsafe fn read_bios_mmap(dest: *mut MemMapEntry) -> usize {
let mut offset: u32 = 0; let mut offset: u32 = 0;
let mut count: usize = 0; let mut count: usize = 0;
debug_assert!((dest as *mut MemMapEntry as usize) < 0x10_0000); debug_assert!((dest as *mut MemMapEntry as usize) < 0x10_0000);
let mut pos = dest;
loop { loop {
dest.as_mut().unwrap_unchecked().acpi30_ext = 1; pos.as_mut().unwrap_unchecked().acpi30_ext = 1;
let regs = BiosIntRegs { let regs = BiosIntRegs {
eax: 0xe820, eax: 0xe820,
ecx: size_of::<MemMapEntry>() as u32, ecx: size_of::<MemMapEntry>() as u32,
edx: SMAP, edx: SMAP,
ebx: offset, ebx: offset,
edi: ((dest as usize) % 0x10) as u32, edi: ((pos as usize) % 0x10) as u32,
es: ((dest as usize) / 0x10) as u16, es: ((pos as usize) / 0x10) as u16,
..Default::default() ..Default::default()
}; };
let result = match do_bios_int(0x15, regs) { let result = match do_bios_int(0x15, regs) {
@ -42,13 +45,13 @@ pub unsafe fn read_bios_mmap(mut dest: *mut MemMapEntry) -> usize {
}; };
if result.ecx < size_of::<MemMapEntry>() as u32 { if result.ecx < size_of::<MemMapEntry>() as u32 {
dest.as_mut().unwrap_unchecked().acpi30_ext = 1; pos.as_mut().unwrap_unchecked().acpi30_ext = 1;
} }
if result.eax != SMAP { if result.eax != SMAP {
break; break;
} }
count += 1; count += 1;
dest = dest.add(1); pos = pos.add(1);
if result.ebx == 0 { if result.ebx == 0 {
break; break;
} else { } else {
@ -56,6 +59,11 @@ pub unsafe fn read_bios_mmap(mut dest: *mut MemMapEntry) -> usize {
} }
} }
let mmap_mut = slice_from_raw_parts_mut(dest, count)
.as_mut()
.unwrap_unchecked();
mmap_mut.sort_unstable();
count count
} }