📄 kernelpage.c
字号:
if (parentDirectory == NULL) return (physicalAddress = NULL); status = kernelLockGet(&(parentDirectory->dirLock)); if (status < 0) return (physicalAddress = NULL); // It could happen that the parentId and childId are the same. (really?) if (parentId != childId) { // Ok. Make room for a new page directory structure for the child. // We do this manually (i.e. without calling createPageDirectory()) // because this shared page directory needs no real memory allocated // to it. childDirectory = pageDirList[numberPageDirectories++]; // Clear the child directory. kernelMemClear((void *) childDirectory, sizeof(kernelPageDirectory)); // Set the process Id of the child's directory childDirectory->processId = childId; // Note that the parent directory is referenced and child directory // is shared. parentDirectory->numberShares++; childDirectory->parent = parentDirectory->processId; } physicalAddress = (void *) parentDirectory->physical; kernelLockRelease(&(parentDirectory->dirLock)); // Return the physical address of the shared page directory. return (physicalAddress);}int kernelPageDeleteDirectory(int processId){ // This will delete a page directory and all of its assoctiated (unshared) // page tables. int status = 0; kernelPageDirectory *directory = NULL; kernelPageTable *table = NULL; int count; // Have we been initialized? if (!initialized) return (status = ERR_NOTINITIALIZED); // Find the page directory belonging to the process. We can't use the // findPageDirectory() function to find it since THAT will always // return the PARENT page directory if a page directory is shared. We // don't want that to happen, so we'll search through the list manually. for (count = 0; count < numberPageDirectories; count ++) if (pageDirList[count]->processId == processId) { directory = pageDirList[count]; break; } if (directory == NULL) return (status = ERR_NOSUCHENTRY); status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (status = ERR_NOLOCK); // Ok, found it. We need to walk through all of its page tables, // deallocating them as we go. for (count = 0; count < PAGE_PAGES_PER_TABLE; count ++) { table = findPageTable(directory, count); if (table) { status = deletePageTable(directory, table); if (status < 0) { kernelLockRelease(&(directory->dirLock)); return (status); } } } // Delete the directory. status = deletePageDirectory(directory); // Return success return (status = 0);}int kernelPageMap(int processId, void *physicalAddress, void *virtualAddress, unsigned size){ // This is a publicly accessible wrapper function for the map() function. // It maps physical pages into an address space, at the specified virtual // address. Parameter checking is done inside the map() function, not here. int status = 0; // next by Davide Airaghi int kernel = 0; kernelPageDirectory *directory = NULL; // Have we been initialized? if (!initialized) return (status = ERR_NOTINITIALIZED); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (status = ERR_NOSUCHENTRY); // next 5 lines by Davide Airaghi kernel = kernelMultitaskerIsLowLevelProcess(processId); if (kernel < 0) kernel = 0; else kernel = 1; status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (status = ERR_NOLOCK); status = map(directory, physicalAddress, &virtualAddress, size, PAGE_MAP_EXACT,kernel); kernelLockRelease(&(directory->dirLock)); return (status);}int kernelPageMapToFree(int processId, void *physicalAddress, void **virtualAddress, unsigned size){ // This is a publicly accessible wrapper function for the map() function. // It maps physical pages into an address space, at the first available // virtual address. Parameter checking is done inside the map() function, // not here. int status = 0; kernelPageDirectory *directory = NULL; int kernel = 0; // Have we been initialized? if (!initialized) return (status = ERR_NOTINITIALIZED); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (status = ERR_NOSUCHENTRY); // next 5 lines by Davide Airaghi kernel = kernelMultitaskerIsLowLevelProcess(processId); if (kernel < 0) kernel = 0; else kernel = 1; status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (status = ERR_NOLOCK); status = map(directory, physicalAddress, virtualAddress, size, PAGE_MAP_ANY,kernel); // last by Davide Airaghi kernelLockRelease(&(directory->dirLock)); return (status);}int kernelPageUnmap(int processId, void *virtualAddress, unsigned size){ // This is a publicly accessible wrapper function for the map() function. // This one is used to remove mapped pages from an address space. Parameter // checking is done inside the map() function, not here. int status = 0; kernelPageDirectory *directory = NULL; // Have we been initialized? if (!initialized) return (status = ERR_NOTINITIALIZED); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (status = ERR_NOSUCHENTRY); status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (status = ERR_NOLOCK); status = unmap(directory, virtualAddress, size); kernelLockRelease(&(directory->dirLock)); return (status);}void *kernelPageGetPhysical(int processId, void *virtualAddress){ // Let's get physical. I wanna get physical. Let me hear your body talk. // Return the physical address mapped to this virtual address. The // virtualAddress parameter is allowed to be NULL. int status = 0; kernelPageDirectory *directory = NULL; void *address = NULL; // Have we been initialized? if (!initialized) return (address = NULL); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (address = NULL); status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (address = NULL); status = findPageTableEntry(directory, (void *) kernelPageRoundDown(virtualAddress), &address); kernelLockRelease(&(directory->dirLock)); if (status < 0) return (address = NULL); else return (address + ((unsigned) virtualAddress % MEMORY_PAGE_SIZE));}void *kernelPageFindFree(int processId, unsigned size){ // Simply locate the virtual address of a range of free pages of the // requested size. int status = 0; kernelPageDirectory *directory = NULL; int pages = 0; void *address = NULL; // Have we been initialized? if (!initialized) return (address = NULL); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (address = NULL); // Calculate the desired number of pages pages = ((size / MEMORY_PAGE_SIZE) + ((size % MEMORY_PAGE_SIZE) != 0)); status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (address = NULL); status = findFreePages(directory, pages, &address); kernelLockRelease(&(directory->dirLock)); if (status < 0) return (address = NULL); else return (address);}int kernelPageSetAttrs(int processId, int set, unsigned char flags, void *virtualAddress, unsigned size){ // This is a wrapper for setPageAttrs() which allows the setting/clearing // of page attributes int status = 0; kernelPageDirectory *directory = NULL; int pages = 0; // Have we been initialized? if (!initialized) return (status = ERR_NOTINITIALIZED); // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) return (status = ERR_NOSUCHENTRY); // Calculate the number of pages pages = ((size / MEMORY_PAGE_SIZE) + ((size % MEMORY_PAGE_SIZE) != 0)); status = kernelLockGet(&(directory->dirLock)); if (status < 0) return (status); status = setPageAttrs(directory, set, flags, virtualAddress, pages); kernelLockRelease(&(directory->dirLock)); return (status);}#ifdef PAGE_DEBUGvoid kernelPageTableDebug(int processId){ kernelPageDirectory *directory = NULL; int numPages = 0; int numTables = 0; kernelPageTable *pageTable = NULL; void *tableAddress = NULL; void *pageAddress = NULL; void *pagePhysical = NULL; void *rangeStart = (void *) -1; void *rangePhysicalStart = 0; unsigned rangeSize = 0; memoryStats stats; memoryBlock *blocksArray = NULL; int count, tableCount, pageCount; // Have we been initialized? if (!initialized) return; // Find the appropriate page directory directory = findPageDirectory(processId); if (directory == NULL) { kernelError(kernel_error, "Page directory %d not found", processId); return; } numPages = (KERNEL_VIRTUAL_ADDRESS / MEMORY_PAGE_SIZE); numTables = (numPages / PAGE_TABLES_PER_DIR); kernelTextPrintLine("Directory %d:\nvirtStart->virtEnd = physStart->physEnd " "(size)\n----------------", processId); rangeStart = (void *) -1; for (tableCount = 0; tableCount < numTables; tableCount ++) { pageTable = findPageTable(directory, tableCount); if (pageTable) { tableAddress = (void *) (tableCount * PAGE_PAGES_PER_TABLE * MEMORY_PAGE_SIZE); for (pageCount = 0; pageCount < PAGE_PAGES_PER_TABLE; pageCount ++) { pageAddress = (tableAddress + (pageCount * MEMORY_PAGE_SIZE)); if (pageTable->virtual->page[pageCount]) { pagePhysical = (void *) (pageTable->virtual->page[pageCount] & 0xFFFFF000); if (rangeStart == (void *) -1) { rangeStart = pageAddress; rangePhysicalStart = pagePhysical; } else if (pageCount && ((void *)(pageTable->virtual->page[pageCount - 1] & 0xFFFFF000) != (pagePhysical - MEMORY_PAGE_SIZE))) { rangeSize = (pageAddress - rangeStart); kernelTextPrintLine("%08x->%08x = %08x->%08x (%08x)", rangeStart, (pageAddress - 1), rangePhysicalStart, (rangePhysicalStart + rangeSize - 1), rangeSize); rangeStart = pageAddress; rangePhysicalStart = pagePhysical; } } else if (rangeStart != (void *) -1) { rangeSize = (pageAddress - rangeStart); kernelTextPrintLine("%08x->%08x = %08x->%08x (%08x)", rangeStart, (pageAddress - 1), rangePhysicalStart, (rangePhysicalStart + rangeSize - 1), rangeSize); rangeStart = (void *) -1; } } } } kernelTextPrintLine("----------------\nPhysical blocks:"); kernelMemoryGetStats(&stats, 0); blocksArray = kernelMemoryGet((stats.usedBlocks * sizeof(memoryBlock)), "memory block list"); kernelMemoryGetBlocks(blocksArray, (stats.usedBlocks * sizeof(memoryBlock)), 0); for (count = 0; count < (int) stats.usedBlocks; count ++) if (blocksArray[count].processId == processId) kernelTextPrintLine("proc=%d %08x->%08x (size %08x) %s", blocksArray[count].processId, blocksArray[count].startLocation, blocksArray[count].endLocation, (blocksArray[count].endLocation - blocksArray[count].startLocation + 1), blocksArray[count].description); kernelMemoryRelease(blocksArray); kernelTextPrintLine("---------------- ...done"); return;}#endif // PAGE_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -