1)合并配置文件:所有的.BIB文件合并成CE.BIB。CE.BIB包含映像NK.BIN中的所有文件;所有.REG文件合并成REGINIT.INI;所有.DAT文件合并成INITOBJ.DAT;所有.DB文件合并成INITDB.INI。在修改配置文件时,一定要注意CE.BIB,REGINIT.INI,INITOBJ.DAT,INITDB.INI是中间文件,修改这些文件不能配置Windows CE。
(2)将REGINIT.INI文件压缩成一个二进制文件DEFAULT.FDF。
(3)根据环境变量COUNTRY的设置,替换模块中的资源,使Windows CE映像满足特定语言的需要,最后生成二进制映像文件NK.BIN。
BIB
在WinCE中使用的一个重要的文件就是BIB文件,全称Binary Image Builder File。在WinCE的编译过程中会用到BIB文件,应该是在最后的Makeimg阶段。所有的BIB文件会被合并成CE.bib文件,然后Romimage.exe会根据BIB文件中的描述来决定哪些文件最终被包含到WinCE image中。当然,BIB文件还决定了WinCE设备内存的分配,其中定义了WinCE image占用哪块内存,Framebuffer占用哪块内存等。
在BIB文件中分为4大项:MEMORY项,CONFIG项,MODULES项和FILES项。下面分别作个解释:
下面会详细介绍BIB的4大项:
1.MEMORY项
一般都在config.bib文件中定义,开头会有MEMORY的字样。这里定义了为WinCE image以及其他模块预留的RAM,同时也定义了WinCE可以使用的RAM。具体格式如下:
MEMORY NAME Start Address Memory Size Type
NAME:该内存区域的名字,必须是唯一的。
Start Address:该内存区域的起始地址,用十六进制表示。
Memory Size:该内存区域的大小,用十六进制表示。
Type:内存区域的类型。包涵的多种类型如下。
类型值 | 描述 |
|
|
|
|
2.CONFIG项
一般在config.bib文件中定义,定义了一些额外的配置参数,其中一些对于WinCE image来说也很重要。具体格式如下;
CONFIG
ITEM=Parameter
ITEM | 描述 |
AUTOSIZE | 允许未被使用的WinCE image的RAM被用作WinCE系统的RAM。默认值为ON。 |
COMPRESSION | 允许Romimage.exe压缩WinCE image中的可写入部分。默认值为ON。 |
BOOTJUMP | 定义了跳转跳转页在RAMIMAGE空间的地址。而不是默认情况下的RAMIMAGE的首地址。默认值为NONE。 |
FSRAMPERCENT | 定义了文件系统使用的内存的百分比。默认值为0x80808080。Byte 0:第一个2MB中,每1MB所包含的4KB的倍数。Byte 1:第二个2MB中,每1MB所包含的4KB的倍数。Byte 2:第三个2MB中,每1MB所包含的4KB的倍数。Byte 3:剩下的内存中,每1MB所包含的4KB的倍数。 |
KERNELFIXUPS | 定义了Romimage.exe是否重新定向内核的可写入区域。默认值为ON,内核的可写入区域被重新定向到RAMIMAGE的起始位置。 |
OUTPUT | 定义了最终生成的image存放的路径。默认为%_FLATRELEASEDIR%。 |
PROFILE | 定义了是否在WinCE image中包含profiler的结构和符号。默认值为OFF。 |
RESETVECTOR | 重新指定跳转页的位置,一般针对MIPS芯片从0x9FC00000开始引导的 |
ROMFLAGS | 内核标记位,可以进行组合:0x01表示禁用按需分页。0x02表示禁用完全内核模式,完全内核模式表示所有的线程都运行在内核模式。0x10表示只信任ROM MODULES中的模块。0x20表示停止刷新TLB。0x40表示按照/base链接选项中的地址加载DLL。 |
ROMSTART | 指WinCE image在内存中的起始地址。 |
ROMSIZE | 指WinCE image的大小。 |
ROMWIDTH | 指数据总线的宽度。 |
ROMOFFSET | 指定一个偏移量来修改.bin文件中的每一个记录的地址。一般用于ROM中的.bin文件加载到RAM来运行的情况,主要是表示存储.bin的位置和运行.bin的位置不一样。 |
SRE | 使Romimage.exe产生一个.sre文件。默认值为OFF。 |
X86BOOT | 定义是否插入一条跳转指令,在x86复位向量地址的时候。 |
3.MODULES项和FILES项
该项列出了所有被包含在WinCE image中的模块以及文件,以及这些模块和文件以什么方式被加载到内存中。具体格式如下:
MODULES Name Path Memory Type
Name:模块的名字,比如一个dll或者exe文件的文件名。
Path:路径,一般都是WinCE的工程的Release目录。
Memory:指定该模块被放在哪个区域,一般都是NK区域。
Type:定义了文件的类型。具体如下:
类型 | 描述 |
S | 系统文件。 |
H | 隐藏文件。 |
R | 只压缩模块的资源部分。 |
C | 压缩模块的所有部分。 |
D | 禁止调试。 |
N | 模块是不可信任的。 |
P | 告诉Romimage.exe不需要检查CPU的类型。 |
K | 告诉Romimage.exe必需固定该模块的内核地址。有该标记的模块只能被LoadKernelLibrary函数加载。 |
X | 告诉Romimage.exe对该模块签名。 |
M | 运行时加载整个模块,不要按需分页。 |
L | 告诉Romimage.exe不要分离ROM DLL。 |
一般FILES项的Type只支持S,H,N,D几个类型,而MODULES项的Type是都支持的。
举个例子吧:
INIT.EXE %_WINCEROOT%RELEASEINIT.EXE NK SH
MYDLL.DLL %_WINCEROOT%RELEASEMYDLL.DLL NK SHC
对于BIB文件来说同样支持“条件编译”,我们可以通过设置环境变量来选择性地将某些模块打包到WinCE image中。一般在BSP中,对于一些驱动模块的环境变量我们IF来进行条件判断。而对于WinCE的系统模块来说,一般都是SYSGEN变量,应该使用@CESYSGEN IF来判断。
我们在BSP的开发中最常见的主要就是eboot.bib,config.bib,platform.bib和project.bib。下面简单介绍一下:
project.bib:该文件主要自创建的WinCE工程中所需的一些文件。
platform.bib:该文件包含了和硬件平台相关的文件,主要以驱动程序为主。
config.bib:该文件描述了WinCE系统的内存的配置。
eboot.bib:该文件描述了WinCE的eboot的内存的配置。
还有其他的一些bib文件,在WinCE系统编译后都会背拷贝到工程的release目录下面。比如common.bib,ie.bib等。这些文件列出了WinCE的组件相关的文件,根据用户订制的系统,会被选择性的打包到WinCE image中。
REG
registry -type
Choosing the correct registry will improve the characteristics and behavior of your target device. The registry type is invisible to applications, but it will change the persistence, boot sequence and speed, and memory usage on your target device.
There are two registry options you can use to select the registry for your target device:
RAM-based registry
Hive-based registry
Ram-based
The RAM-based registry stores all registry data in the object store, which is in RAM. Therefore, registry data persists on warm boots but not on cold boots.
The RAM-based registry is efficient on target devices that often warm boot; it is inefficient on target devices that often cold boot. The RAM-based registry is best suited for single-user target devices with battery-backed RAM or with a lack of persistent storage to use.
The OS allows you to reregistry data in files, also called hives, which can be located on any file system. This allows OEMs to easily persist the registry across cold boots without powering RAM.
The hive-based registry is most efficient on target devices that cold boot often but rarely or never warm boot. It is best suited for target devices with persistent storage or multiple users.
The hive-based registry also provides separate user hives so registry configurations can be customized differently for each user. A multi-user system will contain several user hives. A user's hive can be mounted on logon and unmounted on logoff. trieve all registry information to provide the ability to backup and restore on cold boot. However, it is an item-by-item process and can be very slow for a large registry.
Hive-based
The hive-based registry stores all registry data in files, also called hives, which can be located on any file system. This allows OEMs to easily persist the registry across cold boots without powering RAM.
The hive-based registry is most efficient on target devices that cold boot often but rarely or never warm boot. It is best suited for target devices with persistent storage or multiple users.
The hive-based registry also provides separate user hives so registry configurations can be customized differently for each user. A multi-user system will contain several user hives. A user's hive can be mounted on logon and unmounted on logoff.
补充:
WinCE下面就两种注册表,一种是RAM based,另外就是HIVE based了,缺省用的是前者,如果用前者PB会在编译的时候把common.reg和platform.reg的内容做到一个叫reginit.ini的文件然后压缩成default.***的文件放到XIPKERNEL中去,image在起来的时候会把这个文件解压到RAM中形成RAM based注册表,既然是RAM based那么所有的改动都会在断电后蒸发,哈哈。怎么办呢?其实再笨你也能想出来,保存到磁盘上不就结了吗!?对你太聪明了,但是你想如果你把注册表全放到磁盘(SDMMC或HDD或Flash)上WinCE怎么在没有加载你磁盘的驱动的情况下读到注册表呢?而一般情况加载磁盘的驱动程序也是要注册表的支持啊!嘿,对了,这就是HIVE想到的,看它怎么做。
HIVE把注册表分成两部分(其实是三部分,当时大体还是两步分,把user.hv和system.hv做一部分),第一部分就是叫做boot.hv的注册表,里面的东西就是一些在没有拿到保存在磁盘的注册表之前引导时需要的一些设置,这部分的注册表和RAM based的是一样的,改了之后断电就没了,所以这部分的注册表项都是不需要改动的,需要改动的都放到第二部分就是了,这第二部分就是system.hv和user.hv了,也就是一直提到的要放到磁盘上的注册表. 编译的时候PB会根据platform.reg和Common.reg中的标签判断哪些表项放到boot.hv中,这个标签就是;HIVE BOOT SECTION ;END BOOT SECTION,夹在这个标签之间的表项PB在编译的时候会把它们塞到boot.hv中去(boot.hv是二进制文件,要看里面到底放了哪些表项用一个老外写的工具吧,好像叫d_readvol.exe,到google上找得到的),其他的内容会分别塞到default.hv和user.hv中去,最后会把这三个hv文件统统塞到XIPKERNEL中去,这样WinCE在引导的第一阶段就把所有的hv扔到RAM中去了,然后打开boot.hv拿到必要的资料,这其中包括如何加载放置system.hv的磁盘的驱动,所以那些和加载这个磁盘相关的驱动要统统放到boot.hv中,比如FAT文件系统驱动,mspart分区驱动等等,这里有一点很重要就是假如你用binfs而且device.exe在NK.bin中,那么一定在第一阶段要保证binfs可用,否则这里就不可能为system.hv创造条件了。WinCE第一次启动时候磁盘上没有东东,这个时候WinCE会将内存中的default.hv和user.hv复制到注册表BootVars指定的地方,default.hv往往会被重命名为system.hv,第二次启动会先检查磁盘上的hv是不是和内存中的一致,不一致就加载磁盘上的表项。
1. REG文件
注册表文件,这个和Windows操作系统中使用的注册表文件基本一样,在BSP中主要是Platform.reg,该注册表文件描述了和硬件平台相关的配置,大部分是用来描述驱动的相关信息。
注册标的格式如下:
[KEY1]
"ValueName1"={Value Type}:{data}
"ValueName2"={Value Type}:{data}
[KEY2]
"ValueName1"={Value Type}:{data}
其中Value Type和data相互对应,不同的Value type对应不同的data,具体如下:
Value Type |
data |
|
REG_SZ |
”my string” |
字符串类型 |
REG_DWORD |
dword:NNNN(hex number) |
DWORD类型 |
REG_MULTI_SZ |
multi_sz:”my_string_1”,”my_string_2” |
多字符串类型 |
REG_BINARY |
hex:xx,xx,xx |
二进制类型 |
HEX |
hex(xxxxxxxx):xx,xx,xx,xx |
十六进制类型 |
在注册表中,同样可以使用IF/ENDIF来进行条件包含,其中条件可以是一个WinCE中的环境变量,还可以在该环境变量后加一个空格再加一个惊叹号(“!”),表示没有设置或者不等于的情况,比如:
IF environment variable [= value] [!]
[KEY1]
"ValueName1"={Value Type}:{data}
"ValueName2"={Value Type}:{data}
[KEY2]
"ValueName1"={Value Type}:{data}
ENDIF
如果注册表某一行是以分号(“;”)开始,表示这行是被注释掉的。当然也有一些例外,比如在支持Hive注册表的时候,如下:
; HIVE BOOT SECTION
... reg data...
; END HIVE BOOT SECTION
关于Hive注册表,以前介绍过,这里不多说了。我们在注册表中无非就是创建,删除key,赋值等操作。
创建一个注册表key:
[Key1]
"ValueName"="Value Type"
删除一个注册表key:
[-KEY1]
删除一个注册表值:
"ValueName1"=-
和BSP以及硬件平台相关的注册表配置都放在platform.reg文件中,和WinCE工程相关的配置应该放在project.reg文件中。
在WINCE中,reg文件和bib文件是两种重要的文件,它影响了整个的CE系统。在解析的过程中,原始的Common.bib, Config.bib, Project.bib, Platform.bib等文件会合成为ce.bib,而原始的Common.reg, Project.reg, Platform.reg等文件会合成Reginit.ini文件,并进一步压缩成为default.ftf。
但是在解析过程中,两者的具体合成过程却不尽相同。
(1)合成bib文件
fmerge –bib命令就是合成bib的,它会依次提取下列文件中的项到ce.bib文件中:
config.bib
common.bib
dcom.bib
gdiex.bib
ie.bib
script.bib
servers.bib
shellsdk.bib
shell.bib
wceshellfe.bib
wceappsfe.bib
viewers.bib
directx.bib
datasync.bib
netcf.bib
SQLCE.bib
project.bib
platform.bib
若是在提取过程中遇到相同的项,前面的有效,后面的忽略。假设有个项,如mydll.dll,在project.bib和platform.bib中同时出现,合成过程以在project.bib中的有效,而忽略platform.bib中相同的那项。
(2)合成reg文件
fmerge –reg就是合成reg的命令。它会依次提取下列文件中的项到Reginit.ini文件中:
common.reg
dcom.reg
gdiex.reg
ie.reg
script.reg
servers.reg
shell.reg
wceshellfe.reg
wceappsfe.reg
viewers.reg
directx.reg
datasync.reg
netcf.reg
SQLCE.reg
project.reg
platform.reg
原文:
Note The registry values in Platform.reg override the default values specified in Project.reg and Common.reg. The registry values in Project.reg override the default values specified in Common.reg.
注 意了,在处理相同项时,在这里会与bib文件有所不同。若是在提取过程中遇到相同的项,后面的有效,前面的忽略。即:后面的覆盖前面的。假设有个项,在 project.reg和platform.reg中同时出现,合成过程以在platform.reg中的有效,而忽略project.reg中相同的那 项。这一点十分重要,也值得十分重视。
DB文件
数据库文件,同样也有platform.db和project.db两个文件。但是很少会被用到,特别是platform.db,这些数据库文件都是基于WinCE的对象存储的,会在WinCE启动以后被加载到RAM中,掉电就会丢失,具体格式如下:
Database : "db_name" : hex_type : num_sort_order : <sort order specifier> 1
Record :
Field : field_hex_propid : value
End
End Database
DAT文件
文件系统文件定义了目标设备上基于RAM的文件和文件夹组织情况。当系统冷启动的时候,Filesys.dll通过这个*.dat文件来建立基于RAM的文件和文件夹树,也就是定义有哪些文件夹,哪些文件在什么位置等。每次冷启动的时候,Filesys模块会根据.dat文件中的内容来创建目录以及目录下的文件。
在BSP中我们可以找到platform.dat。在创建一个WinCE的工程以后,可以在工程目录下面找到project.dat。可以在这两个.dat文件中定义我们所需的根目录以及相应的子目录和文件,当然Windows文件夹及其包含的子文件夹除外。
DE>root:-Directory("My Documents")
root:-Directory("Program Files")
Directory("Program Files"):-Directory("My Projects")
Directory("Program Files"):-Directory("Accessories")
Directory("Program Files"):-Directory("Communication")
Directory("Program FilesMy Projects"):-File("My Project Program", "WindowsMyproj.exe")
root:-File("control.lnk", "Windowscontrol.lnk")DE>
简单解释一下,上面的内容是先创建My Documents和Program Files两个根目录,然后在Program Files下面创建My Projects,Accessories和Communication三个子目录,然后拷贝被定义在Windows目录下的存在于ROM中的Myproj.exe文件到My Projects目录下面,且名字为My Project Program。这里需要说明的一点就是,像Myproj.exe这样的文件都是从ROM中拷贝出来的,所以必须在BIB文件中包含了该文件。最后一行意思是在根路径下创建control.lnk,该文件来自ROM中的control.lnk文件,是一个快捷方式文件。
对上面的一些格式做个解释:
1.Root Directory的
DE>root:[-Directory("dir_name")] [-Permdir("dir_name")]
[-File("target_filename", "source_location")]DE>
root:表示根目录。
-Directory(“dir_name”):定义根目录下的目录名。
-Permdir(“dir_name”):定义一个永久的目录,用户是不能通过RemoveDirectory函数删除的。
-File(" target_filename", " source_location"):定义一个目标文件,该文件从ROM中拷贝过来。target_filename为目标文件的文件名,source_location为ROM中的文件,指Windows目录下的某路径下的文件名。
2.Directory的语法格式:
DE>Directory("dir_name"):[-Directory("dir_name")]
[-File("target_filename", "source_location")]DE>
Directory(“dir_name”):表示目录名。””表示根目录。
-Directory(“dir_name”):表示目录下的路径,就是子目录。
-File(" target_filename", " source_location"):定义一个目标文件,该文件从ROM中拷贝过来。target_filename为目标文件的文件名,source_location为ROM中的文件,指Windows目录下的某路径下的文件名。
DAT中所使用的语法定义比较简单,看看例子就知道如何修改了,一般我们会通过修改project.dat和platform.dat来改变WinCE启动后的文件路径结构。其中platform.dat是和平台相关的,而project.dat是和WinCE工程相关的。