Android boot.img 結構

Android 的boot.img 包括 boot header,kernel, ramdisk
首先來看看Makefile是如何產生我們的boot.img的:
boot鏡像不是普通意義上的文件系統,而是一種特殊的Android定製格式,由boot header,壓縮的內核,ramdisk以及second stage loader(可選)組成,可以從mkbootimg.h文件中看到。
boot,img文件跳過4k的文件頭之後,包括兩個 gz包,一個是boot.img-kernel.gz:Linux內核,一個是boot.img-ramdisk.cpio.gz
大概的組成結構如下
*
** +-----------------+ 
** | boot header     | 1 page
** +-----------------+
** | kernel              | n pages  
** +-----------------+
** | ramdisk           | m pages  
** +-----------------+
** | second stage    | o pages
** +-----------------+
boot header爲包括命令行參數等等,地址爲000-----0xFFF
ramdisk爲 1F8B0800000000開頭
kernel爲 0000A0E1 重複8遍開頭

關於boot header這個數據結構我們需要重點注意,在這裏我們關注其中幾個比較重要的值,這些值定義在boot/boardconfig.h裏面,不同的芯片對應vendor下不同的boardconfig,在這裏我們的值分別是(分別是kernel/ramdis/tags載入ram的物理地址):
#define PHYSICAL_DRAM_BASE   0x00200000 
#define KERNEL_ADDR          (PHYSICAL_DRAM_BASE + 0x00008000)
#define RAMDISK_ADDR         (PHYSICAL_DRAM_BASE + 0x01000000)
#define TAGS_ADDR            (PHYSICAL_DRAM_BASE + 0x00000100)
#define NEWTAGS_ADDR         (PHYSICAL_DRAM_BASE + 0x00004000)


上面這些值分別和我們開篇時候提到的那幾個名詞相對應,比如kernel_addr就是ZTEXTADDR,RAMDISK_ADDR就是INITRD_PHYS,而TAGS_ADDR就是PARAMS_PHYS。bootloader會從boot.img的分區中將kernel和ramdisk分別讀入RAM上面定義的地址中,然後就會跳到ZTEXTADDR開始執行。

ramdisk映像是一個最基礎的小型文件系統,它包括了初始化系統所需要的全部核心文件,例如:初始化init進程以及init.rc(可以用於設置很多系統的參數)等文件。以下是一個典型的ramdisk中包含的文件列表:
./init.trout.rc
./default.prop
./proc
./dev
./init.rc
./init
./sys
./init.goldfish.rc
./sbin
./sbin/adbd
./system
./data

如果要分離可以用winhex將boot。img打開
找到0000A0E1 到1F8B0800000000的前面的數據塊保持爲ramdisk.img
找到1F8B0800000000到文件尾部的數據塊保持爲kernel

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


        根據上面的命令我們可以首先看看mkbootimg 這個工具的源文件:system/core/mkbootimg.c。看完之後我們就能很清晰地看到boot.img的內部構造,它是由boot header /kernel  /ramdisk /second stage構成的,其中前3項是必須的,最後一項是可選的。


header + padding + kernel + padding + ramdisk + padding + ...
4 * 2, magic,固定爲"Android!"
4 * 1, kernel長度,小端unsigned
4 * 1, kernel地址,應爲base + 0x00008000 (base爲0x200000)
4 * 1, ramdisk長度,小端unsigned
4 * 1, ramdisk地址,應爲base + 0x01000000
4 * 1, second stage長度,小端unsigned,爲0
4 * 1, second stage地址,應爲base + 0x00f00000
4 * 1, tags地址,應爲base + 0x00000100
4 * 1, page大小,小端unsigned, 爲2048或者4096


4 * 2, 未使用,固定爲0x00
4 * 4, 板子名字,一般爲空
4 * 128, 內核命令參數,爲mem=211M console=ttyMSM2,115200n8 Androidboot.hardware=qcom console=ttyUSBCONSOLE0 androidboot.console=ttyUSBCONSOLE0
4 * 8, id, 爲sha之類,實際寫0x00就可
padding, 以上header爲608字節,把這部分補齊到page_size * 2大小 
kernel_size, kernel內容
padding,把kernel_size補齊到page_size * 2
ramdisk_size, ramdisk內容
padding, 把ramdisk補齊到page_size * 2
second_size, second內容,一般爲0
padding, 補齊second_sise爲page_size,一般爲0
配合 boot.img 來看會比較好理解.


由此可知 boot_img_hdr 中各成員值爲:


 




TAGS_ADDR 如上 target/<your-platform>/rules.mk 所定義的 : 0x40200100, 所以 boot_linux(), 就是傳入TAGS_ADDR,

然後將資料寫入 tag, tag 的結構如下所示.


 

然後進入到 kernel 的入口函數: entry(0, machtype, tags)

轉載地址:http://www.linuxidc.com/Linux/2011-03/33303.htm



發佈了11 篇原創文章 · 獲贊 6 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章