diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Arch/i386/Boot/boot.S | 100 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 70 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.h | 2 |
3 files changed, 74 insertions, 98 deletions
diff --git a/Kernel/Arch/i386/Boot/boot.S b/Kernel/Arch/i386/Boot/boot.S index 7646585453..9289cb5a5f 100644 --- a/Kernel/Arch/i386/Boot/boot.S +++ b/Kernel/Arch/i386/Boot/boot.S @@ -42,8 +42,14 @@ boot_pd0: .global boot_pd3 boot_pd3: .skip 4096 -.global boot_pd3_pde1023_pt -boot_pd3_pde1023_pt: +.global boot_pd0_pt0 +boot_pd0_pt0: +.skip 4096 * 4 +.global boot_pd3_pts +boot_pd3_pts: +.skip 4096 * 4 +.global boot_pd3_pt1023 +boot_pd3_pt1023: .skip 4096 .section .text @@ -69,18 +75,18 @@ pdpt boot_pd0 : 512 pde's - 0: (0-2MB) (id 2MB page) - 1: (2-4MB) (id 2MB page) - 2: (4-6MB) (id 2MB page) - 3: (6-8MB) (id 2MB page) + 0: boot_pd0_pt0 (0-2MB) (id 512 4KB pages) boot_pd3 : 512 pde's - 0: boot_pd3_pde0 (3072-3074MB) (pseudo) - 1: boot_pd3_pde1 (3074-3076MB) (pseudo) - 2: boot_pd3_pde2 (3076-3078MB) (pseudo) - 3: boot_pd3_pde3 (3078-3080MB) (pseudo) - 4: boot_pd3_pde1023_pt (4094-4096MB) (for page table mappings) + 0: boot_pd3_pts[0] (3072-3074MB) (pseudo 512 4KB pages) + 1: boot_pd3_pts[1] (3074-3076MB) (pseudo 512 4KB pages) + 2: boot_pd3_pts[2] (3076-3078MB) (pseudo 512 4KB pages) + 3: boot_pd3_pts[3] (3078-3080MB) (pseudo 512 4KB pages) + 4: boot_pd3_pt1023 (4094-4096MB) (for page table mappings) + +the 9 page tables each contain 512 pte's that map individual 4KB pages + */ start: @@ -104,41 +110,74 @@ start: xorl %eax, %eax rep stosl - /* identity map bottom 8MB using 2MB pages (only PDE, no PTE) */ - movl $4, %ecx + /* clear pd3 */ + movl $(boot_pd3 - 0xc0000000), %edi + movl $1024, %ecx + xorl %eax, %eax + rep stosl + + /* clear pd0's pt's */ + movl $(boot_pd0_pt0 - 0xc0000000), %edi + movl $(1024 * 4), %ecx xorl %eax, %eax + rep stosl + + /* clear pd3's pt's */ + movl $(boot_pd3_pts - 0xc0000000), %edi + movl $(1024 * 5), %ecx + xorl %eax, %eax + rep stosl + + /* add boot_pd0_pt0 to boot_pd0 */ movl $(boot_pd0 - 0xc0000000), %edi -1: + movl $(boot_pd0_pt0 - 0xc0000000), %eax movl %eax, 0(%edi) - /* PS(2MB) + R/W + Present */ - orl $0x83, 0(%edi) + /* R/W + Present */ + orl $0x3, 0(%edi) + + /* add boot_pd3_pts to boot_pd3 */ + movl $4, %ecx + movl $(boot_pd3 - 0xc0000000), %edi + movl $(boot_pd3_pts - 0xc0000000), %eax +1: + movl %eax, 0(%edi) + /* R/W + Present */ + orl $0x3, 0(%edi) addl $8, %edi - addl $(1048576 * 2), %eax + addl $4096, %eax loop 1b - /* clear pd3 */ - movl $(boot_pd3 - 0xc0000000), %edi - movl $1024, %ecx + /* identity map the 0 to 2MB range */ + movl $512, %ecx + movl $(boot_pd0_pt0 - 0xc0000000), %edi + /*movl $0x100000, %eax*/ xorl %eax, %eax - rep stosl - /* pseudo-identity map first 8MB above 3GB mark using 2MB pages again */ - movl $4, %ecx - xorl %eax, %eax - movl $(boot_pd3 - 0xc0000000), %edi 1: movl %eax, 0(%edi) - /* PS(2MB) + R/W + Present */ - orl $0x83, 0(%edi) + /* R/W + Present */ + orl $0x3, 0(%edi) + addl $8, %edi + addl $4096, %eax + loop 1b + + /* pseudo identity map the 3072-3080MB range */ + movl $(512 * 4), %ecx + movl $(boot_pd3_pts - 0xc0000000), %edi + xorl %eax, %eax +1: + movl %eax, 0(%edi) + /* R/W + Present */ + orl $0x3, 0(%edi) addl $8, %edi - addl $(1048576 * 2), %eax + addl $4096, %eax loop 1b /* create an empty page table for the top 2MB at the 4GB mark */ movl $(boot_pd3 - 0xc0000000), %edi - movl $(boot_pd3_pde1023_pt - 0xc0000000), 4088(%edi) + movl $(boot_pd3_pt1023 - 0xc0000000), 4088(%edi) orl $0x3, 4088(%edi) movl $0, 4092(%edi) @@ -158,10 +197,9 @@ start: /* jmp to an address above the 3GB mark */ push %cs - push $1f + push $1f retf 1: - movl %cr3, %eax movl %eax, %cr3 diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 29936251d6..2611f63d4e 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -62,8 +62,6 @@ MemoryManager::MemoryManager() m_kernel_page_directory = PageDirectory::create_kernel_page_directory(); parse_memory_map(); write_cr3(kernel_page_directory().cr3()); - setup_low_identity_mapping(); - setup_low_pseudo_identity_mapping(); protect_kernel_image(); m_shared_zero_page = allocate_user_physical_page(); @@ -73,36 +71,6 @@ MemoryManager::~MemoryManager() { } -void MemoryManager::setup_low_pseudo_identity_mapping() -{ - // This code switches the pseudo-identity mapping (8 first MB above 3G mark) from 2MB pages to 4KB pages. - // The boot code sets it up as 2MB huge pages for convenience. But we need 4KB pages to be able to protect - // the kernel soon! - - for (size_t i = 0; i < 4; ++i) { - m_low_pseudo_identity_mapping_pages[i] = allocate_supervisor_physical_page(); - FlatPtr base = i * (2 * MB); - auto* page_table = (PageTableEntry*)quickmap_page(*m_low_pseudo_identity_mapping_pages[i]); - for (size_t j = 0; j < 512; ++j) { - auto& pte = page_table[j]; - pte.set_physical_page_base(base + j * PAGE_SIZE); - pte.set_writable(true); - pte.set_present(true); - pte.set_execute_disabled(false); - pte.set_user_allowed(false); - } - unquickmap_page(); - } - - auto* pd = quickmap_pd(*m_kernel_page_directory, 3); - for (size_t i = 0; i < 4; ++i) { - pd[i].set_huge(false); - pd[i].set_page_table_base(m_low_pseudo_identity_mapping_pages[i]->paddr().get()); - } - - flush_entire_tlb(); -} - void MemoryManager::protect_kernel_image() { // Disable writing to the kernel text and rodata segments. @@ -120,34 +88,6 @@ void MemoryManager::protect_kernel_image() } } -void MemoryManager::setup_low_identity_mapping() -{ - m_low_page_table = allocate_user_physical_page(ShouldZeroFill::Yes); - - auto* pd_zero = quickmap_pd(kernel_page_directory(), 0); - pd_zero[1].set_present(false); - pd_zero[2].set_present(false); - pd_zero[3].set_present(false); - - auto& pde_zero = pd_zero[0]; - pde_zero.set_page_table_base(m_low_page_table->paddr().get()); - pde_zero.set_present(true); - pde_zero.set_huge(false); - pde_zero.set_writable(true); - pde_zero.set_user_allowed(false); - if (g_cpu_supports_nx) - pde_zero.set_execute_disabled(true); - - for (FlatPtr offset = (1 * MB); offset < (2 * MB); offset += PAGE_SIZE) { - auto& page_table_page = m_low_page_table; - auto& pte = quickmap_pt(page_table_page->paddr())[offset / PAGE_SIZE]; - pte.set_physical_page_base(offset); - pte.set_user_allowed(false); - pte.set_present(offset != 0); - pte.set_writable(offset < (1 * MB)); - } -} - void MemoryManager::parse_memory_map() { RefPtr<PhysicalRegion> region; @@ -574,11 +514,11 @@ void MemoryManager::flush_tlb(VirtualAddress vaddr) : "memory"); } -extern "C" PageTableEntry boot_pd3_pde1023_pt[1024]; +extern "C" PageTableEntry boot_pd3_pt1023[1024]; PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t pdpt_index) { - auto& pte = boot_pd3_pde1023_pt[4]; + auto& pte = boot_pd3_pt1023[4]; auto pd_paddr = directory.m_directory_pages[pdpt_index]->paddr(); if (pte.physical_page_base() != pd_paddr.as_ptr()) { #ifdef MM_DEBUG @@ -595,7 +535,7 @@ PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t PageTableEntry* MemoryManager::quickmap_pt(PhysicalAddress pt_paddr) { - auto& pte = boot_pd3_pde1023_pt[8]; + auto& pte = boot_pd3_pt1023[8]; if (pte.physical_page_base() != pt_paddr.as_ptr()) { #ifdef MM_DEBUG dbg() << "quickmap_pt: Mapping P" << (void*)pt_paddr.as_ptr() << " at 0xffe08000 in pte @ " << &pte; @@ -615,7 +555,7 @@ u8* MemoryManager::quickmap_page(PhysicalPage& physical_page) ASSERT(!m_quickmap_in_use); m_quickmap_in_use = true; - auto& pte = boot_pd3_pde1023_pt[0]; + auto& pte = boot_pd3_pt1023[0]; if (pte.physical_page_base() != physical_page.paddr().as_ptr()) { #ifdef MM_DEBUG dbg() << "quickmap_page: Mapping P" << (void*)physical_page.paddr().as_ptr() << " at 0xffe00000 in pte @ " << &pte; @@ -633,7 +573,7 @@ void MemoryManager::unquickmap_page() { ASSERT_INTERRUPTS_DISABLED(); ASSERT(m_quickmap_in_use); - auto& pte = boot_pd3_pde1023_pt[0]; + auto& pte = boot_pd3_pt1023[0]; pte.clear(); flush_tlb(VirtualAddress(0xffe00000)); m_quickmap_in_use = false; diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index f4293fff35..35c954df5b 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -160,8 +160,6 @@ private: void unregister_region(Region&); void detect_cpu_features(); - void setup_low_identity_mapping(); - void setup_low_pseudo_identity_mapping(); void protect_kernel_image(); void parse_memory_map(); void flush_entire_tlb(); |