; 设置32位不可屏蔽中断任务门去获取不可屏蔽中断异常
mov eax,KissIdt
lea ecx,[eax]+10h ; Descriptor 2
mov byte ptr [ecx+5],085h ; dpl=0, present, taskgate
mov word ptr [ecx+2],KGDT_NMI_TSS
lea ecx,[edi]+KGDT_NMI_TSS
mov byte ptr [ecx+5],089h ; 32bit, dpl=0, present, TSS32, not busy
mov edx,offset FLAT:_KiNMITSS mov eax,edx
mov [ecx+KgdtBaseLow],ax shr eax,16
mov [ecx+KgdtBaseHi],ah mov [ecx+KgdtBaseMid],al mov eax, MINIMUM_TSS_SIZE mov [ecx+KgdtLimitLow],ax
push edx
stdCall _KiInitializeTSS,
; KiInitializeTSS( ; TSS地址 ; ); pop edx
; We are using the DoubleFault stack as the DoubleFault stack and theNMI Task Gate stack and briefly, it is the DPC stack for the first ; processor. mov eax,cr3
mov [edx+TssCr3],eax
mov eax, offset FLAT:_KiDoubleFaultTSS
mov eax, dword ptr [eax+038h] ; get DF stack mov dword ptr [edx+TssEsp0],eax ; use it for NMI stack mov dword ptr [edx+038h],eax
mov dword ptr [edx+020h],offset FLAT:_KiTrap02 mov dword ptr [edx+024h],0 ; eflags
mov word ptr [edx+04ch],KGDT_R0_CODE ; set value for CS mov word ptr [edx+058h],KGDT_R0_PCR ; set value for FS mov [edx+050h],ss
mov word ptr [edx+048h],KGDT_R3_DATA OR RPL_MASK ; Es mov word ptr [edx+054h],KGDT_R3_DATA OR RPL_MASK ; Ds
stdCall _KiInitializePcr,
; 在当前线程对象中设置当前进程指针
mov edx, KissIdleThread
mov ecx, offset FLAT:_KiInitialProcess ; (ecx)-> idle process obj mov [edx]+ThApcState+AsProcess, ecx ; set addr of thread's process
; 设置 PCR: Teb, Prcb 指针.
; Prcb 相关参数将在函数 _KiInitializeKernel中设置
mov dword ptr PCR[PcTeb], 0 ; PCR->Teb = 0
; 初始化KernelDr7和KernelDr6为0. 该操作必须在调试器调用前完成.
mov dword ptr PCR[PcPrcbData+PbProcessorState+PsSpecialRegisters+SrKernelDr6],0 mov dword ptr PCR[PcPrcbData+PbProcessorState+PsSpecialRegisters+SrKernelDr7],0
; 内核IDT重新设置,转换成i386可以识别的次序.该操作只能由引导处理器完成 stdCall _KiSwapIDT
mov eax,KGDT_R3_DATA OR RPL_MASK ; 设置请求特权级RPL为ring 3 mov ds,ax mov es,ax
; 复制陷阱处理器替换内核调试处理器 mov eax, KissIdt ; (eax)-> Idt
push dword ptr [eax+40h] ; 保存双重故障描述符 push dword ptr [eax+44h]
push dword ptr [eax+10h] ; 保存不可屏蔽中断故障描述符 push dword ptr [eax+14h]
mov edi,KissIdt
mov esi,offset FLAT:_IDT mov ecx,offset FLAT:_IDTLEN ; shr ecx,2
rep movsd
pop dword ptr [eax+14h] ; 恢复双重故障描述符
pop dword ptr [eax+10h]
pop dword ptr [eax+44h] ; 恢复不可屏蔽中断故障描述符 pop dword ptr [eax+40h]
ifdef QLOCK_STAT_GATHER
EXTRNP KiCaptureQueuedSpinlockRoutines,0,,FASTCALL fstCall KiCaptureQueuedSpinlockRoutines endif
kiss_notp0: ifndef NT_UP
; 告知引导处理器该处理器已经开始运行. stdCall _KiProcessorStart endif
; A new processor can't come online while execution is frozen ; Take freezelock while adding a processor to the system ; NOTE: don't use SPINLOCK macro - it has debugger stuff in it
@@: test _KiFreezeExecutionLock, 1 jnz short @b
lock bts _KiFreezeExecutionLock, 0 jc short @b
; 添加当前处理器到活动列表,并更新BroadcastMasks
mov ecx, dword ptr KissPbNumber ; 标记该处理器为活动的 mov byte ptr PCR[PcNumber], cl mov eax, 1
shl eax, cl ; 关联字段 mov PCR[PcSetMember], eax mov PCR[PcSetMemberCopy], eax mov PCR[PcPrcbData.PbSetMember], eax
; 初始化处理器间的中断向量表并自增就绪处理器计数值以开启内核调试器.
stdCall _HalInitializeProcessor,
ifdef _APIC_TPR_
; 通过hal记录IRQL表,并传递过来
mov eax, KissLoaderBlock mov eax, [eax]+LpbExtension mov ecx, [eax]+LpeHalpIRQLToTPR mov _HalpIRQLToTPR, ecx
mov ecx, [eax]+LpeHalpVectorToIRQL mov _HalpVectorToIRQL, ecx endif
mov eax, PCR[PcSetMember]
or _KeActiveProcessors, eax ; 活动处理器的新关联值
; 初始化ABIOS数据结构.
; KiInitializeAbios例程必须在KeLoaderBlock初始化完成之后调用
stdCall _KiInitializeAbios,
inc _KeNumberProcessors ; 又有新的处理器被激活 xor eax, eax ; 释放执行锁 mov _KiFreezeExecutionLock, eax
cmp byte ptr KissPbNumber, 0 jnz @f
; 不能在调试器中暂停
stdCall _KdInitSystem, <0,_KeLoaderBlock>
if DEVL
; 给予调试器获得控制权的机会. POLL_DEBUGGER endif ; DEVL