⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernelpage.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 4 页
字号:
  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 + -