reactos操作系统实现(32)
这个函数主要功能就是实现访问不存在的页面。 #001 NTSTATUS #002 NTAPI #003 MmNotPresentFault(KPROCESSOR_MODE Mode, #004 ULONG_PTR Address, #005 BOOLEAN FromMdl) #006 { #007 PMM_AVL_TABLE AddressSpace; #008 MEMORY_AREA* MemoryArea; #009 NTSTATUS Status; #010 BOOLEAN Locked = FromMdl; #011 PFN_TYPE Pfn; #012 #013 DPRINT("MmNotPresentFault(Mode %d,Address %x)/n",Mode,Address); #014
判断访问内存的级别。 #015 if (KeGetCurrentIrql() >= DISPATCH_LEVEL) #016 { #017 DPRINT1("Page fault at high IRQL was %d,address %x/n",KeGetCurrentIrql(),Address); #018 return(STATUS_UNSUCCESSFUL); #019 } #020
判断是否在内核内存,还是在进程内存空间上。 #021 /* #022 * Find the memory area for the faulting address #023 */ #024 if (Address >= (ULONG_PTR)MmSystemRangeStart) #025 { #026 /* #027 * Check permissions #028 */ #029 if (Mode != KernelMode) #030 { #031 DPRINT1("Address: %x/n",Address); #032 return(STATUS_ACCESS_VIOLATION); #033 } #034 AddressSpace = MmGetKernelAddressSpace(); #035 } #036 else #037 { #038 AddressSpace = &PsGetCurrentProcess()->VadRoot; #039 } #040 #041 if (!FromMdl) #042 { #043 MmLockAddressSpace(AddressSpace); #044 } #045
根据内存类型调用不同的缺页中断处理函数。 #046 /* #047 * Call the memory area specific fault handler #048 */ #049 do #050 { #051 MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,(PVOID)Address); #052 if (MemoryArea == NULL || MemoryArea->DeleteInProgress) #053 { #054 if (!FromMdl) #055 { #056 MmUnlockAddressSpace(AddressSpace); #057 } #058 return (STATUS_ACCESS_VIOLATION); #059 } #060 #061 switch (MemoryArea->Type) #062 { #063 case MEMORY_AREA_PAGED_POOL: #064 { #065 Status = MmCommitPagedPoolAddress((PVOID)Address,Locked); #066 break; #067 } #068 #069 case MEMORY_AREA_SYSTEM: #070 Status = STATUS_ACCESS_VIOLATION; #071 break; #072 #073 case MEMORY_AREA_SECTION_VIEW: #074 Status = MmNotPresentFaultSectionView(AddressSpace, #075 MemoryArea, #076 (PVOID)Address, #077 Locked); #078 break; #079 #080 case MEMORY_AREA_VIRTUAL_MEMORY: #081 case MEMORY_AREA_PEB_OR_TEB: #082 Status = MmNotPresentFaultVirtualMemory(AddressSpace, #083 MemoryArea, #084 (PVOID)Address, #085 Locked); #086 break; #087 #088 case MEMORY_AREA_SHARED_DATA: #089 Pfn = MmSharedDataPagePhysicalAddress.LowPart >> PAGE_SHIFT; #090 Status = #091 MmCreateVirtualMapping(PsGetCurrentProcess(), #092 (PVOID)PAGE_ROUND_DOWN(Address), #093 PAGE_READONLY, #094 &Pfn, #095 1); #096 break; #097 #098 default: #099 Status = STATUS_ACCESS_VIOLATION; #100 break; #101 } #102 } #103 while (Status == STATUS_MM_RESTART_OPERATION); #104 #105 DPRINT("Completed page fault handling/n"); #106 if (!FromMdl) #107 { #108 MmUnlockAddressSpace(AddressSpace); #109 } #110 return(Status); #111 } 通过上面的函数,就可以实现读取内存不存在的缺页中断处理。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |