mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Test map_to function
This commit is contained in:
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user