@@ -9,7 +9,7 @@ use memory_addresses::{PhysAddr, VirtAddr};
99
1010#[ cfg( target_arch = "x86_64" ) ]
1111use crate :: arch:: mm:: paging:: PageTableEntryFlagsExt ;
12- use crate :: arch:: mm:: paging:: { self , HugePageSize , PageSize , PageTableEntryFlags } ;
12+ use crate :: arch:: mm:: paging:: { self , HugePageSize , LargePageSize , PageSize , PageTableEntryFlags } ;
1313use crate :: env;
1414use crate :: mm:: device_alloc:: DeviceAlloc ;
1515use crate :: mm:: { PageRangeAllocator , PageRangeBox } ;
@@ -18,6 +18,13 @@ static PHYSICAL_FREE_LIST: InterruptTicketMutex<FreeList<16>> =
1818 InterruptTicketMutex :: new ( FreeList :: new ( ) ) ;
1919pub static TOTAL_MEMORY : AtomicUsize = AtomicUsize :: new ( 0 ) ;
2020
21+ /// When claiming physical memory, ignore all addresses below this one.
22+ /// This ensures we don't accidentally clash with hardcoded low addresses, such
23+ /// as [SMP_BOOT_CODE_ADDRESS].
24+ ///
25+ /// We use a 2MIB size for now, but this is arbitrary, and could likely be lowered.
26+ const MIN_PHYSICAL_ADDRESS : u64 = LargePageSize :: SIZE ;
27+
2128pub struct FrameAlloc ;
2229
2330impl PageRangeAllocator for FrameAlloc {
@@ -132,6 +139,18 @@ unsafe fn detect_from_fdt() -> Result<(), ()> {
132139 VirtAddr :: new ( start_address)
133140 } ;
134141
142+ let start_address = if start_address. as_u64 ( ) < MIN_PHYSICAL_ADDRESS {
143+ // Do not free any address in the real mode addressable range
144+ // We have hardcoded some stuff in the kernel (e.g. SMP_BOOT_CODE_ADDRESS and friends),
145+ // so we don't want to accidentally overwrite them by having an allocation on top
146+ if size <= MIN_PHYSICAL_ADDRESS {
147+ continue ;
148+ }
149+ VirtAddr :: new ( MIN_PHYSICAL_ADDRESS )
150+ } else {
151+ start_address
152+ } ;
153+
135154 let range = PageRange :: new ( start_address. as_usize ( ) , end_address as usize ) . unwrap ( ) ;
136155 unsafe {
137156 FrameAlloc :: deallocate ( range) ;
0 commit comments