Commit 651dbdaa authored by Nifou's avatar Nifou

Add the kernel heap in the process' memory space

parent fb9a941d
Pipeline #164029219 passed with stages
in 8 minutes and 49 seconds
......@@ -56,9 +56,6 @@ pub extern "x86-interrupt" fn timer_interrupt_handler(_: &mut InterruptStackFram
: : : : "intel", "volatile");
}
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
// Save the current context
if !FIRST_TIME.load(Ordering::Relaxed) {
// Use a closure to avoid messing up the stack (with the stack frame)
......
......@@ -48,10 +48,7 @@ use alloc::{alloc::Layout, prelude::v1::String};
use core::panic::PanicInfo;
use multiboot2::MemoryAreaIter;
use memory::{
area::{Area, Areas},
KERNEL_START_PHYS, KERNEL_SIZE,
};
use memory::area::{Area, Areas};
/// An initialization function which runs initializations of all components
pub fn init(mut areas: MemoryAreaIter,
......@@ -97,7 +94,6 @@ pub fn init(mut areas: MemoryAreaIter,
enable_write_protect_bit();
memory::init(Areas::new(
(KERNEL_START_PHYS, KERNEL_START_PHYS + KERNEL_SIZE),
(multiboot_start, multiboot_end),
(area1, area2),
));
......
......@@ -23,12 +23,6 @@ use x86_64::{structures::paging::frame::PhysFrame, PhysAddr};
/// - The multiboot area which must not be written too
/// - The upper and lower memory areas
pub struct Areas {
/// The kernel area's start
pub kernel_start: PhysFrame,
/// The kernel area's end
pub kernel_end: PhysFrame,
/// The multiboot area's start
pub multiboot_start: PhysFrame,
......@@ -44,10 +38,8 @@ pub struct Areas {
impl Areas {
/// Create a new Area's container
pub fn new(kernel: (u64, u64), multiboot: (u64, u64), areas: (Area, Area)) -> Self {
pub fn new(multiboot: (u64, u64), areas: (Area, Area)) -> Self {
Self {
kernel_start: PhysFrame::containing_address(PhysAddr::new(kernel.0)),
kernel_end: PhysFrame::containing_address(PhysAddr::new(kernel.1)),
multiboot_start: PhysFrame::containing_address(PhysAddr::new(multiboot.0)),
multiboot_end: PhysFrame::containing_address(PhysAddr::new(multiboot.1)),
area1: areas.0,
......@@ -60,11 +52,6 @@ impl Areas {
[self.area1.clone(), self.area2.clone()]
}
/// Get the kernel areas
pub fn get_kernel(&self) -> (PhysFrame, PhysFrame) {
(self.kernel_start.clone(), self.kernel_end.clone())
}
/// Get the multiboot areas
pub fn get_multiboot(&self) -> (PhysFrame, PhysFrame) {
(self.multiboot_start.clone(), self.multiboot_end.clone())
......
......@@ -40,7 +40,7 @@ impl NextFrameAllocator {
Self {
areas: areas,
current_area: 0,
next: PhysFrame::containing_address(PhysAddr::new(0)),
next: PhysFrame::containing_address(PhysAddr::new(super::KERNEL_START_PHYS + super::KERNEL_SIZE)),
}
}
......@@ -75,12 +75,6 @@ impl NextFrameAllocator {
if self.next > current_area_last_frame {
// all frames of current area are used, switch to next area
self.choose_next_area();
} else if self.next >= self.areas.get_kernel().0 && self.next <= self.areas.get_kernel().1 {
// `frame` is used by the kernel
self.next = PhysFrame::from_start_address(PhysAddr::new(
self.areas.get_kernel().1.start_address().as_u64() + 4096,
))
.unwrap();
} else if self.next >= self.areas.get_multiboot().0
&& self.next <= self.areas.get_multiboot().1
{
......
......@@ -17,10 +17,10 @@
//! Heap allocator
use linked_list_allocator::LockedHeap;
use super::{KERNEL_START_VIRT, KERNEL_SIZE};
use super::{MULTIBOOT_START_VIRT, MULTIBOOT_SIZE};
/// The start of the kernel's heap in virtual memory
pub const HEAP_START: usize = KERNEL_START_VIRT as usize + KERNEL_SIZE as usize + 4096;
pub const HEAP_START_VIRT: u64 = MULTIBOOT_START_VIRT + MULTIBOOT_SIZE + 4096;
/// The size of the kernel's heap
pub const HEAP_SIZE: usize = 4 * 1024 * 1024;
......@@ -32,6 +32,6 @@ pub static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
/// Initialize the heap allocator
pub fn init() {
unsafe {
HEAP_ALLOCATOR.lock().init(HEAP_START, HEAP_SIZE);
HEAP_ALLOCATOR.lock().init(HEAP_START_VIRT as usize, HEAP_SIZE);
}
}
......@@ -44,9 +44,9 @@ use x86_64::{
use area::Areas;
use frame_allocator::NextFrameAllocator;
use self::table::ProcessPageTable;
use self::heap::{HEAP_START, HEAP_SIZE};
use self::heap::{HEAP_START_VIRT, HEAP_SIZE};
const TMP_PAGE_ADDR: u64 = HEAP_START as u64 + HEAP_SIZE as u64 + 4096;
const TMP_PAGE_ADDR: u64 = HEAP_START_VIRT + HEAP_SIZE as u64 + 4096;
/// The start of the kernel in the Higher Half part (Virtual)
pub const KERNEL_START_VIRT: u64 = 0xc0000000;
......@@ -57,6 +57,15 @@ pub const KERNEL_START_PHYS: u64 = 0;
/// The size of the kernel
pub const KERNEL_SIZE: u64 = 0x800000;
/// The start of the multiboot information structure (Virtual)
pub const MULTIBOOT_START_VIRT: u64 = KERNEL_START_VIRT + KERNEL_SIZE;
/// The start of the multiboot information structure (Virtual)
pub const MULTIBOOT_START_PHYS: u64 = KERNEL_START_PHYS + KERNEL_SIZE;
/// The size of the multiboot information structure
pub const MULTIBOOT_SIZE: u64 = 0xa000;
lazy_static! {
/// A global kernel memory mapper
pub static ref KERNEL_MAPPER: Once<Mutex<RecursivePageTable<'static>>> = Once::new();
......@@ -131,16 +140,19 @@ fn remap_kernel(frame: PhysFrame) -> RecursivePageTable<'static> {
}
// Map the kernel heap
for page in Page::<Size4KiB>::range_inclusive(
Page::containing_address(VirtAddr::new(HEAP_START as u64)),
Page::containing_address(VirtAddr::new(HEAP_START as u64 + HEAP_SIZE as u64))
) {
for (i, page) in Page::<Size4KiB>::range_inclusive(
Page::containing_address(VirtAddr::new(HEAP_START_VIRT)),
Page::containing_address(VirtAddr::new(HEAP_START_VIRT + HEAP_SIZE as u64))
).enumerate() {
let frame = FRAME_ALLOCATOR
.r#try()
.unwrap()
.lock()
.allocate_frame()
.expect("cannot allocate frame");
if i == 0 {
println!("{:#?}", frame);
}
unsafe { mapper.map_to(page, frame, Flags::PRESENT | Flags::WRITABLE, &mut *FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
}
......
......@@ -147,6 +147,11 @@ impl ProcessPageTable {
});
}
/// Unmap a page
pub fn unmap(&mut self, page: Page) {
self.with(|mapper| mapper.unmap(page).unwrap().1.flush());
}
/// Get the process' page table
pub unsafe fn table(&self) -> &'static mut PageTable {
to_page_table(self.p4_frame.start_address().as_u64())
......
......@@ -63,9 +63,6 @@ impl Syscall {
_ => println!("Error"),
}
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
exit(false);
unreachable!();
}
......@@ -78,9 +75,6 @@ impl Syscall {
_ => println!("Error"),
}
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
exit(true);
unreachable!();
}
......@@ -91,9 +85,6 @@ impl Syscall {
// TODO: Send a signal
if sig == SIGABRT {
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
exit(true);
unreachable!();
}
......
......@@ -63,6 +63,18 @@ impl ProcessMemory {
let frame = PhysFrame::containing_address(PhysAddr::new(memory::KERNEL_START_PHYS + i as u64 * 4096));
unsafe { mapper.map_to(page, frame, Flags::PRESENT | Flags::WRITABLE, &mut *memory::FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
}
// Map the kernel heap
for (i, page) in Page::<Size4KiB>::range_inclusive(
Page::containing_address(VirtAddr::new(memory::heap::HEAP_START_VIRT as u64)),
Page::containing_address(VirtAddr::new(memory::heap::HEAP_START_VIRT as u64 + memory::heap::HEAP_SIZE as u64))
).enumerate() {
let frame = PhysFrame::containing_address(PhysAddr::new(memory::MULTIBOOT_START_PHYS + memory::MULTIBOOT_SIZE + i as u64 * 4096));
if i == 0 {
println!("{:#?}", frame);
}
unsafe { mapper.map_to(page, frame, Flags::PRESENT | Flags::WRITABLE, &mut *memory::FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
}
});
Self {
......
......@@ -117,6 +117,10 @@ impl Process {
Flags::PRESENT | Flags::WRITABLE
);
area.mappings(mappings.clone());
for mapping in mappings {
processes.get_mut(&process.pid).unwrap().memory.table.unmap(mapping.1);
}
processes.get_mut(&process.pid).unwrap().memory.map(area);
process.pid
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment