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文件里定义的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值