#001 /* Switch to new kernel stack and startkernel bootstrapping */
#002 KiSetupStackAndInitializeKernel(&KiInitialProcess.Pcb,
#003 InitialThread,
#004 (PVOID)InitialStack,
#005 (PKPRCB)__readfsdword(KPCR_PRCB),
#006 (CCHAR)Cpu,
#007 KeLoaderBlock);
上面这段代码就是开始切换到内核栈初始化的工作。
第一个参数KiInitialProcess.Pcb是内核进程的控制块。
第二个参数InitialThread引导线程结构。
第三个参数InitialStack内核栈。
第四个参数PRCB进程控制块。
第五个参数CPU的序号。
第六个参数KeLoaderBlock是Freeldr.sys传送过来的参数。
接着我们来查看这个函数的实现,先来了解开始部份的代码了,如下:
#001 .globl _KiSetupStackAndInitializeKernel@24
#002 .func KiSetupStackAndInitializeKernel@24
#003 _KiSetupStackAndInitializeKernel@24:
#004
#005 /* Save current stack */
#006 mov esi, esp
上面保存参数栈位置,以便后面可以拷贝参数。
#007
#008 /* Setup the new stack */
#009 mov esp, [esp+12]
#010 sub esp, NPX_FRAME_LENGTH +KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH
这里设置新的栈位置。
#011 push CR0_EM + CR0_TS + CR0_MP
#012
#013 /* Copy all parameters to the new stack*/
#014 push [esi+24]
#015 push [esi+20]
#016 push [esi+16]
#017 push [esi+12]
#018 push [esi+8]
#019 push [esi+4]
#020 xor ebp, ebp
上面拷贝参数到新的栈空间里。
#021 call _KiInitializeKernel@24
接着调用KiInitializeKernel函数来继续初始化内核。
跟着上面后面的代码如下:
#001 /* Set the priority of this thread to 0 */
#002 mov ebx, PCR[KPCR_CURRENT_THREAD]
#003 mov byte ptr [ebx+KTHREAD_PRIORITY], 0
设置当前线程的优先级为0,最低级别。
#004
#005 /* Force interrupts enabled and lowerIRQL back to DISPATCH_LEVEL */
#006 sti
#007 mov ecx, DISPATCH_LEVEL
#008 call @KfLowerIrql@4
先打开中断,然后把本线程调度设置为DISPATCH_LEVEL级别。
#009
#010 /* Set the right wait IRQL */
#011 mov byte ptr [ebx+KTHREAD_WAIT_IRQL],DISPATCH_LEVEL;
设置等待的优先级为DISPATCH_LEVEL。
#012
#013 /* Jump into the idle loop */
#014 jmp @KiIdleLoop@0
最后跳转到引导线程的空闲循环里运行,让其它高优先级的线程运行。
#015 .endfunc
KiSetupStackAndInitializeKernel函数主要切换到新的内核栈,然后调用函数KiInitializeKernel继续初始化内核,然后打开中断降低优先级,最后进入空闲循环里处理,让其它高优先线程继续运行。