reactos操作系统实现(16)

时间:2021-11-22 14:28:09
下面仔细分析这个函数的代码:

#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的序号。

第六个参数KeLoaderBlockFreeldr.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继续初始化内核,然后打开中断降低优先级,最后进入空闲循环里处理,让其它高优先线程继续运行。