姓名:張碩 學(xué)院:電子工程學(xué)院 學(xué)號:19020100006
轉(zhuǎn)自:https://blog.csdn.net/qq_38612145/article/details/107497384
嵌牛導(dǎo)讀:本文主要介紹了uboot基礎(chǔ)以及uboot的工作方式以及常見命令
嵌牛鼻子:嵌入式,uboot
嵌牛提問:uboot有哪些常用命令
嵌牛正文:
uboot基礎(chǔ)
1.為什么要有uboot?
預(yù)備知識
計算機(jī)系統(tǒng)運(yùn)行時的主要核心部件包含3個東西:CPU+外部存儲器+內(nèi)部存儲器
PC機(jī)啟動過程為:PC上電后先執(zhí)行BIOS程序(實(shí)際上PC 的BIOS就是NorFlash),BIOS負(fù)責(zé)初始化DDR內(nèi)存和硬盤压昼,然后從硬盤上將OS鏡像讀取到DDR中护赊,然后跳轉(zhuǎn)到DDR中去執(zhí)行OS直到啟動(OS啟動后BIOS就無用了)
uboot主要作用是用來啟動操作系統(tǒng)內(nèi)核,部署整個計算機(jī)系統(tǒng)耗帕,有操作Flash等板子上硬件的驅(qū)動,提供一個命令行界面供人操作
uboot程序部署在能作為啟動設(shè)備的Flash做上,OS部署在Flash上彪标,內(nèi)存在掉電時無作用,CPU在掉電時不工作
嵌入式系統(tǒng)上電后先執(zhí)行uboot掷豺、然后uboot負(fù)責(zé)初始化DDR捞烟,初始化Flash薄声,然后將OS從Flash中讀取到DDR中,然后啟動OS(OS啟動后uboot就無用了)
2. uboot必須解決的問題
自身可開機(jī)直接啟動
必須根據(jù)具體的SoC的啟動方式來設(shè)計uboot
uboot必須進(jìn)行和硬件相對應(yīng)的代碼級別的更改和移植题画,才能保證響應(yīng)啟動介質(zhì)的啟動默辨,uboot中第一階段的start.S文件中處理了這一塊
能夠引導(dǎo)操作系統(tǒng)內(nèi)核啟動并給內(nèi)核傳參
我們可以在uboot中事先給Linux內(nèi)核準(zhǔn)備一些啟動參數(shù)放在內(nèi)存中特定位置然后傳給內(nèi)核,內(nèi)核啟動后會到這個特定位置去取uboot傳給他的參數(shù)苍息,然后內(nèi)核解析這些參數(shù)
能提供系統(tǒng)部署功能
uboot必須能夠被人借助而完成整個系統(tǒng)在Flash上的燒錄下載工作(裸機(jī)在刷機(jī)時就是利用uboot中的fastboot功能將各種鏡像燒錄到iNand中廓奕,然后從iNand啟動)
能進(jìn)行SoC級和板級硬件管理
uboot中實(shí)現(xiàn)了一部分硬件的控制能力,因為uboot為了完成一些任務(wù)必須讓一些硬件工作档叔。譬如uboot要在刷機(jī)時LCD上顯示進(jìn)度條就必須驅(qū)動LCD桌粉。
SoC級就是SoC內(nèi)部外設(shè),板級就是SoC外面開發(fā)板上面的硬件
uboot存在生命周期
uboot本質(zhì)上是一個裸機(jī)程序衙四,一旦uboot開始SoC就會單純運(yùn)行uboot铃肯,一旦uboot結(jié)束運(yùn)行就無法再回到uboot
uboot入口為開機(jī)自動啟動;出口為啟動內(nèi)核
3. uboot的工作方式
從裸機(jī)程序鏡像uboot.bin說起
uboot的本質(zhì)就是一個裸機(jī)程序传蹈,和裸機(jī)教程中的裸機(jī)程序xx.bin沒有本質(zhì)區(qū)別押逼,區(qū)別主要在于文件大小,uboot在180k-400k之間
uboot本身為一個開源項目惦界,由若干個.c文件和.h文件組成挑格,配置編譯之后會生成一個uboot.bin,這就是uboot這個裸機(jī)的鏡像文件沾歪。然后鏡像文件被合理的燒錄到啟動介質(zhì)中拿去給SoC啟動漂彤,即uboot在沒有運(yùn)行時表現(xiàn)為uboot.bin
uboot運(yùn)行時會被加載到內(nèi)存中,然后逐次拿給CPU去運(yùn)行
uboot的命令式shell界面
有些程序需要人機(jī)交互灾搏,于是程序中就實(shí)現(xiàn)了一個shell
shell并不是操作系統(tǒng)挫望,和操作系統(tǒng)一點(diǎn)關(guān)系都沒有,裸機(jī)也可以有shell
uboot使用的關(guān)鍵點(diǎn):命令和環(huán)境變量
uboot啟動后大部分時間和工作都是在shell下完成的狂窑。uboot部署系統(tǒng)要在shell下輸入命令媳板、要設(shè)置環(huán)境變量也需要在命令行下,要啟動內(nèi)核也要在命令行下輸入命令
uboot中有幾十個命令泉哈,其中一些常用蛉幸,還可以自己給uboot添加命令
uboot的環(huán)境變量和操作系統(tǒng)的環(huán)境變量工作原理和方式幾乎完全相同,uboot的驅(qū)動管理完全照抄了linux的驅(qū)動框架丛晦。系統(tǒng)或者程序在運(yùn)行時可以通過讀取環(huán)境變量來指導(dǎo)程序的運(yùn)行奕纫。環(huán)境變量就是運(yùn)行時的配置屬性。
4. uboot常用命令
命令特點(diǎn)
有些命令有簡化的別名
printenv -> print
setenv -> set
有些命令會帶參數(shù)
每個命令都有事先規(guī)定好的格式采呐,可以通過help命令查看
命令中的特殊符號(譬如單引號)
uboot有些命令帶的參數(shù)非常長若锁,為了告訴uboot這個非常長且中間有好多空格的語句為一整個參數(shù),使用單引號將這個語句引起來
有些命令是一個命令族(譬如movi)
命令族的意思就是好多個命令開頭都是用同一個命令關(guān)鍵字的斧吐,但是后面的參數(shù)不一樣又固,這些命令的功能和作用也不同
同一個命令族中所有的命令都有極大的關(guān)聯(lián)仲器,譬如movi開頭的命令族都和moviNand(EMMC、iNand)操作有關(guān)仰冠。
常見命令
打印環(huán)境變量:printenv/print
命令不用帶參數(shù)乏冀,打印出系統(tǒng)中所有的環(huán)境變量。環(huán)境變量被存儲在Flash的一塊專門區(qū)域洋只,一旦程序中保存了該環(huán)境變量辆沦,下次開機(jī)時該環(huán)境變量的值將維持上一次更改保存后的值
設(shè)置(添加/更改)環(huán)境變量:setenv/set
set name value
保存環(huán)境變量的更改:saveenv/save
不帶參數(shù)拼余,直接執(zhí)行赖钞。是對整體環(huán)境變量的保存
網(wǎng)絡(luò)測試指令:ping
步驟
用網(wǎng)線將電腦和開發(fā)板連接
設(shè)置電腦本地連接IPV4地址為192.168.1.10
確認(rèn)開發(fā)板中uboot里幾個與網(wǎng)絡(luò)相關(guān)的環(huán)境變量的值對不對。最重要的是ipaddr的地址必須與主機(jī)的IP地址在同一個網(wǎng)段內(nèi)仰美。(set ipaddr 192.168.1.xx)
tftp下載命令:tftp
uboot主要目標(biāo)是啟動內(nèi)核担锤,為了完成啟動內(nèi)核必須要能夠部署內(nèi)核蔚晨,而內(nèi)核鏡像需要從主機(jī)中下載燒錄到開發(fā)板的Flash中,下載鏡像的主流方式為fastboot和tftp肛循。fastboot的方式是通過usb線進(jìn)行數(shù)據(jù)傳輸铭腕;tftp是通過網(wǎng)絡(luò)傳輸?shù)?/p>
tftp方式下載時uboot扮演的是tftp客戶端程序角色,主機(jī)中必須有一個tftp服務(wù)器多糠,然后將要下載的鏡像文件放在服務(wù)器的下載目錄中累舷,然后在開發(fā)板中使用uboot的tftp命令去下載
虛擬機(jī)和開發(fā)板ping通的步驟
虛擬機(jī)處選擇橋接方式
在虛擬網(wǎng)絡(luò)編輯器中設(shè)置為橋接到有線網(wǎng)卡
在虛擬機(jī)中設(shè)置IP靜態(tài)地址為192.168.1.102(修改/etc/network/interfaces文件中的內(nèi)容)
重啟網(wǎng)絡(luò)
sudo ifconfig eth0 down
sudo ifconfig eth0 up
在虛擬機(jī)上搭建tftp的下載目錄/tftpboot,將要被下載的鏡像復(fù)制到這個目錄下
檢查開發(fā)板uboot的環(huán)境變量夹孔,注意serverip必須設(shè)置與虛擬機(jī)Ubuntu的ip靜態(tài)地址相同
在開發(fā)板uboot中使用tftp命令下載虛擬機(jī)中的鏡像
tftp 0x30000000 zImage-qt
意思為將服務(wù)器上名為zImage-qt的文件下載到開發(fā)板內(nèi)存的0x30000000地址處
鏡像下載到開發(fā)板DDR中后被盈,uboot就可以用movi指令進(jìn)行鏡像的燒寫了
SD卡/iNand操作指令:movi
開發(fā)板如果用SD卡/EMMC/iNand等作為Flash,則在uboot中操作Flash用指令movi
movi指令是一個命令集析蝴,在uboot中可通過help movi查看
movi 的指令都是movi read和movi write一組的害捕,movi read用來讀取iNand到DDR上绿淋,movi write用來將DDR中的內(nèi)容寫入iNand中闷畸。
NandFlash操作指令:nand
操作方法完全類似于movi指令
內(nèi)存操作指令:mm、mw吞滞、md
DDR中是沒有分區(qū)的佑菩,但是內(nèi)存使用時千萬不能越界,因為uboot是一個裸機(jī)程序裁赠,不像操作系統(tǒng)會由系統(tǒng)整體管理所有內(nèi)存殿漠,則可能會出現(xiàn)程序的覆蓋
md:memory display,顯示內(nèi)存中的內(nèi)容
mw:memory write佩捞,將內(nèi)容寫到內(nèi)存中
mm:memory modify绞幌,修改內(nèi)存中的一塊,會批量逐個修改
啟動內(nèi)核指令:bootm一忱、go
bootm啟動內(nèi)核同時給內(nèi)核傳參莲蜘,而go命令啟動內(nèi)核不傳參谭确。
bootm是正宗的啟動內(nèi)核的命令,go命令本來不是專為啟動內(nèi)核設(shè)計的票渠,go命令的實(shí)質(zhì)是PC直接跳轉(zhuǎn)到一個內(nèi)存地址去運(yùn)行而已逐哈。go命令可以用來在uboot中執(zhí)行任何的裸機(jī)程序
5. uboot環(huán)境變量
如何理解環(huán)境變量
環(huán)境變量有2份,一份在Flash中问顷,一份在DDR中昂秃。uboot開機(jī)時一次性從Flash中讀取全部環(huán)境變量到DDR中作為環(huán)境變量的初始化值,然后使用過程中都是用DDR中這一份杜窄,用戶可以通過saveenv指令將DDR中的環(huán)境變量重新寫入Flash中去更新Flash中環(huán)境變量肠骆。下次開機(jī)時又會從Flash中再讀一次
環(huán)境變量在uboot中是用字符串表示的,注意不要錯別字塞耕,出現(xiàn)保存錯誤環(huán)境變量后set xxx消除并保存
自動運(yùn)行命令設(shè)置:bootcmd
uboot在啟動后會開機(jī)自動倒數(shù)bootdelay秒哗戈,如果沒有打斷則會自動啟動內(nèi)核
uboot中打印環(huán)境變量可以看到
bootcmd=movi read kernel 30008000
上述語句意思為將iNand的kernel分區(qū)讀取到DDR內(nèi)存的0x30008000地址處,然后使用bootm啟動命令從內(nèi)存0x30008000處去啟東內(nèi)核
uboot給kernel傳參:bootargs
Linux內(nèi)核啟動時可以接收uboot給他傳遞的啟動參數(shù)荷科,這些參數(shù)使uboot和內(nèi)核約定好的形式唯咬、內(nèi)容,為了內(nèi)核在不重新編譯的情況下可以用不同的方式啟動
在uboot的環(huán)境變量中設(shè)置bootargs畏浆,然后bootm命令啟動內(nèi)核時會自動將bootargs傳給內(nèi)核
bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3
意義解釋:控制臺使用串口2胆胰,波特率為115200
root=… 根文件系統(tǒng)在SD卡端口0設(shè)備(iNand)第2分區(qū),根文件系統(tǒng)是可讀可寫的
init=… Linux的進(jìn)程1(init進(jìn)程)的路徑
rootfstype=… 根文件系統(tǒng)的類型是ext3
內(nèi)核傳參非常重要刻获。在內(nèi)核移植的時候蜀涨,新手經(jīng)常忘記給內(nèi)核傳參,或者給內(nèi)核傳遞的參數(shù)不對蝎毡,造成內(nèi)核無法啟動
新建厚柳、更改、刪除一個環(huán)境變量的方法
新建和更改
set var value
刪除
set var
修改完環(huán)境變量后一定要保存
6. uboot對Flash和DDR的管理
uboot階段的Flash分區(qū)
所謂分區(qū)沐兵,就是對Flash進(jìn)行分塊管理
PC機(jī)等產(chǎn)品别垮,都是在操作系統(tǒng)下使用硬盤的,整個硬盤由操作系統(tǒng)統(tǒng)一管理扎谎,使用者不用自己太在意分區(qū)問題
在uboot中沒有操作系統(tǒng)碳想,對Flash的管理必須事先使用分區(qū)界定,在部署系統(tǒng)時按照分區(qū)界定方法來部署毁靶,uboot和kernel的軟件中也是按照這個分區(qū)界定來工作就不會出錯
分區(qū)不是固定的胧奔,在一個移植中必須事先設(shè)計好定死。一般在設(shè)計系統(tǒng)移植時就會定好预吆,定的標(biāo)準(zhǔn)是:uboot必須從Flash起始地址開始存放龙填,uboot分區(qū)大小必須保證uboot肯定能放下,一般設(shè)計為512kb或者1MB;環(huán)境變量分區(qū)一般緊貼著uboot來存放岩遗,大小為32KB或多一點(diǎn)胶背;kernel可以緊貼環(huán)境變量存放,大小一般為3MB或5MB或其他喘先;rootfs緊貼著kernel钳吟;剩下的就是自動分區(qū),一般kernel啟動后將自由分區(qū)掛載到rootfs下使用
總結(jié)
各分區(qū)彼此相連
整個Flash充分利用窘拯,從開頭到結(jié)尾
uboot必須在Flash開頭红且,其他分區(qū)相對位置可變
各分區(qū)的大小由系統(tǒng)移植工程師來定
分區(qū)在系統(tǒng)移植前確定好,在uboot中和kernel中使用同一個分區(qū)表
uboot階段DDR的分區(qū)
因為Flash是掉電存在的涤姊,而DDR是掉電消失暇番,因此可以說DDR是每次系統(tǒng)運(yùn)行時才開始部署使用的
內(nèi)存的分區(qū)主要是在Linux內(nèi)核啟動之前,Linux內(nèi)核啟動后內(nèi)核的內(nèi)存管理模塊會接管整個內(nèi)存空間
內(nèi)存分區(qū)關(guān)鍵就在于內(nèi)存中哪一塊用來干什么必須分配好思喊,以避免各個不同功能使用了同一塊內(nèi)存造成覆蓋壁酬。