windows mobile 启动过程.docx
《windows mobile 启动过程.docx》由会员分享,可在线阅读,更多相关《windows mobile 启动过程.docx(19页珍藏版)》请在冰豆网上搜索。
windowsmobile启动过程
WINDOWSMOBILE启动过程
本文档内容来源微软文档或者是MSDN在线帮助文档,最后有网上找到得WM5的启动过程供参考。
BOOTSequence2
Nk.exeBootProcess2
WINDOWSMOBILE5启动过程(网络资料)6
BOOTSequence
在NOR设备正常的引导过程中,初始化程序装载器InitialProgramLoader(IPL)从CPU复位向量表开始运行,如果拥有已存在的BOOTLOADER,则其先运行,之后将控制交给IPL。
对于NAND设备,如果CPUFLASH内存接口支持NAND引导,则在复位时将第一个NAND块的数据流到内部CPURAMBUFFER。
当已启动,IPL读取一个开关或者按钮和一个由UpdateAgent,UpdateBin.exe设置的软件标志位,用于决定是否装载用于映像更新的dateLoader(ULDR)还是装载或启动内核映像(即正常启动)。
IPL已经预先知道了masterBOOTrecord(MBR)的位置并且定位存储在MBR的分区表中的活动分区。
定位了活动分区之后,IPL或者装载活动分区—内核分区的内容倒RAM----在NAND的情况下,或者可能是NOR,或者如果是一个NORXIP内核就跳转到在分区内的启动地址。
Nk.exeBootProcess
WindowsMobile-WindowsEmbeddedCE启动过程
在引导过程中,系统调用kernel,Nk.exe被初始化,然后被引导。
.
在kernel引导过程中,按如下顺序调用函数:
Nk.exe
1、StartUp
2、KernelStartorKernelInitialize
3、
4、OEMInitDebugSerial
5、OEMInit
6、KernelInit
7、HeapInit
8、InitMemoryPool
9、ProcInit
10、SchedInit
11、FirstSchedule
12、SystemStartupFunc
13、IOCTL_HAL_POSTINIT
Startup
在kernel启动过程中这是第一个被调用的函数,该函数初始化CPU到已知状态。
StartUp函数完成如下任务:
1、完成最小的处理器和硬件初始化。
2、屏蔽interrupts,caches,和thememorymanagementunit(MMU).
在StartUp函数初始化CPU后,调用KernelStart或者KernelInitialize函数。
StartUp函数位于%_WINCEROOT%\Platform\\Common\Src\Soc\\Startup\Startup.*,通常用汇编编写并由bootloader分配.
KernelStartorKernelInitialize
OEMadaptationlayer(OAL)建立了任何平台或具体CPU设置,这些被要求用于kernel访问ROM和RAM.。
为了启动系统,他跳转到KernelInitialize(对于基于x86硬件平台)或者KernelStart(对于其他硬件平台)。
在此时,MMU和caches应该被禁用。
KernelStart或KernelInitialize完成如下任务:
1、从ROM中的Copy区通过调用KernelRelocate初始化kernel全局变量。
2、(ARMandX86only)初始化第一级基于OEMAddressTable内容的页面表。
3、(ARMandx86only)启用MMU与caches.
4、为每一种操作模式初始化stacks。
5、通过使用目录表找到Kernel.dll的入口点。
6、跳转到Kernel.dll的入口点------主要的kernel初始化函数
对于MIPS和SHx平台,cache和MMU在Kernel.dll的入口点被启用。
直到MMU被启用,kernel符号地址是无效的并且必须通过OEMAddressTable被转换来获取正确的物理地址。
KernelStart和KernelInitialize函数的实现在%_WINCEROOT%\Private\Winceos\Coreos\Nk\Ldr\.在KernelStart或者KernelInitialize执行完所有任务之后,它为kernel调用主初始化函数。
MainKernelInitializationFunction
主kernel主要负责调用OEM提供的初始化函数,它完成如下任务:
1、建立NKGLOBALS结构体
该结构体定义了所有kernel到kernelindependenttransportlayer(KITL)和OEMadaptationlayer(OAL).的输出。
2、初始化OEMGLOBALS结构体
该结构体定义了所有从OAL到kernel和KITL的输出。
如果映像文件编译有KITL,kernel初始化函数加载Kitl.dll并调用Kitl.dll.入口点函数。
3、使用OEMInitDebugSerial.初始化测试串行口
4、显示通过测试端口WindowsEmbeddedCE开始命令消息
5、初始化硬件平台,使用OEMInit.
6、使用KernelFindMemory程序建立内存。
7、跳转到KernelInit程序来完成初始化,然后跳转到第一个线程。
使用ARMkernel,KernelStart调用ARMInit作为主初始化函数。
OEMInitdebugSerial
OEMInitDebugSerial初始化目标板的测试串行口。
测试功能通过串行设备来通信。
因为bootloader实现了同样的代码,OAL和bootloader可以共享这。
需要实现的串行测试功能:
OEMDebugInit
OEMWriteDebugString
OEMWriteDebugByte
OEMReadDebugByte
NK标志在OEMInitDebugSerial函数完成之后显示。
OEMInit
OEMInit由OEMs实现用来为目标板初始化所后硬件接口。
在此刻的kernelboot过程中中断被禁止,并且kernel不能处理异常。
OEMInit唯一可用到的内核服务事HookInterrupt.OEMInit可通过调用HookInterrupt.来注册interruptserviceroutines(ISRs)。
如下得硬件初始化被要求:
Interrupts
Systemtimer
KITLinterface
依赖硬件可选得初始化包括如下:
Businterfaces.
OEMInit函数实现例子%_WINCEROOT%\Platform\\Src\OAL\.
KernelInit
KernelInit函数压缩装入了内核的初始化,它通过调用不同的初始化函数来如下内核部分:
1、Heap
2、Memorypool.
3、Kernelprocess.
4、Scheduler.
在调用这个函数之后,系统SystemStartupFunc通过已经准备调度第一个线。
KernelInit函数的实现是在专有目录下。
HeapInit
HeapInit初始化kernelheap.
InitMemoryPool
InitMemoryPool初始化kernelmemorypool.
ProcInit
ProcInit初始化WindowsEmbeddedCEkernelprocess.
SchedInit
SchedInit初始化调度程序并创建SystemStartupFunc线程。
FirstSchedule
FirstSchedule启动调度程序。
SystemStartupFunc
SystemStartupFunc运行IOCTL_HAL_POSTINIT.这个函数的实现由OEM代码把握用以完成内核初始化进程。
WINDOWSMOBILE5启动过程(网络资料)
1. startup.首先,内核最先执行的代码位于oal当中,叫做startup,这段代码由微软留给开发者定制。
当然,各个参考bsp里面都有现成的代码,开发者只需在此基础上改动。
在startup()的末尾,会跳转到kernelstart函数。
2. kernelstart. 位于WINCEROOT\Private\winceos\coreos\nk\kernel\mips\startup.s 这里面是汇编代码。
是所有的arm开发板的操作。
所以这里面会根据不同cpu类型作判断。
虽然是汇编代码,好在里面还是有不少注释,通过这些注释,可以看出它里面主要在干什么。
3. KernelRelocate. kernelstart在完成一些必要的初始化之后,会调用KernelRelocate函数,这是一个比较重要的函数,位于WINCEROOT\Private\winceos\coreos\nk\kernel\loader.c. 它会把kernel用到的数据copy的ram里面。
具体的功能msdn里面有解释。
这里的ram就是在config.bib里面指定的具有ram属性的存储区域,不是ramimage. kernelRelocate以pToc为参数,那么pToc的值从何而来呢?
即便你搜索完所有的文件也找不到在那里pToc被赋值。
因为pToc是在makeimage阶段被romimage.exe赋值的,也就是说pToc并不是在代码中被赋值的,是由外力(romimage.exe)改动nk.bin的内容赋值的。
4ARMInit. KernelRelocate处理完成之后,ARMInit会被调用,其中会调用oal当中的OEMInitDebugSerial去初始化调试用的串口。
5.OEMInit.接下来就是大名鼎鼎的OEMInit了。
这个函数由开发者定制。
是c语言的。
由上面的分析我们知道,在进入OEMInit的时候,串口已经初始化完毕,所以现在我们已经可以通过串口打印出一些调试信息了。
而在此之前,我们只能通过led的方式作一些简单的显示。
6.KernelFindMemory. 位于WINCEROOT\Private\winceos\coreos\nk\kernel\loader.c
OEMInit返回之后调用该函数。
这个函数主要是把ram划分为两部分:
object store和应用程序可以使用的部分。
object store就是用于存贮wince的ram file system的,例如开机以后我们看到的\windows目录就是位于ram file system.
7.KernelInit. 位于WINCEROOT\Private\winceos\coreos\nk\kernel\kwin32.c
这部分跟cpu无关,是kernel要完成自己的初始化。
至此,kernel得初始化全部完成,可以开始线程调度。
还有一点需要说明的时,kernel在完成初始化之后,会以IOCTL_HAL_POSTINIT为参数调用OEMIoControl,所以我们可以在这里打印出一句话表明kernel已经初始化完成。
除了kernel本身(nk.exe)之外,第一个被创建的进程就是文件系统,filesys.exe.
虽然他不是kernel本身的一部分,但是如果没有文件系统,wince也是玩不转的,注册表的初始化就是由文件系统来完成。
深入剖析windowsmobile启动过程
转自
硬件平台:
TIomap
软件平台:
WM5.0
相关术语:
RTOS Real-timeOperatingSystem
EBOOT ETHERNETBOOT
IPL InitialProgramLoader
整体流程:
powerON--〉BootROM--->x-loader---->Eboot----->IPL--->OS
下面围绕上述过程展开:
1powerON
这里指的是硬件powerON,当按触powerON键后,系统上电,同时触发CPU复位管脚。
系统进入到BootROM中,执行其中固化的代码。
2 BootROM:
BootROM中固化了一段引导代码,用于系统初始化,初始化必要的寄存器,决定启动流程是正常启动或者启动flashing,进入到x-loader。
BootROM的初始化工作有:
l 关闭可屏蔽中断
l 时钟设置和DPLL设置
l 配置ULPD寄存器,为UART提供48MHz的时钟频率
l 配置ARMCORE内部寄存器
l 配置EMIFS寄存器
l 建立ARMCORE中断向量表
上面的工作实际上就是初始化必要寄存器,例如EMIFS初始化。
在系统上电时候,BootROM代码会检测是否需要擦写flash内容,可以是部分擦写也可以是全部擦写。
擦写工作一般在上电时刻进行,BootROM代码初始化可编程接口(例如USB或者UART串口),然后等待从上位机发过来的bootcommand命令,如果在没有收到或者等待超时,系统正常启动。
(注;上位机是指:
人可以直接发出操控命令的计算机,一般是PC。
从概念上说控制者和提供服务者是上位机,被控制者和被服务者是下位机。
可以理解为主机和从机的关系)
如果等到上位机的bootcommand命令,上位机会downloadFlashloader程序到omap的interalram空间中。
Flashloader是由自身的header,flashloader应用程序和一些附加程序构成。
接着BootROM程序在安全模式下,检查flashloader的signatures来校验其完整性,如果检查失败,系统重启。
如果检查通过,flashloader程序开始运行,它将较大size的OSimagedownloader到Flash介质中。
BootROM决定启动方式:
1)从NOR或者NANDFlash正常启动
2)通过USB或者UART编程后,然后重新正常启动。
BootROM加载x-loader:
OSImage下载到flash后,bootROM代码会从NOR或者NANDflash中查找TOC。
TOC是在flash上的一个数据结构,包含了Image信息,起始位置,大小等等。
TOC可以有多个,每个TOC都对应着一个Image。
NANDflash上TOC最多为16个,最大size为512B。
NORflash情况不一样。
BootROM检测项目名为“x-loader”的TOC,让后将对应的Image加载到内存。
x-loader是一个通用的loader程序,被BootROM从FLASH中启动(NOR),x-loader承担OS的启动,x-loader会被校验然后才会授予权限继续运行。
NORflash上的sub-image具有XIP特性,因此NORflash上的x-loader大小不受限制。
对于NANDflash由于其不支持XIP,所以BootROM在其开始处预留了64K空间,这个预留空间用于启动扇区,至少包含一个TOC,TOC和其对应的image被copy到RAM空间,然后才能被执行。
3x-loader
x-loader的功能有哪些?
a,初始化硬件,如GPIO初始化。
b,加载Eboot代码到RAM空间
c, 跳转到Eboot代码
介绍一下x-loaderTOC实现机制:
xldr_startup.s (src\boot\xldr\)
。
。
。
。
。
。
ALIGN 0x200
DCD0x00000040 ;StartoffsetfromTOCstart(0x240)
DCD0x00000800 ;Size
DCD0x00000000 ;Flags
DCD0x00000000 ;Align
DCD0x00000000 ;Spare
DCD0x4F4C2D58 ;Filename-X-LO
DCD0x52454441 ;Filename-ADER
DCD0x00000000 ;Filename-Blank
DCD0xFFFFFFFF ;terminatingTOCentry
DCD0xFFFFFFFF
DCD0xFFFFFFFF
DCD0xFFFFFFFF
DCD0xFFFFFFFF
DCD0xFFFFFFFF
DCD0xFFFFFFFF
DCD0xFFFFFFFF
StartUp ;(0x240)//X-LOADER入口地址
EXPORTStartUp
INCLUDE..\..\..\common\src\ARM\TI\omap730\startup\hwinit.s
Hwinit.s的主要功能:
l SetSVCmode&disableIRQ/FIQ
l Initializecache&CP15controlregister
l InitializeTIPBBridges
l InitializeEMIFS(flash&debugboardcontroller)
l InitializeEMIFF(DRAMcontroller)
l InitializeOCPT1/OCPT2
l InitializeOCPI
l InitializeUPLD
l InitializeCLKM
l ConfigureOMAP730SoCmultiplexing
l ConfigureOMAP730SoCGPIO
l DisableWatchdogTimer
l SetDMAtoOMAP3.2mode
l ResetUSBmodules
4EBoot
EBoot(ethernetboot)位于MDOC的SPL分区,EBoot主要被PLATFORMBUILDER用来完成对DOC的编程,作为一个系统引导,下载工具,对菜单选项进行操作,并且通过EBoot能够对引导参数进行配置.
首先看看EBOOT对系统进行参数配置所设计到几个重要变量。
l g_bootCfg
typedefstruct{
UINT32signature; //Structuresignature
UINT32version; //Structureversion
DEVICE_LOCATIONbootDevLoc; //Bootdevice
DEVICE_LOCATIONkitlDevLoc;
UINT32kitlFlags; //Debug/KITLmode
UINT32ipAddress;
UINT32ipMask;
UINT32ipRoute;
}BOOT_CFG;
这个全局变量用来保存系统启动配置参数,实际上对菜单选项的操作实质上是对这个结构变量对应部分的设置。
通过BLMenu()来进行菜单选项的操作。
l g_eboot
typedefstruct{
OAL_KITL_TYPEbootDeviceType;
UINT32type;
UINT32numRegions;
UINT32launchAddress;
REGION_INFO_EXregion[BL_MAX_BIN_REGIONS];
UINT32recordOffset;
UINT8 *pReadBuffer;
UINT32readSize;
}EBOOT_CONTEXT;
启动参数的配置是通过菜单选项来实现的,系统通过两个全局变量g_menuNetwork,g_menuMain定义了菜单项,
首先来看看这两个变量的内容:
l staticOAL_BLMENU_ITEMg_menuNetwork[]={
{
L'1',L"ShowCurrentSettings",ShowNetworkSettings,//系统当前设置
NULL,NULL,NULL
},{
L'2',L"Enable/disableKITL",OALBLMenuEnable,//关闭或者使能KITL
L"KITL",&g_bootCfg.kitlFlags,(VOID*)OAL_KITL_FLAGS_ENABLED
},{