在这里,将结合x86的WinCE内核来说明一下CE的初始化过程。
- 在bootloader加载完内核影像后,会跳到影像中指明的起始位置出进行执行。通过对ROMIMAGE工具的分析得知,这个位置既是SOURCE文件中EXEENTRY指定的StartUp。这个函数定义于CSP的oeminit.asm中。
- StartUp在执行时内存映射关系还没有建立起来,因此函数调用使用相对偏移地址;而变量引用时则是映射后的地址。因此,就要变量使用时就要得到变量的物理地址。这就是StratUp和_KernelInitialize中有好多PaFromVa等的原因。StartUp的描述如下:
输入参数 无 输出 无(不会返回) 功能 - 调用_IdentifyCpu得到CPU能力
-
得到_OEMAddressTable的物理地址。代码如下:
call _PAOfStart
_PAOfStart:
pop esi ; (esi) = PA of _PAStartadd esi, OFFSET32 _OEMAddressTable
sub esi, OFFSET32 _PAOfStart ; (esi) = PA of OEMAddressTable - ; argument to KernelInitialize:
; (esi) = Physical Address of OEMAddressTable
; (edi) = CPU capability bits
;
jmp _KernelInitialize -
关于OEMAddressTable。
_OEMAddressTable:
;
; OEMAddressTable 定义了物理地址与虚拟地址间的映射。
; o MUST be in a READONLY Section
; o First Entry MUST be RAM, mapping from 0x80000000 -> 0x00000000
; o each entry is of the format ( VA, PA, cbSize )
; o cbSize must be multiple of 4M
; o last entry must be (0, 0, 0)
; o must have at least one non-zero entry; RAM 0x80000000 -> 0x00000000, size 64M
dd 80000000h, 0, 04000000h; FLASH and other memory, if any
; dd FlashVA, FlashPA, FlashSize; Last entry, all zeros
dd 0, 0, 0
- 现在程序跳入了_KernelInitialize中。这个过程会完成地址的映射(两种映射:cached、uncached)、调用SysteInitialization完成初始化GDT、IDT、TSS、内存等、调用KernelInit完成内核的基础设施的初始化。此时已经建立了一个进程"NK.exe"。现在可以进入NK.exe中运行了,调用Reschedule即可实现切换。