Fix missing kernel/initramfs memory regions

This commit is contained in:
Ruihan Li 2023-12-26 02:20:03 +08:00 committed by Tate, Hongliang Tian
parent 7278589aa2
commit 14ee9c2dc7
4 changed files with 33 additions and 22 deletions

View File

@ -6,7 +6,7 @@ use boot_params::E820Type;
use crate::boot::{
kcmdline::KCmdlineArg,
memory_region::{MemoryRegion, MemoryRegionType},
memory_region::{non_overlapping_regions_from, MemoryRegion, MemoryRegionType},
BootloaderAcpiArg, BootloaderFramebufferArg,
};
use crate::{config::PHYS_OFFSET, vm::paddr_to_vaddr};
@ -114,6 +114,8 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
let mut regions = Vec::<MemoryRegion>::new();
let boot_params = BOOT_PARAMS.get().unwrap();
// Add regions from E820.
let num_entries = boot_params.e820_entries as usize;
for e820_entry in &boot_params.e820_table[0..num_entries] {
regions.push(MemoryRegion::new(
@ -123,7 +125,17 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
));
}
memory_regions.call_once(|| regions);
// Add the kernel region.
regions.push(MemoryRegion::kernel());
// Add the initramfs region.
regions.push(MemoryRegion::new(
boot_params.hdr.ramdisk_image as usize,
boot_params.hdr.ramdisk_size as usize,
MemoryRegionType::Module,
));
memory_regions.call_once(|| non_overlapping_regions_from(regions.as_ref()));
}
/// The entry point of Rust code called by the Linux 64-bit boot compatible bootloader.

View File

@ -136,16 +136,7 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
));
// Add the kernel region.
// These are physical addresses provided by the linker script.
extern "C" {
fn __kernel_start();
fn __kernel_end();
}
regions.push(MemoryRegion::new(
__kernel_start as usize,
__kernel_end as usize - __kernel_start as usize,
MemoryRegionType::Kernel,
));
regions.push(MemoryRegion::kernel());
// Add the initramfs area.
if info.mods_count != 0 {

View File

@ -141,16 +141,7 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
}
// Add the kernel region since Grub does not specify it.
// These are physical addresses provided by the linker script.
extern "C" {
fn __kernel_start();
fn __kernel_end();
}
regions.push(MemoryRegion::new(
__kernel_start as usize,
__kernel_end as usize - __kernel_start as usize,
MemoryRegionType::Kernel,
));
regions.push(MemoryRegion::kernel());
// Add the boot module region since Grub does not specify it.
let mb2_module_tag = mb2_info.module_tags();

View File

@ -40,6 +40,23 @@ impl MemoryRegion {
MemoryRegion { base, len, typ }
}
/// Construct a memory region where kernel sections are loaded.
///
/// Most boot protocols do not mark the place where the kernel loads as unusable. In this case,
/// we need to explicitly construct and append this memory region.
pub fn kernel() -> Self {
// These are physical addresses provided by the linker script.
extern "C" {
fn __kernel_start();
fn __kernel_end();
}
MemoryRegion {
base: __kernel_start as usize,
len: __kernel_end as usize - __kernel_start as usize,
typ: MemoryRegionType::Kernel,
}
}
/// The physical address of the base of the region.
pub fn base(&self) -> usize {
self.base