现在的位置: 首页 > 综合 > 正文

WinCE5读核笔记

2013年12月02日 ⁄ 综合 ⁄ 共 2636字 ⁄ 字号 评论关闭

(一)exception vector到底在哪里?

struct ARM_HIGH是被WinCE5 kernel安放在0xFFFD,0000地址的一个结构体。这个结构体非常大,我说它大不是因为它的 member很多,而是它的每个member都是一个非常大的数组。主要是为了对齐到一些特殊的地址。
我们知道在 core中0xFFFF,0000是high address exception vector的位置,而它就包含在struct ARM_HIGH中。对应于exVectors成员变量。
同时我们从这个结构体可以看出WinCE内核的一些精心安排。
0xFFFD,0000存放MMU第一级页表。第一级页表的地址要对齐到16KB,也就是[13~0]是零。0xFFFD,0000是满足这个要求的。
0xFFFF,2400是Interrupt processer mode用到的stack。
0xFFFF,4900是Abort processer mode用到的stack。
0xFFFF,6800是Fast interrupt processer mode用到的stack。
0xFFFF,C000是kernel mode用的stack。Kernel mode 其实也就是Supervisor processer mode。
值得注意的是stack是由高地址向低地址增长。经查证,上面4个stack地址。其实是stack的高地址。这些stack在使用时,stack会向reserved6这个member延伸。
我想问你的是:ARM processer mode中的undefined mode,他的stack为什么没有定义?
有的!既然kernel stack用的是的reserved6,那么kStack[0x800]这个空间就没人用了,它就是undefined mode的stack空间。
(二) 系统调用

KernelInitMMU启用以后,一段软件结构的初始化函数。它负责system call函数表的建立,和NK.exe这个进程的构建,当然也包括NK.exe的第一次以进程的身份调度运行。就此一个类似于《黑客帝国》的虚拟环境就被建立起来了。或者说由单一线程启动的环境,转为一个多线程并发执行的环境。不过KernelInit只是完成建立这个环境,真的虚拟环境开始不是这个函数的内容。

这个函数最值得看的地方是system call函数表的建立。因为其他的部分是call相应的函数,还看不见具体实现。

SystemAPISets是个32元素的结构体数组。可以看出微软将系统调用函数分成了32组,而每组APT set有一个函数表。

const CINFO *SystemAPISets[NUM_SYSTEM_SETS];

这就是SystemAPISets这个全局变量的声明。它是指针数组。

typedef struct cinfo {

    char        acName[4];  /* 00: object type ID string */

    uchar       disp;       /* 04: type of dispatch */

    uchar       type;       /* 05: api handle type */

    ushort      cMethods;   /* 06: # of methods in dispatch table */

    const PFNVOID *ppfnMethods;/* 08: ptr to array of methods (in server address space) */

    const DWORD *pdwSig;    /* 0C: ptr to array of method signatures */

    PPROCESS    pServer;    /* 10: ptr to server process */

} CINFO;    /* cinfo */

CINFO最重要的成员变量就是ppfnMethods,它是真正的函数列表。

       看看我们最常用的一些函数在哪里?

SystemAPISets[SH_WIN32] = &cinfWin32;

cinfWin32如下这样定义:

const CINFO cinfWin32 = {

    "Wn32",

    DISPATCH_I_KPSL,

    0,

    sizeof(Win32Methods)/sizeof(Win32Methods[0]),

    Win32Methods,

};

真正的函数列表是Win32Methods

const PFNVOID Win32Methods[] = {

    (PFNVOID)SC_Nop,

    (PFNVOID)SC_NotSupported,

    (PFNVOID)SC_CreateAPISet,               //  2

    (PFNVOID)EXT_VirtualAlloc,              //  3

    (PFNVOID)EXT_VirtualFree,               //  4

    (PFNVOID)EXT_VirtualProtect,            //  5

    (PFNVOID)EXT_VirtualQuery,              //  6

    (PFNVOID)SC_VirtualCopy,                //  7

    (PFNVOID)0,                             //  8 Was SC_LoadLibraryW

    (PFNVOID)SC_FreeLibrary,                //  9

    (PFNVOID)SC_GetProcAddressW,            // 10

    (PFNVOID)SC_ThreadAttachOrDetach,       // 11 Was SC_ThreadAttachAllDLLs

    (PFNVOID)0,                             // 12 Was SC_ThreadDetachAllDLLs

    (PFNVOID)SC_GetTickCount,               // 13

       XXXXXXXX还有很多就不一一列举了。

       将系统调用分组的一个重要原因是DISPATCH_I_KPSL这个定义,它定义了这些函数在什么进程空间里,以什么方式调用到。

 

(三) 进程控制块(PCB)的初始化

(四) 重新整理启动过程

抱歉!评论已关闭.