转自:http://www.armce.cn/bbs/thread-26-1-2.html
Nb0格式并不是每个人都能看到的,很多时候玩wince的人往往只知道把bin档下载到device就可以执行了,其实真正在内存中跑的,是XIP的nb0格式。
所幸我们的做法是先在PC上,就把PB编译好的BIN档转换为nb0,然后再用升级工具下载到device的NAND中。今天我们来探讨nb0,也即wince在内存中的真实写照!
下图是根据我们自己的一个nb0的image画的一张layout图,让我们来看看nb0里面到底是什么样的一种结构,图中假设bib设置的RAMIMAGE的起始地址是0x8C000000,大小为0xF00000。如果你的image支持multi-bin,那么在这里我们假设这是第一个支持XIP的region。
1.跳转指令:一般从最开始的位置,这里也就是0x8c000000会有一个跳转指令,可能是方便bootloader在不知道入口地址的情况下,直接跳到nb0的头,执行这句代码就跳转到了nk.exe的入口地址,开始kernel的引导。细心的同学可能会发现,nk.exe的source文件和其他的exe默认入口是Winmain不同,它有一个special的入口地址在此指定,类似的“EXEENTRY=StartUp”,那么这个跳转指令就是指向了StartUp函数了。
2.ECEC标识: 在从开始位置编译0x40左右的位置,会有一个string='ECEC',寻找这个字符串后,接下来的DWORD值就是ROMHDR结构体的地址。
3.ROMHDR:这个结构体基本上描述了wince下面内存的大体布局,图中,ROMHDR位于0x8c0d9840的地址。
结构体的定义如下:
typedef struct ROMHDR {
ULONG dllfirst; //表示的是slot1中的虚拟内存的最低点,也就是说如果还有其他的XIP的image要并进来,它的dll要从这里开始编址。这里是0x01F501FF,DLL的地址是从上向下张的。
ULONG dlllast; //这个是slot1的头顶,这里是0x02000000
ULONG physfirst; //这就是这个XIP region的开始点,对应的是虚拟内存,可以在ce下直接访问,这里是0x8c000000。
ULONG physlast; //这是这个XIP region的结束点,即最后一行有用的数据的虚拟地址。
ULONG nummods;
ULONG ulRAMStart; //这个是说program ram从哪里开始。
ULONG ulRAMFree;
ULONG ulRAMEnd;
ULONG ulCopyEntries;
ULONG ulCopyOffset;
ULONG ulProfileLen;
ULONG ulProfileOffset;
ULONG numfiles;
ULONG ulKernelFlags;
ULONG ulFSRamPercent;
ULONG ulDrivglobStart;
ULONG ulDrivglobLen;
USHORT usCPUType;
USHORT usMiscFlags;
PVOID pExtensions; //这个就是说,当有Multibin在后面的时候,指向一个扩展表来描述后面的的region,下面会描述。图中这张表的地址在0x8c002210.
ULONG ulTrackingStart;
ULONG ulTrackingLen;
} ROMHDR;
详细的每个成员什么作用可以参考下面的URL:http://msdn.microsoft.com/en-us/library/aa908726.aspx
4.ROMHDR Extensions:就是3的扩展表,也是个结构体,如果不是multibin或者当前的nb0文件不是第一个RAMIMAGE,都不会有此表。
该表有一个NEXT指针,指向了0x8c07d550,这个地址保存的是chain的信息表。
5.Chain information: 这个东西可以让系统知道有几个Multibin,大家看图就知道了。
6.FIles and modules index data: 这部分数据往往是在nb0的最末尾,它提供了nb0文件内部的文件信息,就是借助它,你才有可能在CE的windows目录看到我们编译之前的文件。BINFS文件系统也是借助于这些数据给用户提供文件索引的。
7.data:这就是最基本的数据了,romimage把module部分的dll和exe按照PE分析好,事先安排好内存的layout(prefix),放在nb0文件的相应位置,nb0文件和内存是按照字节一一线性对齐的,打个比方来说,在我们的例子里面,文件的0偏移位置就是内存的0x8c000000,那么nb0文件偏移0x40的位置的地址就是内存0x8c000040了,就这么简单。
现在有个问题:nb0里面可以放FILES类型的DLL/EXE或者其他文件?这些应该是不会不实现处理的,放进来会有问题么?我们回去试试看吧,呵呵。
未完待续......