加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(31)

发布时间:2020-12-15 05:02:10 所属栏目:百科 来源:网络整理
导读:下面来分析保存数据时缺页中断函数,它的代码如下: #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 NT

下面来分析保存数据时缺页中断函数,它的代码如下:

#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里处理相应的功能。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读