[英]Passing kernel params from U-Boot to ARM Linux when device tree is used
我一直在研究對某些嵌入式軟件的更改,因為我們希望U-Boot能夠將特定的命令行參數傳遞給內核,而這些參數不一定是事先已知的。
這樣內核就可以知道它是從哪個 U-Boot分區啟動的(我們有兩個副本,一個在/dev/mmc3boot0
和/dev/mmc3boot1
,它們都共享一個(冗余)環境空間,因此我們可以不能單獨使用它來唯一標識實例)。
一種想法是在引導時將每個U-Boot簡單地將其ID寫入共享環境,但這有一個缺點,就是目前有一些變體目前不執行此操作。 因此,如果我們從一個不啟動的啟動,它將寫入其ID;如果從一個不啟動的啟動,則它將寫入ID,如果依賴它,它將不會將ID 改回空白,從而導致信息不正確。
這就是為什么我們考慮使用內核參數的原因-由於較早版本的U-Boot實例從不提供ID,因此我們知道它在boot0
運行。 較新的樣式將提供其實際ID,因此我們可以搜索兩個boot
分區以查看其所在的分區。
為此,我修改了U-Boot,以便它設置ATAG以傳遞所需的額外參數。 特別:
arch\\arm\\include\\asm\\config.h
定義了CONFIG_SYS_BOOT_GET_CMDLINE
,以便調用boot_get_cmdline()
。 boot_get_cmdline()
函數,以便在附加普通參數之前先設置一個特定參數。 換句話說,我們現在得到的不僅僅是plugh=xyzzy
,而是uboot_instance=42 plugh=xyzzy
。 所有這些都可以正常編譯,並且U-Boot成功啟動了內核,但是額外的信息沒有反映在Linux內核中,該內核的內核參數設置為常規的plugh=xyzzy
。
在進一步的研究中,似乎我們不符合調用內核的兩種可能方式。 其中之一與ATAG一起使用,一個與扁平設備樹(FDT)一起使用,並且它們似乎是互斥的(內核啟動代碼根據傳遞的簽名選擇一個或另一個,該簽名通過引用ATAG或FDT結構的指針傳遞)。
所以我的問題是這個。 假設設備樹是您要描述的設備的固定結構,那么當引導加載程序調用內核時,如何傳遞任意的內核命令行參數(在運行時計算)?
您可以在include/configs/<board>.h
為您的平台使用虛擬環境變量。
例如,假定您具有以下(簡化的)UBoot環境變量用於引導:
bootcmd=run mmcargs
run loadimage loadfdt
bootz ${loadaddr} - ${fdt_addr}
mmcargs=setenv bootargs blah=blah
這使用mmcargs
設置要使用的內核命令行。 我們需要做的是以當前UBoot實例不提供任何內容而新的實例提供實際ID的方式插入該虛擬環境變量。 只需進行以下更改即可完成:
mmcargs=setenv bootargs ${uboot_id_stanza} blah=blah
然后,板的初始化過程中,您可以通過設置此變量env_set
API專門寫自己的自定義, board_late_init
在板初始化代碼的board/<vendor>/<init_code>.c
。
以下行應放在board_late_init
函數的末尾:
setenv("uboot_id_stanza", "uboot_id=<uniqueId>");
這樣, uboot_id
變量設置將添加到內核命令行,但是由於您沒有執行saveenv
,因此它不會持久化。 每個UBoot實例都將設置正確的ID(包括未設置ID的舊ID)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.