@@ -112,9 +112,12 @@ where
112112 regions : & mut [ MaybeUninit < MemoryRegion > ] ,
113113 kernel_slice_start : PhysAddr ,
114114 kernel_slice_len : u64 ,
115+ ramdisk_slice_start : Option < PhysAddr > ,
116+ ramdisk_slice_len : u64 ,
115117 ) -> & mut [ MemoryRegion ] {
116118 let mut next_index = 0 ;
117119 let kernel_slice_start = kernel_slice_start. as_u64 ( ) ;
120+ let ramdisk_slice_start = ramdisk_slice_start. map ( |a| a. as_u64 ( ) ) ;
118121
119122 for descriptor in self . original {
120123 let mut start = descriptor. start ( ) ;
@@ -157,8 +160,9 @@ where
157160 kind,
158161 } ;
159162
160- // check if region overlaps with kernel
163+ // check if region overlaps with kernel or ramdisk
161164 let kernel_slice_end = kernel_slice_start + kernel_slice_len;
165+ let ramdisk_slice_end = ramdisk_slice_start. map ( |s| s + ramdisk_slice_len) ;
162166 if region. kind == MemoryRegionKind :: Usable
163167 && kernel_slice_start < region. end
164168 && kernel_slice_end > region. start
@@ -198,6 +202,47 @@ where
198202 Self :: add_region ( before_kernel, regions, & mut next_index) ;
199203 Self :: add_region ( kernel, regions, & mut next_index) ;
200204 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) ;
201246 } else {
202247 // add the region normally
203248 Self :: add_region ( region, regions, & mut next_index) ;
0 commit comments