boot.img的生成过程,解析mkbootimg

Android系统镜像中boot.img如何生成,在此篇文章解开它的神秘面纱。

源码位置:android/system/core/mkbootimg/

boot.img是由文件头信息,内核数据以及文件系统数据组成,它们之间非页面对齐部分用0填充

mkbootimg工具的使用:
int usage(void)
{
    fprintf(stderr,"usage: mkbootimg\n"
            "       --kernel <filename>\n"
            "       --ramdisk <filename>\n"
            "       [ --second <2ndbootloader-filename> ]\n"
            "       [ --cmdline <kernel-commandline> ]\n"
            "       [ --board <boardname> ]\n"
            "       [ --base <address> ]\n"
            "       [ --pagesize <pagesize> ]\n"
            "       -o|--output <filename>\n"
            );
    return 1;
}

在瑞芯微平台上 Android boot.img生成步骤如下:

mkbootimg --kernel $OUT/kernel --ramdisk $OUT/ramdisk.img --second kernel/resource.img --output $OUT/boot.img

boot.img对应的结构体原型:

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]; //存放时间戳,校验和,SHA加密等内容  
}

boot.img加载到内存的位置和包含的镜像的偏移大小:

    unsigned base           = 0x10000000;   //内核加载到内存中的基地址,与内核加载到内存的位置一致
    unsigned kernel_offset  = 0x00008000;   //内核的偏移大小
    unsigned ramdisk_offset = 0x01000000;
    unsigned second_offset  = 0x00f00000;   //扩展模块的偏移大小,在瑞芯微平台主要是resource.img(资源文件)
    unsigned tags_offset    = 0x00000100;
    size_t cmdlen;

获取参数: 

while(argc > 0){
        char *arg = argv[0];
        char *val = argv[1];
        if(argc < 2) {
            return usage();
        }
        argc -= 2;
        argv += 2;
        if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
            bootimg = val;
        } else if(!strcmp(arg, "--kernel")) {
            kernel_fn = val;
        } else if(!strcmp(arg, "--ramdisk")) {
            ramdisk_fn = val;
        } else if(!strcmp(arg, "--second")) {
            second_fn = val;

boot.img中镜像加载到内存的位置,填充结构体: 

    hdr.page_size = pagesize;  //内存块的大小

    hdr.kernel_addr =  base + kernel_offset;  //内核加载的位置
    hdr.ramdisk_addr = base + ramdisk_offset; //radisk文件系统加载的位置
    hdr.second_addr =  base + second_offset; //扩展项加载的位置
    hdr.tags_addr =    base + tags_offset;

将文件整合到boot.img下:
    kernel_data = load_file(kernel_fn, &hdr.kernel_size);
    if(kernel_data == 0) {
        fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
        return 1;
    }

    if(!strcmp(ramdisk_fn,"NONE")) {
        ramdisk_data = 0;
        hdr.ramdisk_size = 0;
    } else {
        ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
        if(ramdisk_data == 0) {
            fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
            return 1;
        }
    }

    if(second_fn) {
        second_data = load_file(second_fn, &hdr.second_size);
        if(second_data == 0) {
            fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
            return 1;
        }
    }

load_file函数将相应的文件偏移整合到boot.img中 

 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Androidboot.img 和 vendor_boot.img 文件都包含了启动引导和操作系统的核心代码,它们通常存储在 Android 设备的 /boot 分区中。如果你想要拆分这些文件以进行定制化或修改,可以按照以下步骤操作: 1. 首先,你需要从设备中提取原始的 boot.img 或 vendor_boot.img 文件。你可以使用工具像 `adb pull /dev/block/boot` 或 `adb pull /dev/block/by-name/boot` 来提取这些文件。 2. 接下来,你需要安装 Android Image Kitchen 工具,这个工具可以用来解压和重新打包 Android 镜像文件,包括 boot.img 和 vendor_boot.img。 3. 执行以下命令,将 boot.img 或 vendor_boot.img 解压到指定目录中: ```bash $ mkdir unpacked-boot $ ./unpackimg.sh boot.img unpacked-boot ``` 或者 ```bash $ mkdir unpacked-vendor-boot $ ./unpackimg.sh vendor_boot.img unpacked-vendor-boot ``` 4. 解压后,你会得到一个名为 `ramdisk` 的目录,这个目录包含了启动引导需要的文件和脚本。你可以在这个目录中进行修改和定制化。 5. 如果你完成了对文件的修改,可以使用以下命令重新打包 boot.img 或 vendor_boot.img: ```bash $ ./mkbootimg.sh --kernel kernel --ramdisk ramdisk.cpio.gz -o new-boot.img ``` 或者 ```bash $ ./mkbootimg.sh --kernel kernel --ramdisk ramdisk.cpio.gz -o new-vendor-boot.img ``` 其中,`kernel` 是原始 boot.img 或 vendor_boot.img 中的内核文件,`ramdisk.cpio.gz` 是你修改后的 ramdisk 目录打包后的文件,`new-boot.img` 或 `new-vendor-boot.img` 是输出的新镜像文件。 6. 最后,将新的 boot.img 或 vendor_boot.img 上传到设备中,并使用以下命令将其刷入设备: ```bash $ fastboot flash boot new-boot.img ``` 或者 ```bash $ fastboot flash vendor_boot new-vendor-boot.img ``` 注意,这些操作可能会导致设备变砖,因此在进行这些操作之前,请务必备份重要的数据和文件,并小心谨慎。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值