Mark all physical memory metadata with memory region info

This commit is contained in:
Zhang Junyang 2025-03-03 22:13:54 +08:00 committed by Tate, Hongliang Tian
parent 28e7c0ff1f
commit 6ed38f5cb0
3 changed files with 48 additions and 9 deletions

View File

@ -10,7 +10,10 @@ use spin::Once;
use crate::{ use crate::{
arch::boot::smp::{bringup_all_aps, get_num_processors}, arch::boot::smp::{bringup_all_aps, get_num_processors},
cpu, cpu,
mm::{frame::Segment, kspace::KernelMeta, paddr_to_vaddr, FrameAllocOptions, PAGE_SIZE}, mm::{
frame::{meta::KernelMeta, Segment},
paddr_to_vaddr, FrameAllocOptions, PAGE_SIZE,
},
task::Task, task::Task,
}; };

View File

@ -492,6 +492,8 @@ pub(crate) unsafe fn init() -> Segment<MetaPageMeta> {
let _ = ManuallyDrop::new(early_seg); let _ = ManuallyDrop::new(early_seg);
} }
mark_unusable_ranges();
Segment::from_unused(meta_page_range, |_| MetaPageMeta {}).unwrap() Segment::from_unused(meta_page_range, |_| MetaPageMeta {}).unwrap()
} }
@ -535,6 +537,45 @@ fn alloc_meta_frames(tot_nr_frames: usize) -> (usize, Paddr) {
(nr_meta_pages, start_paddr) (nr_meta_pages, start_paddr)
} }
/// The metadata of physical pages that cannot be allocated for general use.
#[derive(Debug)]
pub struct UnusableMemoryMeta;
impl_frame_meta_for!(UnusableMemoryMeta);
/// The metadata of physical pages that contains the kernel itself.
#[derive(Debug, Default)]
pub struct KernelMeta;
impl_frame_meta_for!(KernelMeta);
macro_rules! mark_ranges {
($region: expr, $typ: expr) => {{
debug_assert!($region.base() % PAGE_SIZE == 0);
debug_assert!($region.len() % PAGE_SIZE == 0);
let seg = Segment::from_unused($region.base()..$region.end(), |_| $typ).unwrap();
let _ = ManuallyDrop::new(seg);
}};
}
fn mark_unusable_ranges() {
let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
for region in regions.iter() {
use crate::boot::memory_region::MemoryRegionType;
match region.typ() {
MemoryRegionType::BadMemory => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Unknown => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::NonVolatileSleep => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Reserved => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Kernel => mark_ranges!(region, KernelMeta),
MemoryRegionType::Module => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Framebuffer => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Reclaimable => mark_ranges!(region, UnusableMemoryMeta),
MemoryRegionType::Usable => {} // By default it is initialized as usable.
}
}
}
/// Adds a temporary linear mapping for the metadata frames. /// Adds a temporary linear mapping for the metadata frames.
/// ///
/// We only assume boot page table to contain 4G linear mapping. Thus if the /// We only assume boot page table to contain 4G linear mapping. Thus if the

View File

@ -48,7 +48,7 @@ use spin::Once;
use super::{ use super::{
frame::{ frame::{
meta::{impl_frame_meta_for, mapping, MetaPageMeta}, meta::{mapping, KernelMeta, MetaPageMeta},
Frame, Segment, Frame, Segment,
}, },
nr_subpage_per_huge, nr_subpage_per_huge,
@ -214,7 +214,8 @@ pub fn init_kernel_page_table(meta_pages: Segment<MetaPageMeta>) {
}; };
let mut cursor = kpt.cursor_mut(&from).unwrap(); let mut cursor = kpt.cursor_mut(&from).unwrap();
for frame_paddr in to.step_by(PAGE_SIZE) { for frame_paddr in to.step_by(PAGE_SIZE) {
let page = Frame::<KernelMeta>::from_unused(frame_paddr, KernelMeta).unwrap(); // SAFETY: They were initialized at `super::frame::meta::init`.
let page = unsafe { Frame::<KernelMeta>::from_raw(frame_paddr) };
// SAFETY: we are doing mappings for the kernel. // SAFETY: we are doing mappings for the kernel.
unsafe { unsafe {
let _old = cursor.map(page.into(), prop); let _old = cursor.map(page.into(), prop);
@ -246,9 +247,3 @@ pub unsafe fn activate_kernel_page_table() {
crate::mm::page_table::boot_pt::dismiss(); crate::mm::page_table::boot_pt::dismiss();
} }
} }
/// The metadata of pages that contains the kernel itself.
#[derive(Debug, Default)]
pub struct KernelMeta;
impl_frame_meta_for!(KernelMeta);