From c0a96aa7e4de7f4987fb58123b4fd0e0f769f93b Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Tue, 15 Feb 2022 08:53:53 -0700 Subject: [PATCH] Reduce memory used by x86_64 page tables --- src/arch/x86_64/paging.rs | 45 +++++++++++++++++++-------------------- src/main.rs | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/arch/x86_64/paging.rs b/src/arch/x86_64/paging.rs index 5715cd0..847485a 100644 --- a/src/arch/x86_64/paging.rs +++ b/src/arch/x86_64/paging.rs @@ -23,13 +23,10 @@ pub unsafe fn paging_create< D: Disk, M: Iterator<Item=OsMemoryEntry>, V: Iterator<Item=OsVideoMode> ->(os: &mut dyn Os<D, M, V>, kernel_phys: usize) -> Option<usize> { +>(os: &mut dyn Os<D, M, V>, kernel_phys: usize, kernel_size: usize) -> Option<usize> { // Create PML4 let pml4 = paging_allocate(os)?; - // Recursive mapping for compatibility - pml4[511] = pml4.as_ptr() as u64 | 1 << 1 | 1; - { // Create PDP for identity mapping let pdp = paging_allocate(os)?; @@ -38,20 +35,15 @@ pub unsafe fn paging_create< pml4[0] = pdp.as_ptr() as u64 | 1 << 1 | 1; pml4[256] = pdp.as_ptr() as u64 | 1 << 1 | 1; - // Identity map 8 GiB pages + // Identity map 8 GiB using 2 MiB pages for pdp_i in 0..8 { let pd = paging_allocate(os)?; pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; for pd_i in 0..pd.len() { - let pt = paging_allocate(os)?; - pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1; - for pt_i in 0..pt.len() { - let addr = - pdp_i as u64 * 0x4000_0000 + - pd_i as u64 * 0x20_0000 + - pt_i as u64 * 0x1000; - pt[pt_i] = addr | 1 << 1 | 1; - } + let addr = + pdp_i as u64 * 0x4000_0000 + + pd_i as u64 * 0x20_0000; + pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; } } } @@ -63,23 +55,30 @@ pub unsafe fn paging_create< // Link second to last PML4 entry to PDP pml4[510] = pdp.as_ptr() as u64 | 1 << 1 | 1; - // Map 1 GiB at kernel offset - for pdp_i in 0..1 { + // Map kernel_size at kernel offset + let mut kernel_mapped = 0; + let mut pdp_i = 0; + while kernel_mapped < kernel_size && pdp_i < pdp.len() { let pd = paging_allocate(os)?; pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; - for pd_i in 0..pd.len() { + pdp_i += 1; + + let mut pd_i = 0; + while kernel_mapped < kernel_size && pd_i < pd.len(){ let pt = paging_allocate(os)?; pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1; - for pt_i in 0..pt.len() { - let addr = - pdp_i as u64 * 0x4000_0000 + - pd_i as u64 * 0x20_0000 + - pt_i as u64 * 0x1000 + - kernel_phys as u64; + pd_i += 1; + + let mut pt_i = 0; + while kernel_mapped < kernel_size && pt_i < pt.len() { + let addr = (kernel_phys + kernel_mapped) as u64; pt[pt_i] = addr | 1 << 1 | 1; + pt_i += 1; + kernel_mapped += 4096; } } } + assert!(kernel_mapped >= kernel_size); } Some(pml4.as_ptr() as usize) diff --git a/src/main.rs b/src/main.rs index f7ef087..557ecbe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -291,7 +291,7 @@ fn main< kernel }; - let page_phys = unsafe { paging_create(os, kernel.as_ptr() as usize) } + let page_phys = unsafe { paging_create(os, kernel.as_ptr() as usize, kernel.len()) } .expect("Failed to set up paging"); //TODO: properly reserve page table allocations so kernel does not re-use them -- GitLab