stage1: return sorted memory map
This commit is contained in:
parent
21d33b6047
commit
326997330b
1 changed files with 14 additions and 6 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue