From 83bc8a0da5d323bc5769116864edf6f8924b7abe Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 14 Sep 2016 20:47:55 -0600 Subject: [PATCH] Higher-half kernel mapping. Unmap where possible, freeing up lower memory --- arch/x86_64/src/acpi/mod.rs | 72 ++++++++++++++++++++-------- arch/x86_64/src/device/display.rs | 6 ++- arch/x86_64/src/linker.ld | 4 +- arch/x86_64/src/paging/mod.rs | 12 ++--- arch/x86_64/src/start.rs | 2 +- bootloader/x86_64/startup-x86_64.asm | 1 + kernel/syscall/process.rs | 1 + 7 files changed, 68 insertions(+), 30 deletions(-) diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs index ffe4ae9..b23a461 100644 --- a/arch/x86_64/src/acpi/mod.rs +++ b/arch/x86_64/src/acpi/mod.rs @@ -43,6 +43,13 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { println!(" XAPIC {}: {:>08X}", me, local_apic.address); } + let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE)); + let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE)); + + // Map trampoline + active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE); + active_table.flush(trampoline_page); + for madt_entry in madt.iter() { println!(" {:?}", madt_entry); match madt_entry { @@ -50,13 +57,6 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { println!(" This is my local APIC"); } else { if ap_local_apic.flags & 1 == 1 { - // Map trampoline - { - if active_table.translate_page(Page::containing_address(VirtualAddress::new(TRAMPOLINE))).is_none() { - active_table.identity_map(Frame::containing_address(PhysicalAddress::new(TRAMPOLINE)), entry::PRESENT | entry::WRITABLE); - } - } - // Allocate a stack // TODO: Allocate contiguous let stack_start = allocate_frame().expect("no more frames in acpi stack_start").start_address().get(); @@ -128,6 +128,10 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { _ => () } } + + // Unmap trampoline + active_table.unmap(trampoline_page); + active_table.flush(trampoline_page); } else { println!(": Unknown"); } @@ -138,28 +142,43 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option { let start_addr = 0xE0000; let end_addr = 0xFFFFF; - // Map all of the ACPI table space + // Map all of the ACPI RSDT space { let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr)); let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr)); for frame in Frame::range_inclusive(start_frame, end_frame) { - if active_table.translate_page(Page::containing_address(VirtualAddress::new(frame.start_address().get()))).is_none() { - active_table.identity_map(frame, entry::PRESENT | entry::NO_EXECUTE); - } + let page = Page::containing_address(VirtualAddress::new(frame.start_address().get())); + active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE); + active_table.flush(page); } } // Search for RSDP if let Some(rsdp) = RSDP::search(start_addr, end_addr) { - let get_sdt = |sdt_address: usize, active_table: &mut ActivePageTable| -> &'static Sdt { - if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() { + let get_sdt = |sdt_address: usize, active_table: &mut ActivePageTable| -> (&'static Sdt, bool) { + let mapped = if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() { let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address)); - active_table.identity_map(sdt_frame, entry::PRESENT | entry::NO_EXECUTE); - } - &*(sdt_address as *const Sdt) + let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address)); + active_table.map_to(sdt_page, sdt_frame, entry::PRESENT | entry::NO_EXECUTE); + active_table.flush(sdt_page); + true + } else { + false + }; + (&*(sdt_address as *const Sdt), mapped) }; - let rxsdt = get_sdt(rsdp.sdt_address(), active_table); + let drop_sdt = |sdt: &'static Sdt, mapped: bool, active_table: &mut ActivePageTable| { + let sdt_address = sdt as *const Sdt as usize; + drop(sdt); + if mapped { + let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address)); + active_table.unmap(sdt_page); + active_table.flush(sdt_page); + } + }; + + let (rxsdt, rxmapped) = get_sdt(rsdp.sdt_address(), active_table); for &c in rxsdt.signature.iter() { print!("{}", c as char); @@ -167,21 +186,36 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option { println!(":"); if let Some(rsdt) = Rsdt::new(rxsdt) { for sdt_address in rsdt.iter() { - let sdt = get_sdt(sdt_address, active_table); + let (sdt, mapped) = get_sdt(sdt_address, active_table); init_sdt(sdt, active_table); + drop_sdt(sdt, mapped, active_table); } } else if let Some(xsdt) = Xsdt::new(rxsdt) { for sdt_address in xsdt.iter() { - let sdt = get_sdt(sdt_address, active_table); + let (sdt, mapped) = get_sdt(sdt_address, active_table); init_sdt(sdt, active_table); + drop_sdt(sdt, mapped, active_table); } } else { println!("UNKNOWN RSDT OR XSDT SIGNATURE"); } + + drop_sdt(rxsdt, rxmapped, active_table); } else { println!("NO RSDP FOUND"); } + // Unmap all of the ACPI RSDT space + { + let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr)); + let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr)); + for frame in Frame::range_inclusive(start_frame, end_frame) { + let page = Page::containing_address(VirtualAddress::new(frame.start_address().get())); + active_table.unmap(page); + active_table.flush(page); + } + } + None } diff --git a/arch/x86_64/src/device/display.rs b/arch/x86_64/src/device/display.rs index d5e9523..f671475 100644 --- a/arch/x86_64/src/device/display.rs +++ b/arch/x86_64/src/device/display.rs @@ -3,7 +3,7 @@ use ransid::{Console, Event}; use spin::Mutex; use memory::Frame; -use paging::{ActivePageTable, PhysicalAddress, entry}; +use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress, entry}; #[cfg(target_arch = "x86_64")] #[allow(unused_assignments)] @@ -117,6 +117,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { )); *CONSOLE.lock() = Some(Console::new(width/8, height/16)); } + + active_table.unmap(Page::containing_address(VirtualAddress::new(0x5200))); } pub unsafe fn init_ap(active_table: &mut ActivePageTable) { @@ -137,6 +139,8 @@ pub unsafe fn init_ap(active_table: &mut ActivePageTable) { } } } + + active_table.unmap(Page::containing_address(VirtualAddress::new(0x5200))); } /// A display diff --git a/arch/x86_64/src/linker.ld b/arch/x86_64/src/linker.ld index c8c932f..546adaa 100644 --- a/arch/x86_64/src/linker.ld +++ b/arch/x86_64/src/linker.ld @@ -1,8 +1,8 @@ ENTRY(kstart) OUTPUT_FORMAT(elf64-x86-64) -/* KERNEL_OFFSET = 0xffffff0000100000; */ -KERNEL_OFFSET = 0x100000; +KERNEL_OFFSET = 0xffffff0000100000; +/* KERNEL_OFFSET = 0x100000; */ SECTIONS { . = KERNEL_OFFSET; diff --git a/arch/x86_64/src/paging/mod.rs b/arch/x86_64/src/paging/mod.rs index c321534..dc1e180 100644 --- a/arch/x86_64/src/paging/mod.rs +++ b/arch/x86_64/src/paging/mod.rs @@ -78,25 +78,23 @@ pub unsafe fn init(cpu_id: usize, stack_start: usize, stack_end: usize) -> (Acti } } - let mut remap = |start: usize, end: usize, flags: EntryFlags| { + let mut remap = |start: usize, end: usize, flags: EntryFlags, offset: usize| { if end > start { let start_frame = Frame::containing_address(PhysicalAddress::new(start)); let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1)); for frame in Frame::range_inclusive(start_frame, end_frame) { - mapper.identity_map(frame.clone(), flags); - - //let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET)); - //mapper.map_to(page, frame, flags); + let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + offset)); + mapper.map_to(page, frame, flags); } } }; // Remap stack writable, no execute - remap(stack_start, stack_end, PRESENT | NO_EXECUTE | WRITABLE); + remap(stack_start, stack_end, PRESENT | NO_EXECUTE | WRITABLE, 0); // Remap a section with `flags` let mut remap_section = |start: &u8, end: &u8, flags: EntryFlags| { - remap(start as *const _ as usize, end as *const _ as usize, flags); + remap(start as *const _ as usize - ::KERNEL_OFFSET, end as *const _ as usize - ::KERNEL_OFFSET, flags, ::KERNEL_OFFSET); }; // Remap text read-only remap_section(& __text_start, & __text_end, PRESENT); diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index df30403..5e4ad22 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -65,7 +65,7 @@ pub unsafe extern fn kstart() -> ! { } // Initialize memory management - memory::init(0, &__end as *const u8 as usize); + memory::init(0, &__end as *const u8 as usize - ::KERNEL_OFFSET); // TODO: allocate a stack let stack_start = 0x00080000; diff --git a/bootloader/x86_64/startup-x86_64.asm b/bootloader/x86_64/startup-x86_64.asm index 9cb683b..d5a0a79 100644 --- a/bootloader/x86_64/startup-x86_64.asm +++ b/bootloader/x86_64/startup-x86_64.asm @@ -126,6 +126,7 @@ long_mode: ;rust init mov rax, [kernel_base + 0x18] + xchg bx, bx jmp rax long_mode_ap: diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 9c3e5b4..c7ff1ee 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -79,6 +79,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { stack.start_address().get() as *const u8, stack.size()); } + new_stack.unmap(true); stack_option = Some(new_stack); } }