前一篇已经讲完了怎么debug MK908的硬件,关键点是引出了调试用串口,这在后续的分析过程中起到很大作用。
这一篇,将脱离MK908的硬件,从MK908的升级包的角度来看出厂时,MK908的启动和工作方式。
先发布一下,这篇用到的工具的下载地址链接:http://pan.baidu.com/share/home?uk=3409825988
这些是我这几个星期调查过程中,探索到的有用的工具。当然实验过程中用到的工具比分享的要多很多,给大家分享的工具是经过测试以后,觉得很好的对大家有帮助的工具。
先说明一下这篇要用的工具和材料。
afptool --- 升级包的二次解包工具
rkimagemaker --- 升级包的一次解包工具
rk2918_tools-master.zip --- afptool,rkimagemaker等工具的源码
rk统一工具... --- 包括量产工具,开发工具等等,每个工具都有说明
update_mk908... --- MK908的升级包
量产工具+驱动 ... --- 顾名思义了。
这里主要使用的工具就是 rkimagemaker和afptool,还有就是16进制的编辑工具,比如 winhex, ue等等。把这些工具下载安装好后,就可以向下进行了。
先说明一点信息。MK908的CPU使用的是RK3188,rockchip(瑞芯微)公司出品,4核1.6G。
在rockchip的发展过程中,由于一些原因(兼容和扩展性?),在原来android firmware的基础上重新打包,这也是为什么会有2次解包的原因。
首先,来看看rkimagemaker的源码,我们主要关心它的头文件,因为头文件中包含了重要的 header信息,即这个包的格式信息。这个结构体将在升级包的头部,索引后续的所有操作。
最明显的,包的开头有MAGIC字段,用于标识包的类型,“RKFW”应该是 rockchip firmware 的缩写了吧,意思就是 rockchip公司的固件。
向下就是头长度,版本等信息。最重要的是loader_offset,loader_length,image_offset,image_length四个字段。分别表示 bootloader的文件内偏移,大小,子包的文件偏移和大小。根据这两组信息,就可以到指定位置取得bootloader和image的数据。其他的信息,我们可以比照代码,自己理解领会。
先用winhex看看Magic是否正确。
可以看到,Magic是正确的,按照头的格式,得到以下内容(注意大小端,以及内存的存储方式)
header size:0x66
version:4.1.1
code:1.6
日期:2013.9.5 15:45:03
chip:112
loader_offset:0x66
loader_size:0x0002f8ae 190K
image_offset:0x02f914
image_size:0x1d2fc004 466M
我们可以计算出bootloader的地址大小,以及image的地址大小。
下面用工具解包。
成功后在 当前目录下生成两个新的文件:boot.bin firmware.img。boot.bin就是bootloader的二进制文件,firmware.img就是android的升级包。对比一下两个包的大小,跟上面从 winhex分析的结果一样,这说明我们分析的思路是正确的。
在此插一嘴:升级包的组织形式跟系统启动关系不大,把多个包组在一起的目的是方便升级,防止升级时丢包。升级包在升级时会被升级工具按照我们刚才的思路解析,读取出每个子包,再传给MK908。
继续分析生成的2个文件。boot.bin 这个是bootloader的二进制文件,没有源码,估计rockchip也不会轻易流出源码。但是尽管如此,我们还是有办法知道bootloader的内部原理,这个放在下一篇来说吧。这一篇先说firmware.img---android 升级包。
还是先看看afptool的源码吧,关注的依然是头文件。
还是有开头的MAGIC,“RKAF”这个跟上层的magic不同,应该是 rockchip android firmware的缩写吧。从这两个magic的不同可以看出,rockchip为了后续产品(非android)的兼容性,在android firmware的基础上,重新封装了包。也能看出rockchip的决心不只在于android。
我们也可以使用winhex 查看里面的magic是否对应,以及其他一些信息。
好吧,说多了。与上层包不同,android firmware的包头将依赖于两个配置文件 parameter和package-file。其中paramter 也会被烧写到mk908的flash上,在启动中起到很大的作用,而package-file则是指导afptool生成image的。
首先解包,然后再看里面的内容。
这次多了好多文件啊。还是先解释每个文件的作用吧。
parameter和package-file上面说过了。
RK3188Loader --- bootloader,跟上层接触的boot.bin 一模一样,大家可以自己比较一下。
misc.img --- android 启动模式选择的重要分区,里面存储了 BCB结构体
boot.img --- android 启动的重要镜像,包含kernel和ramdisk,使用mkbootimg生成
recover.img ---跟boot.img结构一样,比boot.img有更多的工具,用于系统恢复和升级
system.img -- android 系统的所有内容
backup.img --- update镜像,在recover也损毁的时候,恢复系统。
两个script --- 用于升级时,具体的动作。
好了,还是一个一个的分析吧。这些涉及到了android系统自身的一些机制,其中比较麻烦的是misc和recover两个镜像的关系。要想弄明白,最好是自己看看代码。
代码位置 $Android_SRC/bootable/recovery ,当然还有Makefile,在 build/core/Makefile。
也有前人分析的过程,感觉还是挺好的。http://linux.chinaunix.net/techdoc/develop/2009/04/25/1108935.shtml
用winhex查看misc.img,发现全是0,这当然是正确的,我们在第一次开机时,不需要进到recover模式。
用winhex查看boot.img和recover.img,发现有着相同的Magic:“ANDROID!”,因为它们是用相同的工具生成的。为了理解这两个文件的格式,我们还是看看mkbootimg的源码。同样看头文件
下面还有image的内容分布。
对照其中的注释,大家应该理解bootimg的格式了吧。
那么现在就是如何解开这个文件包了。以下操作强烈建议你使用linux系统,我的环境是 ubuntu12.04。从网盘上下载 perl语言编写的脚本unpack-bootimg.pl。这个脚本的功能就是按照上面分析的格式,进行反向解包。
可以看到,多了几个文件,和一个文件夹。其中 kernel当然就是内核镜像了,ramdisk文件夹就是解完的最终文件系统。其实,这里perl脚本帮我们完成了ramdisk的解包工作,实际上我们可以自己动手解包。
recovery.img的解包过程跟boot.img一样,大家自己试试看。下面我们看看system.img的内容。
linux下有个强大的工具,当你不知道文件是什么格式的时候,可以试试它--- file命令。
发现这是一个ext3文件系统的镜像,下一步就是mount ,查看了。
system.img也被解开了。
backup.img 的格式跟 firmware.img是一样的,大家用 afptool 解它看看,自己分析一下吧。
两个升级脚本文件,是在升级时使用的,里面是用edify脚本语言写的程序,包括烧写擦除等操作,想弄明白,还是看看recovery的代码吧。
终于把升级包解析完了,这样我们在DIY时,该怎么取舍,就不会很迷惑了。下一篇 给大家讲讲 bootloader的工作流程吧。