@@ -112,9 +112,12 @@ where
112
112
regions : & mut [ MaybeUninit < MemoryRegion > ] ,
113
113
kernel_slice_start : PhysAddr ,
114
114
kernel_slice_len : u64 ,
115
+ ramdisk_slice_start : Option < PhysAddr > ,
116
+ ramdisk_slice_len : u64 ,
115
117
) -> & mut [ MemoryRegion ] {
116
118
let mut next_index = 0 ;
117
119
let kernel_slice_start = kernel_slice_start. as_u64 ( ) ;
120
+ let ramdisk_slice_start = ramdisk_slice_start. map ( |a| a. as_u64 ( ) ) ;
118
121
119
122
for descriptor in self . original {
120
123
let mut start = descriptor. start ( ) ;
@@ -157,8 +160,9 @@ where
157
160
kind,
158
161
} ;
159
162
160
- // check if region overlaps with kernel
163
+ // check if region overlaps with kernel or ramdisk
161
164
let kernel_slice_end = kernel_slice_start + kernel_slice_len;
165
+ let ramdisk_slice_end = ramdisk_slice_start. map ( |s| s + ramdisk_slice_len) ;
162
166
if region. kind == MemoryRegionKind :: Usable
163
167
&& kernel_slice_start < region. end
164
168
&& kernel_slice_end > region. start
@@ -198,6 +202,47 @@ where
198
202
Self :: add_region ( before_kernel, regions, & mut next_index) ;
199
203
Self :: add_region ( kernel, regions, & mut next_index) ;
200
204
Self :: add_region ( after_kernel, regions, & mut next_index) ;
205
+ } else if region. kind == MemoryRegionKind :: Usable
206
+ && ramdisk_slice_start. map ( |s| s < region. end ) . unwrap_or ( false )
207
+ && ramdisk_slice_end. map ( |e| e > region. start ) . unwrap_or ( false )
208
+ {
209
+ // region overlaps with ramdisk -> we might need to split it
210
+ let ramdisk_slice_start = ramdisk_slice_start. unwrap ( ) ;
211
+ let ramdisk_slice_end = ramdisk_slice_end. unwrap ( ) ;
212
+
213
+ // ensure that the ramdisk allocation does not span multiple regions
214
+ assert ! (
215
+ ramdisk_slice_start >= region. start,
216
+ "region overlaps with ramdisk, but ramdisk begins before region \
217
+ (ramdisk_start: {ramdisk_slice_start:#x}, region_start: {:#x})",
218
+ region. start
219
+ ) ;
220
+ assert ! (
221
+ ramdisk_slice_end <= region. end,
222
+ "region overlaps with ramdisk, but region ends before ramdisk \
223
+ (ramdisk_end: {ramdisk_slice_end:#x}, region_end: {:#x})",
224
+ region. end,
225
+ ) ;
226
+
227
+ // split the region into three parts
228
+ let before_ramdisk = MemoryRegion {
229
+ end : ramdisk_slice_start,
230
+ ..region
231
+ } ;
232
+ let ramdisk = MemoryRegion {
233
+ start : ramdisk_slice_start,
234
+ end : ramdisk_slice_end,
235
+ kind : MemoryRegionKind :: Bootloader ,
236
+ } ;
237
+ let after_ramdisk = MemoryRegion {
238
+ start : ramdisk_slice_end,
239
+ ..region
240
+ } ;
241
+
242
+ // add the three regions (empty regions are ignored in `add_region`)
243
+ Self :: add_region ( before_ramdisk, regions, & mut next_index) ;
244
+ Self :: add_region ( ramdisk, regions, & mut next_index) ;
245
+ Self :: add_region ( after_ramdisk, regions, & mut next_index) ;
201
246
} else {
202
247
// add the region normally
203
248
Self :: add_region ( region, regions, & mut next_index) ;
0 commit comments