@@ -28,6 +28,7 @@ pub struct LegacyFrameAllocator<I, D> {
28
28
memory_map : I ,
29
29
current_descriptor : Option < D > ,
30
30
next_frame : PhysFrame ,
31
+ start_frame : PhysFrame ,
31
32
}
32
33
33
34
impl < I , D > LegacyFrameAllocator < I , D >
@@ -42,18 +43,32 @@ where
42
43
/// library assumes that references can never point to virtual address `0`.
43
44
pub fn new ( memory_map : I ) -> Self {
44
45
// 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) }
47
49
}
48
50
49
51
/// 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 .
51
53
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 {
52
66
Self {
53
67
original : memory_map. clone ( ) ,
54
68
memory_map,
55
69
current_descriptor : None ,
56
70
next_frame : frame,
71
+ start_frame : frame,
57
72
}
58
73
}
59
74
@@ -121,9 +136,11 @@ where
121
136
let next_free = self . next_frame . start_address ( ) ;
122
137
let kind = match descriptor. kind ( ) {
123
138
MemoryRegionKind :: Usable => {
124
- if end <= next_free {
139
+ if end <= next_free && end > self . start_frame . start_address ( ) {
125
140
MemoryRegionKind :: Bootloader
126
- } else if descriptor. start ( ) >= next_free {
141
+ } else if descriptor. start ( ) >= next_free
142
+ || end <= self . start_frame . start_address ( )
143
+ {
127
144
MemoryRegionKind :: Usable
128
145
} else {
129
146
// part of the region is used -> add it separately
0 commit comments