/*
*by neil chiao (neilchiao at gmail.com)
neilengineer.cublog.cn
*歡迎到「新星灣(www.xinxingwan.com)」指導
*/
arm平台u-boot啟動核心命令如:
bootcmd=bootm 0xc4040014
在./common/cmd_bootm.c檔案中,bootm命令對應的do_bootm函式,當分析uimage中資訊發現os是linux時,呼叫./lib_arm/armlinux.c檔案中的do_bootm_linux函式來啟動linux kernel。
image_header_t header;
ulong load_addr = cfg_load_addr; /* default load address */
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv)
else
//判斷執行bootm時是否指定了程式載入位址,若沒有則使用預設的載入位址,load_addr在此函式前面是這樣定義的: ulong load_addr = cfg_load_addr;
……
memmove (&header, (char *)addr, sizeof(image_header_t));
//將image 的 header(u-boot新增的64byte檔案頭)複製到header指向的記憶體。
if (ntohl(hdr->ih_magic) != ih_magic)
}//判斷檔案頭中的幻數是否為ih_magic,所以如果不是u-boot映象格式,會輸出提示資訊」bad magic number」。
data = (ulong)&header;
len = sizeof(image_header_t);
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)data, len) != checksum)
//檢查image 檔案頭header的crc32校驗和。
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
……
if (verify)
}//檢查image 資料部分data的校驗和。
len_ptr = (ulong *)data;
#if defined(__ppc__)
if (hdr->ih_arch != ih_cpu_ppc)
#elif defined(__arm__)
if (hdr->ih_arch != ih_cpu_arm)
#elif defined(__i386__)
if (hdr->ih_arch != ih_cpu_i386)
……
#else
# error unknown cpu type
#endif
//檢查image header 中的arch型別是否正確。
switch (hdr->ih_type)
//判斷image的型別
……
switch (hdr->ih_comp)
//根據image所採用的壓縮型別,將image解壓到hdr->ih_load指向的位址,這個ih_load就是在做核心映象時mkimage中的-a選項指定的位址,-a選項指定的是核心解壓後的位址。
……
switch (hdr->ih_os)
//核心已經解壓完了,接下來啟動linux核心,把控制權傳遞給了do_bootm_linux函式。
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv,
ulong addr, ulong *len_ptr, int verify)
……
ulong initrd_start, initrd_end; // initrd的起始位址和結束位址
ulong data;
void (*thekernel)(int zero, int arch, uint params);
// linux 核心的入口引數,zero = 0,arch為平台編號,params為傳遞給核心的引數在記憶體中的位址。
image_header_t *hdr = &header;
bd_t *bd = gd->bd;
#ifdef config_cmdline_tag
char *commandline = getenv ("bootargs");
#endif
//如果在include/configs/.h定義了config_cmdline_tag則將bootargs環境變數傳遞給核心。所以如果發現無法向核心傳遞引數,應該檢查一下config_cmdline_tag是否定義。
thekernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
// hdr為指向image header的指標,hdr->ih_ep就是我們用mkimage建立image時-e選項的引數:核心的入口位址。把函式位址hdr->ih_ep(entry point address)賦給thekernel。
……
#ifdef config_initrd_tag
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
……
memcpy((void *)(bd->bi_boot_params + bd_offset), (const void *)bd, sizeof(bd_t));
thekernel (0, bd->bi_arch_number, bd->bi_boot_params);
//給核心傳引數(含根檔案系統位址)。這裡bd->bi_arch_number和bd->bi_boot_params在具體開發板的board_init函式裡面初始化。
gd->bd->bi_arch_number = 387;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
gd->flags = 0;
U boot啟動核心原理
u boot啟動核心原理 arm平台u boot 啟動核心命令如 bootcmd bootm 0xc4040014 在.common cmd bootm.c 檔案中,bootm 命令對應的 do bootm函式,當分析uimage 中資訊發現os是 linux 時,呼叫 lib arm armlin...
U boot啟動核心原理
by neil chiao neilchiao at gmail.com neilengineer.cublog.cn 歡迎到 新星灣 www.xinxingwan.com 指導 arm平台u boot啟動核心命令如 bootcmd bootm 0xc4040014 在.common cmd boo...
uboot啟動核心
假設bootcmd nand read.jffs2 0x30007fc0 kernel bootm 0x30007fc0 1 nand read.jffs2 0x30007fc0 kernel nand read.jffs2 0x30007fc0 kernel 從nand讀出核心 從 讀?從kern...