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

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...