bootm命令函式do_bootm位於cmd_bootm.c,其流程為:
確定是否要校驗uimage和ramdisk裡的資料,預設校驗,若想不校驗:設定了環境變數verify=n。
s = getenv ("verify");
verify = (s && (*s == 'n')) ? 0 : 1;
判斷命令是否制定了 作業系統 的載入位址。如果沒有,使用預設位址cfg_load_addr,一般cfg_load_addr可以在include/configs資料夾自己單板的配置檔案裡配置。
if (argc < 2) else
根據image 載入位址是在 flash還是記憶體,獲取image的 頭資訊。
#ifdef config_has_dataflash
if (addr_dataflash(addr)) else
#endif
memmove (&header, (char *)addr, sizeof(image_header_t));
校驗頭里的magic num和crc是否正確,頭部的crc計算內容是 :頭部64b,且頭部crc處按內容0來計算。
if (ntohl(hdr->ih_magic) != ih_magic) });
.............................................
if (crc32 (0, (uchar *)data, len) != checksum)
根據image type進行不同的處理,如果是linux kernel後面再處理:
switch (hdr->ih_type)
判斷壓縮型別,做不同拷貝處理。
未壓縮:
如果映象中load位址與第乙個引數一致的話,意思是核心已經在loadaddr準備好了,無需處理。
如果映象中load位址與第乙個引數不一致的話,就要從傳遞的位址拷貝到 image指定的loadaddr(hdr->ih_load)了。
如果是壓縮型別gzip或者bzip2:
就呼叫相應解壓縮函式,將映象解壓到image指定的loadaddr(hdr->ih_load)了。預設預留解壓後的大小為8m。當然這個空間大小可以使用這個巨集定義cfg_bootm_len來修改
switch (hdr->ih_comp) else
#else /* !(config_hw_watchdog || config_watchdog) */
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
#endif /* config_hw_watchdog || config_watchdog */
}break;
case ih_comp_gzip:
printf (" uncompressing %s ... ", name);
if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
(uchar *)data, &len) != 0)
break;
.............................................
}判斷如果是核心,暫時不用處理
switch (hdr->ih_type) {
.............................................
case ih_type_kernel:
case ih_type_multi:
/* handled below */
break;
根據映象的不同型別,呼叫不同的作業系統啟動函式。
switch (hdr->ih_os) {
default: /* handled by (original) linux case */
case ih_os_linux:
#ifdef config_silent_console
fixup_silent_linux();
#endif
do_bootm_linux (cmdtp, flag, argc, argv,
addr, len_ptr, verify);
break;
如果linux作業系統就呼叫do_bootm_linux ,其流程為:
如果定義了config_cmdline_tag,就從環境變數取出bootargs,準備傳引數給核心。#ifdef config_cmdline_tag
char *commandline = getenv ("bootargs");
#endif
從映象檔案的頭里提取entry point,即核心的入口位址。
thekernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
確認命令是否傳遞了initrd位址,如果有進行相應的處理
校驗ramdisk的magic num和頭的crc
列印頭並校驗資料crc
/** check if there is an initrd image
*/if (argc >= 3) {
根據配置,準備向核心傳遞相應的引數。
setup_end_tag (bd);
#endif
關閉cache和中斷,啟動核心。
bd->bi_boot_params:傳遞給核心引數位址。tag型別
bd->bi_arch_number:cpu型別
在各自單板的board_init函式中初始化。
cleanup_before_linux ();
thekernel (0, bd->bi_arch_number, bd->bi_boot_params);
四十二 移植bootm命令
2 加上了原版u boot裡dm9000傳送函式裡傳送前後都要清除傳送標誌 3 取消了老師說的要對包進行判斷,實際上不判斷效果還要好一點,那一部分,要求只要在空讀前後有20微妙的時間間隔就好了,經我實際測試,我的開發板確實只用空讀一次就滿足該條件。4 取消了中斷處理函式裡之前為了驗證進的是什麼中斷的...
通過移植bootm命令啟動已經編譯好
首先在移植bootm命令之前,我們要了解bootloader的主要作用 除了初始化cpu和外設外,bootloader還有乙個最大的作用就是啟動linux核心。但是在啟動linux核心之前,有幾個部分是必須先初始化的 1.初始化記憶體 2.初始化串列埠 其實也不是必須的,但可以方便看輸出,檢查錯誤 ...
SQLite VACUUM命令分析
vacuum命令是sqlite的乙個擴充套件功能,模仿postgresql中的相同命令而來。若呼叫vacuum帶乙個表名或索引名,則將整理該錶或索引。在sqlite 1.0中,vacuum命令呼叫 gdbm reorganize 整理後端資料庫檔案。sqlite 2.0.0中去掉了gdbm後端,va...