From 0420e85e4d8656595bf1d429c34b5b7b1968e611 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 19 Apr 2018 00:22:03 +0800 Subject: [PATCH 01/11] Simple VMA & MM struct at extern crate. --- crate/memory/Cargo.toml | 6 +++ crate/memory/src/lib.rs | 6 +++ crate/memory/src/memory_set.rs | 89 ++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 crate/memory/Cargo.toml create mode 100644 crate/memory/src/lib.rs create mode 100644 crate/memory/src/memory_set.rs diff --git a/crate/memory/Cargo.toml b/crate/memory/Cargo.toml new file mode 100644 index 00000000..c914a0d1 --- /dev/null +++ b/crate/memory/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "memory" +version = "0.1.0" +authors = ["WangRunji "] + +[dependencies] diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs new file mode 100644 index 00000000..8eb011ec --- /dev/null +++ b/crate/memory/src/lib.rs @@ -0,0 +1,6 @@ +#![no_std] +#![feature(alloc)] + +extern crate alloc; + +pub mod memory_set; \ No newline at end of file diff --git a/crate/memory/src/memory_set.rs b/crate/memory/src/memory_set.rs new file mode 100644 index 00000000..7b2705f6 --- /dev/null +++ b/crate/memory/src/memory_set.rs @@ -0,0 +1,89 @@ +use alloc::vec::Vec; + +type Addr = usize; + +/// 一片连续内存空间,有相同的访问权限 +/// 对应ucore中 `vma_struct` +#[derive(Debug, Eq, PartialEq)] +pub struct MemoryArea { + pub start_addr: Addr, + pub end_addr: Addr, + pub flags: u32, + pub name: &'static str, +} + +impl MemoryArea { + pub fn contains(&self, addr: Addr) -> bool { + addr >= self.start_addr && addr < self.end_addr + } + fn is_overlap_with(&self, other: &MemoryArea) -> bool { + !(self.end_addr <= other.start_addr || self.start_addr >= other.end_addr) + } +} + +/// 内存空间集合,包含若干段连续空间 +/// 对应ucore中 `mm_struct` +#[derive(Debug)] +pub struct MemorySet { + areas: Vec, +} + +impl MemorySet { + pub fn new() -> Self { + MemorySet { areas: Vec::::new() } + } + pub fn find_area(&self, addr: Addr) -> Option<&MemoryArea> { + self.areas.iter().find(|area| area.contains(addr)) + } + pub fn push(&mut self, area: MemoryArea) { + assert!(area.start_addr <= area.end_addr, "invalid memory area"); + if self.areas.iter() + .find(|other| area.is_overlap_with(other)) + .is_some() { + panic!("memory area overlap"); + } + self.areas.push(area); + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn push_and_find() { + let mut ms = MemorySet::new(); + ms.push(MemoryArea { + start_addr: 0x0, + end_addr: 0x8, + flags: 0x0, + name: "code", + }); + ms.push(MemoryArea { + start_addr: 0x8, + end_addr: 0x10, + flags: 0x1, + name: "data", + }); + assert_eq!(ms.find_area(0x6).unwrap().name, "code"); + assert_eq!(ms.find_area(0x11), None); + } + + #[test] + #[should_panic] + fn push_overlap() { + let mut ms = MemorySet::new(); + ms.push(MemoryArea { + start_addr: 0x0, + end_addr: 0x8, + flags: 0x0, + name: "code", + }); + ms.push(MemoryArea { + start_addr: 0x4, + end_addr: 0x10, + flags: 0x1, + name: "data", + }); + } +} From a1e9ee36b28a015b5e67cdd9010d45c7dc21d08f Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 19 Apr 2018 11:37:13 +0800 Subject: [PATCH 02/11] Basic SwapManager & MockPageTable --- crate/memory/src/lib.rs | 3 +- crate/memory/src/swap/fifo.rs | 50 ++++++++++++++ crate/memory/src/swap/mock_page_table.rs | 88 ++++++++++++++++++++++++ crate/memory/src/swap/mod.rs | 22 ++++++ 4 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 crate/memory/src/swap/fifo.rs create mode 100644 crate/memory/src/swap/mock_page_table.rs create mode 100644 crate/memory/src/swap/mod.rs diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index 8eb011ec..ffdb24b4 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -3,4 +3,5 @@ extern crate alloc; -pub mod memory_set; \ No newline at end of file +pub mod memory_set; +pub mod swap; \ No newline at end of file diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs new file mode 100644 index 00000000..7e92951a --- /dev/null +++ b/crate/memory/src/swap/fifo.rs @@ -0,0 +1,50 @@ +use alloc::vec_deque::VecDeque; +use super::*; + +struct FifoSwapManager { + deque: VecDeque, +} + +impl SwapManager for FifoSwapManager { + fn new(_page_table: &T) -> Self { + FifoSwapManager { + deque: VecDeque::::new() + } + } + + fn tick(&mut self) { + + } + + fn push(&mut self, addr: usize) { + self.deque.push_back(addr); + } + + fn pop(&mut self, addr: usize) { + let id = self.deque.iter() + .position(|&x| x == addr) + .expect("address not found"); + self.deque.remove(id); + } + + fn swap(&mut self) -> Option { + self.deque.pop_front() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test() { +// let mut pt = mock_page_table::MockPageTable::new(); +// let mut sm = FifoSwapManager::new(); +// let write_seq = [3, 1, 4, 2, 5, 2, 1, 2, 3, 4, 5, 1, 1]; +// let pgfault_count = [4, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11]; +// for i in write_seq { +// pt.write(i); +// } + + } +} \ No newline at end of file diff --git a/crate/memory/src/swap/mock_page_table.rs b/crate/memory/src/swap/mock_page_table.rs new file mode 100644 index 00000000..ba5185fc --- /dev/null +++ b/crate/memory/src/swap/mock_page_table.rs @@ -0,0 +1,88 @@ +use alloc::btree_set::BTreeSet; +use super::*; + +pub struct MockPageTable { + mapped_set: BTreeSet, + accessed_set: BTreeSet, + dirty_set: BTreeSet, + pgfault_handler: PgfaultHandler, +} + +type PgfaultHandler = fn(&mut MockPageTable, Addr); + +impl PageTable for MockPageTable { + fn accessed(&self, addr: Addr) -> bool { + self.accessed_set.contains(&addr) + } + fn dirty(&self, addr: Addr) -> bool { + self.dirty_set.contains(&addr) + } +} + +impl MockPageTable { + pub fn new(pgfault_handler: PgfaultHandler) -> Self { + MockPageTable { + mapped_set: BTreeSet::::new(), + accessed_set: BTreeSet::::new(), + dirty_set: BTreeSet::::new(), + pgfault_handler, + } + } + /// Read memory, mark accessed, trigger page fault if not present + pub fn read(&mut self, addr: Addr) { + while !self.mapped_set.contains(&addr) { + (self.pgfault_handler)(self, addr); + } + self.accessed_set.insert(addr); + + } + /// Write memory, mark accessed and dirty, trigger page fault if not present + pub fn write(&mut self, addr: Addr) { + while !self.mapped_set.contains(&addr) { + (self.pgfault_handler)(self, addr); + } + self.accessed_set.insert(addr); + self.dirty_set.insert(addr); + } + pub fn map(&mut self, addr: Addr) { + self.mapped_set.insert(addr); + } + pub fn unmap(&mut self, addr: Addr) { + self.mapped_set.remove(&addr); + } +} + +#[cfg(test)] +mod test { + use super::*; + + static mut PGFAULT_COUNT: usize = 0; + + fn assert_pgfault_eq(x: usize) { + assert_eq!(unsafe{ PGFAULT_COUNT }, x); + } + + #[test] + fn test() { + fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + unsafe{ PGFAULT_COUNT += 1; } + pt.map(addr); + } + let mut pt = MockPageTable::new(pgfault_handler); + + pt.map(0); + pt.read(0); + assert_pgfault_eq(0); + assert!(pt.accessed(0)); + assert!(!pt.dirty(0)); + + pt.write(1); + assert_pgfault_eq(1); + assert!(pt.accessed(1)); + assert!(pt.dirty(1)); + + pt.unmap(0); + pt.read(0); + assert_pgfault_eq(2); + } +} \ No newline at end of file diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs new file mode 100644 index 00000000..8a659217 --- /dev/null +++ b/crate/memory/src/swap/mod.rs @@ -0,0 +1,22 @@ +pub mod fifo; +mod mock_page_table; + +type Addr = usize; + +trait SwapManager { + /// Create and initialize for the swap manager + fn new(page_table: &T) -> Self; + /// Called when tick interrupt occured + fn tick(&mut self); + /// Called when map a swappable page into the memory + fn push(&mut self, addr: Addr); + /// Called to delete the addr entry from the swap manager + fn pop(&mut self, addr: Addr); + /// Try to swap out a page, return then victim + fn swap(&mut self) -> Option; +} + +trait PageTable { + fn accessed(&self, addr: Addr) -> bool; + fn dirty(&self, addr: Addr) -> bool; +} \ No newline at end of file From be6ff50d7f478205493654d985fd09bdadfd7a92 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 19 Apr 2018 12:42:24 +0800 Subject: [PATCH 03/11] Test framework for FifoSwapManager. Not passed. --- crate/memory/src/swap/fifo.rs | 64 +++++++++++++++++++++++++++++------ crate/memory/src/swap/mod.rs | 2 +- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index 7e92951a..8a91f52d 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -1,13 +1,15 @@ use alloc::vec_deque::VecDeque; use super::*; -struct FifoSwapManager { +struct FifoSwapManager { + page_table: &'static T, deque: VecDeque, } -impl SwapManager for FifoSwapManager { - fn new(_page_table: &T) -> Self { +impl SwapManager for FifoSwapManager { + fn new(page_table: &'static T) -> Self { FifoSwapManager { + page_table, deque: VecDeque::::new() } } @@ -35,16 +37,56 @@ impl SwapManager for FifoSwapManager { #[cfg(test)] mod test { use super::*; + use super::mock_page_table::MockPageTable; + + enum MemOp { + R(usize), W(usize) + } + + fn assert_pgfault_eq(x: usize) { + assert_eq!(unsafe{ PGFAULT_COUNT }, x); + } + + // For pgfault_handler: + static mut PGFAULT_COUNT: usize = 0; + static mut PAGE: *mut MockPageTable = 0 as *mut _; + static mut FIFO: *mut FifoSwapManager = 0 as *mut _; + + fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + unsafe{ PGFAULT_COUNT += 1; } + let fifo = unsafe{ &mut *FIFO }; + if let Some(x) = fifo.swap() { + pt.unmap(x); + } + pt.map(addr); + } #[test] fn test() { -// let mut pt = mock_page_table::MockPageTable::new(); -// let mut sm = FifoSwapManager::new(); -// let write_seq = [3, 1, 4, 2, 5, 2, 1, 2, 3, 4, 5, 1, 1]; -// let pgfault_count = [4, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11]; -// for i in write_seq { -// pt.write(i); -// } - + use self::MemOp::{R, W}; + let mut pt = MockPageTable::new(pgfault_handler); + let mut fifo = FifoSwapManager::::new( + unsafe{ &*(&pt as *const _) }); + unsafe { + PAGE = &mut pt as *mut _; + FIFO = &mut fifo as *mut _; + } + let op_seq = [ + R(1), R(2), R(3), R(4), + W(3), W(1), W(4), W(2), W(5), + W(2), W(1), W(2), W(3), W(4), + W(5), R(1), W(1)]; + let pgfault_count = [ + 1, 2, 3, 4, + 4, 4, 4, 4, 5, + 5, 6, 7, 8, 9, + 10, 11, 11]; + for (op, &count) in op_seq.iter().zip(pgfault_count.iter()) { + match op { + R(addr) => pt.read(*addr), + W(addr) => pt.write(*addr), + } + assert_pgfault_eq(count); + } } } \ No newline at end of file diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 8a659217..badc3942 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -5,7 +5,7 @@ type Addr = usize; trait SwapManager { /// Create and initialize for the swap manager - fn new(page_table: &T) -> Self; + fn new(page_table: &'static T) -> Self; /// Called when tick interrupt occured fn tick(&mut self); /// Called when map a swappable page into the memory From 470d5692febd332803a31c02730de02389b992ce Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 19 Apr 2018 15:28:32 +0800 Subject: [PATCH 04/11] Pass test for FifoSwapManager. Change interface. --- crate/memory/src/swap/fifo.rs | 15 +++++++------ crate/memory/src/swap/mock_page_table.rs | 28 ++++++++++++++++-------- crate/memory/src/swap/mod.rs | 4 ++-- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index 8a91f52d..4a006ee1 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -22,14 +22,14 @@ impl SwapManager for FifoSwapManager { self.deque.push_back(addr); } - fn pop(&mut self, addr: usize) { + fn remove(&mut self, addr: usize) { let id = self.deque.iter() .position(|&x| x == addr) .expect("address not found"); self.deque.remove(id); } - fn swap(&mut self) -> Option { + fn pop(&mut self) -> Option { self.deque.pop_front() } } @@ -52,19 +52,20 @@ mod test { static mut PAGE: *mut MockPageTable = 0 as *mut _; static mut FIFO: *mut FifoSwapManager = 0 as *mut _; - fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { unsafe{ PGFAULT_COUNT += 1; } let fifo = unsafe{ &mut *FIFO }; - if let Some(x) = fifo.swap() { - pt.unmap(x); + if !pt.map(addr) { // is full? + pt.unmap(fifo.pop().unwrap()); + pt.map(addr); } - pt.map(addr); + fifo.push(addr); } #[test] fn test() { use self::MemOp::{R, W}; - let mut pt = MockPageTable::new(pgfault_handler); + let mut pt = MockPageTable::new(4, page_fault_handler); let mut fifo = FifoSwapManager::::new( unsafe{ &*(&pt as *const _) }); unsafe { diff --git a/crate/memory/src/swap/mock_page_table.rs b/crate/memory/src/swap/mock_page_table.rs index ba5185fc..b3f0088d 100644 --- a/crate/memory/src/swap/mock_page_table.rs +++ b/crate/memory/src/swap/mock_page_table.rs @@ -5,10 +5,11 @@ pub struct MockPageTable { mapped_set: BTreeSet, accessed_set: BTreeSet, dirty_set: BTreeSet, - pgfault_handler: PgfaultHandler, + page_fault_handler: PageFaultHandler, + capacity: usize, } -type PgfaultHandler = fn(&mut MockPageTable, Addr); +type PageFaultHandler = fn(&mut MockPageTable, Addr); impl PageTable for MockPageTable { fn accessed(&self, addr: Addr) -> bool { @@ -20,18 +21,19 @@ impl PageTable for MockPageTable { } impl MockPageTable { - pub fn new(pgfault_handler: PgfaultHandler) -> Self { + pub fn new(capacity: usize, page_fault_handler: PageFaultHandler) -> Self { MockPageTable { mapped_set: BTreeSet::::new(), accessed_set: BTreeSet::::new(), dirty_set: BTreeSet::::new(), - pgfault_handler, + page_fault_handler, + capacity, } } /// Read memory, mark accessed, trigger page fault if not present pub fn read(&mut self, addr: Addr) { while !self.mapped_set.contains(&addr) { - (self.pgfault_handler)(self, addr); + (self.page_fault_handler)(self, addr); } self.accessed_set.insert(addr); @@ -39,14 +41,20 @@ impl MockPageTable { /// Write memory, mark accessed and dirty, trigger page fault if not present pub fn write(&mut self, addr: Addr) { while !self.mapped_set.contains(&addr) { - (self.pgfault_handler)(self, addr); + (self.page_fault_handler)(self, addr); } self.accessed_set.insert(addr); self.dirty_set.insert(addr); } - pub fn map(&mut self, addr: Addr) { + /// Map a page, return false if no more space + pub fn map(&mut self, addr: Addr) -> bool { + if self.mapped_set.len() == self.capacity { + return false; + } self.mapped_set.insert(addr); + true } + /// Unmap a page pub fn unmap(&mut self, addr: Addr) { self.mapped_set.remove(&addr); } @@ -64,11 +72,11 @@ mod test { #[test] fn test() { - fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { unsafe{ PGFAULT_COUNT += 1; } pt.map(addr); } - let mut pt = MockPageTable::new(pgfault_handler); + let mut pt = MockPageTable::new(2, page_fault_handler); pt.map(0); pt.read(0); @@ -81,6 +89,8 @@ mod test { assert!(pt.accessed(1)); assert!(pt.dirty(1)); + assert_eq!(pt.map(2), false); + pt.unmap(0); pt.read(0); assert_pgfault_eq(2); diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index badc3942..80b1e5a0 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -11,9 +11,9 @@ trait SwapManager { /// Called when map a swappable page into the memory fn push(&mut self, addr: Addr); /// Called to delete the addr entry from the swap manager - fn pop(&mut self, addr: Addr); + fn remove(&mut self, addr: Addr); /// Try to swap out a page, return then victim - fn swap(&mut self) -> Option; + fn pop(&mut self) -> Option; } trait PageTable { From 8d304da4b469bde15ab0849b8330c50f546d7e47 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 23 Apr 2018 18:48:20 +0800 Subject: [PATCH 05/11] MockSwapper --- crate/memory/src/swap/mock_swapper.rs | 53 +++++++++++++++++++++++++++ crate/memory/src/swap/mod.rs | 6 +++ 2 files changed, 59 insertions(+) create mode 100644 crate/memory/src/swap/mock_swapper.rs diff --git a/crate/memory/src/swap/mock_swapper.rs b/crate/memory/src/swap/mock_swapper.rs new file mode 100644 index 00000000..af8d8ba8 --- /dev/null +++ b/crate/memory/src/swap/mock_swapper.rs @@ -0,0 +1,53 @@ +use super::Swapper; +use alloc::btree_map::BTreeMap; + +pub struct MockSwapper { + map: BTreeMap, +} + +impl Swapper for MockSwapper { + fn swap_out(&mut self, data: &[u8; 4096]) -> usize { + let id = self.alloc_id(); + self.map.insert(id, data.clone()); + id + } + + fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]) { + *data = self.map.remove(&token).unwrap(); + } +} + +impl MockSwapper { + pub fn new() -> Self { + MockSwapper {map: BTreeMap::new()} + } + fn alloc_id(&self) -> usize { + (0 .. 100usize).find(|i| !self.map.contains_key(i)).unwrap() + } +} + +#[cfg(test)] +mod test { + use super::*; + use core::mem::uninitialized; + + #[test] + fn test() { + let mut swapper = MockSwapper::new(); + let data: [u8; 4096] = unsafe{ uninitialized() }; + let mut data1: [u8; 4096] = unsafe{ uninitialized() }; + let token = swapper.swap_out(&data); + swapper.swap_in(token, &mut data1); + for (&a, &b) in data.iter().zip(data1.iter()) { + assert_eq!(a, b); + } + } + + #[test] + #[should_panic] + fn invalid_token() { + let mut swapper = MockSwapper::new(); + let mut data: [u8; 4096] = unsafe{ uninitialized() }; + swapper.swap_in(0, &mut data); + } +} \ No newline at end of file diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 80b1e5a0..214779ce 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -1,5 +1,6 @@ pub mod fifo; mod mock_page_table; +mod mock_swapper; type Addr = usize; @@ -19,4 +20,9 @@ trait SwapManager { trait PageTable { fn accessed(&self, addr: Addr) -> bool; fn dirty(&self, addr: Addr) -> bool; +} + +trait Swapper { + fn swap_out(&mut self, data: &[u8; 4096]) -> usize; + fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]); } \ No newline at end of file From e5e27db4ecae978819a4815d93a63aeb8d74b798 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 23 Apr 2018 19:05:44 +0800 Subject: [PATCH 06/11] New page_table mod. Addr -> VirtAddr. --- crate/memory/src/lib.rs | 5 +- .../{swap => page_table}/mock_page_table.rs | 47 +++++++++---------- crate/memory/src/page_table/mod.rs | 10 ++++ crate/memory/src/swap/fifo.rs | 10 ++-- crate/memory/src/swap/mod.rs | 19 +++----- 5 files changed, 49 insertions(+), 42 deletions(-) rename crate/memory/src/{swap => page_table}/mock_page_table.rs (74%) create mode 100644 crate/memory/src/page_table/mod.rs diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index ffdb24b4..4f08587e 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -4,4 +4,7 @@ extern crate alloc; pub mod memory_set; -pub mod swap; \ No newline at end of file +pub mod swap; +pub mod page_table; + +type VirtAddr = usize; \ No newline at end of file diff --git a/crate/memory/src/swap/mock_page_table.rs b/crate/memory/src/page_table/mock_page_table.rs similarity index 74% rename from crate/memory/src/swap/mock_page_table.rs rename to crate/memory/src/page_table/mock_page_table.rs index b3f0088d..b26e6c0f 100644 --- a/crate/memory/src/swap/mock_page_table.rs +++ b/crate/memory/src/page_table/mock_page_table.rs @@ -2,36 +2,47 @@ use alloc::btree_set::BTreeSet; use super::*; pub struct MockPageTable { - mapped_set: BTreeSet, - accessed_set: BTreeSet, - dirty_set: BTreeSet, + mapped_set: BTreeSet, + accessed_set: BTreeSet, + dirty_set: BTreeSet, page_fault_handler: PageFaultHandler, capacity: usize, } -type PageFaultHandler = fn(&mut MockPageTable, Addr); +type PageFaultHandler = fn(&mut MockPageTable, VirtAddr); impl PageTable for MockPageTable { - fn accessed(&self, addr: Addr) -> bool { + fn accessed(&self, addr: VirtAddr) -> bool { self.accessed_set.contains(&addr) } - fn dirty(&self, addr: Addr) -> bool { + fn dirty(&self, addr: VirtAddr) -> bool { self.dirty_set.contains(&addr) } + /// Map a page, return false if no more space + fn map(&mut self, addr: VirtAddr) -> bool { + if self.mapped_set.len() == self.capacity { + return false; + } + self.mapped_set.insert(addr); + true + } + fn unmap(&mut self, addr: VirtAddr) { + self.mapped_set.remove(&addr); + } } impl MockPageTable { pub fn new(capacity: usize, page_fault_handler: PageFaultHandler) -> Self { MockPageTable { - mapped_set: BTreeSet::::new(), - accessed_set: BTreeSet::::new(), - dirty_set: BTreeSet::::new(), + mapped_set: BTreeSet::::new(), + accessed_set: BTreeSet::::new(), + dirty_set: BTreeSet::::new(), page_fault_handler, capacity, } } /// Read memory, mark accessed, trigger page fault if not present - pub fn read(&mut self, addr: Addr) { + pub fn read(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { (self.page_fault_handler)(self, addr); } @@ -39,25 +50,13 @@ impl MockPageTable { } /// Write memory, mark accessed and dirty, trigger page fault if not present - pub fn write(&mut self, addr: Addr) { + pub fn write(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { (self.page_fault_handler)(self, addr); } self.accessed_set.insert(addr); self.dirty_set.insert(addr); } - /// Map a page, return false if no more space - pub fn map(&mut self, addr: Addr) -> bool { - if self.mapped_set.len() == self.capacity { - return false; - } - self.mapped_set.insert(addr); - true - } - /// Unmap a page - pub fn unmap(&mut self, addr: Addr) { - self.mapped_set.remove(&addr); - } } #[cfg(test)] @@ -72,7 +71,7 @@ mod test { #[test] fn test() { - fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { unsafe{ PGFAULT_COUNT += 1; } pt.map(addr); } diff --git a/crate/memory/src/page_table/mod.rs b/crate/memory/src/page_table/mod.rs new file mode 100644 index 00000000..245311af --- /dev/null +++ b/crate/memory/src/page_table/mod.rs @@ -0,0 +1,10 @@ +use super::*; + +pub mod mock_page_table; + +pub trait PageTable { + fn accessed(&self, addr: VirtAddr) -> bool; + fn dirty(&self, addr: VirtAddr) -> bool; + fn map(&mut self, addr: VirtAddr) -> bool; + fn unmap(&mut self, addr: VirtAddr); +} \ No newline at end of file diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index 4a006ee1..fd7c912f 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -3,14 +3,14 @@ use super::*; struct FifoSwapManager { page_table: &'static T, - deque: VecDeque, + deque: VecDeque, } impl SwapManager for FifoSwapManager { fn new(page_table: &'static T) -> Self { FifoSwapManager { page_table, - deque: VecDeque::::new() + deque: VecDeque::::new() } } @@ -29,7 +29,7 @@ impl SwapManager for FifoSwapManager { self.deque.remove(id); } - fn pop(&mut self) -> Option { + fn pop(&mut self) -> Option { self.deque.pop_front() } } @@ -37,7 +37,7 @@ impl SwapManager for FifoSwapManager { #[cfg(test)] mod test { use super::*; - use super::mock_page_table::MockPageTable; + use page_table::mock_page_table::MockPageTable; enum MemOp { R(usize), W(usize) @@ -52,7 +52,7 @@ mod test { static mut PAGE: *mut MockPageTable = 0 as *mut _; static mut FIFO: *mut FifoSwapManager = 0 as *mut _; - fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { unsafe{ PGFAULT_COUNT += 1; } let fifo = unsafe{ &mut *FIFO }; if !pt.map(addr) { // is full? diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 214779ce..6d1c3506 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -1,8 +1,8 @@ -pub mod fifo; -mod mock_page_table; -mod mock_swapper; +use super::*; +use super::page_table::PageTable; -type Addr = usize; +pub mod fifo; +mod mock_swapper; trait SwapManager { /// Create and initialize for the swap manager @@ -10,16 +10,11 @@ trait SwapManager { /// Called when tick interrupt occured fn tick(&mut self); /// Called when map a swappable page into the memory - fn push(&mut self, addr: Addr); + fn push(&mut self, addr: VirtAddr); /// Called to delete the addr entry from the swap manager - fn remove(&mut self, addr: Addr); + fn remove(&mut self, addr: VirtAddr); /// Try to swap out a page, return then victim - fn pop(&mut self) -> Option; -} - -trait PageTable { - fn accessed(&self, addr: Addr) -> bool; - fn dirty(&self, addr: Addr) -> bool; + fn pop(&mut self) -> Option; } trait Swapper { From c0d83ef75bda2e5a9a41c384d9b8bfc8da6904cd Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 25 Apr 2018 13:50:31 +0800 Subject: [PATCH 07/11] Make tests safe, by using Arc & RefCell. --- .../memory/src/page_table/mock_page_table.rs | 38 ++++++----- crate/memory/src/swap/fifo.rs | 67 +++++++++---------- crate/memory/src/swap/mod.rs | 4 +- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/crate/memory/src/page_table/mock_page_table.rs b/crate/memory/src/page_table/mock_page_table.rs index b26e6c0f..bf5f50d2 100644 --- a/crate/memory/src/page_table/mock_page_table.rs +++ b/crate/memory/src/page_table/mock_page_table.rs @@ -1,4 +1,4 @@ -use alloc::btree_set::BTreeSet; +use alloc::{boxed::Box, btree_set::BTreeSet}; use super::*; pub struct MockPageTable { @@ -9,7 +9,7 @@ pub struct MockPageTable { capacity: usize, } -type PageFaultHandler = fn(&mut MockPageTable, VirtAddr); +type PageFaultHandler = Box; impl PageTable for MockPageTable { fn accessed(&self, addr: VirtAddr) -> bool { @@ -44,7 +44,8 @@ impl MockPageTable { /// Read memory, mark accessed, trigger page fault if not present pub fn read(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { - (self.page_fault_handler)(self, addr); + let self_mut = unsafe{ &mut *(self as *mut Self) }; + (self.page_fault_handler)(self_mut, addr); } self.accessed_set.insert(addr); @@ -52,7 +53,8 @@ impl MockPageTable { /// Write memory, mark accessed and dirty, trigger page fault if not present pub fn write(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { - (self.page_fault_handler)(self, addr); + let self_mut = unsafe{ &mut *(self as *mut Self) }; + (self.page_fault_handler)(self_mut, addr); } self.accessed_set.insert(addr); self.dirty_set.insert(addr); @@ -62,29 +64,29 @@ impl MockPageTable { #[cfg(test)] mod test { use super::*; - - static mut PGFAULT_COUNT: usize = 0; - - fn assert_pgfault_eq(x: usize) { - assert_eq!(unsafe{ PGFAULT_COUNT }, x); - } + use alloc::arc::Arc; + use core::cell::RefCell; #[test] fn test() { - fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { - unsafe{ PGFAULT_COUNT += 1; } - pt.map(addr); - } - let mut pt = MockPageTable::new(2, page_fault_handler); + let page_fault_count = Arc::new(RefCell::new(0usize)); + + let mut pt = MockPageTable::new(2, Box::new({ + let page_fault_count1 = page_fault_count.clone(); + move |pt: &mut MockPageTable, addr: VirtAddr| { + *page_fault_count1.borrow_mut() += 1; + pt.map(addr); + } + })); pt.map(0); pt.read(0); - assert_pgfault_eq(0); + assert_eq!(*page_fault_count.borrow(), 0); assert!(pt.accessed(0)); assert!(!pt.dirty(0)); pt.write(1); - assert_pgfault_eq(1); + assert_eq!(*page_fault_count.borrow(), 1); assert!(pt.accessed(1)); assert!(pt.dirty(1)); @@ -92,6 +94,6 @@ mod test { pt.unmap(0); pt.read(0); - assert_pgfault_eq(2); + assert_eq!(*page_fault_count.borrow(), 2); } } \ No newline at end of file diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index fd7c912f..daa796fa 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -1,19 +1,11 @@ use alloc::vec_deque::VecDeque; use super::*; -struct FifoSwapManager { - page_table: &'static T, +struct FifoSwapManager { deque: VecDeque, } -impl SwapManager for FifoSwapManager { - fn new(page_table: &'static T) -> Self { - FifoSwapManager { - page_table, - deque: VecDeque::::new() - } - } - +impl SwapManager for FifoSwapManager { fn tick(&mut self) { } @@ -34,44 +26,45 @@ impl SwapManager for FifoSwapManager { } } +impl FifoSwapManager { + fn new() -> Self { + FifoSwapManager { + deque: VecDeque::::new() + } + } +} + #[cfg(test)] mod test { use super::*; + use alloc::{arc::Arc, boxed::Box}; + use core::cell::RefCell; use page_table::mock_page_table::MockPageTable; enum MemOp { R(usize), W(usize) } - fn assert_pgfault_eq(x: usize) { - assert_eq!(unsafe{ PGFAULT_COUNT }, x); - } - - // For pgfault_handler: - static mut PGFAULT_COUNT: usize = 0; - static mut PAGE: *mut MockPageTable = 0 as *mut _; - static mut FIFO: *mut FifoSwapManager = 0 as *mut _; - - fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { - unsafe{ PGFAULT_COUNT += 1; } - let fifo = unsafe{ &mut *FIFO }; - if !pt.map(addr) { // is full? - pt.unmap(fifo.pop().unwrap()); - pt.map(addr); - } - fifo.push(addr); - } - #[test] fn test() { use self::MemOp::{R, W}; - let mut pt = MockPageTable::new(4, page_fault_handler); - let mut fifo = FifoSwapManager::::new( - unsafe{ &*(&pt as *const _) }); - unsafe { - PAGE = &mut pt as *mut _; - FIFO = &mut fifo as *mut _; - } + let page_fault_count = Arc::new(RefCell::new(0usize)); + + let mut pt = MockPageTable::new(4, Box::new({ + let page_fault_count1 = page_fault_count.clone(); + let mut fifo = FifoSwapManager::new(); + + move |pt: &mut MockPageTable, addr: VirtAddr| { + *page_fault_count1.borrow_mut() += 1; + + if !pt.map(addr) { // is full? + pt.unmap(fifo.pop().unwrap()); + pt.map(addr); + } + fifo.push(addr); + } + })); + let op_seq = [ R(1), R(2), R(3), R(4), W(3), W(1), W(4), W(2), W(5), @@ -87,7 +80,7 @@ mod test { R(addr) => pt.read(*addr), W(addr) => pt.write(*addr), } - assert_pgfault_eq(count); + assert_eq!(*(*page_fault_count).borrow(), count); } } } \ No newline at end of file diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 6d1c3506..6adaa6bf 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -4,9 +4,7 @@ use super::page_table::PageTable; pub mod fifo; mod mock_swapper; -trait SwapManager { - /// Create and initialize for the swap manager - fn new(page_table: &'static T) -> Self; +trait SwapManager { /// Called when tick interrupt occured fn tick(&mut self); /// Called when map a swappable page into the memory From 733c1028360beedb70094f32021a2f3f8dfde5d9 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 25 Apr 2018 15:32:43 +0800 Subject: [PATCH 08/11] EnhancedClockSwapManager --- .../memory/src/page_table/mock_page_table.rs | 40 ++++-- crate/memory/src/page_table/mod.rs | 2 + crate/memory/src/swap/enhanced_clock.rs | 135 ++++++++++++++++++ crate/memory/src/swap/fifo.rs | 7 +- crate/memory/src/swap/mock_swapper.rs | 42 ++++-- crate/memory/src/swap/mod.rs | 19 ++- 6 files changed, 214 insertions(+), 31 deletions(-) create mode 100644 crate/memory/src/swap/enhanced_clock.rs diff --git a/crate/memory/src/page_table/mock_page_table.rs b/crate/memory/src/page_table/mock_page_table.rs index bf5f50d2..c4aaea01 100644 --- a/crate/memory/src/page_table/mock_page_table.rs +++ b/crate/memory/src/page_table/mock_page_table.rs @@ -5,7 +5,7 @@ pub struct MockPageTable { mapped_set: BTreeSet, accessed_set: BTreeSet, dirty_set: BTreeSet, - page_fault_handler: PageFaultHandler, + page_fault_handler: Option, capacity: usize, } @@ -18,6 +18,12 @@ impl PageTable for MockPageTable { fn dirty(&self, addr: VirtAddr) -> bool { self.dirty_set.contains(&addr) } + fn clear_accessed(&mut self, addr: usize) { + self.accessed_set.remove(&addr); + } + fn clear_dirty(&mut self, addr: usize) { + self.dirty_set.remove(&addr); + } /// Map a page, return false if no more space fn map(&mut self, addr: VirtAddr) -> bool { if self.mapped_set.len() == self.capacity { @@ -32,30 +38,33 @@ impl PageTable for MockPageTable { } impl MockPageTable { - pub fn new(capacity: usize, page_fault_handler: PageFaultHandler) -> Self { + pub fn new(capacity: usize) -> Self { MockPageTable { mapped_set: BTreeSet::::new(), accessed_set: BTreeSet::::new(), dirty_set: BTreeSet::::new(), - page_fault_handler, + page_fault_handler: None, capacity, } } + pub fn set_handler(&mut self, page_fault_handler: PageFaultHandler) { + self.page_fault_handler = Some(page_fault_handler); + } + fn trigger_page_fault_if_not_present(&mut self, addr: VirtAddr) { + while !self.mapped_set.contains(&addr) { + let self_mut = unsafe{ &mut *(self as *mut Self) }; + (self.page_fault_handler.as_mut().unwrap())(self_mut, addr); + } + } /// Read memory, mark accessed, trigger page fault if not present pub fn read(&mut self, addr: VirtAddr) { - while !self.mapped_set.contains(&addr) { - let self_mut = unsafe{ &mut *(self as *mut Self) }; - (self.page_fault_handler)(self_mut, addr); - } + self.trigger_page_fault_if_not_present(addr); self.accessed_set.insert(addr); } /// Write memory, mark accessed and dirty, trigger page fault if not present pub fn write(&mut self, addr: VirtAddr) { - while !self.mapped_set.contains(&addr) { - let self_mut = unsafe{ &mut *(self as *mut Self) }; - (self.page_fault_handler)(self_mut, addr); - } + self.trigger_page_fault_if_not_present(addr); self.accessed_set.insert(addr); self.dirty_set.insert(addr); } @@ -71,7 +80,8 @@ mod test { fn test() { let page_fault_count = Arc::new(RefCell::new(0usize)); - let mut pt = MockPageTable::new(2, Box::new({ + let mut pt = MockPageTable::new(2); + pt.set_handler(Box::new({ let page_fault_count1 = page_fault_count.clone(); move |pt: &mut MockPageTable, addr: VirtAddr| { *page_fault_count1.borrow_mut() += 1; @@ -85,11 +95,17 @@ mod test { assert!(pt.accessed(0)); assert!(!pt.dirty(0)); + pt.clear_accessed(0); + assert!(!pt.accessed(0)); + pt.write(1); assert_eq!(*page_fault_count.borrow(), 1); assert!(pt.accessed(1)); assert!(pt.dirty(1)); + pt.clear_dirty(1); + assert!(!pt.dirty(1)); + assert_eq!(pt.map(2), false); pt.unmap(0); diff --git a/crate/memory/src/page_table/mod.rs b/crate/memory/src/page_table/mod.rs index 245311af..d10f6525 100644 --- a/crate/memory/src/page_table/mod.rs +++ b/crate/memory/src/page_table/mod.rs @@ -5,6 +5,8 @@ pub mod mock_page_table; pub trait PageTable { fn accessed(&self, addr: VirtAddr) -> bool; fn dirty(&self, addr: VirtAddr) -> bool; + fn clear_accessed(&mut self, addr: VirtAddr); + fn clear_dirty(&mut self, addr: VirtAddr); fn map(&mut self, addr: VirtAddr) -> bool; fn unmap(&mut self, addr: VirtAddr); } \ No newline at end of file diff --git a/crate/memory/src/swap/enhanced_clock.rs b/crate/memory/src/swap/enhanced_clock.rs new file mode 100644 index 00000000..ea782a5a --- /dev/null +++ b/crate/memory/src/swap/enhanced_clock.rs @@ -0,0 +1,135 @@ +use alloc::vec_deque::VecDeque; +use super::*; + +pub struct EnhancedClockSwapManager { + page_table: &'static mut T, + clock_ptr: usize, + deque: VecDeque, +} + +impl SwapManager for EnhancedClockSwapManager { + fn tick(&mut self) { + } + + fn push(&mut self, addr: usize) { + let pos = if self.clock_ptr == 0 {self.deque.len()} else {self.clock_ptr}; + self.deque.insert(pos, addr); + } + + fn remove(&mut self, addr: usize) { + let id = self.deque.iter() + .position(|&x| x == addr) + .expect("address not found"); + if id < self.clock_ptr { + self.clock_ptr -= 1; + } + self.deque.remove(id); + } + + fn pop(&mut self) -> Option { + loop { + let addr = self.deque[self.clock_ptr]; + let accessed = self.page_table.accessed(addr); + let dirty = self.page_table.dirty(addr); + + match (accessed, dirty) { + (true, _) => { + self.page_table.clear_accessed(addr); + + }, + (false, true) => { + if self.page_table.swap_out(addr).is_ok() { + self.page_table.clear_dirty(addr); + } + }, + _ => { + return self.remove_current(); + } + } + self.move_next(); + } + } +} + + +impl EnhancedClockSwapManager { + pub fn new(page_table: &'static mut T) -> Self { + EnhancedClockSwapManager { + page_table, + clock_ptr: 0, + deque: VecDeque::::new() + } + } + fn remove_current(&mut self) -> Option { + let addr = self.deque.remove(self.clock_ptr); + if self.clock_ptr == self.deque.len() { + self.clock_ptr = 0; + } + return addr; + } + fn move_next(&mut self) { + self.clock_ptr += 1; + if self.clock_ptr == self.deque.len() { + self.clock_ptr = 0; + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::{arc::Arc, boxed::Box}; + use core::mem::uninitialized; + use core::cell::RefCell; + use page_table::mock_page_table::MockPageTable; + + impl SwappablePageTable for MockPageTable { + fn swap_out(&mut self, addr: usize) -> Result<(), ()> { + Ok(()) + } + } + + enum MemOp { + R(usize), W(usize) + } + + #[test] + fn test() { + use self::MemOp::{R, W}; + let page_fault_count = Arc::new(RefCell::new(0usize)); + + let mut pt = Box::new(MockPageTable::new(4)); + let static_pt = unsafe{ &mut *(pt.as_mut() as *mut MockPageTable) }; + pt.set_handler(Box::new({ + let page_fault_count1 = page_fault_count.clone(); + let mut clock = EnhancedClockSwapManager::new(static_pt); + + move |pt: &mut MockPageTable, addr: VirtAddr| { + *page_fault_count1.borrow_mut() += 1; + + if !pt.map(addr) { // is full? + pt.unmap(clock.pop().unwrap()); + pt.map(addr); + } + clock.push(addr); + } + })); + + + let op_seq = [ + R(1), R(2), R(3), R(4), + R(3), W(1), R(4), W(2), R(5), + R(2), W(1), R(2), R(3), R(4)]; + let pgfault_count = [ + 1, 2, 3, 4, + 4, 4, 4, 4, 5, + 5, 5, 5, 6, 7]; + for (op, &count) in op_seq.iter().zip(pgfault_count.iter()) { + match op { + R(addr) => pt.read(*addr), + W(addr) => pt.write(*addr), + } + assert_eq!(*(*page_fault_count).borrow(), count); + } + } +} diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index daa796fa..ed639800 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -1,7 +1,7 @@ use alloc::vec_deque::VecDeque; use super::*; -struct FifoSwapManager { +pub struct FifoSwapManager { deque: VecDeque, } @@ -27,7 +27,7 @@ impl SwapManager for FifoSwapManager { } impl FifoSwapManager { - fn new() -> Self { + pub fn new() -> Self { FifoSwapManager { deque: VecDeque::::new() } @@ -50,7 +50,8 @@ mod test { use self::MemOp::{R, W}; let page_fault_count = Arc::new(RefCell::new(0usize)); - let mut pt = MockPageTable::new(4, Box::new({ + let mut pt = MockPageTable::new(4); + pt.set_handler(Box::new({ let page_fault_count1 = page_fault_count.clone(); let mut fifo = FifoSwapManager::new(); diff --git a/crate/memory/src/swap/mock_swapper.rs b/crate/memory/src/swap/mock_swapper.rs index af8d8ba8..f1b9704e 100644 --- a/crate/memory/src/swap/mock_swapper.rs +++ b/crate/memory/src/swap/mock_swapper.rs @@ -6,14 +6,25 @@ pub struct MockSwapper { } impl Swapper for MockSwapper { - fn swap_out(&mut self, data: &[u8; 4096]) -> usize { + fn swap_out(&mut self, data: &[u8; 4096]) -> Result { let id = self.alloc_id(); self.map.insert(id, data.clone()); - id + Ok(id) } - fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]) { - *data = self.map.remove(&token).unwrap(); + fn swap_update(&mut self, token: usize, data: &[u8; 4096]) -> Result<(), ()> { + if !self.map.contains_key(&token) { + return Err(()); + } + self.map.insert(token, data.clone()); + Ok(()) + } + fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]) -> Result<(), ()> { + match self.map.remove(&token) { + Some(d) => *data = d, + None => return Err(()), + } + Ok(()) } } @@ -31,16 +42,25 @@ mod test { use super::*; use core::mem::uninitialized; + fn assert_data_eq(data1: &[u8; 4096], data2: &[u8; 4096]) { + for (&a, &b) in data2.iter().zip(data1.iter()) { + assert_eq!(a, b); + } + } + #[test] fn test() { let mut swapper = MockSwapper::new(); - let data: [u8; 4096] = unsafe{ uninitialized() }; - let mut data1: [u8; 4096] = unsafe{ uninitialized() }; - let token = swapper.swap_out(&data); - swapper.swap_in(token, &mut data1); - for (&a, &b) in data.iter().zip(data1.iter()) { - assert_eq!(a, b); - } + let mut data: [u8; 4096] = unsafe{ uninitialized() }; + let data1: [u8; 4096] = unsafe{ uninitialized() }; + let token = swapper.swap_out(&data1).unwrap(); + swapper.swap_in(token, &mut data); + assert_data_eq(&data, &data1); + + let data2: [u8; 4096] = unsafe{ uninitialized() }; + swapper.swap_update(token, &data2); + swapper.swap_in(token, &mut data); + assert_data_eq(&data, &data2); } #[test] diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 6adaa6bf..5b9c1083 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -1,10 +1,14 @@ +pub use self::fifo::FifoSwapManager; +pub use self::enhanced_clock::EnhancedClockSwapManager; + use super::*; use super::page_table::PageTable; -pub mod fifo; +mod fifo; +mod enhanced_clock; mod mock_swapper; -trait SwapManager { +pub trait SwapManager { /// Called when tick interrupt occured fn tick(&mut self); /// Called when map a swappable page into the memory @@ -15,7 +19,12 @@ trait SwapManager { fn pop(&mut self) -> Option; } -trait Swapper { - fn swap_out(&mut self, data: &[u8; 4096]) -> usize; - fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]); +pub trait Swapper { + fn swap_out(&mut self, data: &[u8; 4096]) -> Result; + fn swap_update(&mut self, token: usize, data: &[u8; 4096]) -> Result<(), ()>; + fn swap_in(&mut self, token: usize, data: &mut [u8; 4096]) -> Result<(), ()>; +} + +pub trait SwappablePageTable: PageTable { + fn swap_out(&mut self, addr: VirtAddr) -> Result<(), ()>; } \ No newline at end of file From e2e9ead17c3419ff05c4533a8a4cbc3e2d6333f2 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 25 Apr 2018 16:17:15 +0800 Subject: [PATCH 09/11] Improve MockPageTable. Fix tests. --- .../memory/src/page_table/mock_page_table.rs | 69 +++++++++++-------- crate/memory/src/swap/enhanced_clock.rs | 10 +-- crate/memory/src/swap/fifo.rs | 12 ++-- crate/memory/src/swap/mock_swapper.rs | 18 +++-- 4 files changed, 65 insertions(+), 44 deletions(-) diff --git a/crate/memory/src/page_table/mock_page_table.rs b/crate/memory/src/page_table/mock_page_table.rs index c4aaea01..85954b84 100644 --- a/crate/memory/src/page_table/mock_page_table.rs +++ b/crate/memory/src/page_table/mock_page_table.rs @@ -1,10 +1,14 @@ -use alloc::{boxed::Box, btree_set::BTreeSet}; +use alloc::boxed::Box; use super::*; +const PAGE_COUNT: usize = 16; +const PAGE_SIZE: usize = 4096; + pub struct MockPageTable { - mapped_set: BTreeSet, - accessed_set: BTreeSet, - dirty_set: BTreeSet, + mapped: [bool; PAGE_COUNT], + accessed: [bool; PAGE_COUNT], + dirty: [bool; PAGE_COUNT], + data: [u8; PAGE_SIZE * PAGE_COUNT], page_fault_handler: Option, capacity: usize, } @@ -13,36 +17,38 @@ type PageFaultHandler = Box; impl PageTable for MockPageTable { fn accessed(&self, addr: VirtAddr) -> bool { - self.accessed_set.contains(&addr) + self.accessed[addr / PAGE_SIZE] } fn dirty(&self, addr: VirtAddr) -> bool { - self.dirty_set.contains(&addr) + self.dirty[addr / PAGE_SIZE] } fn clear_accessed(&mut self, addr: usize) { - self.accessed_set.remove(&addr); + self.accessed[addr / PAGE_SIZE] = false; } fn clear_dirty(&mut self, addr: usize) { - self.dirty_set.remove(&addr); + self.dirty[addr / PAGE_SIZE] = false; } /// Map a page, return false if no more space fn map(&mut self, addr: VirtAddr) -> bool { - if self.mapped_set.len() == self.capacity { + if self.mapped.iter().filter(|&&b| b).count() == self.capacity { return false; } - self.mapped_set.insert(addr); + self.mapped[addr / PAGE_SIZE] = true; true } fn unmap(&mut self, addr: VirtAddr) { - self.mapped_set.remove(&addr); + self.mapped[addr / PAGE_SIZE] = false; } } impl MockPageTable { pub fn new(capacity: usize) -> Self { + use core::mem::uninitialized; MockPageTable { - mapped_set: BTreeSet::::new(), - accessed_set: BTreeSet::::new(), - dirty_set: BTreeSet::::new(), + mapped: [false; PAGE_COUNT], + accessed: [false; PAGE_COUNT], + dirty: [false; PAGE_COUNT], + data: unsafe{ uninitialized() }, page_fault_handler: None, capacity, } @@ -51,22 +57,26 @@ impl MockPageTable { self.page_fault_handler = Some(page_fault_handler); } fn trigger_page_fault_if_not_present(&mut self, addr: VirtAddr) { - while !self.mapped_set.contains(&addr) { + let page_id = addr / PAGE_SIZE; + while !self.mapped[page_id] { let self_mut = unsafe{ &mut *(self as *mut Self) }; (self.page_fault_handler.as_mut().unwrap())(self_mut, addr); } } /// Read memory, mark accessed, trigger page fault if not present - pub fn read(&mut self, addr: VirtAddr) { + pub fn read(&mut self, addr: VirtAddr) -> u8 { + let page_id = addr / PAGE_SIZE; self.trigger_page_fault_if_not_present(addr); - self.accessed_set.insert(addr); - + self.accessed[page_id] = true; + self.data[addr] } /// Write memory, mark accessed and dirty, trigger page fault if not present - pub fn write(&mut self, addr: VirtAddr) { + pub fn write(&mut self, addr: VirtAddr, data: u8) { + let page_id = addr / PAGE_SIZE; self.trigger_page_fault_if_not_present(addr); - self.accessed_set.insert(addr); - self.dirty_set.insert(addr); + self.accessed[page_id] = true; + self.dirty[page_id] = true; + self.data[addr] = data; } } @@ -98,15 +108,20 @@ mod test { pt.clear_accessed(0); assert!(!pt.accessed(0)); - pt.write(1); + pt.read(1); + assert_eq!(*page_fault_count.borrow(), 0); + assert!(pt.accessed(0)); + + pt.write(0x1000, 0xff); assert_eq!(*page_fault_count.borrow(), 1); - assert!(pt.accessed(1)); - assert!(pt.dirty(1)); + assert!(pt.accessed(0x1000)); + assert!(pt.dirty(0x1000)); + assert_eq!(pt.read(0x1000), 0xff); - pt.clear_dirty(1); - assert!(!pt.dirty(1)); + pt.clear_dirty(0x1000); + assert!(!pt.dirty(0x1000)); - assert_eq!(pt.map(2), false); + assert_eq!(pt.map(0x2000), false); pt.unmap(0); pt.read(0); diff --git a/crate/memory/src/swap/enhanced_clock.rs b/crate/memory/src/swap/enhanced_clock.rs index ea782a5a..64f8a9eb 100644 --- a/crate/memory/src/swap/enhanced_clock.rs +++ b/crate/memory/src/swap/enhanced_clock.rs @@ -117,17 +117,17 @@ mod test { let op_seq = [ - R(1), R(2), R(3), R(4), - R(3), W(1), R(4), W(2), R(5), - R(2), W(1), R(2), R(3), R(4)]; + R(0x1000), R(0x2000), R(0x3000), R(0x4000), + R(0x3000), W(0x1000), R(0x4000), W(0x2000), R(0x5000), + R(0x2000), W(0x1000), R(0x2000), R(0x3000), R(0x4000)]; let pgfault_count = [ 1, 2, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7]; for (op, &count) in op_seq.iter().zip(pgfault_count.iter()) { match op { - R(addr) => pt.read(*addr), - W(addr) => pt.write(*addr), + R(addr) => {pt.read(*addr);}, + W(addr) => pt.write(*addr, 0), } assert_eq!(*(*page_fault_count).borrow(), count); } diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index ed639800..1550c576 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -67,10 +67,10 @@ mod test { })); let op_seq = [ - R(1), R(2), R(3), R(4), - W(3), W(1), W(4), W(2), W(5), - W(2), W(1), W(2), W(3), W(4), - W(5), R(1), W(1)]; + R(0x1000), R(0x2000), R(0x3000), R(0x4000), + W(0x3000), W(0x1000), W(0x4000), W(0x2000), W(0x5000), + W(0x2000), W(0x1000), W(0x2000), W(0x3000), W(0x4000), + W(0x5000), R(0x1000), W(0x1000)]; let pgfault_count = [ 1, 2, 3, 4, 4, 4, 4, 4, 5, @@ -78,8 +78,8 @@ mod test { 10, 11, 11]; for (op, &count) in op_seq.iter().zip(pgfault_count.iter()) { match op { - R(addr) => pt.read(*addr), - W(addr) => pt.write(*addr), + R(addr) => {pt.read(*addr);}, + W(addr) => pt.write(*addr, 0), } assert_eq!(*(*page_fault_count).borrow(), count); } diff --git a/crate/memory/src/swap/mock_swapper.rs b/crate/memory/src/swap/mock_swapper.rs index f1b9704e..8b1bbbc5 100644 --- a/crate/memory/src/swap/mock_swapper.rs +++ b/crate/memory/src/swap/mock_swapper.rs @@ -49,25 +49,31 @@ mod test { } #[test] - fn test() { + fn swap_out_in() { let mut swapper = MockSwapper::new(); let mut data: [u8; 4096] = unsafe{ uninitialized() }; let data1: [u8; 4096] = unsafe{ uninitialized() }; let token = swapper.swap_out(&data1).unwrap(); - swapper.swap_in(token, &mut data); + swapper.swap_in(token, &mut data).unwrap(); assert_data_eq(&data, &data1); + } + #[test] + fn swap_update() { + let mut swapper = MockSwapper::new(); + let mut data: [u8; 4096] = unsafe{ uninitialized() }; + let data1: [u8; 4096] = unsafe{ uninitialized() }; let data2: [u8; 4096] = unsafe{ uninitialized() }; - swapper.swap_update(token, &data2); - swapper.swap_in(token, &mut data); + let token = swapper.swap_out(&data1).unwrap(); + swapper.swap_update(token, &data2).unwrap(); + swapper.swap_in(token, &mut data).unwrap(); assert_data_eq(&data, &data2); } #[test] - #[should_panic] fn invalid_token() { let mut swapper = MockSwapper::new(); let mut data: [u8; 4096] = unsafe{ uninitialized() }; - swapper.swap_in(0, &mut data); + assert_eq!(swapper.swap_in(0, &mut data), Err(())); } } \ No newline at end of file From 09098f0d2f5053e7db0711f265cc4fe74f50d879 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 26 Apr 2018 16:23:54 +0800 Subject: [PATCH 10/11] Add physical mod and reorganize. --- crate/memory/src/lib.rs | 6 ++- crate/memory/src/paging/mod.rs | 4 ++ .../page_table/mock_page_table.rs | 0 .../memory/src/{ => paging}/page_table/mod.rs | 3 +- crate/memory/src/physical/frame.rs | 33 ++++++++++++ .../src/physical/frame_allocator/mod.rs | 11 ++++ crate/memory/src/physical/mod.rs | 9 ++++ crate/memory/src/physical/physaddr.rs | 50 +++++++++++++++++++ crate/memory/src/swap/enhanced_clock.rs | 2 +- crate/memory/src/swap/fifo.rs | 2 +- crate/memory/src/swap/mod.rs | 2 +- 11 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 crate/memory/src/paging/mod.rs rename crate/memory/src/{ => paging}/page_table/mock_page_table.rs (100%) rename crate/memory/src/{ => paging}/page_table/mod.rs (82%) create mode 100644 crate/memory/src/physical/frame.rs create mode 100644 crate/memory/src/physical/frame_allocator/mod.rs create mode 100644 crate/memory/src/physical/mod.rs create mode 100644 crate/memory/src/physical/physaddr.rs diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index 4f08587e..e9dc3de5 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -3,8 +3,10 @@ extern crate alloc; +pub mod physical; +pub mod paging; pub mod memory_set; pub mod swap; -pub mod page_table; -type VirtAddr = usize; \ No newline at end of file +type VirtAddr = usize; +const PAGE_SIZE: usize = 4096; \ No newline at end of file diff --git a/crate/memory/src/paging/mod.rs b/crate/memory/src/paging/mod.rs new file mode 100644 index 00000000..cd6f6b65 --- /dev/null +++ b/crate/memory/src/paging/mod.rs @@ -0,0 +1,4 @@ +pub use self::page_table::*; +use super::*; + +mod page_table; \ No newline at end of file diff --git a/crate/memory/src/page_table/mock_page_table.rs b/crate/memory/src/paging/page_table/mock_page_table.rs similarity index 100% rename from crate/memory/src/page_table/mock_page_table.rs rename to crate/memory/src/paging/page_table/mock_page_table.rs diff --git a/crate/memory/src/page_table/mod.rs b/crate/memory/src/paging/page_table/mod.rs similarity index 82% rename from crate/memory/src/page_table/mod.rs rename to crate/memory/src/paging/page_table/mod.rs index d10f6525..8e1752dd 100644 --- a/crate/memory/src/page_table/mod.rs +++ b/crate/memory/src/paging/page_table/mod.rs @@ -1,6 +1,7 @@ use super::*; +pub use self::mock_page_table::MockPageTable; -pub mod mock_page_table; +mod mock_page_table; pub trait PageTable { fn accessed(&self, addr: VirtAddr) -> bool; diff --git a/crate/memory/src/physical/frame.rs b/crate/memory/src/physical/frame.rs new file mode 100644 index 00000000..d88b1a1b --- /dev/null +++ b/crate/memory/src/physical/frame.rs @@ -0,0 +1,33 @@ +use super::*; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Frame { + number: usize, +} + +impl Frame { + pub fn containing_address(address: PhysAddr) -> Frame { + Frame{ number: address.get() as usize / PAGE_SIZE } + } + //TODO: Set private + pub fn start_address(&self) -> PhysAddr { + PhysAddr::new((self.number * PAGE_SIZE) as u64) + } + + pub fn clone(&self) -> Frame { + Frame { number: self.number } + } + //TODO: Set private +// pub fn range_inclusive(start: Frame, end: Frame) -> FrameIter { +// FrameIter { +// start: start, +// end: end, +// } +// } +} + +impl Drop for Frame { + fn drop(&mut self) { + panic!("frame must be deallocate"); + } +} diff --git a/crate/memory/src/physical/frame_allocator/mod.rs b/crate/memory/src/physical/frame_allocator/mod.rs new file mode 100644 index 00000000..80c508d7 --- /dev/null +++ b/crate/memory/src/physical/frame_allocator/mod.rs @@ -0,0 +1,11 @@ +use super::*; + +pub trait FrameAllocator { + fn allocate_frame(&mut self) -> Option; + fn deallocate_frame(&mut self, frame: Frame); +} + +pub trait MemoryArea { + fn begin(&self) -> PhysAddr; + fn end(&self) -> PhysAddr; +} \ No newline at end of file diff --git a/crate/memory/src/physical/mod.rs b/crate/memory/src/physical/mod.rs new file mode 100644 index 00000000..02e9ca48 --- /dev/null +++ b/crate/memory/src/physical/mod.rs @@ -0,0 +1,9 @@ +pub use self::physaddr::PhysAddr; +pub use self::frame::Frame; +pub use self::frame_allocator::FrameAllocator; + +use super::*; + +mod frame; +mod physaddr; +mod frame_allocator; \ No newline at end of file diff --git a/crate/memory/src/physical/physaddr.rs b/crate/memory/src/physical/physaddr.rs new file mode 100644 index 00000000..3da68715 --- /dev/null +++ b/crate/memory/src/physical/physaddr.rs @@ -0,0 +1,50 @@ +use core::fmt; + +/// Represents a physical memory address +#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)] +pub struct PhysAddr(u64); + +impl PhysAddr { + pub fn new(addr: u64) -> PhysAddr { + PhysAddr(addr) + } + pub fn get(&self) -> u64 { + self.0 + } +} + +impl fmt::Debug for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:#x}", self.0) + } +} + +impl fmt::Binary for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Display for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::LowerHex for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Octal for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::UpperHex for PhysAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} \ No newline at end of file diff --git a/crate/memory/src/swap/enhanced_clock.rs b/crate/memory/src/swap/enhanced_clock.rs index 64f8a9eb..c495d8db 100644 --- a/crate/memory/src/swap/enhanced_clock.rs +++ b/crate/memory/src/swap/enhanced_clock.rs @@ -81,7 +81,7 @@ mod test { use alloc::{arc::Arc, boxed::Box}; use core::mem::uninitialized; use core::cell::RefCell; - use page_table::mock_page_table::MockPageTable; + use paging::MockPageTable; impl SwappablePageTable for MockPageTable { fn swap_out(&mut self, addr: usize) -> Result<(), ()> { diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index 1550c576..9e1213ed 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -39,7 +39,7 @@ mod test { use super::*; use alloc::{arc::Arc, boxed::Box}; use core::cell::RefCell; - use page_table::mock_page_table::MockPageTable; + use paging::MockPageTable; enum MemOp { R(usize), W(usize) diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 5b9c1083..292e425a 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -2,7 +2,7 @@ pub use self::fifo::FifoSwapManager; pub use self::enhanced_clock::EnhancedClockSwapManager; use super::*; -use super::page_table::PageTable; +use super::paging::PageTable; mod fifo; mod enhanced_clock; From 62cb97de8cbe7edd44ff7091399d5677fff7b4ab Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 28 Apr 2018 12:48:16 +0800 Subject: [PATCH 11/11] Fit name conventions by Clion, simplify some names. --- src/arch/x86_64/driver/acpi/mod.rs | 44 ++++---- src/arch/x86_64/driver/acpi/structs.rs | 122 +++++++++++----------- src/arch/x86_64/driver/apic/lapic.rs | 1 + src/arch/x86_64/driver/apic/local_apic.rs | 4 +- src/arch/x86_64/driver/mod.rs | 2 +- src/arch/x86_64/paging/entry.rs | 4 +- src/arch/x86_64/paging/mapper.rs | 16 +-- src/arch/x86_64/paging/mod.rs | 10 +- src/arch/x86_64/paging/temporary_page.rs | 6 +- src/arch/x86_64/smp.rs | 10 +- src/consts.rs | 1 + src/io/vga_writer.rs | 2 +- src/memory/address.rs | 20 ++-- src/memory/area_frame_allocator.rs | 24 ++--- src/memory/frame.rs | 12 +-- src/memory/mod.rs | 45 ++++---- src/memory/stack_allocator.rs | 4 +- 17 files changed, 164 insertions(+), 163 deletions(-) diff --git a/src/arch/x86_64/driver/acpi/mod.rs b/src/arch/x86_64/driver/acpi/mod.rs index a68a2be9..d8752af1 100644 --- a/src/arch/x86_64/driver/acpi/mod.rs +++ b/src/arch/x86_64/driver/acpi/mod.rs @@ -4,23 +4,23 @@ mod structs; use self::structs::*; use consts::*; -pub fn init() -> Result { +pub fn init() -> Result { let rsdp = find_rsdp().expect("acpi: rsdp not found."); - if rsdp.RsdtPhysicalAddress > PHYSICAL_MEMORY_LIMIT { - return Err(ACPI_Error::NotMapped); + if rsdp.rsdt_physical_address > PHYSICAL_MEMORY_LIMIT { + return Err(AcpiError::NotMapped); } - debug!("RSDT at {:#x}", rsdp.RsdtPhysicalAddress); - let rsdt = unsafe{ &*(rsdp.RsdtPhysicalAddress as *const rsdt) }; - let mut madt: Option<&'static madt> = None; + debug!("RSDT at {:#x}", rsdp.rsdt_physical_address); + let rsdt = unsafe{ &*(rsdp.rsdt_physical_address as *const Rsdt) }; + let mut madt: Option<&'static Madt> = None; for i in 0 .. rsdt.entry_count() { let entry = rsdt.entry_at(i); if entry > PHYSICAL_MEMORY_LIMIT { - return Err(ACPI_Error::NotMapped); + return Err(AcpiError::NotMapped); } - let header = unsafe{ &*(entry as *const header) }; + let header = unsafe{ &*(entry as *const Header) }; // debug!("{:?}", header); - if &header.Signature == b"APIC" { - madt = Some(unsafe{ &*(entry as *const madt) }); + if &header.signature == b"APIC" { + madt = Some(unsafe{ &*(entry as *const Madt) }); } } debug!("{:?}", madt); @@ -33,7 +33,7 @@ const PHYSICAL_MEMORY_LIMIT: u32 = 0x0E000000; const PHYSICAL_MEMORY_LIMIT: u32 = 0x80000000; #[derive(Debug)] -pub struct ACPI_Result { +pub struct AcpiResult { pub cpu_num: u8, pub cpu_acpi_ids: [u8; MAX_CPU_NUM], pub ioapic_id: u8, @@ -41,13 +41,13 @@ pub struct ACPI_Result { } #[derive(Debug)] -pub enum ACPI_Error { +pub enum AcpiError { NotMapped, - IOACPI_NotFound, + IoacpiNotFound, } -fn config_smp(madt: &'static madt) -> Result { - let lapic_addr = madt.LapicAddress as *const (); +fn config_smp(madt: &'static Madt) -> Result { + let lapic_addr = madt.lapic_address as *const (); let mut cpu_num = 0u8; let mut cpu_acpi_ids: [u8; MAX_CPU_NUM] = [0; MAX_CPU_NUM]; @@ -56,33 +56,33 @@ fn config_smp(madt: &'static madt) -> Result { debug!("{:?}", entry); match &entry { &MadtEntry::LocalApic(ref lapic) => { - cpu_acpi_ids[cpu_num as usize] = lapic.Id; + cpu_acpi_ids[cpu_num as usize] = lapic.id; cpu_num += 1; }, &MadtEntry::IoApic(ref ioapic) => { - ioapic_id = Some(ioapic.Id); + ioapic_id = Some(ioapic.id); }, _ => {}, } } if ioapic_id.is_none() { - return Err(ACPI_Error::IOACPI_NotFound); + return Err(AcpiError::IoacpiNotFound); } let ioapic_id = ioapic_id.unwrap(); - Ok(ACPI_Result { cpu_num, cpu_acpi_ids, ioapic_id, lapic_addr }) + Ok(AcpiResult { cpu_num, cpu_acpi_ids, ioapic_id, lapic_addr }) } /// See https://wiki.osdev.org/RSDP -- Detecting the RSDP -fn find_rsdp() -> Option<&'static rsdp> { +fn find_rsdp() -> Option<&'static Rsdp> { use util::{Checkable, find_in_memory}; let ebda = unsafe { *(0x40E as *const u16) as usize } << 4; debug!("EBDA at {:#x}", ebda); macro_rules! return_if_find_in { ($begin:expr, $end:expr) => ( - if let Some(addr) = unsafe{ find_in_memory::($begin, $end, 4) } { - return Some(unsafe{ &*(addr as *const rsdp) }); + if let Some(addr) = unsafe{ find_in_memory::($begin, $end, 4) } { + return Some(unsafe{ &*(addr as *const Rsdp) }); } ) } diff --git a/src/arch/x86_64/driver/acpi/structs.rs b/src/arch/x86_64/driver/acpi/structs.rs index 0ec80cf5..de388292 100644 --- a/src/arch/x86_64/driver/acpi/structs.rs +++ b/src/arch/x86_64/driver/acpi/structs.rs @@ -6,48 +6,48 @@ use core::mem::size_of; #[repr(C)] #[derive(Debug)] -pub struct rsdp { - pub Signature: [u8; 8], - pub Checksum: u8, - pub OemId: [i8; 6], - pub Revision: u8, - pub RsdtPhysicalAddress: u32, - pub Length: u32, - pub XsdtPhysicalAddress: u64, - pub ExtendedChecksum: u8, - pub Reserved: [u8; 3], +pub struct Rsdp { + pub signature: [u8; 8], + pub checksum: u8, + pub oem_id: [i8; 6], + pub revision: u8, + pub rsdt_physical_address: u32, + pub length: u32, + pub xsdt_physical_address: u64, + pub extended_checksum: u8, + pub reserved: [u8; 3], } -impl Checkable for rsdp { +impl Checkable for Rsdp { fn check(&self) -> bool { - &self.Signature == b"RSD PTR " && bytes_sum(self) == 0 + &self.signature == b"RSD PTR " && bytes_sum(self) == 0 } } #[repr(C)] #[derive(Debug)] -pub struct header { - pub Signature: [u8; 4], - pub Length: u32, - pub Revision: u8, - pub Checksum: u8, - pub OemId: [i8; 6], - pub OemTableId: [i8; 8], - pub OemRevision: u32, - pub AslCompilerId: [i8; 4], - pub AslCompilerRevision: u32, +pub struct Header { + pub signature: [u8; 4], + pub length: u32, + pub revision: u8, + pub checksum: u8, + pub oem_id: [i8; 6], + pub oem_table_id: [i8; 8], + pub oem_revision: u32, + pub asl_compiler_id: [i8; 4], + pub asl_compiler_revision: u32, } #[repr(C)] #[derive(Debug)] -pub struct rsdt { - pub Header: header, - TableOffsetEntry: [u32; 0], +pub struct Rsdt { + pub header: Header, + table_offset_entry: [u32; 0], } -impl rsdt { +impl Rsdt { pub fn entry_count(&self) -> usize { - (self.Header.Length as usize - size_of::()) / 4 + (self.header.length as usize - size_of::()) / 4 } pub fn entry_at(&self, id: usize) -> u32 { assert!(id < self.entry_count()); @@ -60,62 +60,62 @@ impl rsdt { #[repr(C)] #[derive(Debug)] -pub struct madt { - pub Header: header, - pub LapicAddress: u32, - pub Flags: u32, - Table: [u32; 0], +pub struct Madt { + pub header: Header, + pub lapic_address: u32, + pub flags: u32, + table: [u32; 0], } -impl Checkable for madt { +impl Checkable for Madt { fn check(&self) -> bool { - &self.Header.Signature == b"APIC" && self.Header.Length >= size_of::() as u32 + &self.header.signature == b"APIC" && self.header.length >= size_of::() as u32 } } #[derive(Debug)] pub enum MadtEntry { - Unknown(MadtEntry_Unknown), - LocalApic(MadtEntry_LocalApic), - IoApic(MadtEntry_IoApic), + Unknown(MadtEntryUnknown), + LocalApic(MadtEntryLocalApic), + IoApic(MadtEntryIoApic), } #[repr(C)] #[derive(Debug, Clone)] -pub struct MadtEntry_Unknown { - pub Type: u8, - pub Length: u8, +pub struct MadtEntryUnknown { + pub type_: u8, + pub length: u8, } #[repr(C)] #[derive(Debug, Clone)] -pub struct MadtEntry_LocalApic { - pub Type: u8, // 0 - pub Length: u8, - pub ProcessorId: u8, - pub Id: u8, - pub LapicFlags: u32, +pub struct MadtEntryLocalApic { + pub type_: u8, // 0 + pub length: u8, + pub processor_id: u8, + pub id: u8, + pub lapic_flags: u32, } #[repr(C)] #[derive(Debug, Clone)] -pub struct MadtEntry_IoApic { - pub Type: u8, // 1 - pub Length: u8, - pub Id: u8, - pub Reserved: u8, - pub Address: u32, - pub GlobalIrqBase: u32, +pub struct MadtEntryIoApic { + pub type_: u8, // 1 + pub length: u8, + pub id: u8, + pub reserved: u8, + pub address: u32, + pub global_irq_base: u32, } #[derive(Debug)] pub struct MadtEntryIter<'a> { - madt: &'a madt, + madt: &'a Madt, ptr: *const u8, end_ptr: *const u8, } -impl madt { +impl Madt { pub fn entry_iter(&self) -> MadtEntryIter { let ptr = unsafe{ (self as *const Self).offset(1) } as *const u8; - let end_ptr = unsafe{ ptr.offset(self.Header.Length as isize) }; + let end_ptr = unsafe{ ptr.offset(self.header.length as isize) }; MadtEntryIter { madt: self, ptr, end_ptr } } } @@ -127,12 +127,12 @@ impl<'a> Iterator for MadtEntryIter<'a> { return None; } unsafe { - let typeId = *self.ptr.offset(0); + let type_id = *self.ptr.offset(0); let len = *self.ptr.offset(1); - let ret = Some(match typeId { - 0 => MadtEntry::LocalApic( (&*(self.ptr as *const MadtEntry_LocalApic)).clone() ), - 1 => MadtEntry::IoApic( (&*(self.ptr as *const MadtEntry_IoApic)).clone() ), - _ => MadtEntry::Unknown( (&*(self.ptr as *const MadtEntry_Unknown)).clone() ), + let ret = Some(match type_id { + 0 => MadtEntry::LocalApic( (&*(self.ptr as *const MadtEntryLocalApic)).clone() ), + 1 => MadtEntry::IoApic( (&*(self.ptr as *const MadtEntryIoApic)).clone() ), + _ => MadtEntry::Unknown( (&*(self.ptr as *const MadtEntryUnknown)).clone() ), }); self.ptr = self.ptr.offset(len as isize); ret diff --git a/src/arch/x86_64/driver/apic/lapic.rs b/src/arch/x86_64/driver/apic/lapic.rs index 51f1d463..83aa7e60 100644 --- a/src/arch/x86_64/driver/apic/lapic.rs +++ b/src/arch/x86_64/driver/apic/lapic.rs @@ -1,4 +1,5 @@ extern { + //noinspection RsStaticConstNaming static mut lapic: *const (); fn lapicinit(); // must set `lapic` first fn lapiceoi(); // ack diff --git a/src/arch/x86_64/driver/apic/local_apic.rs b/src/arch/x86_64/driver/apic/local_apic.rs index 0b5c1750..edb228b7 100644 --- a/src/arch/x86_64/driver/apic/local_apic.rs +++ b/src/arch/x86_64/driver/apic/local_apic.rs @@ -3,7 +3,7 @@ use x86::cpuid::CpuId; use x86::msr::*; use memory::Frame; -use paging::{ActivePageTable, PhysicalAddress, Page, VirtualAddress}; +use paging::{ActivePageTable, PhysAddr, Page, VirtualAddress}; use paging::entry::EntryFlags; pub static mut LOCAL_APIC: LocalApic = LocalApic { @@ -32,7 +32,7 @@ impl LocalApic { if ! self.x2 { let page = Page::containing_address(VirtualAddress::new(self.address)); - let frame = Frame::containing_address(PhysicalAddress::new(self.address - ::KERNEL_OFFSET)); + let frame = Frame::containing_address(PhysAddr::new(self.address - ::KERNEL_OFFSET)); let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE); result.flush(active_table); } diff --git a/src/arch/x86_64/driver/mod.rs b/src/arch/x86_64/driver/mod.rs index a6cf151e..708b326c 100644 --- a/src/arch/x86_64/driver/mod.rs +++ b/src/arch/x86_64/driver/mod.rs @@ -7,7 +7,7 @@ pub mod pic; pub mod keyboard; pub mod pit; -pub fn init(mut page_map: F) -> acpi::ACPI_Result +pub fn init(mut page_map: F) -> acpi::AcpiResult where F: FnMut(usize) { assert_has_not_been_called!(); diff --git a/src/arch/x86_64/paging/entry.rs b/src/arch/x86_64/paging/entry.rs index 8f1edf14..813f567b 100644 --- a/src/arch/x86_64/paging/entry.rs +++ b/src/arch/x86_64/paging/entry.rs @@ -18,7 +18,7 @@ impl Entry { pub fn pointed_frame(&self) -> Option { if self.flags().contains(EntryFlags::PRESENT) { - Some(Frame::containing_address( + Some(Frame::of_addr( self.0 as usize & 0x000fffff_fffff000 )) } else { @@ -27,7 +27,7 @@ impl Entry { } pub fn set(&mut self, frame: Frame, flags: EntryFlags) { - assert!(frame.start_address().0 & !0x000fffff_fffff000 == 0); + assert_eq!(frame.start_address().0 & !0x000fffff_fffff000, 0); self.0 = (frame.start_address().0) | flags.bits(); } } diff --git a/src/arch/x86_64/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs index d9a394cb..3524638f 100644 --- a/src/arch/x86_64/paging/mapper.rs +++ b/src/arch/x86_64/paging/mapper.rs @@ -22,10 +22,10 @@ impl Mapper { unsafe { self.p4.as_mut() } } - pub fn translate(&self, virtual_address: VirtualAddress) -> Option { + pub fn translate(&self, virtual_address: VirtAddr) -> Option { let offset = virtual_address % PAGE_SIZE; - self.translate_page(Page::containing_address(virtual_address)) - .map(|frame| PhysicalAddress((frame.start_address().get() + offset) as u64)) + self.translate_page(Page::of_addr(virtual_address)) + .map(|frame| PhysAddr((frame.start_address().get() + offset) as u64)) } pub fn translate_page(&self, page: Page) -> Option { @@ -38,8 +38,8 @@ impl Mapper { if let Some(start_frame) = p3_entry.pointed_frame() { if p3_entry.flags().contains(EntryFlags::HUGE_PAGE) { // address must be 1GiB aligned - assert!(start_frame.start_address().get() % (ENTRY_COUNT * ENTRY_COUNT * PAGE_SIZE) == 0); - return Some(Frame::containing_address( + assert_eq!(start_frame.start_address().get() % (ENTRY_COUNT * ENTRY_COUNT * PAGE_SIZE), 0); + return Some(Frame::of_addr( start_frame.start_address().get() + (page.p2_index() * ENTRY_COUNT + page.p1_index()) * PAGE_SIZE )); @@ -51,8 +51,8 @@ impl Mapper { if let Some(start_frame) = p2_entry.pointed_frame() { if p2_entry.flags().contains(EntryFlags::HUGE_PAGE) { // address must be 2MiB aligned - assert!(start_frame.start_address().get() % ENTRY_COUNT == 0); - return Some(Frame::containing_address( + assert_eq!(start_frame.start_address().get() % ENTRY_COUNT, 0); + return Some(Frame::of_addr( start_frame.start_address().get() + page.p1_index() * PAGE_SIZE )); } @@ -91,7 +91,7 @@ impl Mapper { pub fn identity_map(&mut self, frame: Frame, flags: EntryFlags, allocator: &mut A) where A: FrameAllocator { - let page = Page::containing_address(frame.start_address().to_identity_virtual()); + let page = Page::of_addr(frame.start_address().to_identity_virtual()); self.map_to(page, frame, flags, allocator) } diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index f9130676..ebfc8fae 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -17,7 +17,7 @@ pub struct Page { } impl Page { - pub fn containing_address(address: VirtualAddress) -> Page { + pub fn of_addr(address: VirtAddr) -> Page { assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000, "invalid address: 0x{:x}", address); @@ -43,8 +43,8 @@ impl Page { pub fn range_inclusive(start: Page, end: Page) -> PageIter { PageIter { - start: start, - end: end, + start, + end, } } } @@ -113,7 +113,7 @@ impl ActivePageTable { use x86_64::registers::control_regs; { - let backup = Frame::containing_address( + let backup = Frame::of_addr( control_regs::cr3().0 as usize); // map temporary_page to current p4 table @@ -139,7 +139,7 @@ impl ActivePageTable { use x86_64::registers::control_regs; let old_table = InactivePageTable { - p4_frame: Frame::containing_address( + p4_frame: Frame::of_addr( control_regs::cr3().0 as usize ), }; diff --git a/src/arch/x86_64/paging/temporary_page.rs b/src/arch/x86_64/paging/temporary_page.rs index 4ba6a9ae..e884fe12 100644 --- a/src/arch/x86_64/paging/temporary_page.rs +++ b/src/arch/x86_64/paging/temporary_page.rs @@ -1,6 +1,6 @@ use super::{Page, ActivePageTable}; use super::table::{Table, Level1}; -use memory::{Frame, FrameAllocator, VirtualAddress}; +use memory::{Frame, FrameAllocator, VirtAddr}; pub struct TemporaryPage { page: Page, @@ -12,7 +12,7 @@ impl TemporaryPage { where A: FrameAllocator { TemporaryPage { - page: page, + page, allocator: TinyAllocator::new(allocator), } } @@ -20,7 +20,7 @@ impl TemporaryPage { /// Maps the temporary page to the given frame in the active table. /// Returns the start address of the temporary page. pub fn map(&mut self, frame: Frame, active_table: &mut ActivePageTable) - -> VirtualAddress + -> VirtAddr { use super::entry::EntryFlags; diff --git a/src/arch/x86_64/smp.rs b/src/arch/x86_64/smp.rs index 3bc2af02..707174ca 100644 --- a/src/arch/x86_64/smp.rs +++ b/src/arch/x86_64/smp.rs @@ -1,5 +1,5 @@ -use arch::driver::{acpi::ACPI_Result, apic::start_ap}; -use memory::{MemoryController, PhysicalAddress}; +use arch::driver::{acpi::AcpiResult, apic::start_ap}; +use memory::{MemoryController, PhysAddr}; extern { fn entryother_start(); // physical addr of entryother @@ -8,11 +8,11 @@ extern { const ENTRYOTHER_ADDR: u32 = 0x7000; -pub fn start_other_cores(acpi: &ACPI_Result, mc: &mut MemoryController) { +pub fn start_other_cores(acpi: &AcpiResult, mc: &mut MemoryController) { mc.map_page_identity(ENTRYOTHER_ADDR as usize - 1); mc.map_page_identity(ENTRYOTHER_ADDR as usize); mc.map_page_identity(entryother_start as usize); - mc.map_page_p2v(PhysicalAddress(0)); + mc.map_page_p2v(PhysAddr(0)); copy_entryother(); let args = unsafe{ &mut *(ENTRYOTHER_ADDR as *mut EntryArgs).offset(-1) }; @@ -21,7 +21,7 @@ pub fn start_other_cores(acpi: &ACPI_Result, mc: &mut MemoryController) { let apic_id = acpi.cpu_acpi_ids[i as usize]; *args = EntryArgs { kstack: mc.alloc_stack(7).unwrap().top() as u64, - page_table: page_table, + page_table, stack: 0x8000, // just enough stack to get us to entry64mp }; start_ap(apic_id, ENTRYOTHER_ADDR); diff --git a/src/consts.rs b/src/consts.rs index 19f5cb37..74026b04 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] pub const MAX_CPU_NUM: usize = 8; // Copy from Redox consts.rs: diff --git a/src/io/vga_writer.rs b/src/io/vga_writer.rs index 034b994a..23b966e4 100644 --- a/src/io/vga_writer.rs +++ b/src/io/vga_writer.rs @@ -21,7 +21,7 @@ impl VgaWriter { VgaWriter { column_position: 0, color: Color::LightGray, - buffer: buffer, + buffer, } } diff --git a/src/memory/address.rs b/src/memory/address.rs index 153b189b..e575b5e9 100644 --- a/src/memory/address.rs +++ b/src/memory/address.rs @@ -1,27 +1,27 @@ use consts::{KERNEL_OFFSET, KERNEL_SIZE}; -pub use x86_64::{PhysicalAddress}; -pub type VirtualAddress = usize; +pub use x86_64::PhysicalAddress as PhysAddr; +pub type VirtAddr = usize; pub trait FromToVirtualAddress { fn get(&self) -> usize; - fn to_identity_virtual(&self) -> VirtualAddress; - fn to_kernel_virtual(&self) -> VirtualAddress; - fn from_kernel_virtual(addr: VirtualAddress) -> Self; + fn to_identity_virtual(&self) -> VirtAddr; + fn to_kernel_virtual(&self) -> VirtAddr; + fn from_kernel_virtual(addr: VirtAddr) -> Self; } -impl FromToVirtualAddress for PhysicalAddress { +impl FromToVirtualAddress for PhysAddr { fn get(&self) -> usize { self.0 as usize } - fn to_identity_virtual(&self) -> VirtualAddress { + fn to_identity_virtual(&self) -> VirtAddr { self.0 as usize } - fn to_kernel_virtual(&self) -> VirtualAddress { + fn to_kernel_virtual(&self) -> VirtAddr { assert!((self.0 as usize) < KERNEL_SIZE); self.0 as usize + KERNEL_OFFSET } - fn from_kernel_virtual(addr: VirtualAddress) -> Self { + fn from_kernel_virtual(addr: VirtAddr) -> Self { assert!(addr >= KERNEL_OFFSET && addr < KERNEL_OFFSET + KERNEL_SIZE); - PhysicalAddress((addr - KERNEL_OFFSET) as u64) + PhysAddr((addr - KERNEL_OFFSET) as u64) } } \ No newline at end of file diff --git a/src/memory/area_frame_allocator.rs b/src/memory/area_frame_allocator.rs index d0e38248..bba943c7 100644 --- a/src/memory/area_frame_allocator.rs +++ b/src/memory/area_frame_allocator.rs @@ -1,4 +1,4 @@ -use memory::{Frame, FrameAllocator, PhysicalAddress}; +use memory::{Frame, FrameAllocator, PhysAddr}; use multiboot2::{MemoryAreaIter, MemoryArea}; pub struct AreaFrameAllocator { @@ -21,7 +21,7 @@ impl FrameAllocator for AreaFrameAllocator { // the last frame of the current area let current_area_last_frame = { let address = area.base_addr + area.length - 1; - Frame::containing_address(address as usize) + Frame::of_addr(address as usize) }; if frame > current_area_last_frame { @@ -55,18 +55,18 @@ impl FrameAllocator for AreaFrameAllocator { } impl AreaFrameAllocator { - pub fn new(kernel_start: PhysicalAddress, kernel_end: PhysicalAddress, - multiboot_start: PhysicalAddress, multiboot_end: PhysicalAddress, - memory_areas: MemoryAreaIter) -> AreaFrameAllocator + pub fn new(kernel_start: PhysAddr, kernel_end: PhysAddr, + multiboot_start: PhysAddr, multiboot_end: PhysAddr, + memory_areas: MemoryAreaIter) -> AreaFrameAllocator { let mut allocator = AreaFrameAllocator { - next_free_frame: Frame::containing_address(0), + next_free_frame: Frame::of_addr(0), current_area: None, areas: memory_areas, - kernel_start: Frame::containing_address(kernel_start.0 as usize), - kernel_end: Frame::containing_address(kernel_end.0 as usize), - multiboot_start: Frame::containing_address(multiboot_start.0 as usize), - multiboot_end: Frame::containing_address(multiboot_end.0 as usize), + 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), + multiboot_end: Frame::of_addr(multiboot_end.0 as usize), }; allocator.choose_next_area(); allocator @@ -75,11 +75,11 @@ impl AreaFrameAllocator { fn choose_next_area(&mut self) { self.current_area = self.areas.clone().filter(|area| { let address = area.base_addr + area.length - 1; - Frame::containing_address(address as usize) >= self.next_free_frame + Frame::of_addr(address as usize) >= self.next_free_frame }).min_by_key(|area| area.base_addr); if let Some(area) = self.current_area { - let start_frame = Frame::containing_address(area.base_addr as usize); + let start_frame = Frame::of_addr(area.base_addr as usize); if self.next_free_frame < start_frame { self.next_free_frame = start_frame; } diff --git a/src/memory/frame.rs b/src/memory/frame.rs index 6b9be48c..746dea51 100644 --- a/src/memory/frame.rs +++ b/src/memory/frame.rs @@ -1,4 +1,4 @@ -use super::address::PhysicalAddress; +use super::address::PhysAddr; pub const PAGE_SIZE: usize = 4096; @@ -8,12 +8,12 @@ pub struct Frame { } impl Frame { - pub fn containing_address(address: usize) -> Frame { + pub fn of_addr(address: usize) -> Frame { Frame{ number: address / PAGE_SIZE } } //TODO: Set private - pub fn start_address(&self) -> PhysicalAddress { - PhysicalAddress((self.number * PAGE_SIZE) as u64) + pub fn start_address(&self) -> PhysAddr { + PhysAddr((self.number * PAGE_SIZE) as u64) } pub fn clone(&self) -> Frame { @@ -22,8 +22,8 @@ impl Frame { //TODO: Set private pub fn range_inclusive(start: Frame, end: Frame) -> FrameIter { FrameIter { - start: start, - end: end, + start, + end, } } } diff --git a/src/memory/mod.rs b/src/memory/mod.rs index d039ddb6..9886d147 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -22,13 +22,13 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { let elf_sections_tag = boot_info.elf_sections_tag().expect( "Elf sections tag required"); - let kernel_start = PhysicalAddress(elf_sections_tag.sections() + let kernel_start = PhysAddr(elf_sections_tag.sections() .filter(|s| s.is_allocated()).map(|s| s.start_address()).min().unwrap() as u64); - let kernel_end = PhysicalAddress::from_kernel_virtual(elf_sections_tag.sections() + let kernel_end = PhysAddr::from_kernel_virtual(elf_sections_tag.sections() .filter(|s| s.is_allocated()).map(|s| s.end_address()).max().unwrap()); - let boot_info_start = PhysicalAddress(boot_info.start_address() as u64); - let boot_info_end = PhysicalAddress(boot_info.end_address() as u64); + let boot_info_start = PhysAddr(boot_info.start_address() as u64); + let boot_info_end = PhysAddr(boot_info.end_address() as u64); println!("kernel start: {:#x}, kernel end: {:#x}", kernel_start, @@ -51,8 +51,8 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { use self::paging::Page; use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; - let heap_start_page = Page::containing_address(KERNEL_HEAP_OFFSET); - let heap_end_page = Page::containing_address(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE-1); + let heap_start_page = Page::of_addr(KERNEL_HEAP_OFFSET); + let heap_end_page = Page::of_addr(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE-1); for page in Page::range_inclusive(heap_start_page, heap_end_page) { active_table.map(page, EntryFlags::WRITABLE, &mut frame_allocator); @@ -67,9 +67,9 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { }; MemoryController { - active_table: active_table, - frame_allocator: frame_allocator, - stack_allocator: stack_allocator, + active_table, + frame_allocator, + stack_allocator, } } @@ -77,7 +77,7 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) -> ActivePageTable where A: FrameAllocator { - let mut temporary_page = TemporaryPage::new(Page::containing_address(0xcafebabe), allocator); + let mut temporary_page = TemporaryPage::new(Page::of_addr(0xcafebabe), allocator); let mut active_table = unsafe { ActivePageTable::new() }; let mut new_table = { @@ -94,8 +94,7 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) // section is not loaded to memory continue; } - assert!(section.start_address() % PAGE_SIZE == 0, - "sections need to be page aligned"); + assert_eq!(section.start_address() % PAGE_SIZE, 0, "sections need to be page aligned"); println!("mapping section at addr: {:#x}, size: {:#x}", section.addr, section.size); @@ -103,7 +102,7 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) let flags = EntryFlags::from_elf_section_flags(section); fn to_physical_frame(addr: usize) -> Frame { - Frame::containing_address( + Frame::of_addr( if addr < KERNEL_OFFSET { addr } else { addr - KERNEL_OFFSET }) } @@ -112,18 +111,18 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) let end_frame = to_physical_frame(section.end_address() - 1); for frame in Frame::range_inclusive(start_frame, end_frame) { - let page = Page::containing_address(frame.start_address().to_kernel_virtual()); + let page = Page::of_addr(frame.start_address().to_kernel_virtual()); mapper.map_to(page, frame, flags, allocator); } } // identity map the VGA text buffer - let vga_buffer_frame = Frame::containing_address(0xb8000); + let vga_buffer_frame = Frame::of_addr(0xb8000); mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator); // identity map the multiboot info structure - let multiboot_start = Frame::containing_address(boot_info.start_address()); - let multiboot_end = Frame::containing_address(boot_info.end_address() - 1); + let multiboot_start = Frame::of_addr(boot_info.start_address()); + let multiboot_end = Frame::of_addr(boot_info.end_address() - 1); for frame in Frame::range_inclusive(multiboot_start, multiboot_end) { mapper.identity_map(frame, EntryFlags::PRESENT, allocator); } @@ -134,8 +133,8 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) // turn the stack bottom into a guard page extern { fn stack_bottom(); } - let stack_bottom = PhysicalAddress(stack_bottom as u64).to_kernel_virtual(); - let stack_bottom_page = Page::containing_address(stack_bottom); + let stack_bottom = PhysAddr(stack_bottom as u64).to_kernel_virtual(); + let stack_bottom_page = Page::of_addr(stack_bottom); active_table.unmap(stack_bottom_page, allocator); println!("guard page at {:#x}", stack_bottom_page.start_address()); @@ -157,13 +156,13 @@ impl MemoryController { size_in_pages) } pub fn map_page_identity(&mut self, addr: usize) { - let frame = Frame::containing_address(addr); + let frame = Frame::of_addr(addr); let flags = EntryFlags::WRITABLE; self.active_table.identity_map(frame, flags, &mut self.frame_allocator); } - pub fn map_page_p2v(&mut self, addr: PhysicalAddress) { - let page = Page::containing_address(addr.to_kernel_virtual()); - let frame = Frame::containing_address(addr.get()); + pub fn map_page_p2v(&mut self, addr: PhysAddr) { + let page = Page::of_addr(addr.to_kernel_virtual()); + let frame = Frame::of_addr(addr.get()); let flags = EntryFlags::WRITABLE; self.active_table.map_to(page, frame, flags, &mut self.frame_allocator); } diff --git a/src/memory/stack_allocator.rs b/src/memory/stack_allocator.rs index 72498742..02c864c2 100644 --- a/src/memory/stack_allocator.rs +++ b/src/memory/stack_allocator.rs @@ -64,8 +64,8 @@ impl Stack { fn new(top: usize, bottom: usize) -> Stack { assert!(top > bottom); Stack { - top: top, - bottom: bottom, + top, + bottom, } }