微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

reactos操作系统实现(29)

内存大小好像永远追不上人们的需求,以前以为512K就很大了,到现在内存已经是4G8G内存了,但还是不能满足人们的需求。因为目前的系统都是多进程运行,每个进程都需要占用4G的内存,那么10个进程,就占用相当可观的内存了。这时就需要把进程不经常使用的内存数据切换到硬盘里,需要时再换回来。如果一个进程的内存已经换到硬盘上,而这个进程又想访问那些在硬盘的内存数据时,就会产生一个缺页中断。这个中断是cpu产生的,并且进入操作系统的中断门处理函数里,那么ReactOS是怎么样处理的呢?其实它是调用下面的函数来处理这个中断的,如下:

#001 .func KiTrap14

#002 TRAP_FIXUPS kite_a,kite_t,DoFixupV86,DoNotFixupAbios

#003 _KiTrap14:

#004

中断入口寄存器保存。

#005 /* Enter trap */

#006 TRAP_PROLOG kite_a,kite_t

#007

检查是否有VDM标志。

#008 /* Check if we have a VDM alert */

#009 cmp dword ptr PCR[KPCR_VDM_ALERT],0

#010 jnz VdmAlertGpf

#011

获取当前线程。

#012 /* Get the current thread */

#013 mov edi,PCR[KPCR_CURRENT_THREAD]

#014

获取当前帧指针。

#015 /* Get the stack address of the frame */

#016 lea eax,[esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH]

#017 sub eax,[edi+KTHREAD_INITIAL_STACK]

#018 jz NoFixUp

#019

#020 /* This isn't the base frame,check if it's the second */

#021 cmp eax,-KTRAP_FRAME_EFLAGS

#022 jb NoFixUp

#023

#024 /* Check if we have a TEB */

#025 mov eax,PCR[KPCR_TEB]

#026 or eax,eax

#027 jle NoFixUp

#028

#029 /* Fixup the frame */

#030 call _KiFixupFrame

#031

#032 /* Save CR2 */

#033 NoFixUp:

#034 mov edi,cr2

#035

#036 /* ROS HACK: Sometimes we get called with INTS disABLED! WTF? */

#037 test dword ptr [ebp+KTRAP_FRAME_EFLAGS],EFLAGS_INTERRUPT_MASK

#038 je HandlePf

#039

#040 /* Enable interrupts and check if we got here with interrupts disabled */

#041 sti

#042 test dword ptr [ebp+KTRAP_FRAME_EFLAGS],EFLAGS_INTERRUPT_MASK

#043 jz IllegalState

#044

#045 HandlePf:

#046 /* Send trap frame and check if this is kernel-mode or usermode */

#047 push ebp

#048 mov eax,[ebp+KTRAP_FRAME_CS]

#049 and eax,MODE_MASK

#050 push eax

#051

设置好参数,准备调用函数MmAccessFault来处理缺页错误

#052 /* Send faulting address and check if this is read or write */

#053 push edi

#054 mov eax,[ebp+KTRAP_FRAME_ERROR_CODE]

#055 and eax,1

#056 push eax

#057

#058 /* Call the access fault handler */

#059 call _MmAccessFault@16

#060 test eax,eax

#061 jl AccessFail

#062

已经成功处理了缺页中断,返回调用中断处理。

#063 /* Access fault handled,return to caller */

#064 jmp _Kei386EoiHelper@0

#065

#066 AccessFail:

#067 /* First check if this is a fault in the S-LIST functions */

#068 mov ecx,offset _ExpInterlockedPopEntrySListFault@0

#069 cmp [ebp+KTRAP_FRAME_EIP],ecx

#070 jz SlistFault

#071

#072 /* Check if this is a fault in the syscall handler */

#073 mov ecx,offset copyParams

#074 cmp [ebp+KTRAP_FRAME_EIP],ecx

#075 jz SysCallcopyFault

#076 mov ecx,offset ReadBatch

#077 cmp [ebp+KTRAP_FRAME_EIP],ecx

#078 jnz CheckVdmPf

#079

#080 /* FIXME: Todo */

#081 UNHANDLED_PATH

#082 jmp _Kei386EoiHelper@0

#083

#084 SysCallcopyFault:

#085 /* FIXME: Todo */

#086 UNHANDLED_PATH

#087 jmp _Kei386EoiHelper@0

#088

#089 /* Check if the fault occured in a V86 mode */

#090 CheckVdmPf:

#091 mov ecx,[ebp+KTRAP_FRAME_ERROR_CODE]

#092 shr ecx,1

#093 and ecx,1

#094 test dword ptr [ebp+KTRAP_FRAME_EFLAGS],EFLAGS_V86_MASK

#095 jnz VdmPF

#096

#097 /* Check if the fault occured in a VDM */

#098 mov esi,PCR[KPCR_CURRENT_THREAD]

#099 mov esi,[esi+KTHREAD_APCSTATE_PROCESS]

#100 cmp dword ptr [esi+EPROCESS_VDM_OBJECTS],0

#101 jz CheckStatus

#102

#103 /* Check if we this was in kernel-mode */

#104 test byte ptr [ebp+KTRAP_FRAME_CS],MODE_MASK

#105 jz CheckStatus

#106 cmp word ptr [ebp+KTRAP_FRAME_CS],KGDT_R3_CODE + RPL_MASK

#107 jz CheckStatus

#108

#109 VdmPF:

#110 /* FIXME: Todo */

#111 UNHANDLED_PATH

#112

#113 /* Save EIP and check what kind of status failure we got */

#114 CheckStatus:

#115 mov esi,[ebp+KTRAP_FRAME_EIP]

#116 cmp eax,STATUS_ACCESS_VIOLATION

#117 je AccessViol

#118 cmp eax,STATUS_GUARD_PAGE_VIOLATION

#119 je SpecialCode

#120 cmp eax,STATUS_STACK_OVERFLOW

#121 je SpecialCode

#122

#123 /* Setup an in-page exception to dispatch */

#124 mov edx,ecx

#125 mov ebx,esi

#126 mov esi,edi

#127 mov ecx,3

#128 mov edi,eax

#129 mov eax,STATUS_IN_PAGE_ERROR

#130 call _CommondispatchException

#131

#132 AccessViol:

#133 /* Use more proper status code */

#134 mov eax,KI_EXCEPTION_ACCESS_VIOLATION

#135

#136 SpecialCode:

#137 /* Setup a normal page fault exception */

#138 mov ebx,esi

#139 mov edx,ecx

#140 mov esi,edi

#141 jmp _dispatchTwoParam

#142

#143 SlistFault:

#144 /* FIXME: Todo */

#145 UNHANDLED_PATH

#146

#147 IllegalState:

#148

#149 /* This is completely illegal,bugcheck the system */

#150 push ebp

#151 push esi

#152 push ecx

#153 push eax

#154 push edi

#155 push IRQL_NOT_LESS_OR_EQUAL

#156 call _KeBugCheckWithTf@24

#157

#158 VdmAlertGpf:

#159

#160 /* FIXME: NOT SUPPORTED */

#161 UNHANDLED_PATH

#162 .endfunc

通过上面函数的分析,可以看到主要调用函数MmAccessFault来处理缺页中断,这个函数ntoskrnl/mm/mm.c文件里定义的。

原文地址:https://www.jb51.cc/react/308515.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐