Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Feature/process #49

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@ extern crate hole_list_allocator;
/// Higher-level data structures that use the heap
extern crate alloc;

// NOTE: for mods that involve macros, they must be
// above any mod they will be used from.
#[macro_use]
/// Abstraction of the VGA text buffer
mod vga_buffer;
#[macro_use]
/// IO abstractions in Rust
mod cpuio;
/// Memory management
mod memory;
/// Interrupts code
// This must be pub to expose functions to the linker
pub mod interrupts;
/// IO abstractions in Rust
#[macro_use]
mod cpuio;
mod sync;
mod scheduler;
/// Utilities for multi-CPU processing
Expand Down
7 changes: 7 additions & 0 deletions src/memory/paging/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use multiboot2::ElfSection;
use memory::Frame;

/// A representation of a page table entry.
#[derive(PartialEq,Debug)]
pub struct Entry(u64);

impl Entry {
Expand Down Expand Up @@ -44,6 +45,12 @@ impl Entry {
assert!(frame.start_address() & !0x000fffff_fffff000 == 0);
self.0 = (frame.start_address() as u64) | flags.bits();
}

/// Clones the entry. Trait is not derived, as this could cause
/// a double free.
pub fn clone(&self) -> Entry {
Entry(self.0)
}
}

bitflags! {
Expand Down
18 changes: 15 additions & 3 deletions src/memory/paging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,19 @@ impl InactivePageTable {
/// that is returned has recursive mapping, so activating it is safe.
pub fn new(frame: Frame,
active_table: &mut ActivePageTable,
temporary_page: &mut TemporaryPage)
temporary_page: &mut TemporaryPage,
copy_kernel: bool)
-> InactivePageTable {
{
let table = temporary_page.map_table_frame(frame.clone(), active_table);
// Now that it's mapped we can zero it

// Now that it's mapped we can zero it and copy in the kernel
table.zero();
let active_p4 = active_table.mapper.p4();
if copy_kernel {
active_p4.clone_higher_half_into(table);
}

// Now set up recursive mapping for the table
table[510].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE);
}
Expand Down Expand Up @@ -317,7 +324,7 @@ pub fn remap_the_kernel<FA>(active_table: &mut ActivePageTable,
let mut new_table = {
let frame = allocator.allocate_frame()
.expect("No more frames");
InactivePageTable::new(frame, &mut ACTIVE_TABLE.lock(), &mut temporary_page)
InactivePageTable::new(frame, &mut ACTIVE_TABLE.lock(), &mut temporary_page, false)
};

active_table.with(&mut new_table, &mut temporary_page, |mapper| {
Expand Down Expand Up @@ -397,6 +404,11 @@ pub mod tests {
use tap::TestGroup;

pub fn run() {
test_mapping();
super::table::tests::run();
}

fn test_mapping() {
let mut lock = MEMORY_CONTROLLER.lock();
let &mut MemoryController {
ref mut active_table,
Expand Down
72 changes: 72 additions & 0 deletions src/memory/paging/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ impl<L> Table<L>
entry.set_unused();
}
}

/// Copies the higher half of self into table
pub fn clone_higher_half_into<A>(&self, table: &mut Table<A>)
where A: TableLevel
{
let mut i = 0x100;
while i < self.entries.len() {
table[i] = self.entries[i].clone();
i += 1;
}
}

/// Print all entries of the table
// TODO: Contitionally compile this only when debugging?
pub fn print_entries(&self) {
let mut i = 0;
while i < self.entries.len() {
serial_println!("{:x?}", self.entries[i]);
i += 1
}
}
}

/// These methods can only be used if the given table is a parent to other tables.
Expand Down Expand Up @@ -141,3 +162,54 @@ impl HierarchicalLevel for Level3 {
impl HierarchicalLevel for Level2 {
type NextLevel = Level1;
}

#[cfg(feature = "test")]
pub mod tests {
use memory::{MemoryController,MEMORY_CONTROLLER,FrameAllocate};
use tap::TestGroup;

pub fn run() {
test_copy_higher_half()
}

use ::memory::paging::Page;
use ::memory::paging::TemporaryPage;

fn test_copy_higher_half() {
let mut lock = MEMORY_CONTROLLER.lock();
let &mut MemoryController {
ref mut active_table,
ref mut frame_allocator,
stack_allocator: _,
} = lock.as_mut().unwrap();

let mut tap = TestGroup::new(6);

// map the new table
let addr = 4096 * 512 * 512 * 12; // random address
let page = Page::containing_address(addr);
let mut temp_page = TemporaryPage::new(page, frame_allocator);
let frame = frame_allocator.allocate_frame().expect("Unable to allocate frame.");
let new_p4 = temp_page.map_table_frame(frame, active_table);

// now, clone it from the old one
let active_p4 = active_table.mapper.p4();
active_p4.clone_higher_half_into(new_p4);

tap.diagnostic("Testing copying a p4");
tap.assert_tap(new_p4[0].is_unused(),
"Lower half not zeroed on copied p4 (zero)");
tap.assert_tap(new_p4[0x008].is_unused(),
"Lower half not zeroed on copied p4 (random)");
tap.assert_tap(new_p4[0x0ff].is_unused(),
"Lower half not zeroed on copied p4 (top of lower half)");

tap.assert_tap(new_p4[0x100] == active_p4[0x100],
"Higher half not identical to previous p4 (bottom)");
tap.assert_tap(new_p4[0x108] == active_p4[0x108],
"Higher half not identical to previous p4 (random)");
tap.assert_tap(new_p4[0x1ff] == active_p4[0x1ff],
"Higher half not identical to previous p4 (last entry)");

}
}