1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//! This crate implements a generic page table walker in Rust, which can be used to either
//! introspect or manage virtual address spaces on architectures that implement a Memory Management
//! Unit (MMU) that traverses a hierarchy of page tables to translate virtual address into physical
//! addresses and a set of permissions. Note that paging is not limited to CPUs, and that paging is
//! also common on modern GPUs. The implementations provided here may therefore be useful when
//! implementing drivers for any sort of paging architecture, an operating system, a hypervisor,
//! etc.
//!
//! The page table hierarchies of different architectures are described in the [`arch`] module. In
//! particular, the [`PageFormat`] struct is used to describe a page table hierarchy or layout
//! consisting of one or more [`PageLevel`] structs, where each level describes which virtual
//! address bits are used to index into the page table. [`PageFormat::walk`] and
//! [`PageFormat::walk_mut`] implement a software page table walker that essentially starts at the
//! root address and traverses the page tables one by one using the [`PageFormat`] struct to select
//! the appropriate bits from the virtual address to index into these page tables.
//!
//! While traversing the page tables, the [`PageFormat::walk`] and [`PageFormat::walk_mut`] invoke
//! functions provided by a user supplied type implementing the [`PageWalker`] and
//! [`PageWalkerMut`] traits respectively to operate on the various page table entries (PTEs). Note
//! that there is an immutable version that does not allow modification of the page tables, and a
//! mutable version that does.
//!
//! While it is possible to implement your own [`PageWalker`] and [`PageWalkerMut`], this crate
//! also provides a higher-level abstraction of an virtual address space in [`AddressSpace`] that
//! only requires you to implement a [`PageTableMapper`] for mapping and unmapping page tables. The
//! [`AddressSpace`] then simply offers you the functionality to retrieve and modify the PTEs of
//! existing pages.
//!
//! In addition, when [`PageTableMapper::alloc_page`] and [`PageTableMapper::free_page`] are
//! implemented, the full range of functionality can be used. More specifically, the
//! [`AddressSpace`] provides functions to allocate and free pages for a given virtual address
//! range, change the protection of a given virtual address range and allows mapping and unmapping
//! a physical address range to a given virtual address range for memory-mapped I/O.

#![no_std]
#![deny(missing_docs, rustdoc::broken_intra_doc_links)]

pub mod address_space;
pub mod arch;
pub mod format;
pub mod level;
pub mod table;
pub mod walker;
pub mod walkers;

pub use address_space::{AddressSpace, PageTableMapper};
pub use format::PageFormat;
pub use level::PageLevel;
pub use table::{PageTable, PageTableMut};
pub use walker::{PageWalker, PageWalkerMut, PteType};