diff --git a/Cargo.toml b/Cargo.toml index 7eb63f79..2738b730 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,7 @@ spin = "0.3.4" [dependencies.multiboot2] git = "https://github.com/phil-opp/multiboot2-elf64" + +[dependencies.bitflags] +git = "https://github.com/phil-opp/bitflags.git" +branch = "no_std" diff --git a/src/lib.rs b/src/lib.rs index e0ae38fc..2350abfd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,8 @@ extern crate rlibc; extern crate spin; extern crate multiboot2; +#[macro_use] +extern crate bitflags; #[macro_use] mod vga_buffer; diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 7287b464..064be1c1 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -1,4 +1,5 @@ pub use self::area_frame_allocator::AreaFrameAllocator; +use self::paging::PhysicalAddress; mod area_frame_allocator; mod paging; @@ -14,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/src/memory/paging/entry.rs b/src/memory/paging/entry.rs new file mode 100644 index 00000000..071ee277 --- /dev/null +++ b/src/memory/paging/entry.rs @@ -0,0 +1,45 @@ +use 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) { + assert!(frame.start_address() & !0x000fffff_fffff000 == 0); + self.0 = (frame.start_address() as u64) | flags.bits(); + } +} + +bitflags! { + flags 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/memory/paging/mod.rs b/src/memory/paging/mod.rs index ae5b85fd..d0e7145f 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -1,3 +1,5 @@ +mod entry; + const ENTRY_COUNT: usize = 512; pub type PhysicalAddress = usize;