AM335X有關MMC的啟動參數問題分析


AM335X有關MMC的啟動參數問題分析

一、 問題來源

硬件平台:AM335X芯片

SDK版本:ti-processor-sdk-linux-am335x-evm-03.00.00.04-Linux-x86-Install

使用創龍相關文檔進行參考。

發現問題的過程:使用SD(MMC0)卡啟動UBOOT,內核,文件系統,正常啟動之后,使用固化程序腳本將UBOOT、內核、文件系統固化到EMMC(MMC1)中。再將BOOT引腳設計為從EMMC(MMC1)啟動。

關機后拔下SD卡,啟動起來之后、文件系統內核的加載都是在EMMC中進行。

若關機后不拔下SD卡,啟動后會有如下現象:

1、 uboot從EMMC(MMC1)啟動,

2、 由於啟動參數設置的原因,內核和文件系統還是使用的SD(MMC0)卡中的內容。

二、 啟動參數詳解

1、 相關啟動命令及環境變量如下:

/*默認的args_mmc */

args_mmc=run finduuid;setenv bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw rootfstype=${mmcrootfstype}

/*默認的啟動命令 */

bootcmd=run findfdt; run init_console; run envboot; run mmcboot; setenv mmcdev 1;setenv finduuid part uuid mmc 1:2 uuid;run mmcboot;run nandboot;run distro_bootcmd

/*默認的envboot */

envboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootscript; then run bootscript;else if run loadbootenv; then echo Loaded env from ${bootenvfile};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;fi;fi;

/*默認的finduuid */

finduuid=part uuid mmc 0:2 uuid

/*默認的mmcdev */

mmcdev=0

/*默認的bootpart */

bootpart=0:2

/*默認的mmcboot */

mmcboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};run envboot; if run loadimage; then run mmcloados;fi;fi;

/*默認的loadimage */

loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}

/*默認的nandboot */

nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} NAND.u-boot-spl-os; nand read ${loadaddr} NAND.kernel; bootz ${loadaddr} - ${fdtaddr}

/*默認的distro_bootcmd 、boot_targets */

distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done

boot_targets=mmc0 legacy_mmc0 mmc1 legacy_mmc1 nand0 pxe dhcp

三、啟動過程分析:

1、Uboot起來后查看MMC0(1)有沒有uboot.env,若沒有,就使用默認的UBOOT啟動參數。默認的的啟動參數可以在UBOOT中查看。

2、取出bootcmd,見上一節中的參數,mmcdev初始值為0,本例中沒有loadbootscript和bootenvfile。直接到mmcboot

3、mmcboot從MMC0中啟動。

4、若mmc0啟動未成功(MMC0不存在或者內容不對),則setenv finduuid part uuid mmc 1:2 uuid后,再一次運行mmcboot。

5、若沒有成功,則運行nandboot(2)

6、若還不成功,則運行distro_bootcmd(3)

四、問題原因分析

啟動參數設置不合理,主要由以下幾點:

1、 內核啟動時是從默認的MMC0、MMC1。。。等等去進行查找並啟動,若本來設置的目的是通過MMC1啟動,但是這是若MMC0設備存在並有內核文件在其中,則會被啟動。這也是本文開頭描述的現象。

2、 MMC0若是沒有啟動,應該切換到MMC1,需要重新設置一些環境變量的值,bootcmd中對mmcdev 、 finduuid 進行了重新設置,但是未對bootpart進行重新賦值,這會導致MMC1的內核啟動還是變為了MMC0的內核啟動,參見 mmcboot中的loadimage。

五、問題解決辦法

對應上一節提出的問題,解決辦法如下:

1、 可以使用判斷語句,判斷出當前位置,就是確定是哪個MMC,並從中啟動內核,但是現階段沒有更改,只是保證SD卡中沒有內核文件就好。

2、 增加對bootpart的修改,UBOOT中修改后的bootcmd為:

#define CONFIG_BOOTCOMMAND \

"run findfdt; " \

"run init_console; " \

"run envboot; " \

"run mmcboot; " \

"setenv mmcdev 1;setenv bootpart 1:2;setenv finduuid part uuid mmc 1:2 uuid;" \

"run mmcboot;" \

"run nandboot;" \

"run distro_bootcmd"

 

六、注釋處解釋

(1)uboot.env可以設置存放位置,默認在MMC0,在Am335x_evm.h中設置

/* Not NAND, SPI, NOR or eMMC env, so put ENV in a file on FAT */

#define CONFIG_ENV_IS_IN_FAT

#define FAT_ENV_INTERFACE           "mmc"

#define FAT_ENV_DEVICE_AND_PART             "0:1"

#define FAT_ENV_FILE               "uboot.env"

 

(2)nandboot這個環境變量寫的不合理,應判斷是否存在再進行讀取和啟動。不判斷直接讀取,讀取失敗后還是進行啟動,若這時內存中(kernel_addr_r=0x82000000)剛好有之前讀入的內核,啟動會出問題,問題原因需要進一步明確。

 

(3)distro_bootcmd為依次從上述啟動路徑進行查找內核文件並啟動。過程涉及較多,不進行一一分析。這個為保底的啟動掃描。

 

注:若不進行bootpart的重新設置,不插SD卡,還是會從MMC1啟動,但是這時不是mmcboot從中MMC1啟動的(bootpart設置的還是0:2),而是在distro_bootcmd中掃描到MMC1是啟動的,在這之前會進行nandboot,但是會失敗。若啟動好之后 reboot,則重復上述過程,在nandboot時,發現內存中有內核,則會啟動,就會發生問題。所以還是必須要將bootcmd更新,保證功能的健壯性。

 

反思:

1、總是覺得所有的啟動都是和 BOOTPIN有關,其實只有MLO和UBOOT是與BOOTPIN有關。內核的啟動是與啟動參數有關的。基於本文的分析,啟動命令、參數,尤其是bootcmd與args_mmc是可以靈活配置的。

2、開發方式:起初完全可以利用SD卡進行啟動,uboot.env也存放在SD卡中,內核部分開發完畢后,可以將uboot.env設置到MMC1 中。這時固化uboot及內核到MMC1中。此時從MMC1啟動UBOOT,這個時候就可以重新設置環境變量,使得bootcmd更加精簡。之后保存,將uboot.env保存在MMC1上,之后Uboot啟動后都會去查找uboot.env這個文件。這部分未做嘗試。

可以看出:啟動命令,啟動參數。環境變量文件等都是可以靈活變通的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM