mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Create a temporary_page module
This commit is contained in:
@@ -5,6 +5,7 @@ use self::table::{Table, Level4};
|
|||||||
|
|
||||||
mod entry;
|
mod entry;
|
||||||
mod table;
|
mod table;
|
||||||
|
mod temporary_page;
|
||||||
|
|
||||||
const ENTRY_COUNT: usize = 512;
|
const ENTRY_COUNT: usize = 512;
|
||||||
|
|
||||||
|
|||||||
79
src/memory/paging/temporary_page.rs
Normal file
79
src/memory/paging/temporary_page.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use super::{Page, ActivePageTable, VirtualAddress};
|
||||||
|
use super::table::{Table, Level1};
|
||||||
|
use memory::{Frame, FrameAllocator};
|
||||||
|
|
||||||
|
pub struct TemporaryPage {
|
||||||
|
page: Page,
|
||||||
|
allocator: TinyAllocator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TemporaryPage {
|
||||||
|
pub fn new<A>(page: Page, allocator: &mut A) -> TemporaryPage
|
||||||
|
where A: FrameAllocator
|
||||||
|
{
|
||||||
|
TemporaryPage {
|
||||||
|
page: page,
|
||||||
|
allocator: TinyAllocator::new(allocator),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
use super::entry::WRITABLE;
|
||||||
|
|
||||||
|
assert!(active_table.translate_page(self.page).is_none(),
|
||||||
|
"temporary page is already mapped");
|
||||||
|
active_table.map_to(self.page, frame, WRITABLE, &mut self.allocator);
|
||||||
|
self.page.start_address()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unmaps the temporary page in the active table.
|
||||||
|
pub fn unmap(&mut self, active_table: &mut ActivePageTable) {
|
||||||
|
active_table.unmap(self.page, &mut self.allocator)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps the temporary page to the given page table frame in the active
|
||||||
|
/// table. Returns a reference to the now mapped table.
|
||||||
|
pub fn map_table_frame(&mut self,
|
||||||
|
frame: Frame,
|
||||||
|
active_table: &mut ActivePageTable)
|
||||||
|
-> &mut Table<Level1> {
|
||||||
|
unsafe { &mut *(self.map(frame, active_table) as *mut Table<Level1>) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TinyAllocator([Option<Frame>; 3]);
|
||||||
|
|
||||||
|
impl TinyAllocator {
|
||||||
|
fn new<A>(allocator: &mut A) -> TinyAllocator
|
||||||
|
where A: FrameAllocator
|
||||||
|
{
|
||||||
|
let mut f = || allocator.allocate_frame();
|
||||||
|
let frames = [f(), f(), f()];
|
||||||
|
TinyAllocator(frames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrameAllocator for TinyAllocator {
|
||||||
|
fn allocate_frame(&mut self) -> Option<Frame> {
|
||||||
|
for frame_option in &mut self.0 {
|
||||||
|
if frame_option.is_some() {
|
||||||
|
return frame_option.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deallocate_frame(&mut self, frame: Frame) {
|
||||||
|
for frame_option in &mut self.0 {
|
||||||
|
if frame_option.is_none() {
|
||||||
|
*frame_option = Some(frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("Tiny allocator can hold only 3 frames.");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user