Skip to content

Commit 0021e25

Browse files
committed
paging: Make PageTable Memory be owned by Rust
This allows for less complex linking and less `unsafe` code. It also frees up Rust to place the page tables wherever it wants. Signed-off-by: Joe Richey <[email protected]>
1 parent c5b5a7d commit 0021e25

File tree

3 files changed

+17
-36
lines changed

3 files changed

+17
-36
lines changed

layout.ld

-10
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ ram_max = 2M;
1313
/* Our stack grows down from ram_max. TODO: Add a guard for stack overflows. */
1414
stack_size = 64K;
1515

16-
/* Pagetable locations loaded by Firecracker/cloud-hypervisor */
17-
pml4t = 0x9000;
18-
pml3t = 0xa000;
19-
2016
SECTIONS
2117
{
2218
/* Mapping in the program headers makes it easier to mmap the whole file. */
@@ -32,12 +28,6 @@ SECTIONS
3228

3329
firmware_ram_size = . - ram_min;
3430

35-
/* Memory for identity mapping, keep synced with ADDRESS_SPACE_GIB */
36-
address_space_gib = 4;
37-
. = ALIGN(4K);
38-
pml2ts = .;
39-
. += 4K * address_space_gib;
40-
4131
ASSERT((. <= ram_max - stack_size), "firmware size too big for RAM region")
4232

4333
/* Match edk2's GccBase.lds DISCARD section */

src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#![feature(global_asm)]
15+
#![feature(global_asm, const_in_array_repeat_expressions)]
1616
#![cfg_attr(not(test), no_std)]
1717
#![cfg_attr(not(test), no_main)]
1818
#![cfg_attr(test, allow(unused_imports, dead_code))]

src/paging.rs

+16-25
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,49 @@ use x86_64::{
55
PhysAddr,
66
};
77

8-
// Keep in sync with address_space_gib in layout.ld
8+
// This is the number of GiB we will identity map.
99
const ADDRESS_SPACE_GIB: usize = 4;
1010

11-
pub static MANAGER: AtomicRefCell<Manager> = AtomicRefCell::new(Manager);
12-
pub struct Manager;
13-
14-
extern "C" {
15-
static mut pml4t: PageTable;
16-
static mut pml3t: PageTable;
17-
static mut pml2ts: [PageTable; ADDRESS_SPACE_GIB];
18-
}
19-
20-
struct Tables<'a> {
21-
l4: &'a mut PageTable,
22-
l3: &'a mut PageTable,
23-
l2s: &'a mut [PageTable],
11+
pub static MANAGER: AtomicRefCell<Manager> = AtomicRefCell::new(Manager::new());
12+
pub struct Manager {
13+
l4: PageTable,
14+
l3: PageTable,
15+
l2s: [PageTable; ADDRESS_SPACE_GIB],
2416
}
2517

2618
impl Manager {
27-
fn tables(&mut self) -> Tables {
28-
Tables {
29-
l4: unsafe { &mut pml4t },
30-
l3: unsafe { &mut pml3t },
31-
l2s: unsafe { &mut pml2ts },
19+
const fn new() -> Self {
20+
Manager {
21+
l4: PageTable::new(),
22+
l3: PageTable::new(),
23+
l2s: [PageTable::new(); ADDRESS_SPACE_GIB],
3224
}
3325
}
3426

3527
pub fn setup(&mut self) {
3628
log!("Setting up {} GiB identity mapping", ADDRESS_SPACE_GIB);
37-
let Tables { l4, l3, l2s } = self.tables();
3829

3930
let pt_flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
4031
// Setup Identity map using L2 huge pages
4132
let mut next_addr = PhysAddr::new(0);
42-
for l2 in l2s.iter_mut() {
33+
for l2 in self.l2s.iter_mut() {
4334
for l2e in l2.iter_mut() {
4435
l2e.set_addr(next_addr, pt_flags | PageTableFlags::HUGE_PAGE);
4536
next_addr += Size2MiB::SIZE;
4637
}
4738
}
4839

4940
// Point L3 at L2s
50-
for (i, l2) in l2s.iter().enumerate() {
51-
l3[i].set_addr(phys_addr(l2), pt_flags);
41+
for (i, l2) in self.l2s.iter().enumerate() {
42+
self.l3[i].set_addr(phys_addr(l2), pt_flags);
5243
}
5344

5445
// Point L4 at L3
55-
l4[0].set_addr(phys_addr(l3), pt_flags);
46+
self.l4[0].set_addr(phys_addr(&self.l3), pt_flags);
5647

5748
// Point Cr3 at PML4
5849
let cr3_flags = Cr3::read().1;
59-
let pml4t_frame = PhysFrame::from_start_address(phys_addr(l4)).unwrap();
50+
let pml4t_frame = PhysFrame::from_start_address(phys_addr(&self.l4)).unwrap();
6051
unsafe { Cr3::write(pml4t_frame, cr3_flags) };
6152
log!("Page tables setup");
6253
}

0 commit comments

Comments
 (0)