U boot啟動核心原理

2021-06-01 12:39:18 字數 3497 閱讀 2428

/*

*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...