Windows Mobile boot 过程详解

Wince 中可以比较方便的查看系统启动的过程
OEM开发时,需要写一些初始的代码。这些初始代码要和内核部分的HAL (hardware abstraction layer)相一致。当OEM根据自己的硬件平台搭建一个系统时,HAL和Wince的内核是通过静态链接来生成NK.exe的。
实际上,当OEM Porting 一个Wince新平台时候,他们所写的代码要远远多于HAL。他们还需要写一些Graphics Windowing and Event Subsystem (GWES)下的thin layer代码,以便和GWE使用的一些基本驱动相连接。此外,OEM还必须写一系列设备驱动,包括显示屏,键盘,触摸板,串口,音频设备等等。HAL和驱动通常被称作OEM
适配层,即OAL(OEM Adaptation Layer) .
下面以Reset的过程来分析一下启动的过程:
1. 当系统Reset后,CPU跳到NK.exe的入口地址,即Wince的内核模块的地址。入口点的代码通常是由OEM来写的而不是微软.这部分代码通常是用汇编来写,一般被命名为“Startup”,他主要负责初始化CPU,使内核能操作他。因为Wince上用的大部分是嵌入式的CPU,而这样的CPU通常有大量的寄存器,这些寄存器必须被设置好以便配置系统的速度等。有时还需要配置寄存器的基地址。Startup 也常常用来对一些缓存进行初始化,以确保ensuring that the system is in an uncached, flat addressing mode.
当Startup 完成任务后,他将跳转到内核的入口点--KernelStart。这是微软为NK写的代码。KernelStart开始配置虚拟内存管理器,初始化默认handler的中断向量列表;并且调用下层的OEM层初始化debug串口。
2.
然后KernelStart通过KernelRelocate从ROM拷贝已初始化好的堆数据到RAM中,以初始化他的本地堆。现在本地的堆已经为NK.exe初始化好了,此时代码的动作更像一个程序而不是Loader了。然后内核回调下面的HAL的OEMInit 程序。OEMInit通常是用C写的,他的工作是去初始化所有的OEM制定的硬件。主要包括:hooking interrupts, initializing timers, and testing memory.
3.
系统对集成的外围设备做一些初始的配置,然后放置他们为哑态,直到他们的驱动能被载入。在启动过程中,OEMInit 通常画一些闪点在显示屏上。当OEMIint返回后,内核回调进入HAL,询问系统是否有可用的RAM。当OEM在创建一个ROM Image时应该大概估计一下RAM的大小和位置,并定义一下他们的大小和分配。OEM用程序OEMGetExtensionDRAM来告诉内核是否有可用的RAM.一旦OEMGetExtensionDRAM返回,内核能中断并调用调度程序来安排系统的第一个线程。此时,内核开始查找文件“FileSys.exe” 并开始那个应用。系统载入器(用来把EXEs和 DLLs载入到内存)按照一定的顺序查找并定位FileSys.exe.
内核通过扩展可以来决定是否把系统连接到debugging station。debugging station是指运行着特定调试软件的PC.
4.
PC和Wince系统可以通过串口,并口或者专用的以太网来连接。如果系统发现存在这样的链接的话,当系统要求载入一个文件时,载入器将在PC上查找这个模块(EXEs或者DLLs)。常用的技巧是,我们可以无缝的扩展Wince的\Windows目录去包括任何Debugging PC上特定目录下的模块。这样系统会载入那些BOOT过程中没载入的模块。然后,当系统开始运行后,你可以直接载入PC上的模块,而不用把他们拷贝到Wince的目标存储区。FileSys 用来管理文件系统,数据库函数和注册。当FileSys被载入时,他会在RAM中查找是否有已经初始化好的文件系统。如果找到了,他就使用这个已经初始化好的文件系统,并允许Wince的设备存放数据到RAM的文件系统上。如果没找到的话,他会创建一个能和ROM里的文件融合的空RAM文件系统。FileSys通过一个ROM Image 内建的列表可以知道那些文件是存在ROM中的。(ROM Image 是通过ROM builder program来生成的,ROM builder program可以把所有单独的程序合并为一个Image)。FileSys通过一个存储在ROM上的文件来读取系统默认的目录结构。目录结构的入口组成是由微软推荐的。除了初始化文件系统以外,FileSys还创建默认的数据库Images和默认注册表。默认数据库和和注册表的初始化images也是被微软和OEM定义在ROM的文件中的,这个文件驱动的初始化过程,允许OEMs自定义文件系统的初始化images。
一旦文件系统初始化完成后,系统初始化就能够继续进行。但是,在这个时候内核需要去等待,因为他需要来自的注册表的数据去继续启动的过程。特别是,内核会查找注册表里面[HKEY_LOCAL_MACHINE]\Init下面的值。这个键下面的值将提供,name,order以及一些依赖关系。那些能被启动的进程都是通过Launchxx来指定的,其中xx是一个启动顺序的数字。一个可选的值Dependxx,用来启动一个有依赖关系的应用,即他的启动依赖于指定的XX,其中XX在顺序队列里要比他早。
例如:
Value                   Data            Comments
Launch10                SHELL.EXE

Launch20                DEVICE.EXE

Launch30                GWES.EXE
Depend30                0014            Depends on Device (0x14 == 20)

Launch50                EXPLORER.EXE
Depend50                0014 001E       Depends on Device and GWE
内核启动这些应用的顺序是按照他们Lannch后面数字的大小来的。内核要载入每一个列出的应用。当应用成功的完成初始化后,他通过函数SignalStarted 发送成功初始化信号给内核,同时把XX也传给内核。内核通过这些应用对SignalStarted的调用,能知道任何相关的进程现在能被启动。这个启动列表通常是由OEM使用。你可以插入其他的应用到这个列表。只要保证了你的应用所以懒得应用已经被提前载入了就行。例如:你可以写一个应用,在Device之后,GWES之前载入他,只要你的应用在GWES被初始化之前不调用任何window manager or the graphics functions等就可以。注:如果你在Explorer之前开始一个具有标准用户接口的应用的时候,你会给Explorer代码麻烦,所以除非你要启动一个应用来支持系统的服务,否则你应该使用Explorer在StartUp来启动你的应用。此外,你不会独立的成功启动依赖于Explorer的应用,因为Explorer.exe初始化时不调用SignalStarted。
Shell.exe
Shell是一个比较有趣的应用,因为在大多数系统中他甚至不在ROM中。Shell.exe是CESH的Wince部分,命令行监视器。因为Shell不在ROM中,所以只有通过把系统和PC debugging station相连接后才能载入他。通常他都是自动载入的。
CESH 使用内核去连接debugging PC来和程序员交流信息。CESH在PC上打开一个console session,可以替代一个在PC上正打开的文件。CESH 调试器给OEM提供了大量有用的函数。 首先,他给OEM开发者一个命令行的SHELL,在PC上运行他能开始一个应用,查询系统状态,读写系统的内存等等。
CESH调试器也让开发者方便的操作Wince debug zones 的调试信息。当你开发时,调试信息的输出是很有用的。Wince 中调试信息是通过串口发送的。这样常常有 很多无关的信息烦扰你去发现有用的信息。debug zones允许开发者能够通过使用宏,选择性地打开和关闭来自代码的调试消息输出。这允许您跟踪代码的执行状况,而无需暂停操作系统。每个信息被分配到16个debug zones之一,因此,开发者能使用CESH来打开或关闭16个zones的每一个。

posted on 2008-04-17 18:15  Luckyer  阅读(1479)  评论(1编辑  收藏  举报

导航