Image 指的是內核鏡像,大約4M
zImage 指的是壓縮的內核鏡像,大約2M
uImage 是在zImage的頭部添加了64字節信息,包含了內核版本,加載位置,生成時間,大小信息等
1 boot.img
boot.img是由文件頭信息,內核數據以及文件系統數據組成,它們之間非頁面對齊部分用0填充
文件頭信息的具體結構可以在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]; //存放時間戳,校驗和,SHA加密等內容 }
在build/core/Makefile裏,INSTALLED_BOOTIMAGE_TARGET 是生成boot.img ,其中參數爲INTERNAL_BOOTIMAGE_ARGS ,該參數
主要是--kernel , 用到了BOARD_KERNEL_BASE ,而在device/qcom/BoardConfig.mk中,會定義 BOARD_KERNEL_BASE
這樣mkbootimg :
--kernel kernel --ramdisk ramdisk.img --cmdline $(BOARD_KERNEL_CMDLINE)
--base $(BOARD_KERNEL_BASE) --pagesize 2048
mkbootimg的代碼在system/core/mkbootimg 它分析參數後,依次寫入header, kernel ,ramdisk .
header參數爲:
kernel_addr = base 0x8000 --- 內核加載的基地址
ramdisk_addr = base 0x01100000
tags_addr = base 0x1000
確認 boot loader 所用的內核基地址必須和內核映像在編譯時所用的運行基地址一致,假設你的內核映像在
編譯時用的基地址是 0xc0008000,但你的 boot loader 卻將它加載到 0xc0010000 處去執行,那麼內核映像
當然不能正確地執行了。
在Kernel/arch/arm 下面的Makefile.boot 中指定了內核編譯鏈接的基地址。
zreladdr ---- kernel_addr
params_phys ---- tags_addr
3 boot.img的加載
在lk 中, smem_ptable_init 函數中會初始化 smem_apps_flash_start ,它通過讀share memory ,也就是ARM9端傳入的0:APPS
這樣在targe_init函數中,會將offset = smem_apps_flash_start , 然後ptable_add將第一個分區的地址設置爲offset .
在ARM9 中 有兩個文件 partition.h 和 partition.c
partition.h 中定義了:
FLASH_PARTI_APPS "0:APPS" --- 對於boot.img
partition.c 中定義了所有的分區的大小, 這樣smem_apps_flash_start 其實就爲ARM9的所有image的大小。
4 ARM9中的實現
函數smem_retrieve_mibib 中將分配 smem_alloc , 也就是有512 字節的 MIBIB區
MIBIB區 : 16個字節是header
每個分區 28個字節
這樣共有16個分區
每個分區信息,flash_partition_entry 包括了name 和 offset .
這樣ARM11 測 根據name 爲0:APPS 得到offset ,也就是該分區的起始地址。
MIBIB 分區 是通過根據 mjnand -c mibib_xxx.cfg 得到
參考:
https://blog.51cto.com/u_15460167/4828920