From 66e478da7f8364c555035216f5e1d776f4f399b2 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Tue, 29 May 2018 08:30:35 -0600 Subject: [PATCH 1/7] Create inactive page table Make a new module for creation of processes, and in that module, create a new page table that will become the address space for our new process Copy p3 entries to new p4 table Copy the kernel (in the higher half) into the new address space. Many memory-module functions are made public to allow this. --- src/lib.rs | 4 +++ src/memory/mod.rs | 12 ++++----- src/memory/paging/entry.rs | 3 ++- src/memory/paging/mapper.rs | 2 +- src/memory/paging/mod.rs | 6 ++--- src/memory/paging/table.rs | 2 +- src/process.rs | 50 +++++++++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 src/process.rs diff --git a/src/lib.rs b/src/lib.rs index 04959ce..abbd5f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,8 @@ mod memory; /// Interrupts code // This must be pub to expose functions to the linker pub mod interrupts; +/// Process Management +mod process; /// IO abstractions in Rust #[macro_use] mod cpuio; @@ -106,6 +108,8 @@ pub extern "C" fn rust_main(multiboot_info_address: usize) -> ! { println!("Try to write some things!"); vga_buffer::change_color(vga_buffer::Color::White, vga_buffer::Color::Black); + process::create_process(); + #[cfg(feature = "test")] { run_tests(); shutdown(); diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 251e209..8b94c69 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -27,7 +27,7 @@ mod area_frame_allocator; /// Physical frame allocator that uses a bitmap. mod frame_bitmap; /// Virtual paging module. -mod paging; +pub mod paging; /// The kernel is linked to `KERNEL_BASE + 1M` pub const KERNEL_BASE: usize = 0xFFFF_FFFF_8000_0000; @@ -41,14 +41,14 @@ const HEAP_START: usize = 0o000_001_000_0000; const HEAP_SIZE: usize = 25 * PAGE_SIZE; /// A struct that gives access to the physical and virtual memory managers. -struct MemoryController { - active_table:ActivePageTable, - frame_allocator: FrameBitmap, - stack_allocator: stack_allocator::StackAllocator, +pub struct MemoryController { + pub active_table:ActivePageTable, + pub frame_allocator: FrameBitmap, + pub stack_allocator: stack_allocator::StackAllocator, } /// A static `MemoryController`. Will always be Some(_) after init completes. -static MEMORY_CONTROLLER: Mutex> = Mutex::new(None); +pub static MEMORY_CONTROLLER: Mutex> = Mutex::new(None); /// Allocates a stack of `size` pages diff --git a/src/memory/paging/entry.rs b/src/memory/paging/entry.rs index 911c736..0f59c3e 100644 --- a/src/memory/paging/entry.rs +++ b/src/memory/paging/entry.rs @@ -12,7 +12,8 @@ use multiboot2::ElfSection; use memory::Frame; /// A representation of a page table entry. -pub struct Entry(u64); +#[derive(Clone)] +pub struct Entry(pub u64); impl Entry { /// Checks if an entry is unused. diff --git a/src/memory/paging/mapper.rs b/src/memory/paging/mapper.rs index 3a2875e..747c79f 100644 --- a/src/memory/paging/mapper.rs +++ b/src/memory/paging/mapper.rs @@ -16,7 +16,7 @@ use core::ptr::Unique; /// An interface to the active page table. pub struct Mapper { /// This must be `Table::P4` - p4: Unique>, + pub p4: Unique>, } impl Mapper { diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 1a6898c..2b6ddfd 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -26,7 +26,7 @@ mod entry; /// Abstraction of the page table. mod table; /// A page to temporarily map a frame. -mod temporary_page; +pub mod temporary_page; /// An interface to the active page table. mod mapper; @@ -189,7 +189,7 @@ impl Iterator for PageIter { /// An abstraction to the Active table, dereferences to the `Mapper` type. pub struct ActivePageTable { - mapper: Mapper, + pub mapper: Mapper, } impl Deref for ActivePageTable { @@ -270,7 +270,7 @@ impl ActivePageTable { /// A level 4 table that is not yet used pub struct InactivePageTable { - p4_frame: Frame, + pub p4_frame: Frame, } impl InactivePageTable { diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index 23c33d4..1351aaf 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -30,7 +30,7 @@ pub const P4: *mut Table = 0o177777_776_776_776_776_0000 as *mut _; /// A page table pub struct Table { - entries: [Entry; ENTRY_COUNT], + pub entries: [Entry; ENTRY_COUNT], level: PhantomData, } diff --git a/src/process.rs b/src/process.rs new file mode 100644 index 0000000..a30f34b --- /dev/null +++ b/src/process.rs @@ -0,0 +1,50 @@ +// Copyright 2016 Phillip Oppermann, Calvin Lee and JJ Garzella. +// See the README.md file at the top-level directory of this +// distribution. +// +// Licensed under the MIT license , at your option. +// This file may not be copied, modified, or distributed +// except according to those terms. + +use memory::{MemoryController,MEMORY_CONTROLLER,FrameAllocate,KERNEL_BASE}; +use memory::paging::{Page, InactivePageTable}; +use memory::paging::temporary_page::TemporaryPage; + + +pub fn create_process() { + // Step 1 - create new page directory + let mut lock = MEMORY_CONTROLLER.lock(); + let &mut MemoryController { + ref mut active_table, + ref mut frame_allocator, + stack_allocator: _, + } = lock.as_mut().unwrap(); + + let frame = frame_allocator.allocate_frame().expect("Unable to allocate frame"); + + // random unmapped address + let addr = 4096 * 512 * 512 * 12; + let page = Page::containing_address(addr); + //assert!(active_table.mapper.translate(addr).is_none(), "Chose bad page"); + let mut temp_page = TemporaryPage::new(page, frame_allocator); + + let inactive_table = InactivePageTable::new(frame, active_table, &mut temp_page); + println!("Inactive Table created!"); + + // Step 2 - copy the kernel over + { + let table = temp_page.map_table_frame(inactive_table.p4_frame, active_table); + + let mut i: usize = 0; + for entry in unsafe{ active_table.mapper.p4.as_ref().entries.iter()} { + if KERNEL_BASE as u64 <= entry.0 { + //let new_entry = (*entry).clone() + table[i] = (*entry).clone(); + } + i += 1 + } + } + println!("Kernel copied"); + +} From bc0adddfec445261bad2a5a56412dc64e7a4f171 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Wed, 6 Jun 2018 08:08:18 -0600 Subject: [PATCH 2/7] Revert all public changes to paging mod Done so that the code in process can be factored into the paging mod, removing the necessecity for everything to be public. --- src/lib.rs | 4 ++-- src/memory/mod.rs | 12 ++++++------ src/memory/paging/entry.rs | 2 +- src/memory/paging/mapper.rs | 2 +- src/memory/paging/mod.rs | 6 +++--- src/memory/paging/table.rs | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index abbd5f2..4af1f05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,7 +52,7 @@ mod memory; // This must be pub to expose functions to the linker pub mod interrupts; /// Process Management -mod process; +//mod process; /// IO abstractions in Rust #[macro_use] mod cpuio; @@ -108,7 +108,7 @@ pub extern "C" fn rust_main(multiboot_info_address: usize) -> ! { println!("Try to write some things!"); vga_buffer::change_color(vga_buffer::Color::White, vga_buffer::Color::Black); - process::create_process(); + //process::create_process(); #[cfg(feature = "test")] { run_tests(); diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 8b94c69..251e209 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -27,7 +27,7 @@ mod area_frame_allocator; /// Physical frame allocator that uses a bitmap. mod frame_bitmap; /// Virtual paging module. -pub mod paging; +mod paging; /// The kernel is linked to `KERNEL_BASE + 1M` pub const KERNEL_BASE: usize = 0xFFFF_FFFF_8000_0000; @@ -41,14 +41,14 @@ const HEAP_START: usize = 0o000_001_000_0000; const HEAP_SIZE: usize = 25 * PAGE_SIZE; /// A struct that gives access to the physical and virtual memory managers. -pub struct MemoryController { - pub active_table:ActivePageTable, - pub frame_allocator: FrameBitmap, - pub stack_allocator: stack_allocator::StackAllocator, +struct MemoryController { + active_table:ActivePageTable, + frame_allocator: FrameBitmap, + stack_allocator: stack_allocator::StackAllocator, } /// A static `MemoryController`. Will always be Some(_) after init completes. -pub static MEMORY_CONTROLLER: Mutex> = Mutex::new(None); +static MEMORY_CONTROLLER: Mutex> = Mutex::new(None); /// Allocates a stack of `size` pages diff --git a/src/memory/paging/entry.rs b/src/memory/paging/entry.rs index 0f59c3e..245606f 100644 --- a/src/memory/paging/entry.rs +++ b/src/memory/paging/entry.rs @@ -13,7 +13,7 @@ use memory::Frame; /// A representation of a page table entry. #[derive(Clone)] -pub struct Entry(pub u64); +pub struct Entry(u64); impl Entry { /// Checks if an entry is unused. diff --git a/src/memory/paging/mapper.rs b/src/memory/paging/mapper.rs index 747c79f..3a2875e 100644 --- a/src/memory/paging/mapper.rs +++ b/src/memory/paging/mapper.rs @@ -16,7 +16,7 @@ use core::ptr::Unique; /// An interface to the active page table. pub struct Mapper { /// This must be `Table::P4` - pub p4: Unique>, + p4: Unique>, } impl Mapper { diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 2b6ddfd..1a6898c 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -26,7 +26,7 @@ mod entry; /// Abstraction of the page table. mod table; /// A page to temporarily map a frame. -pub mod temporary_page; +mod temporary_page; /// An interface to the active page table. mod mapper; @@ -189,7 +189,7 @@ impl Iterator for PageIter { /// An abstraction to the Active table, dereferences to the `Mapper` type. pub struct ActivePageTable { - pub mapper: Mapper, + mapper: Mapper, } impl Deref for ActivePageTable { @@ -270,7 +270,7 @@ impl ActivePageTable { /// A level 4 table that is not yet used pub struct InactivePageTable { - pub p4_frame: Frame, + p4_frame: Frame, } impl InactivePageTable { diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index 1351aaf..23c33d4 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -30,7 +30,7 @@ pub const P4: *mut Table = 0o177777_776_776_776_776_0000 as *mut _; /// A page table pub struct Table { - pub entries: [Entry; ENTRY_COUNT], + entries: [Entry; ENTRY_COUNT], level: PhantomData, } From ef225d441780b98f65cf3b76fe5ec7610babd0f6 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Wed, 6 Jun 2018 21:13:14 -0600 Subject: [PATCH 3/7] Add copying funcitonality to talbe mod Add a method that copies a table into a new frame, copying the higher half of the entries. --- src/lib.rs | 2 +- src/memory/paging/table.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4af1f05..f5cbd4c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,7 +108,7 @@ pub extern "C" fn rust_main(multiboot_info_address: usize) -> ! { println!("Try to write some things!"); vga_buffer::change_color(vga_buffer::Color::White, vga_buffer::Color::Black); - //process::create_process(); + // process::create_process(); #[cfg(feature = "test")] { run_tests(); diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index 23c33d4..d99163a 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -43,6 +43,23 @@ impl Table entry.set_unused(); } } + + pub fn clone_higher_half(&self, allocator: &mut A) -> &mut Table + where A: FrameAllocate + { + let frame = allocator.allocate_frame().expect("Unable to allocate frame."); + + let table: &mut Table = unsafe { &mut *(frame.start_address() as *mut _) }; + // TODO: is this necessary? + table.zero(); + + let mut i = 0b1_0000_0000; // == 0x100 == 256 + while i < self.entries.len() { + table[i] = self.entries[i].clone(); + i += 1; + } + table + } } /// These methods can only be used if the given table is a parent to other tables. From 019c6b57adb55c46ae36f92501e30d2486497873 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Fri, 8 Jun 2018 09:45:11 -0600 Subject: [PATCH 4/7] Add copy kernel option to InactivePageTable Fix the copy_higher_half() method of Table to map the table before using it Found bug(?) in recursive mapping of original table, put in a fixme Add testing for copy_higher_half() Derive a few traits to help with debugging of entries. Also, wrote print_entries() method on Table Remove the now unused src/process.rs file Finally, add the option to copy the higher half upon creation of an InactivePageTable. This is not default behavior because of the aforementioned bug. --- src/lib.rs | 6 ++-- src/memory/paging/entry.rs | 2 +- src/memory/paging/mod.rs | 27 ++++++++++++-- src/memory/paging/table.rs | 73 +++++++++++++++++++++++++++++++++----- src/process.rs | 50 -------------------------- 5 files changed, 92 insertions(+), 66 deletions(-) delete mode 100644 src/process.rs diff --git a/src/lib.rs b/src/lib.rs index f5cbd4c..6c098e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,9 @@ extern crate alloc; #[macro_use] /// Abstraction of the VGA text buffer mod vga_buffer; +/// IO abstractions in Rust +#[macro_use] +mod cpuio; /// Memory management mod memory; /// Interrupts code @@ -53,9 +56,6 @@ mod memory; pub mod interrupts; /// Process Management //mod process; -/// IO abstractions in Rust -#[macro_use] -mod cpuio; mod sync; mod scheduler; /// Utilities for multi-CPU processing diff --git a/src/memory/paging/entry.rs b/src/memory/paging/entry.rs index 245606f..4674a83 100644 --- a/src/memory/paging/entry.rs +++ b/src/memory/paging/entry.rs @@ -12,7 +12,7 @@ use multiboot2::ElfSection; use memory::Frame; /// A representation of a page table entry. -#[derive(Clone)] +#[derive(Clone,PartialEq,Debug)] pub struct Entry(u64); impl Entry { diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 1a6898c..9b7e6d4 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -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); } @@ -317,9 +324,18 @@ pub fn remap_the_kernel(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) }; + //FIXME: for some reason the p3 at the 511th position + // in this original p4 is not recursively mapped correctly. + // This code triggers that. + // + //serial_println!("About to try to map at 511th p4, 510th p3, 0th p2"); + //let frame = allocator.allocate_frame().unwrap(); + //let page = Page::containing_address(0xffffffff80101000); + //active_table.mapper.map_to(page, frame, EntryFlags::PRESENT, &mut allocator).expect("Unable to map sample page"); + active_table.with(&mut new_table, &mut temporary_page, |mapper| { let elf_sections_tag = boot_info.elf_sections_tag() @@ -397,6 +413,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, diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index d99163a..5efb52b 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -44,21 +44,23 @@ impl Table } } - pub fn clone_higher_half(&self, allocator: &mut A) -> &mut Table - where A: FrameAllocate + pub fn clone_higher_half_into(&self, table: &mut Table) + where A: TableLevel { - let frame = allocator.allocate_frame().expect("Unable to allocate frame."); - - let table: &mut Table = unsafe { &mut *(frame.start_address() as *mut _) }; - // TODO: is this necessary? - table.zero(); - let mut i = 0b1_0000_0000; // == 0x100 == 256 while i < self.entries.len() { table[i] = self.entries[i].clone(); i += 1; } - table + } + + // TODO: Contitionally compile this only when debugging? + pub fn print_entries(&self) { + let mut i = 0x0; + while i < self.entries.len() { + serial_println!("{:x?}", self.entries[i]); + i += 1 + } } } @@ -158,3 +160,56 @@ 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[0b0_0001_0000].is_unused(), + "Lower half not zeroed on copied p4 (random)"); + tap.assert_tap(new_p4[0b0_1111_1111].is_unused(), + "Lower half not zeroed on copied p4 (top of lower half)"); + + tap.assert_tap(new_p4[0b1_0000_0000] == active_p4[0b1_0000_0000], + "Higher half not identical to previous p4 (bottom)"); + tap.assert_tap(new_p4[0b1_0000_1000] == active_p4[0b1_0000_1000], + "Higher half not identical to previous p4 (random)"); + tap.assert_tap(new_p4[510] == active_p4[510], + "Higher half not identical to previous p4 (recursive mapping)"); + + } +} diff --git a/src/process.rs b/src/process.rs deleted file mode 100644 index a30f34b..0000000 --- a/src/process.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 Phillip Oppermann, Calvin Lee and JJ Garzella. -// See the README.md file at the top-level directory of this -// distribution. -// -// Licensed under the MIT license , at your option. -// This file may not be copied, modified, or distributed -// except according to those terms. - -use memory::{MemoryController,MEMORY_CONTROLLER,FrameAllocate,KERNEL_BASE}; -use memory::paging::{Page, InactivePageTable}; -use memory::paging::temporary_page::TemporaryPage; - - -pub fn create_process() { - // Step 1 - create new page directory - let mut lock = MEMORY_CONTROLLER.lock(); - let &mut MemoryController { - ref mut active_table, - ref mut frame_allocator, - stack_allocator: _, - } = lock.as_mut().unwrap(); - - let frame = frame_allocator.allocate_frame().expect("Unable to allocate frame"); - - // random unmapped address - let addr = 4096 * 512 * 512 * 12; - let page = Page::containing_address(addr); - //assert!(active_table.mapper.translate(addr).is_none(), "Chose bad page"); - let mut temp_page = TemporaryPage::new(page, frame_allocator); - - let inactive_table = InactivePageTable::new(frame, active_table, &mut temp_page); - println!("Inactive Table created!"); - - // Step 2 - copy the kernel over - { - let table = temp_page.map_table_frame(inactive_table.p4_frame, active_table); - - let mut i: usize = 0; - for entry in unsafe{ active_table.mapper.p4.as_ref().entries.iter()} { - if KERNEL_BASE as u64 <= entry.0 { - //let new_entry = (*entry).clone() - table[i] = (*entry).clone(); - } - i += 1 - } - } - println!("Kernel copied"); - -} From cec0ca7d7c931141da6b75b0d36fd404ecf6295f Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Fri, 8 Jun 2018 18:52:04 -0600 Subject: [PATCH 5/7] Change binary constants to hex --- src/memory/paging/table.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index 5efb52b..53ad904 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -47,7 +47,7 @@ impl Table pub fn clone_higher_half_into(&self, table: &mut Table) where A: TableLevel { - let mut i = 0b1_0000_0000; // == 0x100 == 256 + let mut i = 0x100; while i < self.entries.len() { table[i] = self.entries[i].clone(); i += 1; @@ -56,7 +56,7 @@ impl Table // TODO: Contitionally compile this only when debugging? pub fn print_entries(&self) { - let mut i = 0x0; + let mut i = 0; while i < self.entries.len() { serial_println!("{:x?}", self.entries[i]); i += 1 @@ -174,7 +174,6 @@ pub mod tests { use ::memory::paging::Page; use ::memory::paging::TemporaryPage; - fn test_copy_higher_half() { let mut lock = MEMORY_CONTROLLER.lock(); let &mut MemoryController { @@ -199,14 +198,14 @@ pub mod tests { 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[0b0_0001_0000].is_unused(), + tap.assert_tap(new_p4[0x008].is_unused(), "Lower half not zeroed on copied p4 (random)"); - tap.assert_tap(new_p4[0b0_1111_1111].is_unused(), + tap.assert_tap(new_p4[0x0ff].is_unused(), "Lower half not zeroed on copied p4 (top of lower half)"); - tap.assert_tap(new_p4[0b1_0000_0000] == active_p4[0b1_0000_0000], + tap.assert_tap(new_p4[0x100] == active_p4[0x100], "Higher half not identical to previous p4 (bottom)"); - tap.assert_tap(new_p4[0b1_0000_1000] == active_p4[0b1_0000_1000], + tap.assert_tap(new_p4[0x108] == active_p4[0x108], "Higher half not identical to previous p4 (random)"); tap.assert_tap(new_p4[510] == active_p4[510], "Higher half not identical to previous p4 (recursive mapping)"); From 4ca73c78f30c12fb7eb20abe4eb30538e973d7a4 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Mon, 11 Jun 2018 15:05:40 -0600 Subject: [PATCH 6/7] Improve safety and documentation Remove references to deleted process.rs Add note about macros in lib.rs Small visual fixes Check kernel table instead of recursively mapped one in tests of clone_higher_half() Make entry not have the clone type, simply a clone method that could be unsafe. --- src/lib.rs | 8 +++----- src/memory/paging/entry.rs | 8 +++++++- src/memory/paging/table.rs | 7 ++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c098e4..6f014a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,19 +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; -/// IO abstractions in Rust #[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; -/// Process Management -//mod process; mod sync; mod scheduler; /// Utilities for multi-CPU processing @@ -108,8 +108,6 @@ pub extern "C" fn rust_main(multiboot_info_address: usize) -> ! { println!("Try to write some things!"); vga_buffer::change_color(vga_buffer::Color::White, vga_buffer::Color::Black); - // process::create_process(); - #[cfg(feature = "test")] { run_tests(); shutdown(); diff --git a/src/memory/paging/entry.rs b/src/memory/paging/entry.rs index 4674a83..d4b5069 100644 --- a/src/memory/paging/entry.rs +++ b/src/memory/paging/entry.rs @@ -12,7 +12,7 @@ use multiboot2::ElfSection; use memory::Frame; /// A representation of a page table entry. -#[derive(Clone,PartialEq,Debug)] +#[derive(PartialEq,Debug)] pub struct Entry(u64); impl Entry { @@ -45,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! { diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index 53ad904..82c30b1 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -44,6 +44,7 @@ impl Table } } + /// Copies the higher half of self into table pub fn clone_higher_half_into(&self, table: &mut Table) where A: TableLevel { @@ -54,6 +55,7 @@ impl Table } } + /// Print all entries of the table // TODO: Contitionally compile this only when debugging? pub fn print_entries(&self) { let mut i = 0; @@ -167,7 +169,6 @@ pub mod tests { use tap::TestGroup; pub fn run() { - test_copy_higher_half() } @@ -207,8 +208,8 @@ pub mod tests { "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[510] == active_p4[510], - "Higher half not identical to previous p4 (recursive mapping)"); + tap.assert_tap(new_p4[0x1ff] == active_p4[0x1ff], + "Higher half not identical to previous p4 (last entry)"); } } From 8ed2f9361c17cc4704e4f9c97a5d399a4cc34b39 Mon Sep 17 00:00:00 2001 From: JJ Garzella Date: Sat, 7 Jul 2018 21:31:25 -0600 Subject: [PATCH 7/7] Remove comment with paging error The recursive mapping error has been deemed a non-issue, so the comment with the fixme has been removed. --- src/memory/paging/mod.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 9b7e6d4..83333ae 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -327,15 +327,6 @@ pub fn remap_the_kernel(active_table: &mut ActivePageTable, InactivePageTable::new(frame, &mut ACTIVE_TABLE.lock(), &mut temporary_page, false) }; - //FIXME: for some reason the p3 at the 511th position - // in this original p4 is not recursively mapped correctly. - // This code triggers that. - // - //serial_println!("About to try to map at 511th p4, 510th p3, 0th p2"); - //let frame = allocator.allocate_frame().unwrap(); - //let page = Page::containing_address(0xffffffff80101000); - //active_table.mapper.map_to(page, frame, EntryFlags::PRESENT, &mut allocator).expect("Unable to map sample page"); - active_table.with(&mut new_table, &mut temporary_page, |mapper| { let elf_sections_tag = boot_info.elf_sections_tag()