Explorar el Código

Kernel: Create page structures correctly in boot.s

etaIneLp hace 5 años
padre
commit
826dc94187
Se han modificado 3 ficheros con 74 adiciones y 98 borrados
  1. 69 31
      Kernel/Arch/i386/Boot/boot.S
  2. 5 65
      Kernel/VM/MemoryManager.cpp
  3. 0 2
      Kernel/VM/MemoryManager.h

+ 69 - 31
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
 

+ 5 - 65
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;

+ 0 - 2
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();