diff --git a/kernel-rs/Cargo.toml b/kernel-rs/Cargo.toml
index 84dde790..f7771995 100644
--- a/kernel-rs/Cargo.toml
+++ b/kernel-rs/Cargo.toml
@@ -8,9 +8,10 @@ crate-type = ["staticlib"]
[dependencies]
rlibc = "1.0"
-spin = "0.4.5"
+bitflags = "1.0.1"
+# spin = "0.4.5"
multiboot2 = { path = "multiboot2-elf64" }
-[dependencies.lazy_static]
-version = "0.2.4"
-features = ["spin_no_std"]
+# [dependencies.lazy_static]
+# version = "0.2.4"
+# features = ["spin_no_std"]
diff --git a/kernel-rs/src/context.rs b/kernel-rs/src/context.rs
index fddab663..6569012d 100644
--- a/kernel-rs/src/context.rs
+++ b/kernel-rs/src/context.rs
@@ -19,7 +19,7 @@ pub struct Context {
impl Context
{
pub fn new(multiboot_start: usize) -> Context {
- let boot_info = multiboot2::load(multiboot_start);
+ let boot_info = unsafe { multiboot2::load(multiboot_start) };
let multiboot_end = multiboot_start + boot_info.total_size();
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs
index bbf6f05c..89dca7fa 100644
--- a/kernel-rs/src/lib.rs
+++ b/kernel-rs/src/lib.rs
@@ -8,9 +8,7 @@
extern crate rlibc;
extern crate multiboot2; //slightly modified fork from official 0.3.2
-#[macro_use]
-extern crate lazy_static;
-extern crate spin;
+#[macro_use] extern crate bitflags;
/// 80x25 screen and simplistic terminal driver
#[macro_use] pub mod vga;
@@ -28,6 +26,7 @@ pub mod acpi;
pub mod memory;
use context::*;
+use memory::*;
use vga::{Color, ColorCode};
diff --git a/kernel-rs/src/memory/mod.rs b/kernel-rs/src/memory/mod.rs
index aa2b620e..68b3abd9 100644
--- a/kernel-rs/src/memory/mod.rs
+++ b/kernel-rs/src/memory/mod.rs
@@ -1,8 +1,10 @@
pub const PAGE_SIZE: usize = 4096;
mod area_allocator;
+mod paging;
pub use self::area_allocator::*;
+use self::paging::PhysicalAddress;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Frame {
@@ -13,6 +15,10 @@ impl Frame {
fn containing_address(address: usize) -> Frame {
Frame{ number: address / PAGE_SIZE }
}
+
+ fn start_address(&self) -> PhysicalAddress {
+ self.number * PAGE_SIZE
+ }
}
pub trait FrameAllocator {
diff --git a/kernel-rs/src/memory/paging/entry.rs b/kernel-rs/src/memory/paging/entry.rs
new file mode 100644
index 00000000..506bbf6a
--- /dev/null
+++ b/kernel-rs/src/memory/paging/entry.rs
@@ -0,0 +1,47 @@
+use memory::Frame;
+
+pub struct Entry(u64);
+
+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;
+ }
+}
+
+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 // actual addr is bits 12-51
+ ))
+ } else {
+ None
+ }
+ }
+
+ pub fn set(&mut self, frame: Frame, flags: EntryFlags) {
+ assert!!(frame.start_address() & !0x000fffff_fffff000 == 0);
+ self.0 = (frame.start_address() as u64) | flags.bits();
+ }
+}
diff --git a/kernel-rs/src/memory/paging/mod.rs b/kernel-rs/src/memory/paging/mod.rs
new file mode 100644
index 00000000..17896565
--- /dev/null
+++ b/kernel-rs/src/memory/paging/mod.rs
@@ -0,0 +1,10 @@
+use memory::PAGE_SIZE;
+
+const ENTRY_COUNT: usize = 512;
+
+pub type PhysicalAddress = usize;
+pub type VirtualAddress = usize;
+
+pub struct Page {
+ number: usize,
+}
diff --git a/kernel-rs/src/memory/paging/table.rs b/kernel-rs/src/memory/paging/table.rs
new file mode 100644
index 00000000..aa11a3ab
--- /dev/null
+++ b/kernel-rs/src/memory/paging/table.rs
@@ -0,0 +1,28 @@
+use memory::paging::entry::*;
+use memory::paging::ENTRY_COUNT;
+
+use core::ops::{Index, IndexMut};
+
+pub struct Table {
+ entries: [Entry; ENTRY_COUNT],
+}
+
+impl Table {
+ 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(&self, index: usize) -> &mut Entry {
+ &mut self.entries[index]
+ }
+}