@@ -28,6 +28,7 @@ pub struct LegacyFrameAllocator<I, D> {
2828 memory_map : I ,
2929 current_descriptor : Option < D > ,
3030 next_frame : PhysFrame ,
31+ start_frame : PhysFrame ,
3132}
3233
3334impl < I , D > LegacyFrameAllocator < I , D >
@@ -42,18 +43,32 @@ where
4243 /// library assumes that references can never point to virtual address `0`.
4344 pub fn new ( memory_map : I ) -> Self {
4445 // skip frame 0 because the rust core library does not see 0 as a valid address
45- let start_frame = PhysFrame :: containing_address ( PhysAddr :: new ( 0x1000 ) ) ;
46- Self :: new_starting_at ( start_frame, memory_map)
46+ // also skip the first 1MB of frames, there are use cases that require lower conventional memory access. (Such as SMP SIPI)
47+ let start_frame = PhysFrame :: containing_address ( PhysAddr :: new ( 0x100000 ) ) ;
48+ unsafe { Self :: unsafe_new_starting_at ( start_frame, memory_map) }
4749 }
4850
4951 /// Creates a new frame allocator based on the given legacy memory regions. Skips any frames
50- /// before the given `frame`.
52+ /// before the given `frame`, or 0x100000, whichever is higher .
5153 pub fn new_starting_at ( frame : PhysFrame , memory_map : I ) -> Self {
54+ if frame. start_address ( ) . as_u64 ( ) < 0x100000 {
55+ // Skip the first 1MB of frames, regardless of what was requested.
56+ // there are use cases that require lower conventional memory access. (Such as SMP SIPI)
57+ return Self :: new ( memory_map) ;
58+ }
59+
60+ return unsafe { Self :: unsafe_new_starting_at ( frame, memory_map) } ;
61+ }
62+
63+ /// Creates a new frame allocator based on the given legacy memory regions. Skips any frames
64+ /// before the given `frame`, without attempting to protect the lower 1MB of memory.
65+ pub unsafe fn unsafe_new_starting_at ( frame : PhysFrame , memory_map : I ) -> Self {
5266 Self {
5367 original : memory_map. clone ( ) ,
5468 memory_map,
5569 current_descriptor : None ,
5670 next_frame : frame,
71+ start_frame : frame,
5772 }
5873 }
5974
@@ -121,9 +136,11 @@ where
121136 let next_free = self . next_frame . start_address ( ) ;
122137 let kind = match descriptor. kind ( ) {
123138 MemoryRegionKind :: Usable => {
124- if end <= next_free {
139+ if end <= next_free && end > self . start_frame . start_address ( ) {
125140 MemoryRegionKind :: Bootloader
126- } else if descriptor. start ( ) >= next_free {
141+ } else if descriptor. start ( ) >= next_free
142+ || end <= self . start_frame . start_address ( )
143+ {
127144 MemoryRegionKind :: Usable
128145 } else {
129146 // part of the region is used -> add it separately
0 commit comments