XiaomiRouter自學(xué)之路(08-U-boot啟動數(shù)值具體說明)
在上一章節(jié)的[U-boot啟動過程]中篙耗,我們分析到U-boot倒計(jì)時后的參數(shù)選擇悯舟,這一章節(jié)我們將對各參數(shù)選擇后執(zhí)行的具體功能代碼進(jìn)行分析,讓我們更深入的理解代碼在內(nèi)存录肯、Flash之間的搬運(yùn)過程永罚。
再來查看下各數(shù)值代表的含義
0: System Load Linux then write to Flash via Serial.
1: Load system code to SDRAM via TFTP.
2:Load system code then write to Flash via TFTP.
3: Boot system code via Flash (default).
4: Entr boot command line interface.
7: Load Boot Loader code then write to Flash via Serial.
8: System Load UBoot to SDRAM via TFTP.
9: Load Boot Loader code then write to Flash via TFTP.
將其分類下悯森,其實(shí)就很明了:
- 兩種文件需要更新:U-boot荐糜、System
- 兩種更新方式:Serial巷怜、tftp
- 更新到兩個位置:SDRAM、Flash
- 數(shù)值3:從Flash啟動系統(tǒng)
- 數(shù)值4:進(jìn)入U-boot命令行模式
1.進(jìn)入U-boot命令行模式
case '4':
printf(" \n%d: System Enter Boot Command Line Interface.\n", SEL_ENTER_CLI);
printf ("\n%s\n", version_string);
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
break;
case 4就是循環(huán)執(zhí)行main_loop()函數(shù)暴氏,該函數(shù)位于common/main.c中
main_loop函數(shù)就是一直檢測用戶所輸入的命令延塑,然后進(jìn)行解析執(zhí)行對于的代碼,那哪些命令才可以被解析正確呢答渔,如果用戶想自己加入一個命令呢关带?
這邊使用的是U_BOOT_CMD宏定義,如ping命令的定義如下:
U_BOOT_CMD(
ping, 2, 1, do_ping,
"ping\t- send ICMP ECHO_REQUEST to network host\n",
"pingAddress\n"
);
U_BOOT_CMD的定義如下研儒,第一個參數(shù)name即要輸入的命令豫缨,maxargs為最大長度,rep表示可重復(fù)性端朵,cmd為輸入命令后索要執(zhí)行的函數(shù)如這邊的do_ping()函數(shù),usage/help都是提示信息燃箭。
define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
知道U_BOOT_CMD的定義后冲呢,我們就知道如何添加自己的命令,以及輸入每個命令的具體代碼在哪里尋找招狸。
2.兩種
上面總結(jié)了以下兩種:
- 兩種文件需要更新:U-boot敬拓、System
- 兩種更新方式:Serial、tftp
- 更新到兩個位置:SDRAM裙戏、Flash
解釋下就是通過Serial/tftp的方式將U-boot/System燒錄到SDRAM/Flash乘凸,所以也很直觀。
我們先來看下兩種方式即Serial和tftp累榜,當(dāng)選擇不同的方式時营勤,就會選擇不同的接口函數(shù)。
觀察代碼我們可以發(fā)現(xiàn):
- 當(dāng)選擇tftp模式時壹罚,先通過
tftp_config()
函數(shù)設(shè)置網(wǎng)絡(luò)環(huán)境葛作,然后再通過do_tftpb()
函數(shù)進(jìn)行數(shù)據(jù)的上傳。 - 當(dāng)選擇serial模式時猖凛,則通過
do_load_serial_bin(()
函數(shù)進(jìn)行數(shù)據(jù)的上傳赂蠢。
這邊先普及一個知識,我們數(shù)據(jù)的轉(zhuǎn)移過程是先通過tftp/serial從本地上傳到運(yùn)行內(nèi)存SDRAM中辨泳,然后在從SDRAM寫入介質(zhì)Flash中虱岂,所以上面的這兩個接口函數(shù)都是將文件上傳到運(yùn)行內(nèi)存SDRAM中玖院。
兩種方式知道了,那接著看兩個位置SDRAM和Flash第岖。
- SDRAM上面已經(jīng)說明了难菌,通過
do_tftpb()
和do_load_serial_bin(()
函數(shù)即可。 - 由于使用的是spi flash绍傲,所以寫入Flash則使用接口函數(shù)
raspi_erase_write()
來實(shí)現(xiàn)扔傅。
既然更新方式和更新位置知道了,那剩下的更新文件U-boot和System是如何區(qū)分的烫饼,細(xì)心的你可能會發(fā)現(xiàn)在調(diào)用do_tftpb()
猎塞、do_load_serial_bin(()
、raspi_erase_write()
時都是有帶不同的參數(shù)的杠纵,這些參數(shù)就是用來區(qū)分我們U-boot/System所要存放的具體地址荠耽。
在include/configs/rt2880.h中有如下定義:
#define CFG_BOOTLOADER_SIZE 0x20000
#define CFG_CONFIG_SIZE 0x10000
#define CFG_FACTORY_SIZE 0x10000
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_BOOTLOADER_SIZE)
#define CFG_FACTORY_ADDR (CFG_FLASH_BASE + CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE)
#define CFG_KERN_ADDR (CFG_FLASH_BASE + (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE))
#ifdef DUAL_IMAGE_SUPPORT
#define CFG_KERN2_ADDR (CFG_FLASH2_BASE + (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE))
可以很直觀的看出各信息在Flash中的存放位置,Uboot-config-factory-kernel比藻。
3.從Flash啟動系統(tǒng)
if(BootType == '3') {
char *argv[2];
sprintf(addr_str, "0x%X", CFG_KERN_ADDR);
argv[1] = &addr_str[0];
printf(" \n3: System Boot system code via Flash.\n");
do_bootm(cmdtp, 0, 2, argv);
}
啟動系統(tǒng)也是比較直觀的铝量,調(diào)用do_bootm()函數(shù),該函數(shù)位于common/cmd_bootm.c中银亲,do_bootm()函數(shù)將地址參數(shù)傳輸進(jìn)去慢叨,里面通過raspi_read()函數(shù)進(jìn)行讀取特定的位置到內(nèi)存,然后執(zhí)行务蝠,即所說的啟動系統(tǒng)拍谐,當(dāng)然在啟動的過程會有一系列的驗(yàn)證等動作。
U-boot啟動數(shù)值具體說明的分析就到這邊馏段,有感悟時會持續(xù)會更新轩拨。
注:以上內(nèi)容都是本人在學(xué)習(xí)過程積累的一些心得,難免會有參考到其他文章的一些知識院喜,如有侵權(quán)亡蓉,請及時通知我,我將及時刪除或標(biāo)注內(nèi)容出處喷舀,如有錯誤之處也請指出砍濒,進(jìn)行探討學(xué)習(xí)。文章只是起一個引導(dǎo)作用元咙,詳細(xì)的數(shù)據(jù)解析內(nèi)容還請查看XiaomiRouter相關(guān)教程梯影,感謝您的查閱。