ROMIMAGE工具解析(ARM平台)
来源:互联网 发布:wdcp php版本升级 编辑:程序博客网 时间:2024/04/30 20:02
一.wince6 OS 编译大体过程
build (public code)->sysgen->build (BSP)->buildrel->makeimg, 其中makeimg 命令调用romimage.exe (运行该命令romimage.exe ce.bib )产生最终的nk.bin 。其中ce.bib 是merge 了系统中所有bib 文件( 当然包括config.bib 和platform.bib) 。
二.ce.bib 中的内容包含四大部分
1. MEMORY section 划分内存块
格式:Name Start Size Type
Name :唯一名称
Start :每块内存base address
Size :划分大小
Type :"rom_8" "rom_16" "romx8" "ram" "ramimage" "nandimage" "reserved" "fixupvar" "extension" "chain information" 详细解释请参考http://msdn.microsoft.com/en-us/library/ms923584.aspx
Romimage.exe 解析该部分内容,如果有一块内存区域没有指定type 并且Name 是“reserve” ,type 就被指定为reserve
2. CONFIG section 设置配置变量
AUTOSIZE :
格式:AUTOSIZE=OFF|ON
默认为OFF ,config.bib 中定义RAM 用于进程和存储对象内存区域,RAMIMAGE 用于保存image 。如果为ON ,RAM 和RAMIMAGE 合并成一个部分,从低地址开始预留RAMIMAGE 大小,其余大小作为RAM
BOOTJUMP :
格式:BOOTJUMP =address|NONE
默认为NONE ,内核启动从OAL 的startup 地址执行。如果指定一个在RAMIMAGE 范围的值,那就从指定的地址开始执行
COMPRESSION :
格式:COMPRESSION = OFF|ON
默认为ON ,对于文件,默认全部压缩,对于模块默认压缩可写部分。如果模块在.bib 中定义时具有C 属性(表明压缩模块所有部分),那么当前这个选项就忽略了
FSRAMPERCENT :
格式:FSRAMPERCENT=number
文件系统分配的内存的百分比。
例如number 为0xAABBCCDD, 那么文件系统分配的内存的百分比为(0xAA+0xBB+0xCC
+0xDD)/1024
KERNELFIXUPS:
格式:KERNELFIXUPS=OFF|ON
默认值为ON 。如果为ON ,romimage.exe 具有Base Relocations
PROFILE :
格式PROFILE =OFF|ON
默认为OFF。如果为ON,使用symbols(文件map信息)
3.MODULES section定义OS镜像包含哪些模块,并指定模块被加载到那块内存区域
格式:Name Path Memory Type
Name :模块名
Path :真实的模块地址
Memory :该模块被加载到那块内存区域,区域为MEMORY section 部分的name 值
Type : 模块的存放属性
- S :系统文件
- H :隐藏文件
- R : 只压缩模块的资源部分(默认模块是不压缩的)
- C :压缩模块所有部分
- D :禁止调试
- N :标志模块是非信任的
- P :忽略CPU 类型
- Q: 双模式,如果该模块为user mode ,这时会在kernel mode 上也对应一个K.+ 模块名
- K :指定模块为kernel mode
- Z :like kernel mode
- X :指定romimage.exe 对此模块验证签名
- M :运行时加载整个模块,而不是按需分页
4. FILE section 定义OS 镜像包含哪些文件,并指定文件被加载到那块内存区域
格式:Name Path Memory Type
Name :文件名
Path :真实的文件地址
Memory :该文件被加载到那块内存区域,区域为MEMORY section 部分的name 值
Type : 模块的存放属性
- S :系统文件
- H :隐藏文件
- Q: 双模式,如果该文件为user mode ,这时会在kernel mode 上也对应一个K.+ 文件名
- U :不压缩(默认压缩)
三.Romiamge.exe 处理过程(non multixip )
1. syn module name ,如果name 与path 中模块名不相等,就从MODULES section path 拷贝(同时拷贝它对应的pdb, map, rel 文件)到本目录以name 命名
2. 使nk.exe 为MODULES section 的第一个module
3. 使具有“Z ”属性的模块在前半部分,一般是NK.exe ,kitl.dll , kernel.dll (这三个家伙将被load 到static mapped cached 区间,从RAMIMAGE start address 开始)
4. 如果AUTOSIZE=ON ,合并RAM 和RAMIMAGE
6. 定位每个module load address 偏移 地址 和 relocation 偏移 地址
7. 如果模块不具有Z 属性, 根据config PROFILE 值,如果为ON ,从module 文件或者对应的map 文件得到symbol 信息。读取nk.map 得到pTOC offset
8. 重定位模块 image pages 地址
以RAMIMAGE 开始地址为base address 。如果module 是NK.exe ,对于.kdata 段align 64K ,其它情况align 4K
7. Fix up relocation ,根据.reloc 段和.rel 文件。
8. 压缩module 。
9. 如果module 具有X type ,签名处理
10. 压缩FILE section ,如果COMPRESSION=ON ,压缩所有file
11. compact image . 由于alignpage ,所剩下没使用ram pace 。收集未填充数据的ram ,标记为hole ram 。移动module readwrite section 到未利用的ram address 中,移动module 头信息和setcion table 到hole ram address 中.
12. 设置Copylist 链表信息类型为 COPYentry
typedef struct COPYentry {
ULONG ulSource ; // copy source address
ULONG ulDest ; // copy destination address
ULONG ulCopyLen ; // copy length
ULONG ulDestLen ; // copy destination length
// (zero fill to end if > ulCopyLen)
} COPYentry ;
If (模块具有Z 属性,不等于.kdata section 的读写段,例如.data section )
{
COPYentry::ulSource = o32_obj ::o32_dataptr ;// 对应段的头信息
COPYentry::ulDest = o32_obj ::o32_realaddr ;
COPYentry::ulCopyLen = o32_obj ::min_size ();
COPYentry::ulDestLen = o32_obj ::o32_vsize ;
}
o32_obj 为image section file 结构为
typedef struct o32_obj { /* .EXE memory object table entry */
unsigned char o32_name [E32OBJNAMEBYTES ];/* Object name */
unsigned long o32_vsize ; /* Virtual memory size */
unsigned long o32_rva ; /* Object relative virtual address */
unsigned long o32_psize ; /* Physical file size of init. data */
unsigned long o32_dataptr ; /* Image pages offset */
unsigned long o32_realaddr ; /* pointer to actual */
unsigned long o32_access ; /* assigned access */
unsigned long o32_temp3 ;
unsigned long o32_flags ; /* Attribute flags for the object */
} o32_obj , *LPo32_obj ;
13. 创建NK.bin , 写magic “ B000FF/n ” image start ,image length 到文件中。
14. 写module/file toc 。 从 hole ram , 得到ROMHDR 的在实际内存中的load address romhdr_offset (第一个满足sizeof (ROMHDR )大小的hole ram 块),写romhdr_offset + sizeof (ROMHDR )值(地址),tocs 大小 size , tocs check sum 到文件,写tocs 内容到文件
MODULE toc ,结构:
typedef struct TOCentry { // MODULE BIB section structure
DWORD dwFileAttributes ;
FILETIME ftTime ;
DWORD nFileSize ;
LPSTR lpszFileName ;
ULONG ulE32Offset ; // Offset to E32 structure ,文件头偏移
ULONG ulO32Offset ; // Offset to O32 structure ,第一个image 段偏移
ULONG ulLoadOffset ; // MODULE load buffer offset
} TOCentry , *LPTOCentry ;
FILE toc, 结构:
typedef struct FILESentry { // FILES BIB section structure
DWORD dwFileAttributes ;
FILETIME ftTime ;
DWORD nRealFileSize ;
DWORD nCompFileSize ;
LPSTR lpszFileName ;
ULONG ulLoadOffset ; // FILES load buffer offset
} FILESentry , *LPFILESentry ;
15. 写 MODULE 到文件中,各个section data( 格式:地址(o32_obj::o32_dataptr), 大小,checksum , data), 各个module 头信息,section 头信息, 和module 文件名
16. 写FILE data 到文件
17. 写 ROM signature 到文件。依次写入Address 为RAMIMAGE start address + 0x40 ,length 为2*sizeof (DWORD ), check sum ,Data 为 0x43454345 (“ECEC ”),romhdr_offset.
18. 写 TOC pointer 到文件, 依次写入Address 为RAMIMAGE start address + 0x40 + 2*sizeof (DWORD ),length 为sizeof (DWORD ),check sum ,Data 为 TOC 偏移(romhdr_offset - RAMIMAGE start address )
19. 写copylist 信息 到文件 . 依次写入Address 为 第一个满足 copylist 大小的hole ram 块地址 ,length 为copylist 大小 ,check sum , Data 为copylist 大小
20. 写romhdr 信息. 依次写入Address 为 romhdr_offset ,length 为sizeof( ROMHDR) ,check sum , Data 为romhdr data.
ROMHDR 结构: typedef struct ROMHDR {
ULONG dllfirst ; // first DLL address ,用户模式下第一个模块load address 、// 默认为0x4001c001
ULONG dlllast ; // last DLL address ,用户模式下最后一个模块load address
// 默认为0x4001c001
ULONG physfirst ; // first physical address, 为RAMIMAGE 的start address
ULONG physlast ; // highest physical address ,一般为ROMHDR 的结束地址
ULONG nummods ; // number of TOCentry's ,模块的个数
ULONG ulRAMStart ; // start of RAM, physlast align 64k 值
ULONG ulRAMFree ; // start of RAM free space , 所有Z 属性模块的各个段大小之和( 对于每个段的大小为align_page(max(o32_vsize, o32_psize)) )
ULONG ulRAMEnd ; // end of RAM , RAM type 结束地址
ULONG ulCopyEntries ; // number of copy section entries ,, // Z 属性模块个数
ULONG ulCopyOffset ; // offset to copy section
ULONG ulProfileLen ; // length of PROFentries RAM
ULONG ulProfileOffset ; // offset to PROFentries
ULONG numfiles ; // number of FILES
ULONG ulKernelFlags ; // optional kernel flags from ROMFLAGS .bib config option
ULONG ulFSRamPercent ; // Percentage of RAM used for filesystem
// from FSRAMPERCENT .bib config option
// byte 0 = #4K chunks/Mbyte of RAM for filesystem 0-2Mbytes 0-255
// byte 1 = #4K chunks/Mbyte of RAM for filesystem 2-4Mbytes 0-255
// byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255
// byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255
ULONG ulDrivglobStart ; // device driver global starting address
ULONG ulDrivglobLen ; // device driver global length
USHORT usCPUType ; // CPU (machine) Type
USHORT usMiscFlags ; // Miscellaneous flags
PVOID pExtensions ; // pointer to ROM Header extensions
ULONG ulTrackingStart ; // tracking memory starting address
ULONG ulTrackingLen ; // tracking memory ending address
} ROMHDR ;
21. 写 Address 为 0x00000000 ,length 为 jump address ,check sum 0x00000000 到文件
22. 写image 大小到文件,重新fseek (image_file , 11, SEEK_SET ) ,写入image size(s_romhdr .physlast -s_romhdr .physfirst )
四 NK.bin 文件结构
"B000FF/x0A" //7 字节大小
↓
ImageStartAddress, ImageLength //8 字节大小
↓
RecordAddress, RecordLength, RecordChecksum, Data…….// module/file toc 信息
↓
RecordAddress, RecordLength, RecordChecksum, Data…// modulese 信息
↓
RecordAddress, RecordLength, RecordChecksum, Data…// files 信息
↓
RecordAddress, RecordLength, RecordChecksum, Data 为 0x43454345 // ROM signature
↓
RecordAddress, RecordLength, RecordChecksum, Data 为 0x43454345 // TOC pointer
↓
RecordAddress, RecordLength, RecordChecksum, Data 为 0x43454345 // copylist 信息
↓
RecordAddress, RecordLength, RecordChecksum, Data 为 0x43454345 // romhdr 信息
↓
0x00000000 , JumpAddress , 0x00000000 // 启动地址startup 地址
本文粗鲁地分析了ROMIMAGE 工具,欢迎大家拍砖, 把我的错误暴露在阳光下 ……
- ROMIMAGE工具解析(ARM平台)
- (转)关于romimage
- romimage
- strace工具移植到ARM(davinci)平台
- 制作ARM平台交叉编译工具链
- arm平台linux移植ethtool工具
- 构建ARM平台的交叉工具链第一部分
- ARM平台mtd-utils-1.3.1工具制作
- Linux平台下ARM-Linux交叉编译工具链
- linux下arm平台Qt编译环境搭建与解析
- linux下arm平台Qt编译环境搭建与解析
- ARM平台
- neon指令集(arm平台优化)
- 揭秘Romimage生成的.nb0.bin文件(绝对原创,禁止转载)
- windows平台下解析apk的工具:apkUtil
- 从skyeye学习arm( 工具篇)
- 构建arm交叉编译工具(toolchHOWTO)
- 动手做嵌入式产品之第一部分:构建ARM平台的交叉工具链
- HTTP POST GET 本质区别详解
- 支持输入法变更事件的InputPanel
- 积分积分
- oracle修改SGA后无法启动的临时解决方法
- 如何把7771网址大全删除
- ROMIMAGE工具解析(ARM平台)
- 用CSS Hack解决浏览器兼容性问题
- 验房流程
- 收藏几本linux编程的书,需要的时候一本本买回来
- Windows Mobile获取存储卡容量及使用情况
- 条件指令
- struts2使用json时需要注意的问题
- QTP-实现对文本文件的读写
- 快速获得Google Chrome最新版本