android固件集成

作为一套完整的build集成系统,需要包含两方面的内容,一个就是烧写软件,另一个就是完整固件。这两者应该是分开的,完整固件里面不应该包括任何跟烧写相关的内容。本文将围绕炬力s900方案的固件集成环境来做一个介绍。

烧写组件
炬力方案集成出的android固件应该包括几个文件,其中有一个是.fw为后缀的,它是炬力firmware文件,其中打包的就是烧写套件。一般炬力的量产工具都是通过usb来做烧写,这个fw文件会最先被下载到设备端。
其实在fw文件中打包了一套嵌入式linux系统,这一套系统不会被写到flash或者emmc中,它只是在设备的ram中加载,真正的目的是为了烧写正常的android固件到flash或者emmc中。

烧写系统下载到设备上以后,会在ram中加载,也就是相当于启动了一个linux最小系统。在这个linux系统的支持下,我们才能完成接下来对整个android固件的烧写。

在烧写之前会首先对存储器进行分区,这个分区表是可以配置的。分区后就要开始烧写具体的固件了。s900固件分为如下几个镜像文件:
misc.img
recovery.img
system.img
bootloader.bin
uboot.bin
其中前三个是需要烧写到具体的分区的,可以在分区配置表中指定。而后两个是用来在正常启动时加载系统的,它们不会被烧写进入分区,而是作为独立程序使用dd烧写到保留地址处。

正常固件
我们知道android的底层使用的也是linux系统,那么作为linux系统,几个必不可少的组件我们都要清楚,可以从linux的启动过程来分析。
linux的启动,首先从CPU内的BROM运行,然后跳转到SPL,SPL用来初始化DDR,并加载uboot,uboot加载uImage,uImge的运行还需要一个rootfs。
从上述的启动过程,可以知道必不可少的有spl/uboot/uImage/ramdisk.
当然了作为android系统,它毕竟还是与linux有所不同,它有自己的一套文件系统。它把存储器分为多个分区,如system分区、recorvery分区、misc分区等等。

spl和uboot是启动起来后首先进行加载的,我们知道BROM是一块很小的内存,它的功能是有限的,所以一般都不会支持文件系统或者分区。所以我们的spl以及uboot镜像就不能烧写到flash或者emmc的分区中。因为分区中的东西是受文件系统控制的,我们无法准确获知某一个程序的地址,就无法在BROM中进行加载。所以我们需要把spl和uboot用dd命令烧写在分区外的地方,上一节已经提到过了,并且是确定的一个跳转地址,所以炬力的分区方案都会在起始位置留出一段空间,那就是为spl和uboot保留的地方。

炬力的spl程序是自己开发的一套加载程序,没有使用uboot-spl功能。当然了,这部分处于知识产权的保护是闭源的,主要是用arm汇编+c语言开发的,主要是实现了ddr的一些初始化,板级硬件的初始化,并且是可配置的,具体的我就不能多说了。它经过编译后会生成一个bootloader.bin的文件,这个就是我们需要的spl了。uboot经过编译后会生成uboot.bin,这个也是我们需要的。

接下来就要看kernel和ramdisk了。kernel的运行需要两部分,一个就是uImage,另一个就是dtb文件,dtb是dts文件经过编译后生成的,可以被kernel读取的配置文件了。当uboot加载以后,其中就会对分区以及文件系统进行支持了,所以在uboot启动后才会加载运行的东西我们都可以放在分区中。

这样我们的工作就简单多了,不用使用dd来烧写了,而只需要把uImage和ramdisk拷贝到一个分区即可,炬力方案是把他们都放在了misc.img中,并最终烧写到misc分区。光有uImage和ramdisk还不能正确的启动kernel,还有一个就是uenv.txt,它是uboot用来读取来初始化kernel运行环境的,我们也可以对他进行一些个性化配置,它也是被放置到misc分区的。
ramdisk就是android编译过程所生成的ramdisk.img,是android的根文件系统。一般情况下ramdisk和uImage都是放在同一个分区的。
kernel和ramdisk加载了以后,android就起来了,就启动了android的那一套init系统了。

boot.img–android原生启动方案
android编译完成后还会生成一个boot.img,这个镜像文件我们压根就没有用它,那么这个是什么东东呢?其实boot.img是android原生的一个启动镜像实现方案。boot.img里面其实打包的就是uImage和ramdisk.img,它是通过工具mkbootimg来打包生成的。比如:

out/host/linux-x86/bin/mkbootimg  --kernel out/target/product/msm7630_surf/kernel --ramdisk out/target/product/msm7630_surf/ramdisk.img --cmdline "console=ttyMSM1,115200n8 androidboot.hardware=qcom" --base 0x00200000 --pagesize 4096 --output out/target/product/msm7630_surf/boot.img

boot.img由header、kernel image、ramdisk三部分构成。
文件头信息的具体结构可以system/core/mkbootimg/bootimg.h中看到:

struct boot_img_hdr  
 {  
     unsigned char magic[BOOT_MAGIC_SIZE];  
     unsigned  kernel_size;  
     unsigned  kernel_addr;  
     unsigned  ramdisk_size;  
     unsigned  ramdisk_addr;  
     unsigned  second_size;  
     unsigned  second_addr;  
     unsigned  tags_addr;  
     unsigned  page_size;  
     unsigned  unused[2];  
     unsigned  char  name[BOOT_NAME_SIZE]  
     unsigned  char cmdline[BOOT_ARGS_SIZE]  
     unsigned  id[8];  
 }

如果采用android这套启动方案,我们可以不用uboot来启动kernel,而是需要根据这个header的信息重新编写bootloader,由bootloader直接跳转到kernel的入口来启动android。当然了,每个厂商都不一样,炬力也没有使用这种方式来做。

炬力的分区方案采用的GPT分区方式,bootloader.bin烧写在2M+512B的位置,uboot.bin烧写在3M位置。分区起始位置在16M的地方。
保留空间

                                          OFFSET
GPT分区表                                        0
bootloader.bin                               2M+512Byte
uboot.bin                                    3M

分区

                                       OFFSET
MISC                                        16M
RECOVERY                                    64M
SYSTEM                                      112M
BOOT_MSG                                   1672M
DATA                                       1673M
CACHE                                      2185M
DATA_BAK                                   2697M
UDISK                                      2698M
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值