kernel/arch/x86_64/boot/
mm.rs1use crate::arch::x86_64::boot::entry::LIMINE_MEMMAP_REQUEST;
7use crate::lib::addr::{PhysAddr, VirtAddr};
8use crate::lib::panic::kernel_panic;
9use crate::lib::panic_codes::PanicCode;
10use crate::lib::types::boot_info::KernelSectionInfo;
11use crate::lib::types::fmt_buffer::FmtBuffer;
12use crate::mm::pmm::FRAME_SIZE;
13use crate::mm::vmm::Vmm;
14use crate::mm::vmm::address_space::AddressSpace;
15use crate::mm::vmm::boot_mapping::BootMappings;
16use crate::mm::vmm::traits::VmmPaging;
17use crate::state::kstate::KSTATE;
18use crate::{kdebug, mm};
19use limine::memmap::MEMMAP_BOOTLOADER_RECLAIMABLE;
20use limine::request::{MemmapRespData, Response};
21
22pub fn mm_init(section_info: &KernelSectionInfo) {
23 let kernel_page: VirtAddr;
24 let boot_mappings: BootMappings;
25
26 if let Some(memmap_response) = LIMINE_MEMMAP_REQUEST.response() {
27 unsafe { KSTATE.mm.init_pmm(mm::pmm::Pmm::init(memmap_response.entries())) };
29 (kernel_page, boot_mappings) = Vmm::setup_kernel_paging(section_info);
30
31 } else {
34 kernel_panic(
35 PanicCode::InitFailure,
36 "Limine did not provide an initial memmap"
37 );
38 }
39
40 mm::heap::init(kernel_page);
41
42 unsafe { KSTATE.mm.init_kernel_addr_space(AddressSpace::empty(kernel_page)) };
44 if let Err(error) = unsafe {
46 KSTATE.mm.kernel_addr_space().lock().setup_kernel_vmas(&boot_mappings)
47 } {
48 use core::fmt::Write;
49
50 let mut buffer: FmtBuffer<64> = FmtBuffer::new();
51 let _ = write!(buffer, "Failed to set up kernel VMAs ({:?})", error);
52
53 kernel_panic(
54 PanicCode::InitFailure,
55 buffer.as_str()
56 );
57 }
58}
59
60fn reclaim_bootloader_memory(memmap_response: &Response<MemmapRespData>) {
61 let mut pmm = unsafe { KSTATE.mm.pmm().lock() };
64
65 #[cfg(feature = "debug-logging")]
66 let (mut total_bytes, mut total_entries) = (0u64, 0u64);
67
68 const MAX_ENTRIES: usize = 256;
69
70 let mut entries: [(u64, u64); MAX_ENTRIES] = [(0, 0); MAX_ENTRIES];
71 let mut num_entries: usize = 0;
72
73 for entry in memmap_response.entries() {
74 if entry.type_ != MEMMAP_BOOTLOADER_RECLAIMABLE {
75 continue;
76 }
77
78 entries[num_entries] = (entry.base, entry.length);
79 num_entries += 1;
80 }
81
82 if num_entries >= MAX_ENTRIES {
83 kernel_panic(
84 PanicCode::InitFailure,
85 "Found more reclaimable bootloader entries than currently supported"
86 );
87 }
88
89 for i in 0..num_entries {
90 #[cfg(feature = "debug-logging")]
91 {
92 total_entries += 1;
93 total_bytes += entries[i].1;
94 }
95
96 let mut base_addr = entries[i].0;
97 let mut remaining = entries[i].1;
98
99 kdebug!("[reclaim] base={:#x} len={:#x}", base_addr, remaining);
100
101 while remaining >= FRAME_SIZE {
102 let mut order = 10usize;
103 while order > 0 {
104 let block_size = FRAME_SIZE << order;
105 if base_addr % block_size == 0 && remaining >= block_size {
106 break;
107 }
108 order -= 1;
109 }
110
111 pmm.free(PhysAddr::new(base_addr), order);
112
113 let block_size = FRAME_SIZE << order;
114 base_addr += block_size;
115 remaining -= block_size;
116 }
117 }
118
119 kdebug!("reclaimed {} bootloader memory entries ({} MiB)", total_entries, total_bytes / 1024 / 1024);
120}