diff --git a/Cargo.toml b/Cargo.toml
index 7e405757..ba3cd0de 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,6 +24,7 @@ once = "0.3.3"
linked_list_allocator = "0.5.0"
redox_syscall = "0.1.37"
xmas-elf = "0.6"
+arrayvec = { version = "0.4.7", default-features = false }
[build-dependencies]
cc = "1.0"
diff --git a/src/consts.rs b/src/consts.rs
index f8c07e3c..a267e79a 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -26,7 +26,7 @@ pub const MAX_CPU_NUM: usize = 8;
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - PML4_SIZE;
pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK)/PML4_SIZE;
/// Size of kernel heap
- pub const KERNEL_HEAP_SIZE: usize = 1 * 1024 * 1024; // 1 MB
+ pub const KERNEL_HEAP_SIZE: usize = 2 * 1024 * 1024; // 1 MB
/// Offset to kernel percpu variables
//TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE;
diff --git a/src/lib.rs b/src/lib.rs
index 0a40bb74..4a5dde8c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,6 +33,7 @@ extern crate lazy_static;
extern crate bit_field;
extern crate syscall as redox_syscall;
extern crate xmas_elf;
+extern crate arrayvec;
#[macro_use] // print!
mod io;
@@ -76,7 +77,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! {
// FIXME: 开启SMP后,导致switch_to_user中设置rsp无效
// arch::smp::start_other_cores(&acpi, &mut memory_controller);
- process::init(&mut memory_controller);
+ process::init(memory_controller);
unsafe{ arch::interrupt::enable(); }
diff --git a/src/memory/area_frame_allocator.rs b/src/memory/area_frame_allocator.rs
index 68ebee2b..981339b1 100644
--- a/src/memory/area_frame_allocator.rs
+++ b/src/memory/area_frame_allocator.rs
@@ -1,10 +1,11 @@
use memory::{Frame, FrameAllocator, PhysAddr};
use multiboot2::{MemoryAreaIter, MemoryArea};
+use arrayvec::ArrayVec;
pub struct AreaFrameAllocator {
next_free_frame: Frame,
- current_area: Option<&'static MemoryArea>,
- areas: MemoryAreaIter,
+ current_area: Option,
+ areas: ArrayVec<[Area; 4]>,
kernel_start: Frame,
kernel_end: Frame,
multiboot_start: Frame,
@@ -62,10 +63,12 @@ impl AreaFrameAllocator {
multiboot_start: PhysAddr, multiboot_end: PhysAddr,
memory_areas: MemoryAreaIter) -> AreaFrameAllocator
{
+ let areas: ArrayVec<[Area; 4]> = memory_areas.map(|a| Area::from(a)).collect();
+
let mut allocator = AreaFrameAllocator {
next_free_frame: Frame::of_addr(0),
current_area: None,
- areas: memory_areas,
+ areas,
kernel_start: Frame::of_addr(kernel_start.0 as usize),
kernel_end: Frame::of_addr(kernel_end.0 as usize),
multiboot_start: Frame::of_addr(multiboot_start.0 as usize),
@@ -76,10 +79,11 @@ impl AreaFrameAllocator {
}
fn choose_next_area(&mut self) {
- self.current_area = self.areas.clone().filter(|area| {
+ self.current_area = self.areas.iter().filter(|area| {
let address = area.end_address() - 1;
Frame::of_addr(address as usize) >= self.next_free_frame
- }).min_by_key(|area| area.start_address());
+ }).min_by_key(|area| area.start_address())
+ .map(|area| area.clone());
if let Some(area) = self.current_area {
let start_frame = Frame::of_addr(area.start_address());
@@ -89,3 +93,30 @@ impl AreaFrameAllocator {
}
}
}
+
+#[derive(Debug, Copy, Clone)]
+pub struct Area {
+ start: usize,
+ end: usize,
+}
+
+impl Area {
+ pub fn start_address(&self) -> usize {
+ self.start
+ }
+ pub fn end_address(&self) -> usize {
+ self.end
+ }
+ pub fn size(&self) -> usize {
+ self.end - self.start
+ }
+}
+
+impl<'a> From<&'a MemoryArea> for Area {
+ fn from(a: &'a MemoryArea) -> Self {
+ Area {
+ start: a.start_address(),
+ end: a.end_address(),
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/memory/memory_set.rs b/src/memory/memory_set.rs
index 65ef6fed..9a376a0e 100644
--- a/src/memory/memory_set.rs
+++ b/src/memory/memory_set.rs
@@ -44,6 +44,14 @@ impl MemoryArea {
name,
}
}
+ pub unsafe fn as_slice(&self) -> &[u8] {
+ use core::slice;
+ slice::from_raw_parts(self.start_addr as *const u8, self.end_addr - self.start_addr)
+ }
+ pub unsafe fn as_slice_mut(&self) -> &mut [u8] {
+ use core::slice;
+ slice::from_raw_parts_mut(self.start_addr as *mut u8, self.end_addr - self.start_addr)
+ }
pub fn contains(&self, addr: VirtAddr) -> bool {
addr >= self.start_addr && addr < self.end_addr
}
@@ -58,16 +66,17 @@ impl MemoryArea {
/// 内存空间集合,包含若干段连续空间
/// 对应ucore中 `mm_struct`
+#[derive(Clone)]
pub struct MemorySet {
areas: Vec,
- page_table: Option,
+// page_table: Option,
}
impl MemorySet {
pub fn new() -> Self {
MemorySet {
areas: Vec::::new(),
- page_table: None,
+// page_table: None,
}
}
/// Used for remap_kernel() where heap alloc is unavailable
@@ -76,7 +85,7 @@ impl MemorySet {
let cap = slice.len() / size_of::();
MemorySet {
areas: Vec::::from_raw_parts(slice.as_ptr() as *mut MemoryArea, 0, cap),
- page_table: None,
+// page_table: None,
}
}
pub fn find_area(&self, addr: VirtAddr) -> Option<&MemoryArea> {
@@ -88,8 +97,8 @@ impl MemorySet {
.is_none(), "memory area overlap");
self.areas.push(area);
}
- pub fn map(&mut self, pt: &mut Mapper) {
- for area in self.areas.iter_mut() {
+ pub fn map(&self, pt: &mut Mapper) {
+ for area in self.areas.iter() {
match area.phys_start_addr {
Some(phys_start) => {
for page in Page::range_of(area.start_addr, area.end_addr) {
@@ -105,13 +114,16 @@ impl MemorySet {
}
}
}
- pub fn unmap(&mut self, pt: &mut Mapper) {
- for area in self.areas.iter_mut() {
+ pub fn unmap(&self, pt: &mut Mapper) {
+ for area in self.areas.iter() {
for page in Page::range_of(area.start_addr, area.end_addr) {
pt.unmap(page);
}
}
}
+ pub fn iter(&self) -> impl Iterator- {
+ self.areas.iter()
+ }
}
impl Debug for MemorySet {
diff --git a/src/memory/mod.rs b/src/memory/mod.rs
index 32da9d49..36f5f619 100644
--- a/src/memory/mod.rs
+++ b/src/memory/mod.rs
@@ -18,8 +18,6 @@ mod stack_allocator;
mod address;
mod frame;
-pub static ACITVE_PAGETABLE: Mutex = Mutex::new(unsafe { ActivePageTable::new() });
-
pub static FRAME_ALLOCATOR: Mutex