reactos操作系统实现(31)
下面来分析保存数据时缺页中断函数,它的代码如下: #001 NTSTATUS #002 NTAPI #003 MmpAccessFault(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
调试输出。 #012 DPRINT("MmAccessFault(Mode %d,Address %x)/n",Mode,Address); #013
判断请求优先级是否大于DISPATCH_LEVEL级别,如果大于这个级别,就需要不能进行缺页处理。 #014 if (KeGetCurrentIrql() >= DISPATCH_LEVEL) #015 { #016 DPRINT1("Page fault at high IRQL was %d/n",KeGetCurrentIrql()); #017 return(STATUS_UNSUCCESSFUL); #018 }
判断当前进程是否为空。 #019 if (PsGetCurrentProcess() == NULL) #020 { #021 DPRINT("No current process/n"); #022 return(STATUS_UNSUCCESSFUL); #023 } #024
通过缺页中断的内存地址找到内存块。 #025 /* #026 * Find the memory area for the faulting address #027 */ #028 if (Address >= (ULONG_PTR)MmSystemRangeStart) #029 {
如果是内存地址在系统范围内存里,就需要检查是否在内核模式下访问,否则在用户状态下访问是非法的。 #030 /* #031 * Check permissions #032 */ #033 if (Mode != KernelMode) #034 { #035 DPRINT1("MmAccessFault(Mode %d,Address); #036 return(STATUS_ACCESS_VIOLATION); #037 } #038 AddressSpace = MmGetKernelAddressSpace(); #039 } #040 else #041 { #042 AddressSpace = &PsGetCurrentProcess()->VadRoot; #043 } #044
判断是否需要锁住内存。 #045 if (!FromMdl) #046 { #047 MmLockAddressSpace(AddressSpace); #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_SYSTEM: #064 Status = STATUS_ACCESS_VIOLATION; #065 break; #066
内存已经放分页缓存。 #067 case MEMORY_AREA_PAGED_POOL: #068 Status = STATUS_SUCCESS; #069 break; #070
这里就找到相应的内存块。 #071 case MEMORY_AREA_SECTION_VIEW: #072 Status = MmAccessFaultSectionView(AddressSpace, #073 MemoryArea, #074 (PVOID)Address, #075 Locked); #076 break; #077
虚拟内存非法访问 #078 case MEMORY_AREA_VIRTUAL_MEMORY: #079 Status = STATUS_ACCESS_VIOLATION; #080 break; #081
共享内存非法访问。 #082 case MEMORY_AREA_SHARED_DATA: #083 Status = STATUS_ACCESS_VIOLATION; #084 break; #085
缺省都是返回非法访问内存。 #086 default: #087 Status = STATUS_ACCESS_VIOLATION; #088 break; #089 } #090 } #091 while (Status == STATUS_MM_RESTART_OPERATION); #092
查找到内存块完成,并进行内存解锁操作。 #093 DPRINT("Completed page fault handling/n"); #094 if (!FromMdl) #095 { #096 MmUnlockAddressSpace(AddressSpace); #097 } #098 return(Status); #099 } 上面这个函数,先判断缺页内存地址在系统空间,还是在用户空间,然后再在相应的空间里查找地址所有内存块。如果找到内存,就在函数MmAccessFaultSectionView里处理相应的功能。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |