Skip to content

Commit 6b23732

Browse files
committed
Fix: Mark ramdisk frames as used in memory map
1 parent 1b84c46 commit 6b23732

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

common/src/legacy_memory_region.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -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);

common/src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -293,14 +293,14 @@ where
293293
None
294294
};
295295
let ramdisk_slice_len = system_info.ramdisk_len;
296-
let ramdisk_slice_start = if let Some(ramdisk_address) = system_info.ramdisk_addr {
296+
let ramdisk_slice_phys_start = system_info.ramdisk_addr.map(PhysAddr::new);
297+
let ramdisk_slice_start = if let Some(physical_address) = ramdisk_slice_phys_start {
297298
let start_page = mapping_addr_page_aligned(
298299
config.mappings.ramdisk_memory,
299300
system_info.ramdisk_len,
300301
&mut used_entries,
301302
"ramdisk start",
302303
);
303-
let physical_address = PhysAddr::new(ramdisk_address);
304304
let ramdisk_physical_start_page: PhysFrame<Size4KiB> =
305305
PhysFrame::containing_address(physical_address);
306306
let ramdisk_page_count = (system_info.ramdisk_len - 1) / Size4KiB::SIZE;
@@ -404,6 +404,7 @@ where
404404
kernel_slice_len,
405405
kernel_image_offset,
406406

407+
ramdisk_slice_phys_start,
407408
ramdisk_slice_start,
408409
ramdisk_slice_len,
409410
}
@@ -433,6 +434,7 @@ pub struct Mappings {
433434
pub kernel_slice_len: u64,
434435
/// Relocation offset of the kernel image in virtual memory.
435436
pub kernel_image_offset: VirtAddr,
437+
pub ramdisk_slice_phys_start: Option<PhysAddr>,
436438
pub ramdisk_slice_start: Option<VirtAddr>,
437439
pub ramdisk_slice_len: u64,
438440
}
@@ -516,6 +518,8 @@ where
516518
memory_regions,
517519
mappings.kernel_slice_start,
518520
mappings.kernel_slice_len,
521+
mappings.ramdisk_slice_phys_start,
522+
mappings.ramdisk_slice_len,
519523
);
520524

521525
log::info!("Create bootinfo");

0 commit comments

Comments
 (0)