Linux-基礎入門-學習筆記(3):uboot常用命令與環境變量

Linux-基礎入門-學習筆記(3):uboot常用命令與環境變量

一、uboot基礎知識

1. 類比PC機與嵌入式系統的啓動過程

(1)PC機
典型的PC機的部署: BIOS程序部署在PC機主板上(隨主板出廠時已經預製了),操作系統部署在硬盤上,內存在掉電時無作用,CPU在掉電時不工作。
PC機啓動過程: PC上電後先執行BIOS程序(實際上PC的BIOS就是NorFlash),BIOS程序負責初始化DDR內存,負責初始化硬盤,然後從硬盤上將OS鏡像讀取到DDR中,然後跳轉到DDR中去執行OS直到啓動(OS啓動後BIOS就無用了)。

(2)嵌入式系統
典型嵌入式系統的部署: uboot程序部署在Flash(能作爲啓動設備的Flash)上、OS部署在FLash(嵌入式系統中用Flash代替了硬盤)上、內存在掉電時無作用,CPU在掉電時不工作。
嵌入式系統啓動過程: 嵌入式系統上電後先執行uboot、然後uboot負責初始化DDR,初始化Flash,然後將OS從Flash中讀取到DDR中,然後啓動OS(OS啓動後uboot就無用了)

總結:我們可以看出,嵌入式系統與PC機的部署和啓動方式基本相同。嵌入式系統中的uboot相當於PC機的BIOS。

(3)android
android系統啓動過程: android系統的啓動和linux系統幾乎一樣(只是在內核啓動後加載根文件系統後不同了)。
可以認爲啓動分爲2個階段:第一個階段是uboot到OS啓動;第二個階段是OS啓動後到rootfs加載到命令行執行。

2. uboot的作用

uboot就是universal bootloader(通用的啓動代碼),通用的意思就是在各種地方都可以用。所以說uboot具有可移植性
uboot具有可移植性並不是說uboot在哪個開發板都可以隨便用,而是說uboot具有在源代碼級別的移植能力,可以針對多個開發板進行移植,移植後就可以在這個開發板上使用了。

uboot的主要作用是:
(1)uboot主要作用是用來啓動操作系統內核。
(2)uboot還要負責部署整個計算機系統。
(3)uboot中還有操作Flash等板子上硬盤的驅動。
(4)uboot還得提供一個命令行界面供人來操作。

3. uboot需要解決的問題

(1)自身可開機直接啓動
一般的SoC都支持多種啓動方式,譬如SD卡啓動、NorFlash啓動、NandFlash啓動等·····uboot要能夠開機啓動,必須根據具體的SoC的啓動設計來設計uboot。
uboot必須進行和硬件相對應的代碼級別的更改和移植,才能夠保證可以從相應的啓動介質啓動。uboot中第一階段的start.S文件中具體處理了這一塊。

(2)能夠引導操作系統內核啓動並給內核傳參
uboot的終極目標就是啓動內核。 linux內核在設計的時候,設計爲可以被傳參。也就是說我們可以在uboot中事先給linux內核準備一些啓動參數放在內存中特定位置然後傳給內核,內核啓動後會到這個特定位置去取uboot傳給他的參數,然後在內核中解析這些參數這些參數將被用來指導linux內核的啓動過程

(3)能提供系統部署功能
uboot必須能夠被人藉助而完成整個系統(包括uboot、kernel、rootfs等的鏡像)在Flash上的燒錄下載工作
例如利用uboot中的fastboot功能將各種鏡像燒錄到iNand中,然後從iNand啓動。

(4)能進行soc級和板級硬件管理
uboot中實現了一部分硬件的控制能力(uboot中初始化了一部分硬件),因爲uboot爲了完成一些任務必須讓這些硬件工作。譬如uboot要實現刷機必須能驅動iNand,譬如uboot要在刷機時LCD上顯示進度條就必須能驅動LCD,譬如uboot能夠通過串口提供操作界面就必須驅動串口。譬如uboot要實現網絡功能就必須驅動網卡芯片。

(5)uboot的“生命週期”
uboot本質上是一個裸機程序(不是操作系統),一旦uboot開始SoC就會單純運行uboot(意思就是uboot運行的時候別的程序是不可能同時運行的,一旦uboot結束運行則無法再回到uboot,所以uboot啓動了內核後uboot自己本身就死了)。
uboot的入口和出口:uboot的入口就是開機自動啓動,uboot的唯一出口就是啓動內核。uboot還可以執行很多別的任務(譬如燒錄系統),但是其他任務執行完後都可以回到uboot的命令行繼續執行uboot命令,而啓動內核命令一旦執行就回不來了

二、uboot常用命令

uboot啓動後大部分時間和工作都是在shell下完成的,譬如uboot要部署(就是燒錄)系統要在shell下輸命令、要設置環境變量也得在命令行地下,要啓動內核也要在命令行底下敲命令。命令就是uboot的shell中可以識別的各種命令。

uboot的有些命令帶的參數非常長,爲了告訴uboot這個非常長而且中間有好多個空格的東西是給他的一整個參數,所以用單引號將這個很長且中間有空格隔開的參數引起來。

序號 命令行 備註
1 printenv/print 打印出系統所有的環境變量
2 setenv/set name value 設置更改環境變量 ,name爲環境變量名,value爲對該環境變量設置的內容
3 saveenv/save 保存環境變量的更改,下次重啓仍存在
4 ping pingAddress 測試對應地址下的網絡鏈接是否通
5 tftp [loadaddress] [bootfilename] 將bootfile文件下載到指定的loadaddress地址中
nfs [loadaddress] [bootfilename] 原理同tftp
6 movi init 查看內存信息
movi read {u-boot / kernel} {addr} 從內存中讀取數據
movi write {fwbl1 / u-boot / kernel} {addr} 寫數據到內存中
movi read rootfs {addr} [bytes(hex)] 按某個字節大小讀取根文件系統中的數據
movi write rootfs {addr} [bytes(hex)] 按某個字節大小讀取根文件系統中的數據
7 mm [.b, .w, .l] address 逐個單元的修改內存中的某一塊數據
md [.b, .w, .l] address 顯示內存中的內容
mw [.b, .w, .l] address 將內容寫到內存中
8 bootm/go 啓動內核(bootm啓動內核同時給內核傳參,而go命令啓動內核不傳參)

命令演示:
1、printenv/print
在這裏插入圖片描述
在這裏插入圖片描述
print命令不用帶參數,作用是打印出系統中所有的環境變量
環境變量就好像程序的全局變量一樣。程序中任何地方都可以根據需要去調用或者更改環境變量(一般都是調用),環境變量和全局變量不同之處在於:全局變量的生命週期是在程序的一次運行當中,開始運行時誕生程序結束時死亡,下次運行程序時從頭開始;但是環境變量被存儲在Flash的另一塊專門區域(Flash上有一個環境變量分區),一旦我們在程序中保存了該環境變量,那麼下次開機時該環境變量的值將維持上一次更改保存後的值
2、setenv/set
在這裏插入圖片描述
(1)新建一個環境變量,使用set var value
(2)更改一個環境變量,使用set var value
(3)刪除一個環境變量,使用set var

3、saveenv/save
在這裏插入圖片描述
在這裏插入圖片描述
這裏說明一下,當啓動後,uboot會將Flash中的環境變量拷貝一份到內存中去,set命令只能更改內存中的環境變量,下次重啓後仍爲Flash中的環境變量;save命令則能同步內存中的環境變量到Flash中環境變量的分區,下次重啓仍保持設置值。

4、ping

首先聲明:主機windows地址192.168.1.10,開發板uboot或linux的地址爲192.168.1.20,虛擬機ubuntu地址爲192.168.1.141

(1)ping開發板和主機之間的網絡鏈接
1)首先將開發板和主機之間的網線插好。
2)設置主機的IP地址和子網掩碼。控制面板->網絡和Internet->網絡和共享中心->更改適配器設置->設置主機IP地址爲192.168.1.10
在這裏插入圖片描述
3)設置開發板IP地址爲192.168.1.20
在這裏插入圖片描述
這裏要想ping通,一定要在一個網段下,並且子網掩碼相同。
網段的概念:一個IP地址分爲2部分,一部分是網段地址,另一部分是網段內的主機地址(由子網掩碼來區分哪一部分是網段地址,哪一部分是IP地址)。在子網掩碼是255.255.255.0的情況下,192.168.1.10這個IP地址的前三部分(192.168.1.)屬於網段地址,第4部分(10)屬於主機地址。

4)通過開發板ping主機。
在這裏插入圖片描述
(2)ping開發板和虛擬機ubuntu之間的網絡鏈接
1)設置虛擬機上網爲橋接方式。虛擬機->設置->網絡適配器
在這裏插入圖片描述
2)虛擬機的菜單中有個“虛擬網絡編輯器”,這裏面要設置爲橋接到有線網卡。(默認是自動的,如果選了自動,那麼虛擬機會自動橋接到無線網卡上,但是我們卻是通過有線網卡來連接開發板的,自然ping不通)。
在這裏插入圖片描述
3)設置虛擬機的IP地址爲192.168.1.141
也可以通過 /etc/network/interfaces文件來設置靜態的然後重啓。
在這裏插入圖片描述
在這裏插入圖片描述
4)通過開發板ping虛擬機。
在這裏插入圖片描述
5)虛擬機Ping開發板。
在這裏插入圖片描述
(3)ping uboot和主機/ubuntu之間的網絡鏈接
設置uboot中的環境變量,再ping主機/ubuntu。
在這裏插入圖片描述
5、tftp
uboot本身主要目標是啓動內核,爲了完成啓動內核必須要能夠部署內核,uboot爲了部署內核就需要將內核鏡像從主機中下載過來然後燒錄到本地flash中。uboot如何從主機(windows或者虛擬機ubuntu)下載鏡像到開發板上?有很多種方式,主流方式是:fastboot和tftp
fastboot的方式是通過USB線進行數據傳輸。而tftp的方式是通過有線網絡的。

tftp方式下載時實際上uboot扮演的是tftp客戶端程序角色,主機windows或虛擬機ubuntu中必須有一個tftp服務器,然後將要下載的鏡像文件放在服務器的下載目錄中,然後開發板中使用uboot的tftp命令去下載即可。
搭建ubuntu的tftp服務器方法

1)我的虛擬機搭建的時候設置的tftp下載目錄是 /tftpboot,將要被下載的鏡像複製到這個目錄下。
在這裏插入圖片描述
2)檢查開發板uboot的環境變量,注意serverip必須設置爲虛擬機ubuntu的ip地址。(serverip這個環境變量的意義就是主機tftp服務器的ip地址)
3)然後在開發板的uboot下先ping通虛擬機ubuntu,然後再嘗試下載:tftp 0x30000000 zImage-qt(意思是將服務器上名爲zImage-qt的文件下載到開發板內存的0x30000000地址處。)
在這裏插入圖片描述
6、movi
開發板如果用SD卡/EMMC/iNand等作爲Flash,則在uboot中操作flash的指令爲movi(或mmc)。
在這裏插入圖片描述
movi的指令都是movi read和movi write一組的,movi read用來讀取iNand到DDR上,movi write用來將DDR中的內容寫入iNand中。
在這裏插入圖片描述
7、內存操作指令:mm、mw、md
md就是memory display,用來顯示內存中的內容。(.b字節爲單位 .w2個字節 .l4個字節
在這裏插入圖片描述

mw就是memory write,將內容寫到內存中。在這裏插入圖片描述

mm就是memory modify,修改內存中的某一塊,說白了還是寫內存(如果需要批量的逐個單元的修改內存,用mm最合適)。在這裏插入圖片描述
8、bootm,go
待補充……

三、uboot的環境變量

uboot的環境變量和操作系統的環境變量工作原理和方式幾乎完全相同。環境變量可以被認爲是系統的全局變量,環境變量名都是系統內置的。系統或者我們自己的程序在運行時可以通過讀取環境變量來指導程序的運行。環境變量就是運行時的配置屬性

環境變量有2份,一份在Flash中,另一份在DDR中。 uboot開機時一次性從Flash中讀取全部環境變量到DDR中作爲環境變量的初始化值,然後使用過程中都是用DDR中這一份,用戶可以用save指令將DDR中的環境變量重新寫入Flash中去更新Flash中環境變量。下次開機時又會從Flash中再讀一次。
在這裏插入圖片描述

環境變量 表示的意義
mtdpart=80000 400000 3000000 mtd分區
baudrate=115200 串口波特率
ethaddr=00:40:5c:26:0a:5b 開發板的本地網卡的MAC地址
bootargs…… 在uboot的環境變量中設置bootargs,然後bootm命令啓動內核時會自動將bootargs傳給內核
bootcmd…… uboot開機自動啓動時實際就是在內部執行了bootcmd這個環境變量的值所對應的命令集
bootdelay=5 開機自動倒數bootdelay秒
netmask=netmask 255.255.255.0 子網掩碼
ipaddr=192.168.1.20 開發板的本地IP地址
gatewayip=192.168.1.1 開發板的本地網關地址
serverip=192.168.1.141 開發板通過tftp指令去tftp服務器下載東西時,tftp服務器的IP地址

四、uboot對flash和DDR的管理

1. uboot階段Flash的分區

所謂分區,就是說對Flash進行分塊管理。
PC機等產品中,因爲大家都是在操作系統下使用硬盤的,整個硬盤由操作系統統一管理,操作系統會使用文件系統幫我們管理硬盤空間。(管理保證了文件之間不會互相堆疊),於是乎使用者不用自己太過在意分區問題。
在uboot中是沒有操作系統的,因此我們對Flash(相當於硬盤)的管理必須事先使用分區界定(實際上在uboot中和kernel中都有個分區表,分區表就是我們在做系統移植時對Flash的整體管理分配方法)。有了這個界定後,我們在部署系統時按照分區界定方法來部署,uboot和kernel的軟件中也是按照這個分區界定來工作,就不會錯。
分區方法不是一定的,不是固定的,是可以變動的。但是在一個移植中必須事先設計好定死,一般在設計系統移植時就會定好,定的標準是:

  • uboot: uboot必須從Flash起始地址開始存放(也許是扇區0,也許是扇區1,也許是其他,取決於SoC的啓動設計),uboot分區的大小必須保證uboot肯定能放下,一般設計爲512KB或者1MB(因爲一般uboot肯定不足512KB,給再大其實也可以工作,但是浪費);
  • 環境變量: 環境變量分區一般緊貼着uboot來存放,大小爲32KB或者更多一點。
  • kernel: kernel可以緊貼環境變量存放,大小一般爲3MB或5MB或其他。
  • rootfs: 一般也是緊貼着,看用到了多大。
  • 剩下的就是自由分區,一般kernel啓動後將自由分區掛載到rootfs下使用。

總結:
(1)各分區彼此相連,前面一個分區的結尾就是後一個分區的開頭。
(2)整個flash充分利用,從開頭到結尾。
(3)uboot必須在Flash開頭,其他分區相對位置是可變的。
(4)各分區的大小由系統移植工程師自己來定,一般定爲合適大小(不能太小,太小了容易溢出;不能太大,太大了浪費空間)
(5)分區在系統移植前確定好,在uboot中和kernel中使用同一個分區表。將來在系統部署時和系統代碼中的分區方法也必須一樣。(燒錄時要按照分區表進行燒錄)

2. uboot階段DDR的分區

DDR的分區和Flash的分區不同,主要是因爲Flash是掉電存在的,而DDR是掉電消失,因此可以說DDR是每次系統運行時纔開始部署使用的。
內存的分區主要是在linux內核啓動起來之前,linux內核啓動後內核的內存管理模塊會接管整個內存空間,那時候就不用我們來管了。
注意內存分區關鍵就在於內存中哪一塊用來幹什麼必須分配好,以避免各個不同功能使用了同一塊內存造成的互相踩踏。譬如說我們tftp 0x23E00000 zImage去下載zImage到內存的0x23E00000處就會出錯,因爲這個內存處實際是uboot的鏡像所在。這樣下載會導致下載的zImage把內存中的uboot給沖掉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章