Test map_to function

This commit is contained in:
Philipp Oppermann
2015-12-09 13:45:39 +01:00
parent 5b4e457439
commit cf5ea7664e
2 changed files with 39 additions and 2 deletions

View File

@@ -817,6 +817,31 @@ So a stack overflow overwrites the P2 table, starting at the last entry. But the
To fix it, we double the stack size to `4096 * 2`. Now the last byte gets translated to `Some(1073741823)` correctly. To avoid this kind of bug in the future, we need to add a guard page to the stack, which causes an exception on stack overflow. We will do that in the next post when we remap the kernel. To fix it, we double the stack size to `4096 * 2`. Now the last byte gets translated to `Some(1073741823)` correctly. To avoid this kind of bug in the future, we need to add a guard page to the stack, which causes an exception on stack overflow. We will do that in the next post when we remap the kernel.
### map_to
Let's test the `map_to` function:
```rust
let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
let page = Page::containing_address(addr);
let frame = allocator.allocate_frame().expect("no more frames");
println!("None = {:?}, map to {:?}",
page_table.translate(addr),
frame);
page_table.map_to(page, frame, EntryFlags::empty(), allocator);
println!("Some = {:?}", page_table.translate(addr));
println!("next free frame: {:?}", allocator.allocate_frame());
```
We just map some random page to a free frame. To be able to borrow the page table as `&mut`, we need to make it mutable.
You should see output similar to this:
```
None = None, map to Frame { number: 0 }
Some = Some(0)
next free frame: Some(Frame { number: 3 })
```
It's frame 0 because it's the first frame returned by the frame allocator. Since we map the 42th P3 entry, the mapping code needs to create a P2 and a P1 table. So the next free frame returned by the allocator is frame 3.
## What's next? ## What's next?
In the next post we will extend this module and add a function to modify inactive page tables. Through that function, we will create a new page table hierarchy that maps the kernel correctly using 4KiB pages. Then we will switch to the new table to get a safer kernel environment. In the next post we will extend this module and add a function to modify inactive page tables. Through that function, we will create a new page table hierarchy that maps the kernel correctly using 4KiB pages. Then we will switch to the new table to get a safer kernel environment.

View File

@@ -16,7 +16,7 @@ pub struct Page {
} }
impl Page { impl Page {
fn containing_address(address: VirtualAddress) -> Page { pub fn containing_address(address: VirtualAddress) -> Page {
assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000, assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
"invalid address: 0x{:x}", "invalid address: 0x{:x}",
address); address);
@@ -147,12 +147,24 @@ impl RecursivePageTable {
pub fn test_paging<A>(allocator: &mut A) pub fn test_paging<A>(allocator: &mut A)
where A: FrameAllocator where A: FrameAllocator
{ {
let page_table = unsafe { RecursivePageTable::new() }; let mut page_table = unsafe { RecursivePageTable::new() };
// test translate
println!("Some = {:?}", page_table.translate(0)); println!("Some = {:?}", page_table.translate(0));
println!("Some = {:?}", page_table.translate(4096)); // second P1 entry println!("Some = {:?}", page_table.translate(4096)); // second P1 entry
println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry
println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry
println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry
println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte
// test map_to
let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
let page = Page::containing_address(addr);
let frame = allocator.allocate_frame().expect("no more frames");
println!("None = {:?}, map to {:?}",
page_table.translate(addr),
frame);
page_table.map_to(page, frame, EntryFlags::empty(), allocator);
println!("Some = {:?}", page_table.translate(addr));
println!("next free frame: {:?}", allocator.allocate_frame());
} }