mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 13:06:33 +00:00
Heapless memory region initialization
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0c8200dc7b
commit
51349a3da1
@ -38,7 +38,7 @@ pub(crate) fn init() {
|
||||
let mut writer = {
|
||||
let framebuffer = boot::framebuffer_arg();
|
||||
let mut size = 0;
|
||||
for region in memory_regions() {
|
||||
for region in memory_regions().iter() {
|
||||
if region.typ() == MemoryRegionType::Framebuffer {
|
||||
size = region.len();
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
pub mod smp;
|
||||
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use alloc::string::String;
|
||||
use core::arch::global_asm;
|
||||
|
||||
use fdt::Fdt;
|
||||
@ -13,7 +13,10 @@ use spin::Once;
|
||||
use crate::{
|
||||
boot::{
|
||||
kcmdline::KCmdlineArg,
|
||||
memory_region::{non_overlapping_regions_from, MemoryRegion, MemoryRegionType},
|
||||
memory_region::{
|
||||
non_overlapping_regions_from, MemoryRegion, MemoryRegionArray, MemoryRegionType,
|
||||
MAX_REGIONS,
|
||||
},
|
||||
BootloaderAcpiArg, BootloaderFramebufferArg,
|
||||
},
|
||||
early_println,
|
||||
@ -50,8 +53,8 @@ fn init_acpi_arg(acpi: &'static Once<BootloaderAcpiArg>) {
|
||||
|
||||
fn init_framebuffer_info(_framebuffer_arg: &'static Once<BootloaderFramebufferArg>) {}
|
||||
|
||||
fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
let mut regions = Vec::<MemoryRegion>::new();
|
||||
fn init_memory_regions(memory_regions: &'static Once<MemoryRegionArray>) {
|
||||
let mut regions = MemoryRegionArray::new();
|
||||
|
||||
for region in DEVICE_TREE.get().unwrap().memory().regions() {
|
||||
if region.size.unwrap_or(0) > 0 {
|
||||
@ -89,7 +92,7 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
));
|
||||
}
|
||||
|
||||
memory_regions.call_once(|| non_overlapping_regions_from(regions.as_ref()));
|
||||
memory_regions.call_once(|| regions.into_non_overlapping());
|
||||
}
|
||||
|
||||
fn parse_initramfs_range() -> Option<(usize, usize)> {
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! The Linux 64-bit Boot Protocol supporting module.
|
||||
//!
|
||||
|
||||
use alloc::{borrow::ToOwned, format, string::String, vec::Vec};
|
||||
use alloc::{borrow::ToOwned, format, string::String};
|
||||
use core::ffi::CStr;
|
||||
|
||||
use linux_boot_params::{BootParams, E820Type, LINUX_BOOT_HEADER_MAGIC};
|
||||
@ -12,7 +12,7 @@ use spin::Once;
|
||||
use crate::{
|
||||
boot::{
|
||||
kcmdline::KCmdlineArg,
|
||||
memory_region::{non_overlapping_regions_from, MemoryRegion, MemoryRegionType},
|
||||
memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType},
|
||||
BootloaderAcpiArg, BootloaderFramebufferArg,
|
||||
},
|
||||
mm::kspace::{paddr_to_vaddr, LINEAR_MAPPING_BASE_VADDR},
|
||||
@ -118,39 +118,45 @@ impl From<E820Type> for MemoryRegionType {
|
||||
}
|
||||
}
|
||||
|
||||
fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
let mut regions = Vec::<MemoryRegion>::new();
|
||||
fn init_memory_regions(memory_regions: &'static Once<MemoryRegionArray>) {
|
||||
let mut regions = MemoryRegionArray::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(
|
||||
e820_entry.addr as usize,
|
||||
e820_entry.size as usize,
|
||||
e820_entry.typ.into(),
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
e820_entry.addr as usize,
|
||||
e820_entry.size as usize,
|
||||
e820_entry.typ.into(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Add the kernel region.
|
||||
regions.push(MemoryRegion::kernel());
|
||||
regions.push(MemoryRegion::kernel()).unwrap();
|
||||
|
||||
// Add the initramfs region.
|
||||
regions.push(MemoryRegion::new(
|
||||
boot_params.hdr.ramdisk_image as usize,
|
||||
boot_params.hdr.ramdisk_size as usize,
|
||||
MemoryRegionType::Module,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
boot_params.hdr.ramdisk_image as usize,
|
||||
boot_params.hdr.ramdisk_size as usize,
|
||||
MemoryRegionType::Module,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
// Add the AP boot code region that will be copied into by the BSP.
|
||||
regions.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
memory_regions.call_once(|| non_overlapping_regions_from(regions.as_ref()));
|
||||
memory_regions.call_once(|| regions.into_non_overlapping());
|
||||
}
|
||||
|
||||
/// The entry point of the Rust code portion of Asterinas.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use alloc::string::String;
|
||||
use core::arch::global_asm;
|
||||
|
||||
use spin::Once;
|
||||
@ -8,7 +8,7 @@ use spin::Once;
|
||||
use crate::{
|
||||
boot::{
|
||||
kcmdline::KCmdlineArg,
|
||||
memory_region::{non_overlapping_regions_from, MemoryRegion, MemoryRegionType},
|
||||
memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType},
|
||||
BootloaderAcpiArg, BootloaderFramebufferArg,
|
||||
},
|
||||
mm::{
|
||||
@ -103,8 +103,8 @@ fn init_framebuffer_info(framebuffer_arg: &'static Once<BootloaderFramebufferArg
|
||||
});
|
||||
}
|
||||
|
||||
fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
let mut regions = Vec::<MemoryRegion>::new();
|
||||
fn init_memory_regions(memory_regions: &'static Once<MemoryRegionArray>) {
|
||||
let mut regions = MemoryRegionArray::new();
|
||||
|
||||
let info = MB1_INFO.get().unwrap();
|
||||
|
||||
@ -116,7 +116,7 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
entry.length().try_into().unwrap(),
|
||||
entry.memory_type(),
|
||||
);
|
||||
regions.push(region);
|
||||
regions.push(region).unwrap();
|
||||
}
|
||||
|
||||
// Add the framebuffer region.
|
||||
@ -126,14 +126,16 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
height: info.framebuffer_table.height as usize,
|
||||
bpp: info.framebuffer_table.bpp as usize,
|
||||
};
|
||||
regions.push(MemoryRegion::new(
|
||||
fb.address,
|
||||
(fb.width * fb.height * fb.bpp + 7) / 8, // round up when divide with 8 (bits/Byte)
|
||||
MemoryRegionType::Framebuffer,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
fb.address,
|
||||
(fb.width * fb.height * fb.bpp + 7) / 8, // round up when divide with 8 (bits/Byte)
|
||||
MemoryRegionType::Framebuffer,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
// Add the kernel region.
|
||||
regions.push(MemoryRegion::kernel());
|
||||
regions.push(MemoryRegion::kernel()).unwrap();
|
||||
|
||||
// Add the initramfs area.
|
||||
if info.mods_count != 0 {
|
||||
@ -145,22 +147,26 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
(*(paddr_to_vaddr(modules_addr + 4) as *const u32)) as usize,
|
||||
)
|
||||
};
|
||||
regions.push(MemoryRegion::new(
|
||||
start,
|
||||
end - start,
|
||||
MemoryRegionType::Module,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
start,
|
||||
end - start,
|
||||
MemoryRegionType::Module,
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Add the AP boot code region that will be copied into by the BSP.
|
||||
regions.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
// Initialize with non-overlapping regions.
|
||||
memory_regions.call_once(move || non_overlapping_regions_from(regions.as_ref()));
|
||||
memory_regions.call_once(move || regions.into_non_overlapping());
|
||||
}
|
||||
|
||||
/// Representation of Multiboot Information according to specification.
|
||||
|
@ -1,9 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::string::{String, ToString};
|
||||
use core::arch::global_asm;
|
||||
|
||||
use multiboot2::{BootInformation, BootInformationHeader, MemoryAreaType};
|
||||
@ -12,7 +9,7 @@ use spin::Once;
|
||||
use crate::{
|
||||
boot::{
|
||||
kcmdline::KCmdlineArg,
|
||||
memory_region::{non_overlapping_regions_from, MemoryRegion, MemoryRegionType},
|
||||
memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType},
|
||||
BootloaderAcpiArg, BootloaderFramebufferArg,
|
||||
},
|
||||
mm::kspace::paddr_to_vaddr,
|
||||
@ -99,8 +96,8 @@ impl From<MemoryAreaType> for MemoryRegionType {
|
||||
}
|
||||
}
|
||||
|
||||
fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
let mut regions = Vec::<MemoryRegion>::new();
|
||||
fn init_memory_regions(memory_regions: &'static Once<MemoryRegionArray>) {
|
||||
let mut regions = MemoryRegionArray::new();
|
||||
|
||||
let mb2_info = MB2_INFO.get().unwrap();
|
||||
|
||||
@ -117,7 +114,7 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
(end - start).try_into().unwrap(),
|
||||
area_typ,
|
||||
);
|
||||
regions.push(region);
|
||||
regions.push(region).unwrap();
|
||||
}
|
||||
|
||||
if let Some(Ok(fb_tag)) = mb2_info.framebuffer_tag() {
|
||||
@ -128,35 +125,41 @@ fn init_memory_regions(memory_regions: &'static Once<Vec<MemoryRegion>>) {
|
||||
height: fb_tag.height() as usize,
|
||||
bpp: fb_tag.bpp() as usize,
|
||||
};
|
||||
regions.push(MemoryRegion::new(
|
||||
fb.address,
|
||||
(fb.width * fb.height * fb.bpp + 7) / 8, // round up when divide with 8 (bits/Byte)
|
||||
MemoryRegionType::Framebuffer,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
fb.address,
|
||||
(fb.width * fb.height * fb.bpp + 7) / 8, // round up when divide with 8 (bits/Byte)
|
||||
MemoryRegionType::Framebuffer,
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Add the kernel region since Grub does not specify it.
|
||||
regions.push(MemoryRegion::kernel());
|
||||
regions.push(MemoryRegion::kernel()).unwrap();
|
||||
|
||||
// Add the boot module region since Grub does not specify it.
|
||||
let mb2_module_tag = mb2_info.module_tags();
|
||||
for module in mb2_module_tag {
|
||||
regions.push(MemoryRegion::new(
|
||||
module.start_address() as usize,
|
||||
module.module_size() as usize,
|
||||
MemoryRegionType::Module,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
module.start_address() as usize,
|
||||
module.module_size() as usize,
|
||||
MemoryRegionType::Module,
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Add the AP boot code region that will be copied into by the BSP.
|
||||
regions.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
));
|
||||
regions
|
||||
.push(MemoryRegion::new(
|
||||
super::smp::AP_BOOT_START_PA,
|
||||
super::smp::ap_boot_code_size(),
|
||||
MemoryRegionType::Reclaimable,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
// Initialize with non-overlapping regions.
|
||||
memory_regions.call_once(move || non_overlapping_regions_from(regions.as_ref()));
|
||||
memory_regions.call_once(move || regions.into_non_overlapping());
|
||||
}
|
||||
|
||||
/// The entry point of Rust code called by inline asm.
|
||||
|
@ -3,8 +3,7 @@
|
||||
//! Information of memory regions in the boot phase.
|
||||
//!
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
use core::mem::swap;
|
||||
use core::ops::Deref;
|
||||
|
||||
use crate::mm::kspace::kernel_loaded_offset;
|
||||
|
||||
@ -40,10 +39,19 @@ pub struct MemoryRegion {
|
||||
|
||||
impl MemoryRegion {
|
||||
/// Constructs a valid memory region.
|
||||
pub fn new(base: usize, len: usize, typ: MemoryRegionType) -> Self {
|
||||
pub const fn new(base: usize, len: usize, typ: MemoryRegionType) -> Self {
|
||||
MemoryRegion { base, len, typ }
|
||||
}
|
||||
|
||||
/// Constructs a bad memory region.
|
||||
pub const fn bad() -> Self {
|
||||
MemoryRegion {
|
||||
base: 0,
|
||||
len: 0,
|
||||
typ: MemoryRegionType::BadMemory,
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs 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,
|
||||
@ -83,11 +91,11 @@ impl MemoryRegion {
|
||||
|
||||
/// Removes range `t` from self, resulting in 0, 1 or 2 truncated ranges.
|
||||
/// We need to have this method since memory regions can overlap.
|
||||
pub fn truncate(&self, t: &MemoryRegion) -> Vec<MemoryRegion> {
|
||||
pub fn truncate(&self, t: &MemoryRegion) -> MemoryRegionArray<2> {
|
||||
if self.base < t.base {
|
||||
if self.base + self.len > t.base {
|
||||
if self.base + self.len > t.base + t.len {
|
||||
vec![
|
||||
MemoryRegionArray::from(&[
|
||||
MemoryRegion {
|
||||
base: self.base,
|
||||
len: t.base - self.base,
|
||||
@ -98,72 +106,153 @@ impl MemoryRegion {
|
||||
len: self.base + self.len - (t.base + t.len),
|
||||
typ: self.typ,
|
||||
},
|
||||
]
|
||||
])
|
||||
} else {
|
||||
vec![MemoryRegion {
|
||||
MemoryRegionArray::from(&[MemoryRegion {
|
||||
base: self.base,
|
||||
len: t.base - self.base,
|
||||
typ: self.typ,
|
||||
}]
|
||||
}])
|
||||
}
|
||||
} else {
|
||||
vec![*self]
|
||||
MemoryRegionArray::from(&[*self])
|
||||
}
|
||||
} else if self.base < t.base + t.len {
|
||||
if self.base + self.len > t.base + t.len {
|
||||
vec![MemoryRegion {
|
||||
MemoryRegionArray::from(&[MemoryRegion {
|
||||
base: t.base + t.len,
|
||||
len: self.base + self.len - (t.base + t.len),
|
||||
typ: self.typ,
|
||||
}]
|
||||
}])
|
||||
} else {
|
||||
vec![]
|
||||
MemoryRegionArray::new()
|
||||
}
|
||||
} else {
|
||||
vec![*self]
|
||||
MemoryRegionArray::from(&[*self])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Truncates regions, resulting in a set of regions that does not overlap.
|
||||
/// The maximum number of regions that can be handled.
|
||||
///
|
||||
/// The truncation will be done according to the type of the regions, that
|
||||
/// usable and reclaimable regions will be truncated by the unusable regions.
|
||||
pub fn non_overlapping_regions_from(regions: &[MemoryRegion]) -> Vec<MemoryRegion> {
|
||||
// We should later use regions in `regions_unusable` to truncate all
|
||||
// regions in `regions_usable`.
|
||||
// The difference is that regions in `regions_usable` could be used by
|
||||
// the frame allocator.
|
||||
let mut regions_usable = Vec::<MemoryRegion>::new();
|
||||
let mut regions_unusable = Vec::<MemoryRegion>::new();
|
||||
/// The choice of 512 is probably fine since old Linux boot protocol only
|
||||
/// allows 128 regions.
|
||||
//
|
||||
// TODO: confirm the number or make it configurable.
|
||||
pub const MAX_REGIONS: usize = 512;
|
||||
|
||||
for r in regions {
|
||||
match r.typ {
|
||||
MemoryRegionType::Usable | MemoryRegionType::Reclaimable => {
|
||||
regions_usable.push(*r);
|
||||
}
|
||||
_ => {
|
||||
regions_unusable.push(*r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `regions_*` are 2 rolling vectors since we are going to truncate
|
||||
// the regions in a iterative manner.
|
||||
let mut regions = Vec::<MemoryRegion>::new();
|
||||
let regions_src = &mut regions_usable;
|
||||
let regions_dst = &mut regions;
|
||||
// Truncate the usable regions.
|
||||
for &r_unusable in ®ions_unusable {
|
||||
regions_dst.clear();
|
||||
for r_usable in &*regions_src {
|
||||
regions_dst.append(&mut r_usable.truncate(&r_unusable));
|
||||
}
|
||||
swap(regions_src, regions_dst);
|
||||
}
|
||||
|
||||
// Combine all the regions processed.
|
||||
let mut all_regions = regions_unusable;
|
||||
all_regions.append(&mut regions_usable);
|
||||
all_regions
|
||||
/// A heapless set of memory regions.
|
||||
///
|
||||
/// The set cannot contain more than `LEN` regions.
|
||||
pub struct MemoryRegionArray<const LEN: usize = MAX_REGIONS> {
|
||||
regions: [MemoryRegion; LEN],
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl<const LEN: usize> Default for MemoryRegionArray<LEN> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize> Deref for MemoryRegionArray<LEN> {
|
||||
type Target = [MemoryRegion];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.regions[..self.count]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize> MemoryRegionArray<LEN> {
|
||||
/// Constructs an empty set.
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
regions: [MemoryRegion::bad(); LEN],
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs from an array of regions.
|
||||
pub fn from(array: &[MemoryRegion]) -> Self {
|
||||
Self {
|
||||
regions: core::array::from_fn(|i| {
|
||||
if i < array.len() {
|
||||
array[i]
|
||||
} else {
|
||||
MemoryRegion::bad()
|
||||
}
|
||||
}),
|
||||
count: array.len(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends a region to the set.
|
||||
///
|
||||
/// If the set is full, an error is returned.
|
||||
pub fn push(&mut self, region: MemoryRegion) -> Result<(), &'static str> {
|
||||
if self.count < self.regions.len() {
|
||||
self.regions[self.count] = region;
|
||||
self.count += 1;
|
||||
Ok(())
|
||||
} else {
|
||||
Err("MemoryRegionArray is full")
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the set.
|
||||
pub fn clear(&mut self) {
|
||||
self.count = 0;
|
||||
}
|
||||
|
||||
/// Truncates regions, resulting in a set of regions that does not overlap.
|
||||
///
|
||||
/// The truncation will be done according to the type of the regions, that
|
||||
/// usable and reclaimable regions will be truncated by the unusable regions.
|
||||
///
|
||||
/// If the output regions are more than `LEN`, the extra regions will be ignored.
|
||||
pub fn into_non_overlapping(self) -> Self {
|
||||
// We should later use regions in `regions_unusable` to truncate all
|
||||
// regions in `regions_usable`.
|
||||
// The difference is that regions in `regions_usable` could be used by
|
||||
// the frame allocator.
|
||||
let mut regions_usable = MemoryRegionArray::<LEN>::new();
|
||||
let mut regions_unusable = MemoryRegionArray::<LEN>::new();
|
||||
|
||||
for r in self.iter() {
|
||||
match r.typ {
|
||||
MemoryRegionType::Usable | MemoryRegionType::Reclaimable => {
|
||||
// If usable memory regions exceeded it's fine to ignore the rest.
|
||||
let _ = regions_usable.push(*r);
|
||||
}
|
||||
_ => {
|
||||
regions_unusable
|
||||
.push(*r)
|
||||
.expect("Too many unusable memory regions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `regions_*` are 2 rolling vectors since we are going to truncate
|
||||
// the regions in a iterative manner.
|
||||
let mut regions = MemoryRegionArray::<LEN>::new();
|
||||
let regions_src = &mut regions_usable;
|
||||
let regions_dst = &mut regions;
|
||||
// Truncate the usable regions.
|
||||
for r_unusable in regions_unusable.iter() {
|
||||
regions_dst.clear();
|
||||
for r_usable in regions_src.iter() {
|
||||
for truncated in r_usable.truncate(r_unusable).iter() {
|
||||
let _ = regions_dst.push(*truncated);
|
||||
}
|
||||
}
|
||||
core::mem::swap(regions_src, regions_dst);
|
||||
}
|
||||
|
||||
// Combine all the regions processed.
|
||||
let mut all_regions = regions_unusable;
|
||||
for r in regions_usable.iter() {
|
||||
let _ = all_regions.push(*r);
|
||||
}
|
||||
all_regions
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,12 @@ pub mod kcmdline;
|
||||
pub mod memory_region;
|
||||
pub mod smp;
|
||||
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use alloc::string::String;
|
||||
|
||||
use kcmdline::KCmdlineArg;
|
||||
use spin::Once;
|
||||
|
||||
use self::memory_region::MemoryRegion;
|
||||
use self::memory_region::MemoryRegionArray;
|
||||
|
||||
/// ACPI information from the bootloader.
|
||||
///
|
||||
@ -99,7 +99,7 @@ define_global_static_boot_arguments!(
|
||||
initramfs, INITRAMFS, &'static [u8];
|
||||
acpi_arg, ACPI_ARG, BootloaderAcpiArg;
|
||||
framebuffer_arg, FRAMEBUFFER_ARG, BootloaderFramebufferArg;
|
||||
memory_regions, MEMORY_REGIONS, Vec<MemoryRegion>;
|
||||
memory_regions, MEMORY_REGIONS, MemoryRegionArray;
|
||||
);
|
||||
|
||||
/// The initialization method of the boot module.
|
||||
|
Reference in New Issue
Block a user