android boot image格式分析

boot.img和recovery.img的格式是google自定义的。


1. image的完整构成

一个完整的bootimage是由boot header、kernel、ramdisk、second stage(可选)、X509证书(可选)、签名信息(可选)组成。原始的boot.img只包括boot header、kernel、ramdisk、second stage(可选),且一般而言second staga都是没有的。

2. 原始boot.img格式
包括文件头boot_img_hdr,kernel.gz(Linux内核zImage),以及ramdisk.cpio.gz(根文件系统)
结构如下:
*
** +-----------------+
** | boot header     | 1 page
** +-----------------+
** | kernel              | n pages
** +-----------------+
** | ramdisk           | m pages
** +-----------------+
** | second stage    | o pages
** +-----------------+


原始boot.img的每部分都是页对齐的。其中boot header固定占用1个page的大小。kernel、ramdisk、second stage实际的大小会在boot header中标明。


3. boot header结构

boot header其实就是一个结构体struct boot_img_hdr,它的定义如下

struct boot_img_hdr
{
    unsigned char magic[BOOT_MAGIC_SIZE]; /* 8 byte */

    unsigned kernel_size;  /* size in bytes */
    unsigned kernel_addr;  /* physical load addr */

    unsigned ramdisk_size; /* size in bytes */
    unsigned ramdisk_addr; /* physical load addr */

    unsigned second_size;  /* size in bytes */
    unsigned second_addr;  /* physical load addr */

    unsigned tags_addr;    /* physical addr for kernel tags */
    unsigned page_size;    /* flash page size we assume */
    unsigned unused[2];    /* future expansion: should be 0 */

    unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
    
    unsigned char cmdline[BOOT_ARGS_SIZE];

    unsigned id[8]; /* timestamp / checksum / sha1 / etc */
};


这里有几个比较重要的值。一个是page_size,这个是页大小。前面说了,boot.img的每个部分都是页对齐的,那一个page的大小就记录在page_size里,通常是2048,也就是2K对齐。kernel_size是kernel.gz的原始大小,页对齐后,kernel占用的空间会比kernel_size大,多余的部分用0填充。ramdisk_size是ramdisk的原始大小,页对齐后,ramdisk占用的空间会比ramdisk_size大,多余的部分用0填充。


4. 签名

如果需要在android启动时对boot.img进行校验,确保其合法性,那么就需要在编译完成后对boot.img进行签名。google对boot.img的签名方式,就是使用verity .pk8对原始的boot.img进行加密。并且在boot.img的最后追加对应的verity.x509.pem证书,以及一段加密数据(也就是签名信息)

追加的证书,并不是直接把源码里面的verity.x509.pem粘贴上去的,而是做了编码的转换。verity.x509.pem是base64编码的,而追加的证书是二进制的ASN1格式。追加的证书也是页对齐的。ASN1格式会标明证书的实际大小。证书的开头是整个证书的大小,一般开头是0x30 0x82 0xaa 0xbb,30表示SEQUENCE, 0x82表示长度占用两个2字节,那么证书长度就是0xaabb。追加证书时也是页对齐的。(这里android 7.0和android 5.x似乎略有差别,android 5.x并没有做对齐处理)

除了证书以外,还有签名。签名是对原始boot.img的内容计算hash后,把hash值进行加密后得到的内容。具体的hash算法和加密算法都是在证书里规定的。最后得到的签名长度跟hash和加密算法相关。例如证书里规定sha1RSA2048,sha1摘要长度是160bit,那么RSA密文的长度就是256字节,所以最后的签名信息长度是256字节,且签名信息是不需要页对齐的。

https://source.android.com/security/verifiedboot/verified-boot?hl=zh-cn


5. 镜像大小

boot.img的总大小是

total = align(sizeof(struct boot_img_hdr))
        + align(kernel_size) 
        + align(ramdisk_size) 
        + align(second_size) 
        + align(cert_size) 
        + signature_size;



  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值