浏览代码

Free physical pages allocated for a process's page directory on exit.

Also use a ProcessPagingScope instead of region aliasing to implement
create-process ELF loading.
Andreas Kling 6 年之前
父节点
当前提交
90ddbca127
共有 8 个文件被更改,包括 113 次插入55 次删除
  1. 40 27
      Kernel/MemoryManager.cpp
  2. 14 8
      Kernel/MemoryManager.h
  3. 3 3
      Kernel/ProcFileSystem.cpp
  4. 7 13
      Kernel/Process.cpp
  5. 2 1
      Kernel/Process.h
  6. 44 2
      Kernel/init.cpp
  7. 2 0
      Kernel/types.h
  8. 1 1
      Userland/id.cpp

+ 40 - 27
Kernel/MemoryManager.cpp

@@ -17,7 +17,7 @@ MemoryManager& MM
 
 
 MemoryManager::MemoryManager()
 MemoryManager::MemoryManager()
 {
 {
-    m_kernel_page_directory = (dword*)0x5000;
+    m_kernel_page_directory = (PageDirectory*)0x4000;
     m_pageTableZero = (dword*)0x6000;
     m_pageTableZero = (dword*)0x6000;
     m_pageTableOne = (dword*)0x7000;
     m_pageTableOne = (dword*)0x7000;
 
 
@@ -32,10 +32,19 @@ MemoryManager::~MemoryManager()
 
 
 void MemoryManager::populate_page_directory(Process& process)
 void MemoryManager::populate_page_directory(Process& process)
 {
 {
-    memset(process.m_pageDirectory, 0, 4096);
+    memset(process.m_page_directory, 0, sizeof(PageDirectory));
+    process.m_page_directory[0] = m_kernel_page_directory[0];
+    process.m_page_directory[1] = m_kernel_page_directory[1];
+}
 
 
-    process.m_pageDirectory[0] = m_kernel_page_directory[0];
-    process.m_pageDirectory[1] = m_kernel_page_directory[1];
+void MemoryManager::release_page_directory(Process& process)
+{
+    ASSERT_INTERRUPTS_DISABLED();
+    for (size_t i = 0; i < 1024; ++i) {
+        auto paddr = process.m_page_directory->physical_addresses[i];
+        if (!paddr.is_null())
+            m_freePages.append(paddr);
+    }
 }
 }
 
 
 void MemoryManager::initializePaging()
 void MemoryManager::initializePaging()
@@ -44,7 +53,7 @@ void MemoryManager::initializePaging()
     static_assert(sizeof(MemoryManager::PageTableEntry) == 4);
     static_assert(sizeof(MemoryManager::PageTableEntry) == 4);
     memset(m_pageTableZero, 0, 4096);
     memset(m_pageTableZero, 0, 4096);
     memset(m_pageTableOne, 0, 4096);
     memset(m_pageTableOne, 0, 4096);
-    memset(m_kernel_page_directory, 0, 4096);
+    memset(m_kernel_page_directory, 0, 8192);
 
 
 #ifdef MM_DEBUG
 #ifdef MM_DEBUG
     kprintf("MM: Kernel page directory @ %p\n", m_kernel_page_directory);
     kprintf("MM: Kernel page directory @ %p\n", m_kernel_page_directory);
@@ -68,7 +77,7 @@ void MemoryManager::initializePaging()
     );
     );
 }
 }
 
 
-void* MemoryManager::allocatePageTable()
+void* MemoryManager::allocate_page_table()
 {
 {
     auto ppages = allocatePhysicalPages(1);
     auto ppages = allocatePhysicalPages(1);
     dword address = ppages[0].get();
     dword address = ppages[0].get();
@@ -77,39 +86,40 @@ void* MemoryManager::allocatePageTable()
     return (void*)address;
     return (void*)address;
 }
 }
 
 
-auto MemoryManager::ensurePTE(dword* page_directory, LinearAddress laddr) -> PageTableEntry
+auto MemoryManager::ensurePTE(PageDirectory* page_directory, LinearAddress laddr) -> PageTableEntry
 {
 {
     ASSERT_INTERRUPTS_DISABLED();
     ASSERT_INTERRUPTS_DISABLED();
-    dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
-    dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
+    dword page_directory_index = (laddr.get() >> 22) & 0x3ff;
+    dword page_table_index = (laddr.get() >> 12) & 0x3ff;
 
 
-    PageDirectoryEntry pde = PageDirectoryEntry(&page_directory[pageDirectoryIndex]);
+    PageDirectoryEntry pde = PageDirectoryEntry(&page_directory->entries[page_directory_index]);
     if (!pde.isPresent()) {
     if (!pde.isPresent()) {
 #ifdef MM_DEBUG
 #ifdef MM_DEBUG
-        dbgprintf("MM: PDE %u not present, allocating\n", pageDirectoryIndex);
+        dbgprintf("MM: PDE %u not present, allocating\n", page_directory_index);
 #endif
 #endif
-        if (pageDirectoryIndex == 0) {
+        if (page_directory_index == 0) {
             pde.setPageTableBase((dword)m_pageTableZero);
             pde.setPageTableBase((dword)m_pageTableZero);
             pde.setUserAllowed(false);
             pde.setUserAllowed(false);
             pde.setPresent(true);
             pde.setPresent(true);
             pde.setWritable(true);
             pde.setWritable(true);
-        } else if (pageDirectoryIndex == 1) {
+        } else if (page_directory_index == 1) {
             pde.setPageTableBase((dword)m_pageTableOne);
             pde.setPageTableBase((dword)m_pageTableOne);
             pde.setUserAllowed(false);
             pde.setUserAllowed(false);
             pde.setPresent(true);
             pde.setPresent(true);
             pde.setWritable(true);
             pde.setWritable(true);
         } else {
         } else {
-            auto* pageTable = allocatePageTable();
+            auto* page_table = allocate_page_table();
 #ifdef MM_DEBUG
 #ifdef MM_DEBUG
-            dbgprintf("MM: PDE %x allocated page table #%u (for laddr=%p) at %p\n", page_directory, pageDirectoryIndex, laddr.get(), pageTable);
+            dbgprintf("MM: PDE %x allocated page table #%u (for laddr=%p) at %p\n", page_directory, page_directory_index, laddr.get(), page_table);
 #endif
 #endif
-            pde.setPageTableBase((dword)pageTable);
+            page_directory->physical_addresses[page_directory_index] = PhysicalAddress((dword)page_table);
+            pde.setPageTableBase((dword)page_table);
             pde.setUserAllowed(true);
             pde.setUserAllowed(true);
             pde.setPresent(true);
             pde.setPresent(true);
             pde.setWritable(true);
             pde.setWritable(true);
         }
         }
     }
     }
-    return PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
+    return PageTableEntry(&pde.pageTableBase()[page_table_index]);
 }
 }
 
 
 void MemoryManager::protectMap(LinearAddress linearAddress, size_t length)
 void MemoryManager::protectMap(LinearAddress linearAddress, size_t length)
@@ -217,8 +227,8 @@ void MemoryManager::enter_kernel_paging_scope()
 void MemoryManager::enter_process_paging_scope(Process& process)
 void MemoryManager::enter_process_paging_scope(Process& process)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
-    current->m_tss.cr3 = (dword)process.m_pageDirectory;
-    asm volatile("movl %%eax, %%cr3"::"a"(process.m_pageDirectory));
+    current->m_tss.cr3 = (dword)process.m_page_directory;
+    asm volatile("movl %%eax, %%cr3"::"a"(process.m_page_directory));
 }
 }
 
 
 void MemoryManager::flushEntireTLB()
 void MemoryManager::flushEntireTLB()
@@ -234,7 +244,7 @@ void MemoryManager::flushTLB(LinearAddress laddr)
     asm volatile("invlpg %0": :"m" (*(char*)laddr.get()));
     asm volatile("invlpg %0": :"m" (*(char*)laddr.get()));
 }
 }
 
 
-void MemoryManager::map_region_at_address(dword* page_directory, Region& region, LinearAddress laddr, bool user_allowed)
+void MemoryManager::map_region_at_address(PageDirectory* page_directory, Region& region, LinearAddress laddr, bool user_allowed)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     auto& zone = *region.zone;
     auto& zone = *region.zone;
@@ -252,7 +262,7 @@ void MemoryManager::map_region_at_address(dword* page_directory, Region& region,
     }
     }
 }
 }
 
 
-void MemoryManager::unmap_range(dword* page_directory, LinearAddress laddr, size_t size)
+void MemoryManager::unmap_range(PageDirectory* page_directory, LinearAddress laddr, size_t size)
 {
 {
     ASSERT((size % PAGE_SIZE) == 0);
     ASSERT((size % PAGE_SIZE) == 0);
 
 
@@ -287,6 +297,9 @@ byte* MemoryManager::create_kernel_alias_for_region(Region& region)
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     auto laddr = allocate_linear_address_range(region.size);
     auto laddr = allocate_linear_address_range(region.size);
     map_region_at_address(m_kernel_page_directory, region, laddr, false);
     map_region_at_address(m_kernel_page_directory, region, laddr, false);
+#ifdef MM_DEBUG
+    dbgprintf("MM: Created alias L%x for L%x\n", laddr.get(), region.linearAddress.get());
+#endif
     return laddr.asPtr();
     return laddr.asPtr();
 }
 }
 
 
@@ -301,7 +314,7 @@ bool MemoryManager::unmapRegion(Process& process, Region& region)
     auto& zone = *region.zone;
     auto& zone = *region.zone;
     for (size_t i = 0; i < zone.m_pages.size(); ++i) {
     for (size_t i = 0; i < zone.m_pages.size(); ++i) {
         auto laddr = region.linearAddress.offset(i * PAGE_SIZE);
         auto laddr = region.linearAddress.offset(i * PAGE_SIZE);
-        auto pte = ensurePTE(process.m_pageDirectory, laddr);
+        auto pte = ensurePTE(process.m_page_directory, laddr);
         pte.setPhysicalPageBase(0);
         pte.setPhysicalPageBase(0);
         pte.setPresent(false);
         pte.setPresent(false);
         pte.setWritable(false);
         pte.setWritable(false);
@@ -321,7 +334,7 @@ bool MemoryManager::unmapSubregion(Process& process, Subregion& subregion)
     ASSERT(numPages);
     ASSERT(numPages);
     for (size_t i = 0; i < numPages; ++i) {
     for (size_t i = 0; i < numPages; ++i) {
         auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
         auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
-        auto pte = ensurePTE(process.m_pageDirectory, laddr);
+        auto pte = ensurePTE(process.m_page_directory, laddr);
         pte.setPhysicalPageBase(0);
         pte.setPhysicalPageBase(0);
         pte.setPresent(false);
         pte.setPresent(false);
         pte.setWritable(false);
         pte.setWritable(false);
@@ -344,7 +357,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion)
     ASSERT(numPages);
     ASSERT(numPages);
     for (size_t i = 0; i < numPages; ++i) {
     for (size_t i = 0; i < numPages; ++i) {
         auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
         auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
-        auto pte = ensurePTE(process.m_pageDirectory, laddr);
+        auto pte = ensurePTE(process.m_page_directory, laddr);
         pte.setPhysicalPageBase(zone.m_pages[firstPage + i].get());
         pte.setPhysicalPageBase(zone.m_pages[firstPage + i].get());
         pte.setPresent(true);
         pte.setPresent(true);
         pte.setWritable(true);
         pte.setWritable(true);
@@ -359,7 +372,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion)
 
 
 bool MemoryManager::mapRegion(Process& process, Region& region)
 bool MemoryManager::mapRegion(Process& process, Region& region)
 {
 {
-    map_region_at_address(process.m_pageDirectory, region, region.linearAddress, true);
+    map_region_at_address(process.m_page_directory, region, region.linearAddress, true);
     return true;
     return true;
 }
 }
 
 
@@ -367,7 +380,7 @@ bool MemoryManager::validate_user_read(const Process& process, LinearAddress lad
 {
 {
     dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
     dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
     dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
     dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
-    auto pde = PageDirectoryEntry(&process.m_pageDirectory[pageDirectoryIndex]);
+    auto pde = PageDirectoryEntry(&process.m_page_directory->entries[pageDirectoryIndex]);
     if (!pde.isPresent())
     if (!pde.isPresent())
         return false;
         return false;
     auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
     auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
@@ -382,7 +395,7 @@ bool MemoryManager::validate_user_write(const Process& process, LinearAddress la
 {
 {
     dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
     dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
     dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
     dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
-    auto pde = PageDirectoryEntry(&process.m_pageDirectory[pageDirectoryIndex]);
+    auto pde = PageDirectoryEntry(&process.m_page_directory->entries[pageDirectoryIndex]);
     if (!pde.isPresent())
     if (!pde.isPresent())
         return false;
         return false;
     auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
     auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);

+ 14 - 8
Kernel/MemoryManager.h

@@ -17,6 +17,11 @@ enum class PageFaultResponse {
     Continue,
     Continue,
 };
 };
 
 
+struct PageDirectory {
+    dword entries[1024];
+    PhysicalAddress physical_addresses[1024];
+};
+
 struct Zone : public Retainable<Zone> {
 struct Zone : public Retainable<Zone> {
     friend ByteBuffer procfs$mm();
     friend ByteBuffer procfs$mm();
 public:
 public:
@@ -78,6 +83,7 @@ public:
     void unregisterZone(Zone&);
     void unregisterZone(Zone&);
 
 
     void populate_page_directory(Process&);
     void populate_page_directory(Process&);
+    void release_page_directory(Process&);
 
 
     byte* create_kernel_alias_for_region(Region&);
     byte* create_kernel_alias_for_region(Region&);
     void remove_kernel_alias_for_region(Region&, byte*);
     void remove_kernel_alias_for_region(Region&, byte*);
@@ -93,14 +99,14 @@ private:
     ~MemoryManager();
     ~MemoryManager();
 
 
     LinearAddress allocate_linear_address_range(size_t);
     LinearAddress allocate_linear_address_range(size_t);
-    void map_region_at_address(dword* page_directory, Region&, LinearAddress, bool user_accessible);
-    void unmap_range(dword* page_directory, LinearAddress, size_t);
+    void map_region_at_address(PageDirectory*, Region&, LinearAddress, bool user_accessible);
+    void unmap_range(PageDirectory*, LinearAddress, size_t);
 
 
     void initializePaging();
     void initializePaging();
     void flushEntireTLB();
     void flushEntireTLB();
     void flushTLB(LinearAddress);
     void flushTLB(LinearAddress);
 
 
-    void* allocatePageTable();
+    void* allocate_page_table();
 
 
     void protectMap(LinearAddress, size_t length);
     void protectMap(LinearAddress, size_t length);
     void identityMap(LinearAddress, size_t length);
     void identityMap(LinearAddress, size_t length);
@@ -185,9 +191,9 @@ private:
         dword* m_pte;
         dword* m_pte;
     };
     };
 
 
-    PageTableEntry ensurePTE(dword* pageDirectory, LinearAddress);
+    PageTableEntry ensurePTE(PageDirectory*, LinearAddress);
 
 
-    dword* m_kernel_page_directory;
+    PageDirectory* m_kernel_page_directory;
     dword* m_pageTableZero;
     dword* m_pageTableZero;
     dword* m_pageTableOne;
     dword* m_pageTableOne;
 
 
@@ -203,7 +209,7 @@ struct KernelPagingScope {
     ~KernelPagingScope() { MM.enter_process_paging_scope(*current); }
     ~KernelPagingScope() { MM.enter_process_paging_scope(*current); }
 };
 };
 
 
-struct OtherProcessPagingScope {
-    OtherProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
-    ~OtherProcessPagingScope() { MM.enter_process_paging_scope(*current); }
+struct ProcessPagingScope {
+    ProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
+    ~ProcessPagingScope() { MM.enter_process_paging_scope(*current); }
 };
 };

+ 3 - 3
Kernel/ProcFileSystem.cpp

@@ -78,7 +78,7 @@ ByteBuffer procfs$pid_vm(Process& process)
 ByteBuffer procfs$pid_stack(Process& process)
 ByteBuffer procfs$pid_stack(Process& process)
 {
 {
     ProcessInspectionScope scope(process);
     ProcessInspectionScope scope(process);
-    OtherProcessPagingScope pagingScope(process);
+    ProcessPagingScope pagingScope(process);
     struct RecognizedSymbol {
     struct RecognizedSymbol {
         dword address;
         dword address;
         const KSym* ksym;
         const KSym* ksym;
@@ -147,14 +147,14 @@ ByteBuffer procfs$mm()
         zonePageCount += zone->m_pages.size();
         zonePageCount += zone->m_pages.size();
     auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_zones.size() + zonePageCount * 10);
     auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_zones.size() + zonePageCount * 10);
     char* ptr = (char*)buffer.pointer();
     char* ptr = (char*)buffer.pointer();
-    ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size());
-    ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size());
     for (auto* zone : MM.m_zones) {
     for (auto* zone : MM.m_zones) {
         ptr += ksprintf(ptr, "Zone %p size: %u\n  ", zone, zone->size());
         ptr += ksprintf(ptr, "Zone %p size: %u\n  ", zone, zone->size());
         for (auto page : zone->m_pages)
         for (auto page : zone->m_pages)
             ptr += ksprintf(ptr, "%x ", page);
             ptr += ksprintf(ptr, "%x ", page);
         ptr += ksprintf(ptr, "\n");
         ptr += ksprintf(ptr, "\n");
     }
     }
+    ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size());
+    ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size());
     buffer.trim(ptr - (char*)buffer.pointer());
     buffer.trim(ptr - (char*)buffer.pointer());
     return buffer;
     return buffer;
 }
 }

+ 7 - 13
Kernel/Process.cpp

@@ -285,22 +285,17 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
 
 
     ExecSpace space;
     ExecSpace space;
     Region* region = nullptr;
     Region* region = nullptr;
-    byte* region_alias = nullptr;
 
 
-    KernelPagingScope pagingScope;
+    ProcessPagingScope pagingScope(*t);
     space.hookableAlloc = [&] (const String& name, size_t size) {
     space.hookableAlloc = [&] (const String& name, size_t size) {
         if (!size)
         if (!size)
             return (void*)nullptr;
             return (void*)nullptr;
         size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
         size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
         region = t->allocateRegion(size, String(name));
         region = t->allocateRegion(size, String(name));
-        ASSERT(region);
-        region_alias = MM.create_kernel_alias_for_region(*region);
-        return (void*)region_alias;
+        return (void*)region->linearAddress.get();
     };
     };
     bool success = space.loadELF(move(elfData));
     bool success = space.loadELF(move(elfData));
     if (!success) {
     if (!success) {
-        if (region)
-            MM.remove_kernel_alias_for_region(*region, region_alias);
         delete t;
         delete t;
         kprintf("Failure loading ELF %s\n", path.characters());
         kprintf("Failure loading ELF %s\n", path.characters());
         error = -ENOEXEC;
         error = -ENOEXEC;
@@ -325,15 +320,12 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
     t->m_tss.eip = (dword)space.symbolPtr("_start");
     t->m_tss.eip = (dword)space.symbolPtr("_start");
     if (!t->m_tss.eip) {
     if (!t->m_tss.eip) {
         // FIXME: This is ugly. If we need to do this, it should be at a different level.
         // FIXME: This is ugly. If we need to do this, it should be at a different level.
-        if (region)
-            MM.remove_kernel_alias_for_region(*region, region_alias);
         delete t;
         delete t;
         error = -ENOEXEC;
         error = -ENOEXEC;
         return nullptr;
         return nullptr;
     }
     }
 
 
     ASSERT(region);
     ASSERT(region);
-    MM.remove_kernel_alias_for_region(*region, region_alias);
 
 
     ProcFileSystem::the().addProcess(*t);
     ProcFileSystem::the().addProcess(*t);
 
 
@@ -414,7 +406,7 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
     , m_tty(tty)
     , m_tty(tty)
     , m_parentPID(parentPID)
     , m_parentPID(parentPID)
 {
 {
-    m_pageDirectory = (dword*)kmalloc_page_aligned(4096);
+    m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory));
     MM.populate_page_directory(*this);
     MM.populate_page_directory(*this);
 
 
     m_file_descriptors.resize(m_max_open_file_descriptors);
     m_file_descriptors.resize(m_max_open_file_descriptors);
@@ -456,7 +448,7 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
     m_tss.ss = ss;
     m_tss.ss = ss;
     m_tss.cs = cs;
     m_tss.cs = cs;
 
 
-    m_tss.cr3 = (dword)m_pageDirectory;
+    m_tss.cr3 = (dword)m_page_directory;
 
 
     if (isRing0()) {
     if (isRing0()) {
         // FIXME: This memory is leaked.
         // FIXME: This memory is leaked.
@@ -502,6 +494,8 @@ Process::~Process()
         kfree(m_kernelStack);
         kfree(m_kernelStack);
         m_kernelStack = nullptr;
         m_kernelStack = nullptr;
     }
     }
+
+    MM.release_page_directory(*this);
 }
 }
 
 
 void Process::dumpRegions()
 void Process::dumpRegions()
@@ -610,9 +604,9 @@ void Process::processDidCrash(Process* crashedProcess)
 
 
 void Process::doHouseKeeping()
 void Process::doHouseKeeping()
 {
 {
-    InterruptDisabler disabler;
     if (s_deadProcesses->isEmpty())
     if (s_deadProcesses->isEmpty())
         return;
         return;
+    InterruptDisabler disabler;
     Process* next = nullptr;
     Process* next = nullptr;
     for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
     for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
         next = deadProcess->next();
         next = deadProcess->next();

+ 2 - 1
Kernel/Process.h

@@ -10,6 +10,7 @@
 #include "TTY.h"
 #include "TTY.h"
 
 
 class FileHandle;
 class FileHandle;
+class PageDirectory;
 class Region;
 class Region;
 class Subregion;
 class Subregion;
 class Zone;
 class Zone;
@@ -149,7 +150,7 @@ private:
 
 
     void allocateLDT();
     void allocateLDT();
 
 
-    dword* m_pageDirectory { nullptr };
+    PageDirectory* m_page_directory { nullptr };
 
 
     Process* m_prev { nullptr };
     Process* m_prev { nullptr };
     Process* m_next { nullptr };
     Process* m_next { nullptr };

+ 44 - 2
Kernel/init.cpp

@@ -49,13 +49,20 @@ static byte parseHexDigit(char nibble)
     return 10 + (nibble - 'a');
     return 10 + (nibble - 'a');
 }
 }
 
 
+#ifdef KSYMS
 static Vector<KSym, KmallocEternalAllocator>* s_ksyms;
 static Vector<KSym, KmallocEternalAllocator>* s_ksyms;
+static bool s_ksyms_ready;
 
 
 Vector<KSym, KmallocEternalAllocator>& ksyms()
 Vector<KSym, KmallocEternalAllocator>& ksyms()
 {
 {
     return *s_ksyms;
     return *s_ksyms;
 }
 }
 
 
+volatile bool ksyms_ready()
+{
+    return s_ksyms_ready;
+}
+
 const KSym* ksymbolicate(dword address)
 const KSym* ksymbolicate(dword address)
 {
 {
     if (address < ksyms().first().address || address > ksyms().last().address)
     if (address < ksyms().first().address || address > ksyms().last().address)
@@ -90,7 +97,37 @@ static void loadKsyms(const ByteBuffer& buffer)
         ksyms().append({ address, String(startOfName, bufptr - startOfName) });
         ksyms().append({ address, String(startOfName, bufptr - startOfName) });
         ++bufptr;
         ++bufptr;
     }
     }
+    s_ksyms_ready = true;
+}
+
+void dump_backtrace()
+{
+    if (!current)
+        return;
+    extern volatile bool ksyms_ready();
+    if (!ksyms_ready())
+        return;
+    dword stack_variable;
+    struct RecognizedSymbol {
+        dword address;
+        const KSym* ksym;
+    };
+    Vector<RecognizedSymbol> recognizedSymbols;
+    for (dword* stackPtr = &stack_variable; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) {
+        dword retaddr = stackPtr[1];
+        if (auto* ksym = ksymbolicate(retaddr))
+            recognizedSymbols.append({ retaddr, ksym });
+    }
+    size_t bytesNeeded = 0;
+    for (auto& symbol : recognizedSymbols) {
+        bytesNeeded += symbol.ksym->name.length() + 8 + 16;
+    }
+    for (auto& symbol : recognizedSymbols) {
+        unsigned offset = symbol.address - symbol.ksym->address;
+        dbgprintf("%p  %s +%u\n", symbol.address, symbol.ksym->name.characters(), offset);
+    }
 }
 }
+#endif
 
 
 static void undertaker_main() NORETURN;
 static void undertaker_main() NORETURN;
 static void undertaker_main()
 static void undertaker_main()
@@ -109,8 +146,8 @@ static void spawn_stress()
     for (unsigned i = 0; i < 10000; ++i) {
     for (unsigned i = 0; i < 10000; ++i) {
         int error;
         int error;
         Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
         Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
-        kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal);
-        kprintf("delta:%u\n", sum_alloc - lastAlloc);
+//        kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal);
+//        kprintf("delta:%u\n", sum_alloc - lastAlloc);
         lastAlloc = sum_alloc;
         lastAlloc = sum_alloc;
         sleep(60);
         sleep(60);
     }
     }
@@ -223,6 +260,11 @@ void init()
 {
 {
     cli();
     cli();
 
 
+#ifdef KSYMS
+    s_ksyms = nullptr;
+    s_ksyms_ready = false;
+#endif
+
     kmalloc_init();
     kmalloc_init();
     vga_init();
     vga_init();
 
 

+ 2 - 0
Kernel/types.h

@@ -66,6 +66,8 @@ public:
     void set(dword address) { m_address = address; }
     void set(dword address) { m_address = address; }
     void mask(dword m) { m_address &= m; }
     void mask(dword m) { m_address &= m; }
 
 
+    bool is_null() const { return m_address == 0; }
+
     byte* asPtr() { return reinterpret_cast<byte*>(m_address); }
     byte* asPtr() { return reinterpret_cast<byte*>(m_address); }
     const byte* asPtr() const { return reinterpret_cast<const byte*>(m_address); }
     const byte* asPtr() const { return reinterpret_cast<const byte*>(m_address); }
 
 

+ 1 - 1
Userland/id.cpp

@@ -9,7 +9,7 @@ int main(int c, char** v)
 
 
     struct passwd* pw = getpwuid(uid);
     struct passwd* pw = getpwuid(uid);
 
 
-    printf("uid=%u(%s), gid=%u\n", uid, pw ? pw->pw_name : "n/a", gid);
+    printf("uid=%u(%s), gid=%u, pid=%u\n", uid, pw ? pw->pw_name : "n/a", gid, getpid());
     return 0;
     return 0;
 }
 }