diff --git a/src/arch/x86_64/memory/paging/entry.rs b/src/arch/x86_64/memory/paging/entry.rs
new file mode 100644
index 0000000..e2c8f9b
--- /dev/null
+++ b/src/arch/x86_64/memory/paging/entry.rs
@@ -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 {
+ 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;
+ }
+}
diff --git a/src/arch/x86_64/memory/paging/mod.rs b/src/arch/x86_64/memory/paging/mod.rs
new file mode 100644
index 0000000..cd4078e
--- /dev/null
+++ b/src/arch/x86_64/memory/paging/mod.rs
@@ -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,
+}
diff --git a/src/arch/x86_64/memory/paging/table.rs b/src/arch/x86_64/memory/paging/table.rs
new file mode 100644
index 0000000..b5ec2d5
--- /dev/null
+++ b/src/arch/x86_64/memory/paging/table.rs
@@ -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 for Table {
+ type Output = Entry;
+
+ fn index(&self, index: usize) -> &Entry {
+ &self.entries[index]
+ }
+}
+
+impl IndexMut for Table {
+ fn index_mut(&mut self, index: usize) -> &mut Entry {
+ &mut self.entries[index]
+ }
+}