【正点原子MP157连载】 第十章 U-boot使用-摘自【正点原子】【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)實驗平臺:正點原子STM32MP157開發(fā)板
2)購買鏈接:https://item.taobao.com/item.htm?&id=629270721801
3)全套實驗源碼+手冊+視頻下載地址:http://www.openedv.com/thread-318813-1-1.html
4)正點原子官方B站:https://space.bilibili.com/394620890
5)正點原子STM32MP157技術(shù)交流群:691905614
第十章 U-boot使用
在移植U-Boot之前,我們肯定要先使用一下U-Boot,得先體驗一下U-Boot是個什么東西。STM32MP157開發(fā)板光盤資料里面已經(jīng)提供了一個正點原子團隊已經(jīng)移植好的U-Boot,本章我們就直接編譯這個移植好的U-Boot,然后燒寫到EMMC里面啟動,啟動U-Boot以后就可以學(xué)習(xí)使用U-Boot的命令。
10.1 U-Boot簡介
Linux 系統(tǒng)要啟動需要通過bootloader 程序引導(dǎo),也就說芯片上電以后先運行一段bootloader程序。這段bootloader程序會先初始化DDR等外設(shè),然后將Linux內(nèi)核從flash(NAND,NOR FLASH,SD,EMMC 等)拷貝到 DDR 中,最后啟動 Linux 內(nèi)核。當(dāng)然了,bootloader 的實際工作要復(fù)雜的多,但是它最主要的工作就是啟動 Linux 內(nèi)核,bootloader 和 Linux 內(nèi)核的關(guān)系就跟 PC 上的 BIOS 和 Windows 的關(guān)系一樣,bootloader 就相當(dāng)于 BIOS。所以我們要先搞定bootloader,很慶幸,有很多現(xiàn)成的 bootloader 軟件可以使用,比如 U-Boot、vivi、RedBoot 等等,其中以 U-Boot 使用最為廣泛,為了方便書寫,本書會將 U-Boot 寫為 uboot。
uboot 的全稱是 Universal Boot Loader,uboot 是一個遵循 GPL 協(xié)議的開源軟件,uboot是一個裸機代碼,可以看作是一個裸機綜合例程。現(xiàn)在的 uboot 已經(jīng)支持液晶屏、網(wǎng)絡(luò)、USB等高級功能。uboot 官網(wǎng)為http://www.denx.de/wiki/U-Boot/,如圖10.1.1所示:
圖10.1.1 uboot官網(wǎng)
我們可以在 uboot 官網(wǎng)下載 uboot 源碼,點擊圖10.1.1中左側(cè) Topics 中的“Source Code”,打開以后如圖10.1.2所示:
圖10.1.2 uboot源碼界面
點擊圖10.1.2中的“FTP”,進入其 FTP 服務(wù)器即可看到 uboot 源碼,如圖10.1.3所示:
圖10.1.3 uboot源碼
圖10.1.3中就是 uboot 原汁原味的源碼文件,目前最新的版本是 2020.10。但是我們一般不會直接用 uboot 官方的 U-Boot 源碼的。uboot 官方的 uboot 源碼是給半導(dǎo)體廠商準(zhǔn)備的,半導(dǎo)體廠商會下載 uboot 官方的 uboot 源碼,然后將自家相應(yīng)的芯片移植進去。也就是說半導(dǎo)體廠商會自己維護一個版本的 uboot,這個版本的 uboot 相當(dāng)于是他們定制的。既然是定制的,那么肯定對自家的芯片支持會很全,雖然 uboot 官網(wǎng)的源碼中一般也會支持他們的芯片,但是絕對是沒有半導(dǎo)體廠商自己維護的 uboot 全面。ST提供了2020.01版本的uboot,在6.1.1小節(jié)獲取ST官方系統(tǒng)源碼中我們已經(jīng)得到了ST官方uboot源碼, 進入到如下目錄:
/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi
uboot源碼如圖10.1.4所示:
圖10.1.4 ST官方uboot源碼
圖10.1.4中的“u-boot-stm32mp-2020.01-r0”就是ST官方uboot源碼包,它支持了STM32MP1家族全系列芯片(后續(xù)ST也會一直更新,添加新的SOC進去),而且支持各種啟動方式,比如EMMC、NAND 等等,這些都是 uboot 官方所不支持的。但是圖10.1.4中的 uboot 是針對ST 自家評估板的,如果要在我們自己的板子上跑,那么就需要對其進行修改,使其支持我們自己做的板子,正點原子的 STM32MP157開發(fā)板就是自己做的板子,雖然大部分都參考了 ST 官方的STM32MP157 EVK開發(fā)板,但是還是有很多不同的地方,所以需要修改 ST 官方的 uboot,使其適配正點原子的 STM32MP157開發(fā)板。所以當(dāng)我們拿到開發(fā)板以后,是有三種uboot 的,這三種 uboot的區(qū)別如表10.1.1所示:
種類 描述
uboot官方的uboot代碼 由uboot官方維護開發(fā)的uboot版本,版本更新快,基本包含所有常用的芯片。
半導(dǎo)體廠商的uboot代碼 半導(dǎo)體廠商維護的一個uboot,專門針對自家的芯片,在對自家芯片支持上要比uboot官方的好。
開發(fā)板廠商的uboot代碼 開發(fā)板廠商在半導(dǎo)體廠商提供的uboot基礎(chǔ)上加入了對自家開發(fā)板的支持。
表10.1.1 三種uboot的區(qū)別
那么這三種uboot該如何選擇呢?首先uboot官方的基本是不會用的,因為支持太弱了。最常用的就是半導(dǎo)體廠商或者開發(fā)板廠商的 uboot,如果你用的半導(dǎo)體廠商的評估板,那么就使用半導(dǎo)體廠商的 uboot,如果你是購買的第三方開發(fā)板,比如正點原子的 STM32MP157開發(fā)板,那么就使用正點原子提供的 uboot 源碼(也是在半導(dǎo)體廠商的 uboot 上修改的)。當(dāng)然了,你也可以在購買了第三方開發(fā)板以后使用半導(dǎo)體廠商提供的 uboot,只不過有些外設(shè)驅(qū)動可能不支持,需要自己移植,這個就是我們常說的 uboot 移植。本節(jié)是 uboot 的使用,所以就直接使用正點原子已經(jīng)移植好的 uboot,這個已經(jīng)放到了開發(fā)板光盤中了,路徑為:開發(fā)板光盤?1、程序源碼?1、正點原子Linux出廠系統(tǒng)源碼?u-boot-stm32mp-2020.01-gdb8d2374-v1.0.tar.bz2。
10.2 U-Boot初次編譯
10.2.1 編譯
首先需要在 Ubuntu 中安裝一些庫,否則編譯uboot會報錯,安裝命令如下:
sudo apt-get install libncurses5-dev bison flex
在 Ubuntu 中創(chuàng)建存放 uboot 的目錄,比如我這里新建了一個名為“alientek_uboot”的文件夾用于存放正點原子提供的 uboot 源碼。alientek_uboot文件夾創(chuàng)建成功以后使用 FileZilla 軟件將正點原子提供的 uboot 源碼拷貝到此目錄中,正點原子提供的 uboot 源碼已經(jīng)放到了開發(fā)板光盤中,路徑為:開發(fā)板光盤?1、程序源碼?1、正點原子Linux出廠系統(tǒng)源碼?u-boot-stm32mp-2020.01-xxxxxxxx-v1.0.tar.bz2(“xxxxxxxxx”為uboot打包時候的版本號,每次打包其版本號都不同!所以大家不要糾結(jié)于開發(fā)板光盤中的uboot源碼打包版本號是否和教程里面的一致)。將stm32mp-2020.01-xxxxxxxx-v1.0.tar.bz2拷貝到前面新建的 alientek_uboot 文件夾下,完成以后如圖10.2.1.1所示:
圖10.2.1.1 正點原子出廠uboot源碼
使用如下命令對其進行解壓縮:
tar -vxf u-boot-stm32mp-2020.01-gdb8d2374-v1.0.tar.bz2
解壓完成以后如圖10.2.1.2所示:
圖10.2.1.2 解壓后的Uboot
圖10.2.1.2中除了u-boot-stm32mp-2020.01-gdb8d2374-v1.0.tar.bz2這個正點原子提供uboot源碼壓縮包以外,其他的文件和文件夾都是解壓出來的 uboot 源碼。執(zhí)行以下命令,編譯正點原子提供的uboot。
上面命令每次編譯的時候都要指定ARCH、CROSS_COMPILE和DEVICE_TREE,這三個含義如下:
ARCH:指定所使用的平臺架構(gòu),這里肯定是arm。
CROSS_COMPILE:所使用的交叉編譯器前綴,本教程使用的是交叉編譯器前綴為arm-none-linux-gnueabihf-。
DEVICE_TREE:設(shè)備樹文件,uboot也支持設(shè)備樹,所以在編譯的時候需要指定設(shè)備樹文件,不同的硬件其設(shè)備樹文件肯定不同,這里為stm32mp157d_atk,也就是正點原子的STM32MP157開發(fā)板對應(yīng)的設(shè)備樹。
編譯的時候每次都輸入ARCH和CROSS_COMPILE比較麻煩,為了方便起見,我們可以直接修改uboot的Makefile文件,在里面直接對ARCH和CROSS_COMPILE進行賦值,也就是直接將ARCH設(shè)置為arm,CROSS_COMPILE設(shè)置為arm-none-linux-gnueabihf-,修改完成以后如圖10.2.1.3所示:
圖10.2.1.3 設(shè)置ARCH和CROSS_COMPILE值
注意!不能在Makefile里面對DEVICE_TREE進行復(fù)制,因為沒用,必須在編譯的時候手動輸入!
設(shè)置好Makefile里面的ARCH和CROSS_COMPILE以后就可以將編譯命令簡化為如下所示:
上述命令和前面的相比就要簡潔很多,最后的“make V=1”是真正的編譯命令,V=1表示編譯uboot的時候輸出詳細的編譯過程,方便我們觀察uboot編譯過程。直接輸入“make”命令的話默認(rèn)使用單線程編譯,編譯速度會比較慢,可以通過添加“-j”選項來使用多線程編譯,比如使用8線程編譯,最后的編譯命令就是:
make V=1 DEVICE_TREE=stm32mp157d-atk all -j8 //8線程編譯
uboot編譯完成如圖10.2.1.4所示:
圖10.2.1.4 uboot編譯成功
編譯完成以后的 就會在uboot源碼目錄下生成相應(yīng)的鏡像文件,如圖10.2.1.5所示:
圖10.2.1.5 編譯后生成的uboot可執(zhí)行文件
可以看出,編譯完成以后 uboot 源碼多了一些文件,重點是u-boot.bin和u-boot.stm32這兩個文件。u-boot.bin是uboot的二進制可執(zhí)行文件,u-boot.stm32是在u-boot.bin前面添加了256個字節(jié)頭部信息。STM32MP1內(nèi)部ROM代碼和TF-A在運行uboot的時候要求前面添加頭部信息,所以這就是為什么uboot也有這個頭部信息的原因。
10.2.2 燒寫
使用STM32CubeProgrammer將上面編譯出來的u-boot.stm32鏡像燒寫到開發(fā)板的EMMC里面,修改前面創(chuàng)建的tf-a.tsv文件,添加uboot燒寫指令(其實在9.3.2小節(jié)已經(jīng)講過了),在最后面添加下面這行:
示例代碼10.2.2.1 uboot燒寫指令
P 0x06 ssbl Binary mmc1 0x00080000 u-boot.stm32
修改以后的tf-a.tsv如圖10.2.2.1所示:
圖10.2.2.1 修改后的tf-a.tsv
最后將上一小節(jié)編譯出來的u-boot.stm32,拷貝到前面創(chuàng)建的images目錄下(在做TF-A實驗的就有u-boot.stm32這個文件,我們只要替換就行)。
一切準(zhǔn)備就緒以后就可以使用STM32CubeProgrammer軟件通過USB OTG將uboot燒寫到開發(fā)板上的EMMC里面,等到燒寫完成。完成以后設(shè)置開發(fā)板上的撥碼開關(guān),設(shè)置從EMMC啟動,然后用USB Type-C線將開發(fā)板上的USB_TTL接口與電腦連接起來,因為我們要在串口終端里面輸入命令來操作uboot。
打開MobaXterm,設(shè)置好串口參數(shù),最后復(fù)位開發(fā)板。在 MobaXterm 上出現(xiàn)“Hit any key tostop autoboot: ”倒計時的時候按下鍵盤上的回車鍵,默認(rèn)是 1 秒倒計時,在 1 秒倒計時結(jié)束以后如果沒有按下回車鍵的話 uboot 就會使用默認(rèn)參數(shù)來啟動 Linux 內(nèi)核了(如果內(nèi)核存在的話,如果Linux內(nèi)核不存在那么就會進入到uboot的命令行模式)。如果在 1 秒倒計時結(jié)束之前按下回車鍵,那么就會進入 uboot 的命令行模式,如圖10.2.2.2所示:
圖10.2.2.2 uboot啟動log信息
從圖10.2.2.2可以看出,當(dāng)進入到 uboot 的命令行模式以后,左側(cè)會出現(xiàn)一個“STM32MP=>”標(biāo)志。uboot 啟動的時候會輸出一些信息,這些信息如下所示:
簡單講解一下uboot啟動過程的log信息:
第 1 行是 uboot 版本號和編譯時間,可以看出,當(dāng)前的 uboot 版本號是 2020.01,編譯時間是 2020 年 11月 24 日 17: 17。
第3行是CPU的信息,可以看出CPU型號為STM32MP157DAA。
第4行是板子信息,當(dāng)前板子是ST公司的STM32MP157D eval開發(fā)板,這個信息是可以改的,因為正點原子是直接參考ST公司的EVK開發(fā)板移植的uboot,所以這部分信息也就沒改。
第5行是板子的一些信息,比如工作在trusted模式下。
第6行是DDR的大小為1GB。
第7~12行它們的頻率分別為,MPU頻率、MCU頻率、AXI總線頻率、PER的頻率、DDR頻率。
第13行是看門狗信息,喂狗時間為32s。
第14行是NAND的大小,因為正點原子的STM32MP157開發(fā)板沒有NAND,所以這里就是0MB。
第15行是板子上MMC設(shè)備,一共有兩個,SD/MMC0 (SD卡)和SD/MMC1 (EMMC)。
第16行是從MMC里獲取環(huán)境變量。
第17~19行是標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤所使用的終端,這里都使用串口(serial)作為終端。
第20~23行是網(wǎng)絡(luò)相關(guān)信息,網(wǎng)絡(luò)的MAC地址從OTP里獲取,因為我們的OTP沒有設(shè)置MAC地址,所以就獲取失敗。這里的網(wǎng)絡(luò)是可以用的,只是因為沒有MAC地址所以提示沒有找到網(wǎng)絡(luò),可以自行添加相關(guān)環(huán)境變量來設(shè)置MAC地址,后面會講如何設(shè)置。
第 25 行是倒計時提示,默認(rèn)倒計時 1 秒,倒計時結(jié)束之前按下回車鍵就會進入 Linux 命令行模式。如果在倒計時結(jié)束以后沒有按下回車鍵,那么 Linux 內(nèi)核就會啟動,Linux 內(nèi)核一旦啟動,uboot 就會壽終正寢。
uboot的主要作用是引導(dǎo)kernel,我們現(xiàn)在已經(jīng)進入 uboot 的命令行模式了,進入命令行模式以后就可以給 uboot 發(fā)號施令了。當(dāng)然了,不能隨便發(fā)號施令,得看看 uboot 支持哪些命令,然后使用這些uboot 所支持的命令來做一些工作,下一節(jié)就講解 uboot 命令的使用。
10.3 U-Boot命令使用
進入uboot的命令行模式以后輸入“help”或者“?”,然后按下回車即可查看當(dāng)前uboot所支持的命令,如圖10.3.1所示:
圖10.3.1 uboot的命令列表(部分)
圖10.3.1中只是 uboot 的一部分命令,具體的命令列表以實際為準(zhǔn)。圖10.3.1中的命令并不是 uboot 所支持的所有命令,說過 uboot 是可配置的,需要什么命令就使能什么命令。所以圖10.3.1中的命令是正點原子提供的 uboot 中使能的命令,uboot 支持的命令還有很多,而且也可以在 uboot 中自定義命令。這些命令后面都跟有命令說明,用于描述此命令的作用,但是命令具體怎么用呢?我們輸入“help(或?) 命令名”既可以查看命令的詳細用法,以“bootz”這個命令為例,我們輸入如下命令即可查看“bootz”這個命令的用法:
? bootz 或 help bootz
結(jié)果如圖10.3.2所示:
圖10.3.2 bootz 命令使用說明
圖10.3.2列出了“bootz”這個命令的詳細說明,其它的命令也可以使用此方法查詢具體的使用方法。接下來我們學(xué)習(xí)一下一些常用的 uboot 命令。
10.3.1 查詢命令
常用的和信息查詢有關(guān)的命令有 3 個:bdinfo、printenv 和 version。先來看一下 bdinfo 命令,此命令用于查看板子信息,直接輸入“bdinfo”即可,結(jié)果如圖10.3.1.1示:
圖10.3.1.1 bdinfo 命令
從圖10.3.1.1中可以看出 DRAM 的起始地址和大小、BOOT參數(shù)保存起始地址、波特率、sp(堆棧指針)起始地址等信息。命令“printenv”用于輸出環(huán)境變量信息,uboot 也支持 TAB 鍵自動補全功能,輸入“print”然后按下 TAB 鍵就會自動補全命令。直接輸入“print”也可以,因為整個uboot命令中只有printenv的前綴是“print”,所以當(dāng)輸入print以后就只有printenv命令了。輸入“print”,然后按下回車鍵,環(huán)境變量如圖10.3.1.2所示:
圖10.3.1.2 printenv 命令部分結(jié)果
圖10.3.1.2只是printenv命令的部分內(nèi)容,STM32MP1系列的環(huán)境變量有很多,比如 baudrate、board、board_name、boot_device、bootcmd、bootdelay等等。uboot 中的環(huán)境變量都是字符串,既然叫做環(huán)境變量,那么它的作用就和“變量”一樣。比如 bootdelay 這個環(huán)境變量就表示 uboot 啟動延時時間,默認(rèn) bootdelay=1,也就默認(rèn)延時 1秒。前面說的 1 秒倒計時就是由 bootdelay 定義的,如果將 bootdelay 改為 5 的話就會倒計時 5s了。uboot 中的環(huán)境變量是可以修改的,有專門的命令來修改環(huán)境變量的值,稍后我們會講解。
命令 version 用于查看 uboot 的版本號,輸入“version”,uboot 版本號如圖10.3.1.3所示:
圖10.3.1.3 version命令結(jié)果
總結(jié)
以上是生活随笔為你收集整理的【正点原子MP157连载】 第十章 U-boot使用-摘自【正点原子】【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人空间岁末大回报活动12月28日获奖名
- 下一篇: 【正点原子Linux连载】第十八章 Ca