uBoot和Linux內核中涉及到的幾個地址參數的理解
*************************************************
arch/arm/Makefile
//內核運行虛擬地址TEXTADDR = 0xC0008000
*************************************************
arch/arm/boot/Makefile
//內核加載地址ZRELADDR = 0x20008000
*************************************************
arch/arm/boot/compressed/Makefile
//自解壓程序地址ZTEXTADDR = 0x00000000
(linux-2.4.19-rmk7內核的自解壓函數gunzip位於
/lib/inflate.c中,為gzip-1.0.3版本,現在在PC上使用gzip
函數壓縮出來的文件不能被gzip-1.0.3版本的gunzip識別,所以linux-2.4.19-rmk7
內核自解壓的功能等於不能使用,默認值ZTEXTADDR= 0x00000000
表示不使用。(只能通過uBoot的gunzip解壓加載)
)
***********************************************
//uImage存放地址 = 0x21000000
***********************************************
mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage
-A:CPU類型
-O:操作系統
-C:采用的壓縮方式
-a:內核加載地址
-e:內核入口地址
***********************************************
uBoot的do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
函數將檢驗存放到0x21000000地址處的經過mkimage格式化的uImage數據的頭部
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
}image_header_t;
(ih_ep值為0x20008000,ih_load值為0x20008000)
如果頭部各個域值和crc合法,那麼do_bootm將調用如下gunzip解壓函數對
0x21000000 +sizeof(image_header_t)地址處的壓縮內核進行解壓:
gunzip((void*)ntohl(hdr->ih_load),0x400000,data,(int*)&len);
1.hdr->ih_load 為輸出數據地址0x20008000
2.0x400000 為gunzip解壓輸出數據上限值-4M
3.data 為輸入數據地址data=0x21000000 +sizeof(image_header_t);
4.Len 為輸入數據長度len = ntohl(hdr->ih_size );
解壓完成後將會存儲解壓後數據的實際大小
壓縮的Linux內核文件uImage,經由gunzip解壓函數後,通過
do_bootm_linux (cmdtp, flag, argc, argv,addr, len_ptr, verify);
函數向Linux內核傳遞內核運行所需的5個參數
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep ;
1.hdr->ih_ep 為0x20008000
/*
* Linux Kernel Parameters:
* r3: ptr to board info data
* r4: initrd_start or 0 if no initrd
* r5: initrd_end - unused if r4 is 0
* r6: Start of command line string
* r7: End of command line string
*/
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
這樣完成了Linux系統啟動所需要5個參數的傳遞,至此uBoot的工作已經結束,Linux將在0x20008000地址處正式運行。