WinCE6.0内核

来源:互联网 发布:域名和空间的关系 编辑:程序博客网 时间:2024/04/28 10:01
 

Wince支持arm, mips, sh, x86四种平台,所以在kernel下存在4个目录对应4个平台相关代码, 只分析arm的。

[内核编译]

Kernel.dll=kern.dll

编译kern.dll =<nkcompr.lib> + <nkmapfile.lib> + <nkmsgq.lib> + oemstub.lib + nklogger.lib + nkmain.lib + fulllibc.lib链接成nk模块。前面3个库是可选的:组件[compression]决定变量sysgen_nkcompr,进而决定是否包括nkcompr.组件[Memory Mapped Files]决定变量sysgen_nkmapfile,进而决定是否包括nkmapfile。 组件[Message Queue]决定变量sysgen_msgqueue,进而决定是否包括nkmsgq。 fulllibc.lib就是c语言库, 狭义上的内核就是nkmain.lib

[进入内核之前 --设计一个nkldr]

OAL跳转到内核本来是KernelStart(g_oalAddressTable); 因为wince6特性OAL和kernel分离, 这时候没有直接跳转到kernel的入口点, 而是nkldr.lib的KernelStart转了一下。KernelStart()根据参数,首先设定一级页表,初始化堆栈(NKStartup是c语言入口),启动MMU和cache,并且将KDATA段地址做为参数,真正跳转到内核kern.dll的入口NKStartup(pKdata).。nkldr怎么找到kernel.dll? 根据关键字kernel.dll直接在镜像里面搜寻然后重定位。以后再把这个过程细细挖掘。

[NKStartup的参数KData是什么?]

其实就是一个数据结构, 它位于nkldr的data区。如下:

         AREA |.KDATA|,DATA,NOINIT

KDataArea

PTs      %        0x4000           ; space for first-level page table

ExceptionVectors

         %        0x0400     ; space for exception vectors

         %        0x0400     ; space for interrupt stack

         %        0x0100     ; space for FIQ stack

         %        0x0700     ; space for Abort stack

KPage   %        0x0c00    ; space for kernel stack & KDataStruct

HighPT %        0x0400    ; 2nd level page table to map 0xFFF00000

KDEnd %        0

撇开实现, 单纯去理解的话, 和传递一个结构体指针没有什么区别。 再问: 这个数据结构干嘛的,代表什么? 这得明白高地址分配。

[高地址分配]

    ^ 0xFFFD0000

FirstPT          # 0x4000

              # 0x4000

              # 0x8000

              # 0x10000        ; not mapped

ExVector      # 0x0400         ; vectors and table

              # 0x0400   ; 1K interrupt stack             (ffff0400)

IntStack        # 0x0100 ; 256 byte FIQ stack             (ffff0800)

FIQStack       # 0x0700 ; 2K-256 abort stack             (ffff0900)

AbortStack   #0xC000-0x1000;not mapped                 (ffff1000)

KDBase        # 0x07E0         ; 2K-32 kernel stack

KStack         # 0x0020         ; temporary register save area

KData          # 0x400          ; kernel data area

FirstPT就 是之前说的一级页表所在。大小16kbytes。 后面保留了2块区域,也许是提供给2级页表使用。 ExVector是异常入口, Arm有个机 制, 通过设定p15, 可以将异常入口从0x18改成高地址 FFFF0000. IntStack, FIQStack, AbortStack, KStack分别是各个模式以及内核的堆栈。 KData就是内 核参数区了。

typedef struct ARM_HIGH {

     ulong    firstPT[4096];       // 0xFFFD0000: 1st level page table

     char     reserved2[0x20000-0x4000];

     char     exVectors[0x400];    // 0xFFFF0000: exception vectors

     char     reserved3[0x2400-0x400];

     char     intrStack[0x400];    // 0xFFFF2400: interrupt stack

     char     reserved4[0x4900-0x2800];

     char     abortStack[0x700];   // 0xFFFF4900: abort stack

     char     reserved5[0x6800-0x5000];

     char     fiqStack[0x100];     // 0xFFFF6800: FIQ stack

     char     reserved6[0xC000-0x6900];

     char     kStack[0x800];       // 0xFFFFC000: kernel stack

     struct KDataStruct kdata;    // 0xFFFFC800: kernel data page

} ARM_HIGH;

[回顾启动流程]

Mdarm.c文件的最后一个函数NKStartup()就是kern.dll的入口点。

NKStartup()

ARMSetup()

OEMInitDebugSerial()   

OEMInit()               

KernelFindMemroy()

KernelStart()

KernelInit()

APICallInit();

HeapInit();

InitMemoryPool();

PROCInit();

VMInit(g_pprcNK);

THRDInit();

MapfileInit();

FirstSchedule();

THRDInit()初始化了第一个线程是SystemStartupFunc, 所以FirstSchedule开始第一次调度, 就调度到SystemStartupFunc函数开始执行:

SystemStartupFunc()

KernelInit2();

LoaderInit();

PagePoolInit();

LoggerInit();

SysDebugInit();

CreateKernelThread(Monitor1);

InitMsgQueue();

InitWatchDog();

CreateKernelThread(PowerHandlerGuardThrd);

CreateKernelThread(RunApps);

While(1) {

NKWatiForSingleObject(ONE_DAY);

}

RunApps()里面就是启动filesys.exe了, 在ce6是filesys.dll.后面的事情是另一波了。
原创粉丝点击