织梦CMS - 轻松建站从此开始!

罗索

WinCE6.0内核

jackyhwei 发布于 2010-09-29 13:52 点击:次 
Wince支持arm, mips, sh, x86四种平台,所以在kernel下存在4个目录对应4个平台相关代码, 只分析arm的。
TAG:

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.后面的事情是另一波了。
(ch_ff)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201009/10229.html]
本文出处:百度博客 作者:ch_ff
顶一下
(0)
0%
踩一下
(1)
100%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容