WinCE6.0bootloader的研究
为了加载操作系统映像至内存,Bootloader在BSP的开发中至关重要。
1.BootLoader的架构
1.1 Bootloader简介
Bootloader是建立在操作系统内核运行之前的一小段程序,通过这段小程序,可以初始化硬件设备、建立系统的内存空间映射图,从而将系统的软硬件环境带到一个已知的状态,以便为最终调用操作系统内核准备好正确的环境。最终,Bootloader把操作系统内核映像加载到RAM中,并将系统控制权传递给它。
一个典型的bootloader是由blcommon、OEM代码、EBOOT和网络驱动程序等组成,如图1所示:
图1 Bootloader的架构
Windows CE提供了BLCOMMON、EBOOT以及网络驱动程序相应的程序库,因此设计时建议尽量复用这些程序库,这样可以快速且高质量地完成Bootloader的开发。
1.2 Bootloader启动分析
当打开电源或者复位时,CPU首先执行Startup函数,Startup函数通常由汇编语言代码编写,主要用来建立存储器访问和初始化缓存。然后Startup函数跳转到Boot loader的第一个C语言函数main,该函数会接着调用BLCOMMON框架的BootloaderMain接口函数。Blcommon框架被实现为blcommon.lib库,并与平台特定的Bootloader代码进行链接。Bootloader的工作流程和函数调用如图2所示:
图2 Boot loader的工作流程和函数调用
具体解释如下:
1.系统上电或者复位后执行的第一条语句,主要功能是对目标系统的嵌入式CPU执行最基本的初始化,为CPU准备一个合适的运行环境,如清空TLB和cache、关中断、配置PLL、设置内存控制器。
2.调用BootloaderMain函数。进入高级语言的代码处理。
3. BootloaderMain函数调用KernelRelocate函数对Bootloader的全局变量重定位。
4.调用OEMDebugInit函数来初始化Boot loader的调试功能串口,这样就可以使用串口打印调试信息了。
5.调用OEMPlatformInit函数,进一步初始化目标嵌入式硬件平台,很多和平台相关的初始化工作都可以在这个函数中完成,比如时钟、下载传输端口、Flash存储器等。
6.调用OEMPreDownload函数,该函数在下载镜像之前被调用。从流程上来说应该是为下载内核做一些准备工作,该函数执行后,根据返回值得不同可以选择下载内核,或者跳转执行。 最典型的是通过调试串口向用户输出菜单选项然后接收用户的相应输入。
7.如果OEMPreDownload函数返回BL_DOWNLOAD时,将会从主机下载Windows CE image。
8.如果OEMPreDownload函数返回BL_JUMP时,直接跳转到Windows CE image所在的位置开始执行或者从本地存储器加载的操作系统镜像中运行。
其中涉及的OEM函数都是需要用户自己实现的,然后被BLCOMMON模块来调用。
2 Bootloader配置文件的编写
在实现Boot loader中需要OEM用户自己编写的部分之后,需要编写以下配置文件:
SOURCES文件:定义了代码的编译方法。编译程序通过SOURCES文件决定如何对代码进行编译和链接。
Makefile文件:需要包含Windows CE的通用Makefile。
Dirs文件:定义了对应文件夹的子目录,编译器通过Dirs文件确定要编译的文件位置。
Eboot.bib文件:该文件描述了Windows CE下Eboot的内存的配置。下面以2440通用配置为例:
; Name Start Size Type
; ------- -------- -------- ----
ARGS 80020800 00000800 RESERVED ;bootloader和操作系统共享此区域
BINFS 80021000 00005000 RESERVED ;二进制ROM映像文件系统
STACK 8002c000 00004000 RESERVED ;bootloader栈,16KB
EBOOT 80038000 00040000 RAMIMAGE ;eboot的大小256KB,在实现LOGO时候注意不能超过此值
RAM 800a0000 00020000 RAM ;bootloader RAM 128KB
; Area used to cache nk.bin while programming flash
FLSCACHE 80200000 01400000 RESERVED
DISPLAY 80100000 00100000 RESERVED
CONFIG
COMPRESSION=OFF
PROFILE=OFF
KERNELFIXUPS=ON
; ROMOFFSET=25FC8000
SRE=ON
ROMSTART=80038000
ROMWIDTH=32
ROMSIZE=00040000
MODULES
; Name Path Memory Type
; -------------- ---------------------------------------------- -----------
nk.exe $(_TARGETPLATROOT)\target\$(_TGTCPU)\$(WINCEDEBUG)\eboot.exe EBOOT
在实现上述配置文件之后,就可以编译Bootloader的代码,最终生成Eboot.bin的文件,通过对其的烧写,可以顺利完成内核镜像文件的下载。
这里,我稍微解释一下,可能对初学者有用。eboot.bib和config.bib中都有CONFIG配置区域,二者有什么区别和联系呢?
联系就是二者都是配置选项,毫无疑问,二者的语法意思也是一样的。
不同之处在于,eboot.bib的配置选项是对eboot.bin或者eboot.nb0镜像的创建、加载以及存储方式进行设置,而config.bib的配置选项是对NK.BIN或者NK.NB0镜像的创建、加载以及存储方式进行设置。