Browse Source

Preliminary data structures required for a page table manager

master
3moon 8 years ago
parent
commit
8e2ee50f66
3 changed files with 99 additions and 0 deletions
  1. +49
    -0
      src/arch/x86_64/memory/paging/entry.rs
  2. +21
    -0
      src/arch/x86_64/memory/paging/mod.rs
  3. +29
    -0
      src/arch/x86_64/memory/paging/table.rs

+ 49
- 0
src/arch/x86_64/memory/paging/entry.rs View File

@ -0,0 +1,49 @@
use arch::x86_64::memory::Frame;
pub struct Entry(u64);
impl Entry {
pub fn is_unused(&self) -> bool {
self.0 == 0
}
pub fn set_unused(&mut self) {
self.0 = 0;
}
pub fn flags(&self) -> EntryFlags {
EntryFlags::from_bits_truncate(self.0)
}
pub fn pointed_frame(&self) -> Option<Frame> {
if self.flags().contains(PRESENT) {
Some(Frame::containing_address(
self.0 as usize & 0x000fffff_fffff000
))
} else {
None
}
}
pub fn set(&mut self, frame: Frame, flags: EntryFlags) {
// Frame physical address must be page-aligned and smaller than 2^52
assert!(frame.start_address() & !0x000fffff_fffff000 == 0);
self.0 = (frame.start_address() as u64) | flags.bits();
}
}
bitflags! {
pub struct EntryFlags: u64 {
const PRESENT = 1 << 0;
const WRITABLE = 1 << 1;
const USER_ACCESSIBLE = 1 << 2;
const WRITE_THROUGH = 1 << 3;
const NO_CACHE = 1 << 4;
const ACCESSED = 1 << 5;
const DIRTY = 1 << 6;
const HUGE_PAGE = 1 << 7;
const GLOBAL = 1 << 8;
const NO_EXECUTE = 1 << 63;
}
}

+ 21
- 0
src/arch/x86_64/memory/paging/mod.rs View File

@ -0,0 +1,21 @@
//! Paging subsystem.
//!
//! Extremely ripped off from Phil Oppermann's tutorials, because I don't feel like writing
//! a paging system off the top of my head today.
use super::PAGE_SIZE;
mod entry;
mod table;
/// Upper bound on entries per page table
const ENTRY_COUNT: usize = 512;
/// Helper type aliases used to make function signatures more expressive
pub type PhysicalAddress = usize;
pub type VirtualAddress = usize;
/// A representation of a virtual page
pub struct Page {
index: usize,
}

+ 29
- 0
src/arch/x86_64/memory/paging/table.rs View File

@ -0,0 +1,29 @@
use core::ops::{Index, IndexMut};
use super::entry::*;
use super::ENTRY_COUNT;
pub struct Table {
entries: [Entry; ENTRY_COUNT],
}
impl Table {
pub fn zero(&mut self) {
for entry in self.entries.iter_mut() {
entry.set_unused();
}
}
}
impl Index<usize> for Table {
type Output = Entry;
fn index(&self, index: usize) -> &Entry {
&self.entries[index]
}
}
impl IndexMut<usize> for Table {
fn index_mut(&mut self, index: usize) -> &mut Entry {
&mut self.entries[index]
}
}

Loading…
Cancel
Save