首页 > 代码库 > android系统重新刷ROM简记(二)

android系统重新刷ROM简记(二)

在Android顶层源码目录使用make编译完成后,会生成这样一个目录: 

out/target/product/xxx,该目录内部有我们需要的boot.img,system.img等文件,boot.img使用kernel和out/target/product/xxx/root(广义的ramdisk)目录打包而成,也就是说boot.img是由kernel和ramdisk.img生成得到。 

在android的编译框架中,把许多固定的、反复用到的目录路径定义为宏变量,而上述生成的目录 

out/target/product/xxx的宏为PRODUCT_OUT 

out/target/product/xxx/system的宏即为:TARGET_OUT 

而out/target/product/xxx/root的宏即为:TARGET_ROOT_OUT, 

out/target/product/xxx/root主要是由system/core/rootdir目录拷贝得到的, 

 

 

而对于编译过程中bootloader,kernel以及system的规定都是放在build/core/Makefile文件中。启动规定了编译生成的规则。 

 

1 

2 

3 

4 

5 

6 

7 

#build/core/Makefile 

  

INTERNAL_BOOTIMAGE_ARGS := \ 

  

            --kernel $(INSTALLED_KERNEL_TARGET) \ 

  

            --ramdisk $(INSTALLED_RAMDISK_TARGET) 

显然,boot.img中包含了Image和ramdisk.img文件,但boot.img中的内容远不只这么多,本文将介绍 

boot.img中的其它参数,boot.img的生成以及最终boot.img的组成格式. 

INTERNAL_BOOTIMAGE_ARGS还包含以下内容: 

1.附加的内核命令行(cmdline): BOARD_KERNEL_CMDLINE 

同样在build/core/Makefile中,有以下一段内容(strip起到去除空格的作用): 

? 

1 

2 

3 

4 

5 

6 

7 

BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) 

  

ifdef BOARD_KERNEL_CMDLINE 

  

    INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)" 

  

#endif 

而BOARD_KERNEL_CMDLINE则在文件device/telechips/tcc88xx-common/BoardConfigCommon.mk中定义: 

? 

1 

BOARD_KERNEL_CMDLINE := console=ttyTCC, 115200n8 

2.内核加载的基地址,BOARD_KERNEL_BASE 

同样在build/core/Makefile中,有以下一段内容: 

? 

1 

2 

3 

4 

5 

6 

7 

BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE)) 

  

ifdef BOARD_KERNEL_BASE 

  

    INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE) 

  

endif 

而BOARD_KERNEL_BASE也在device/telechips/tcc88xx-common/BoardConfigCommon.mk中定义。 

? 

1 

BOARD_KERNEL_BASE := 0x40000000 

3.映像的页面大小:BOARD_KERNEL_PAGESIZE 

同样在build/core/Makefile中,有以下一段内容: 

? 

1 

2 

3 

4 

5 

6 

7 

BOARD_KERNEL_PAGESIZE:= $(strip $(BOARD_KERNEL_PAGESIZE)) 

  

ifdef BOARD_KERNEL_PAGESIZE 

  

    INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE) 

  

endif 

而BOARD_KERNEL_PAGESIZE 却在device/telechips/tcc8800/BoardConfig.mk中定义: 

? 

1 

BOARD_KERNEL_PAGESIZE := 8192 

剩下的内容就是生成boot.img的关键语句,在 build/core/Makefile中,内容如下: 

? 

1 

2 

3 

4 

5 

INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img 

  

$(INTALLED_BOOTIMAGE_TARGET) : $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILE 

  

      $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS)  --output $@ 

到此,我们可以知道 INTERNAL_BOOTIMAGE_ARGS的内容是: 

? 

1 

2 

3 

4 

--kernel     out/target/product/tcc8800/kernel 

--ramdisk   out/target/product/tcc8800/ramdisk.img 

--cmdline   console=ttyTCC,115200n8 

--base 0x40000000  --pagesize 8192 

而预知boot.img的格式,必须查看MKBOOTIMG这个程序,其实就是out/host/linux-x86/bin/mkbootimg中的mkbootimg程序。 

mkbootimg程序由system/core/mkbootimg工程生成得到,为此我们来看看其中的mkbootimg.c文件,其中有这样一段: 

? 

1 

2 

3 

4 

5 

6 

7 

8 

9 

10 

11 

12 

13 

//信息头部分 

if(write(fd,&hdr,sizeof(hdr)) != sizeof(hdr)) goto fail; 

if(write_padding(fd,pagesize,sizeof(hdr))) goto fail; 

  

//内核部分 

if(write(fd,&kernel_data, hdr.kernel_size)!= hdr.kernel_size) 

   goto fail; 

if(write_padding(fd,pagesize,hdr.kernel_size)) goto fail; 

  

//文件系统部分 

if(write(fd,&ramdisk_data,hdr.ramdisk_size)!= hdr.ramdisk_size) 

   goto fail; 

if(wirte_padding(fd,pagesize,hdr.ramdisk_size)) goto fail; 

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

查看write_padding的代码),文件头信息的具体结构可以在system/core/mkbootimg/bootimg.h中看到: 

? 

1 

2 

3 

4 

5 

6 

7 

8 

9 

10 

11 

12 

13 

14 

15 

16 

17 

18 

19 

20 

21 

22 

23 

24 

25 

26 

27 

28 

29 

30 

31 

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的大致组成结构了。 

android系统重新刷ROM简记(二)