Skip to content

Commit

Permalink
[kernel] E: Check lower memory regions are available
Browse files Browse the repository at this point in the history
  • Loading branch information
rafael0121 committed Sep 11, 2024
1 parent 09a7549 commit 350f3c6
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 10 deletions.
9 changes: 8 additions & 1 deletion src/hal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,20 @@ pub fn init(
memory_regions: &mut LinkedList<MemoryRegion<VirtualAddress>>,
mmio_regions: &mut LinkedList<TruncatedMemoryRegion<VirtualAddress>>,
madt: &Option<MadtInfo>,
mem_lower: Option<u32>,
) -> Result<Hal, Error> {
info!("initializing hardware abstraction layer...");

let mut ioports: IoPortAllocator = IoPortAllocator::new();
let mut ioaddresses: IoMemoryAllocator = IoMemoryAllocator::new();
let mut platform: Platform =
platform::init(&mut ioports, &mut ioaddresses, memory_regions, mmio_regions, madt)?;
platform::init(
&mut ioports,
&mut ioaddresses,
memory_regions,
mmio_regions,
madt,
mem_lower)?;

// Initialize the interrupt manager.
let intman: Option<InterruptManager> = match platform.arch.controller.take() {
Expand Down
5 changes: 5 additions & 0 deletions src/hal/platform/bootinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use ::alloc::collections::LinkedList;
pub struct BootInfo {
/// ACPI MADT information.
pub madt: Option<MadtInfo>,
/// Lower memory size.
pub mem_lower: Option<u32>,
/// General-purpose memory regions.
pub memory_regions: LinkedList<MemoryRegion<VirtualAddress>>,
/// Memory-mapped I/O regions.
Expand All @@ -52,6 +54,7 @@ impl BootInfo {
/// # Parameters
///
/// - `madt`: ACPI MADT information.
/// - `mem_lower`: Available Lower memory.
/// - `memory_regions`: General-purpose memory regions.
/// - `mmio_regions`: Memory-mapped I/O regions.
/// - `kernel_modules`: Kernel modules.
Expand All @@ -62,12 +65,14 @@ impl BootInfo {
///
pub fn new(
madt: Option<MadtInfo>,
mem_lower: Option<u32>,
memory_regions: LinkedList<MemoryRegion<VirtualAddress>>,
mmio_regions: LinkedList<TruncatedMemoryRegion<VirtualAddress>>,
kernel_modules: LinkedList<KernelModule>,
) -> Self {
Self {
madt,
mem_lower,
memory_regions,
mmio_regions,
kernel_modules,
Expand Down
3 changes: 2 additions & 1 deletion src/hal/platform/microvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ pub fn parse_bootinfo(magic: u32, info: usize) -> Result<BootInfo, Error> {
kernel_modules.push_back(module);
}

Ok(BootInfo::new(None, LinkedList::new(), LinkedList::new(), kernel_modules))
Ok(BootInfo::new(None, None, LinkedList::new(), LinkedList::new(), kernel_modules))
}

pub fn init(
Expand All @@ -209,6 +209,7 @@ pub fn init(
_memory_regions: &mut LinkedList<MemoryRegion<VirtualAddress>>,
_mmio_regions: &mut LinkedList<TruncatedMemoryRegion<VirtualAddress>>,
madt: &Option<MadtInfo>,
_mem_lower: Option<u32>
) -> Result<Platform, Error> {
Ok(Platform {
arch: x86::init(ioports, ioaddresses, madt)?,
Expand Down
2 changes: 1 addition & 1 deletion src/hal/platform/pc/mboot/basic_mem_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Imports
//==================================================================================================

use ::error::{
use ::sys::error::{
Error,
ErrorCode,
};
Expand Down
38 changes: 34 additions & 4 deletions src/hal/platform/pc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ use ::arch::{
cpu::pic,
mem,
};
use ::sys::error::Error;
use ::sys::error::{
Error,
ErrorCode,
};
use ::sys::{
config,
mm::VirtualAddress,
Expand Down Expand Up @@ -107,7 +110,16 @@ pub struct Platform {
#[cfg(feature = "bios")]
fn register_bios_data_area(
memory_regions: &mut LinkedList<MemoryRegion<VirtualAddress>>,
mem_lower_size: usize,
) -> Result<(), Error> {

// This is possible because mem_lower_size start at address 0x0.
if mem_lower_size < bios::BiosDataArea::BASE + mem::PAGE_SIZE {
let reason: &str = "bios data memory region is not available";
error!("register_bios_data_area(): {:?}", reason);
return Err(Error::new(ErrorCode::OutOfMemory, reason));
}

let bios_data_area: MemoryRegion<VirtualAddress> = MemoryRegion::new(
"bios data area",
VirtualAddress::from_raw_value(bios::BiosDataArea::BASE)?
Expand Down Expand Up @@ -156,6 +168,7 @@ pub fn init(
memory_regions: &mut LinkedList<MemoryRegion<VirtualAddress>>,
mmio_regions: &mut LinkedList<TruncatedMemoryRegion<VirtualAddress>>,
madt: &Option<MadtInfo>,
mem_lower: Option<u32>,
) -> Result<Platform, Error> {
// Register I/O ports for 8259 PIC.
ioports.register_read_write(pic::PIC_CTRL_MASTER as u16)?;
Expand All @@ -182,8 +195,25 @@ pub fn init(

// Register BIOS data area.
#[cfg(feature = "bios")]
register_bios_data_area(memory_regions)?;
let mem_lower_size = match mem_lower {
Some(mem_lower_size) => {
mem_lower_size as usize
},
None => {
let reason: &str = "availability of lower memory is not known";
error!("init(): {:?}", reason);
return Err(Error::new(ErrorCode::InvalidArgument, reason));
}
};

register_bios_data_area(memory_regions, mem_lower_size)?;

// This is possible because mem_lower start at address 0x0.
if mem_lower_size < platform::TRAMPOLINE_ADDRESS.into_raw_value() + mem::PAGE_SIZE {
let reason: &str = "trampoline memory region is not available";
error!("init(): {:?}", reason);
return Err(Error::new(ErrorCode::OutOfMemory, reason));
}
// Trampoline.
let trampoline: MemoryRegion<VirtualAddress> = MemoryRegion::new(
"trampoline",
Expand All @@ -195,7 +225,7 @@ pub fn init(
memory_regions.push_back(trampoline);

// Register video display memory.
// TODO: we should read this region from the multi-boot information passed by Grub.
// FIXME: https://github.com/nanvix/kernel/issues/435
let video_display_memory: TruncatedMemoryRegion<VirtualAddress> = TruncatedMemoryRegion::new(
"video display memory",
PageAligned::from_raw_value(0x000a0000)?,
Expand All @@ -207,7 +237,7 @@ pub fn init(
mmio_regions.push_back(video_display_memory);

// Bios memory.
// TODO: we should read this region from the multi-boot information passed by Grub.
// FIXME: https://github.com/nanvix/kernel/issues/435
let bios: MemoryRegion<VirtualAddress> = MemoryRegion::new(
"bios memory",
VirtualAddress::from_raw_value(0x000c0000)?,
Expand Down
16 changes: 13 additions & 3 deletions src/kmain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,19 @@ pub extern "C" fn kmain(kargs: &KernelArguments) {

// Parse kernel arguments.
info!("parsing kernel arguments...");
let (madt, mut memory_regions, mut mmio_regions, kernel_modules): (
let (madt, mem_lower, mut memory_regions, mut mmio_regions, kernel_modules): (
Option<MadtInfo>,
Option<u32>,
LinkedList<MemoryRegion<VirtualAddress>>,
LinkedList<TruncatedMemoryRegion<VirtualAddress>>,
LinkedList<KernelModule>,
) = match kargs.parse() {
Ok(bootinfo) => {
(bootinfo.madt, bootinfo.memory_regions, bootinfo.mmio_regions, bootinfo.kernel_modules)
(bootinfo.madt,
bootinfo.mem_lower,
bootinfo.memory_regions,
bootinfo.mmio_regions,
bootinfo.kernel_modules)
},
Err(err) => {
panic!("failed to parse kernel arguments: {:?}", err);
Expand Down Expand Up @@ -255,7 +260,12 @@ pub extern "C" fn kmain(kargs: &KernelArguments) {
}
}

let mut hal: Hal = match hal::init(&mut memory_regions, &mut mmio_regions, &madt) {
let mut hal: Hal = match hal::init(
&mut memory_regions,
&mut mmio_regions,
&madt,
mem_lower)
{
Ok(hal) => hal,
Err(err) => {
panic!("failed to initialize hardware abstraction layer: {:?}", err);
Expand Down

0 comments on commit 350f3c6

Please sign in to comment.