我很庆幸在公司的产品开发过程中并没有受到Boot Loader带来的阻力,因为我们采用MSDOS+Loadcepc来启动CE操作系统。显然这样的幸运不是永远的,所以对Boot Loader应该有足够的研究和了解,做到未雨绸缪。
Boot Loader是定制Windows CE操作系统过程中一个重要的开发环节。Boot Loader的作用正如名字中的两个单词:Boot,既引导系统,如果基于CE的产品采用BIOS实现硬件初始化和配置,那么Boot Loader只需引导软件系统。如果没有采用BIOS,那么Boot Loader的作用还包括实现BIOS的基本功能;Loader,既加载操作系统,在整个系统正常启动后Boot Loader通过不同的方式加载CE的内核文件nk.bin。当Boot Loader把nk.bin解压到RAM后就把CPU控制权交给CE内核。x86平台的Boot Loader种类最多,下面就对x86平台的Boot Loader做一说明:
x86 ROM Boot Loader
又叫Rom Boot,记得以前写过的文章中提到了Rom Boot。Rom Boot 被设计存放在Flash/EEPROM中,也就是原来BIOS的位置,这样当上电后CPU到固定地址执行代码,也就是执行了Rom Boot包含的代码,它对整个硬件系统进行初始化和检测,并且支持通过网卡从远程机器上下载nk.bin或者从本地IDE/ATA 硬盘的活动分区中寻找nk.bin文件加载。Rom Boot的优点就是引导并且加载速度快,而且它自身完成了所有的操作,这样就不用BIOS、MSDOS,更不用Loadcepc了。缺点就是需要CE开发者读懂它的源码并修改。CE提供了Rom Boot的所有源码,读者可以查找标题为"x86 Source Organization"的帮助文档,在这个文档中列举了所有相关的目录及内容,另外还列举了四种网卡的驱动程序源码所在目录。
x86 BIOS Boot Loader
BIOS Boot Loader和MSDOS+Loadcepc两种方式差不多,BIOS Boot Loader只是不需要MSDOS操作系统,它仍然需要BIOS和FAT文件系统。下面讲一下采用BIOS Boot Loader的系统的引导顺序:系统上电后BIOS执行完硬件初始化和配置后,BIOS检查引导设备的启动顺序,如果引导设备是硬盘、CF卡、DOC(Disk-On-Chip)一类的存储设备,那么就加载这些存储器上的主引导扇区(Master Boot Sector)中的实模式代码到内存,然后执行这些代码。这里提到的代码被称为主引导记录(MBR)。MBR首先在分区表(同样位于主引导扇区)中寻找活动分区,如果存在活动分区,那么加载位于这个活动分区的第一个扇区上的代码到内存,然后执行这些代码。这里提到的活动分区的第一个扇区被称为引导扇区(Boot Sector)。引导扇区上的代码的功能是找到并且加载BIOS Boot Loader,BIOS Boot Loader再加载nk.bin。引导扇区的源码位于%_WINCEROOT%\Public\Common\Oak\Csp\i486\Biosloader\Bootsector目录下。有一个现成的引导扇区镜像文件,它的路径为%_WINCEROOT%\Public\Common\Oak\Csp\i486\Biosloader\Diskimages\Setupdisk\Bsect.img 。而对于BIOS Boot Loader,CE提供了Setupdisk.144和Bootdisk.144两个文件,以“.144”为扩展名的文件的解压我在前面的文章中讲过了。这两个文件解开后都包含了引导扇区和Boot Loader的镜像文件。执行“mkdisk C:”批处理命令将这两个镜像文件写到磁盘上。mkdisk会设置Boot Loader的隐藏属性,这样在列出根目录下所有文件时不会显示Boot Loader的文件。
MSDOS+Loadcepc
这种方式非常简单,在MSDOS启动后再执行loadcepc.exe,让loadcepc加载nk.bin到内存后再把CPU控制权交给CE内核程序。loadcepc在前面的文章中已经讲过了。
下面根据一般的Boot Loader源码来分析一下Boot Loader的组成:
Boot Loader由两部分组成:OEM启动代码(OEM startup code)和主代码(main code)。OEM启动代码是最先执行的部分,它的功能是初始化内存寄存器、设置CPU频率、初始化高速缓存等。之后它跳转到主代码中执行。一般OEM启动代码都是用汇编编写。主代码一般用C语言编写,它负责其它所有任务,在执行的同时还能够将执行的相关信息显示在屏幕上。一般添加公司LOGO或者其它启动LOGO都在此修改。