mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-30 05:42:37 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									c70afd045e
								
							
						
					
					
						commit
						90ddbca127
					
				
					 8 changed files with 113 additions and 55 deletions
				
			
		|  | @ -17,7 +17,7 @@ MemoryManager& MM | |||
| 
 | ||||
| MemoryManager::MemoryManager() | ||||
| { | ||||
|     m_kernel_page_directory = (dword*)0x5000; | ||||
|     m_kernel_page_directory = (PageDirectory*)0x4000; | ||||
|     m_pageTableZero = (dword*)0x6000; | ||||
|     m_pageTableOne = (dword*)0x7000; | ||||
| 
 | ||||
|  | @ -32,10 +32,19 @@ MemoryManager::~MemoryManager() | |||
| 
 | ||||
| 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() | ||||
|  | @ -44,7 +53,7 @@ void MemoryManager::initializePaging() | |||
|     static_assert(sizeof(MemoryManager::PageTableEntry) == 4); | ||||
|     memset(m_pageTableZero, 0, 4096); | ||||
|     memset(m_pageTableOne, 0, 4096); | ||||
|     memset(m_kernel_page_directory, 0, 4096); | ||||
|     memset(m_kernel_page_directory, 0, 8192); | ||||
| 
 | ||||
| #ifdef MM_DEBUG | ||||
|     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); | ||||
|     dword address = ppages[0].get(); | ||||
|  | @ -77,39 +86,40 @@ void* MemoryManager::allocatePageTable() | |||
|     return (void*)address; | ||||
| } | ||||
| 
 | ||||
| auto MemoryManager::ensurePTE(dword* page_directory, LinearAddress laddr) -> PageTableEntry | ||||
| auto MemoryManager::ensurePTE(PageDirectory* page_directory, LinearAddress laddr) -> PageTableEntry | ||||
| { | ||||
|     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()) { | ||||
| #ifdef MM_DEBUG | ||||
|         dbgprintf("MM: PDE %u not present, allocating\n", pageDirectoryIndex); | ||||
|         dbgprintf("MM: PDE %u not present, allocating\n", page_directory_index); | ||||
| #endif | ||||
|         if (pageDirectoryIndex == 0) { | ||||
|         if (page_directory_index == 0) { | ||||
|             pde.setPageTableBase((dword)m_pageTableZero); | ||||
|             pde.setUserAllowed(false); | ||||
|             pde.setPresent(true); | ||||
|             pde.setWritable(true); | ||||
|         } else if (pageDirectoryIndex == 1) { | ||||
|         } else if (page_directory_index == 1) { | ||||
|             pde.setPageTableBase((dword)m_pageTableOne); | ||||
|             pde.setUserAllowed(false); | ||||
|             pde.setPresent(true); | ||||
|             pde.setWritable(true); | ||||
|         } else { | ||||
|             auto* pageTable = allocatePageTable(); | ||||
|             auto* page_table = allocate_page_table(); | ||||
| #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 | ||||
|             pde.setPageTableBase((dword)pageTable); | ||||
|             page_directory->physical_addresses[page_directory_index] = PhysicalAddress((dword)page_table); | ||||
|             pde.setPageTableBase((dword)page_table); | ||||
|             pde.setUserAllowed(true); | ||||
|             pde.setPresent(true); | ||||
|             pde.setWritable(true); | ||||
|         } | ||||
|     } | ||||
|     return PageTableEntry(&pde.pageTableBase()[pageTableIndex]); | ||||
|     return PageTableEntry(&pde.pageTableBase()[page_table_index]); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
|     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() | ||||
|  | @ -234,7 +244,7 @@ void MemoryManager::flushTLB(LinearAddress laddr) | |||
|     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; | ||||
|     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); | ||||
| 
 | ||||
|  | @ -287,6 +297,9 @@ byte* MemoryManager::create_kernel_alias_for_region(Region& region) | |||
|     InterruptDisabler disabler; | ||||
|     auto laddr = allocate_linear_address_range(region.size); | ||||
|     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(); | ||||
| } | ||||
| 
 | ||||
|  | @ -301,7 +314,7 @@ bool MemoryManager::unmapRegion(Process& process, Region& region) | |||
|     auto& zone = *region.zone; | ||||
|     for (size_t i = 0; i < zone.m_pages.size(); ++i) { | ||||
|         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.setPresent(false); | ||||
|         pte.setWritable(false); | ||||
|  | @ -321,7 +334,7 @@ bool MemoryManager::unmapSubregion(Process& process, Subregion& subregion) | |||
|     ASSERT(numPages); | ||||
|     for (size_t i = 0; i < numPages; ++i) { | ||||
|         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.setPresent(false); | ||||
|         pte.setWritable(false); | ||||
|  | @ -344,7 +357,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion) | |||
|     ASSERT(numPages); | ||||
|     for (size_t i = 0; i < numPages; ++i) { | ||||
|         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.setPresent(true); | ||||
|         pte.setWritable(true); | ||||
|  | @ -359,7 +372,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion) | |||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
|  | @ -367,7 +380,7 @@ bool MemoryManager::validate_user_read(const Process& process, LinearAddress lad | |||
| { | ||||
|     dword pageDirectoryIndex = (laddr.get() >> 22) & 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()) | ||||
|         return false; | ||||
|     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 pageTableIndex = (laddr.get() >> 12) & 0x3ff; | ||||
|     auto pde = PageDirectoryEntry(&process.m_pageDirectory[pageDirectoryIndex]); | ||||
|     auto pde = PageDirectoryEntry(&process.m_page_directory->entries[pageDirectoryIndex]); | ||||
|     if (!pde.isPresent()) | ||||
|         return false; | ||||
|     auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]); | ||||
|  |  | |||
|  | @ -17,6 +17,11 @@ enum class PageFaultResponse { | |||
|     Continue, | ||||
| }; | ||||
| 
 | ||||
| struct PageDirectory { | ||||
|     dword entries[1024]; | ||||
|     PhysicalAddress physical_addresses[1024]; | ||||
| }; | ||||
| 
 | ||||
| struct Zone : public Retainable<Zone> { | ||||
|     friend ByteBuffer procfs$mm(); | ||||
| public: | ||||
|  | @ -78,6 +83,7 @@ public: | |||
|     void unregisterZone(Zone&); | ||||
| 
 | ||||
|     void populate_page_directory(Process&); | ||||
|     void release_page_directory(Process&); | ||||
| 
 | ||||
|     byte* create_kernel_alias_for_region(Region&); | ||||
|     void remove_kernel_alias_for_region(Region&, byte*); | ||||
|  | @ -93,14 +99,14 @@ private: | |||
|     ~MemoryManager(); | ||||
| 
 | ||||
|     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 flushEntireTLB(); | ||||
|     void flushTLB(LinearAddress); | ||||
| 
 | ||||
|     void* allocatePageTable(); | ||||
|     void* allocate_page_table(); | ||||
| 
 | ||||
|     void protectMap(LinearAddress, size_t length); | ||||
|     void identityMap(LinearAddress, size_t length); | ||||
|  | @ -185,9 +191,9 @@ private: | |||
|         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_pageTableOne; | ||||
| 
 | ||||
|  | @ -203,7 +209,7 @@ struct KernelPagingScope { | |||
|     ~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); } | ||||
| }; | ||||
|  |  | |||
|  | @ -78,7 +78,7 @@ ByteBuffer procfs$pid_vm(Process& process) | |||
| ByteBuffer procfs$pid_stack(Process& process) | ||||
| { | ||||
|     ProcessInspectionScope scope(process); | ||||
|     OtherProcessPagingScope pagingScope(process); | ||||
|     ProcessPagingScope pagingScope(process); | ||||
|     struct RecognizedSymbol { | ||||
|         dword address; | ||||
|         const KSym* ksym; | ||||
|  | @ -147,14 +147,14 @@ ByteBuffer procfs$mm() | |||
|         zonePageCount += zone->m_pages.size(); | ||||
|     auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_zones.size() + zonePageCount * 10); | ||||
|     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) { | ||||
|         ptr += ksprintf(ptr, "Zone %p size: %u\n  ", zone, zone->size()); | ||||
|         for (auto page : zone->m_pages) | ||||
|             ptr += ksprintf(ptr, "%x ", page); | ||||
|         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()); | ||||
|     return buffer; | ||||
| } | ||||
|  |  | |||
|  | @ -285,22 +285,17 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi | |||
| 
 | ||||
|     ExecSpace space; | ||||
|     Region* region = nullptr; | ||||
|     byte* region_alias = nullptr; | ||||
| 
 | ||||
|     KernelPagingScope pagingScope; | ||||
|     ProcessPagingScope pagingScope(*t); | ||||
|     space.hookableAlloc = [&] (const String& name, size_t size) { | ||||
|         if (!size) | ||||
|             return (void*)nullptr; | ||||
|         size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
 | ||||
|         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)); | ||||
|     if (!success) { | ||||
|         if (region) | ||||
|             MM.remove_kernel_alias_for_region(*region, region_alias); | ||||
|         delete t; | ||||
|         kprintf("Failure loading ELF %s\n", path.characters()); | ||||
|         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"); | ||||
|     if (!t->m_tss.eip) { | ||||
|         // 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; | ||||
|         error = -ENOEXEC; | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(region); | ||||
|     MM.remove_kernel_alias_for_region(*region, region_alias); | ||||
| 
 | ||||
|     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_parentPID(parentPID) | ||||
| { | ||||
|     m_pageDirectory = (dword*)kmalloc_page_aligned(4096); | ||||
|     m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory)); | ||||
|     MM.populate_page_directory(*this); | ||||
| 
 | ||||
|     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.cs = cs; | ||||
| 
 | ||||
|     m_tss.cr3 = (dword)m_pageDirectory; | ||||
|     m_tss.cr3 = (dword)m_page_directory; | ||||
| 
 | ||||
|     if (isRing0()) { | ||||
|         // FIXME: This memory is leaked.
 | ||||
|  | @ -502,6 +494,8 @@ Process::~Process() | |||
|         kfree(m_kernelStack); | ||||
|         m_kernelStack = nullptr; | ||||
|     } | ||||
| 
 | ||||
|     MM.release_page_directory(*this); | ||||
| } | ||||
| 
 | ||||
| void Process::dumpRegions() | ||||
|  | @ -610,9 +604,9 @@ void Process::processDidCrash(Process* crashedProcess) | |||
| 
 | ||||
| void Process::doHouseKeeping() | ||||
| { | ||||
|     InterruptDisabler disabler; | ||||
|     if (s_deadProcesses->isEmpty()) | ||||
|         return; | ||||
|     InterruptDisabler disabler; | ||||
|     Process* next = nullptr; | ||||
|     for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) { | ||||
|         next = deadProcess->next(); | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include "TTY.h" | ||||
| 
 | ||||
| class FileHandle; | ||||
| class PageDirectory; | ||||
| class Region; | ||||
| class Subregion; | ||||
| class Zone; | ||||
|  | @ -149,7 +150,7 @@ private: | |||
| 
 | ||||
|     void allocateLDT(); | ||||
| 
 | ||||
|     dword* m_pageDirectory { nullptr }; | ||||
|     PageDirectory* m_page_directory { nullptr }; | ||||
| 
 | ||||
|     Process* m_prev { nullptr }; | ||||
|     Process* m_next { nullptr }; | ||||
|  |  | |||
|  | @ -49,13 +49,20 @@ static byte parseHexDigit(char nibble) | |||
|     return 10 + (nibble - 'a'); | ||||
| } | ||||
| 
 | ||||
| #ifdef KSYMS | ||||
| static Vector<KSym, KmallocEternalAllocator>* s_ksyms; | ||||
| static bool s_ksyms_ready; | ||||
| 
 | ||||
| Vector<KSym, KmallocEternalAllocator>& ksyms() | ||||
| { | ||||
|     return *s_ksyms; | ||||
| } | ||||
| 
 | ||||
| volatile bool ksyms_ready() | ||||
| { | ||||
|     return s_ksyms_ready; | ||||
| } | ||||
| 
 | ||||
| const KSym* ksymbolicate(dword address) | ||||
| { | ||||
|     if (address < ksyms().first().address || address > ksyms().last().address) | ||||
|  | @ -90,8 +97,38 @@ static void loadKsyms(const ByteBuffer& buffer) | |||
|         ksyms().append({ address, String(startOfName, bufptr - startOfName) }); | ||||
|         ++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() | ||||
| { | ||||
|  | @ -109,8 +146,8 @@ static void spawn_stress() | |||
|     for (unsigned i = 0; i < 10000; ++i) { | ||||
|         int error; | ||||
|         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; | ||||
|         sleep(60); | ||||
|     } | ||||
|  | @ -223,6 +260,11 @@ void init() | |||
| { | ||||
|     cli(); | ||||
| 
 | ||||
| #ifdef KSYMS | ||||
|     s_ksyms = nullptr; | ||||
|     s_ksyms_ready = false; | ||||
| #endif | ||||
| 
 | ||||
|     kmalloc_init(); | ||||
|     vga_init(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -66,6 +66,8 @@ public: | |||
|     void set(dword address) { m_address = address; } | ||||
|     void mask(dword m) { m_address &= m; } | ||||
| 
 | ||||
|     bool is_null() const { return m_address == 0; } | ||||
| 
 | ||||
|     byte* asPtr() { return reinterpret_cast<byte*>(m_address); } | ||||
|     const byte* asPtr() const { return reinterpret_cast<const byte*>(m_address); } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ int main(int c, char** v) | |||
| 
 | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling