1. 程式人生 > >為什麼要有uboot?帶你全面分析嵌入式linux系統啟動過程中uboot的作用

為什麼要有uboot?帶你全面分析嵌入式linux系統啟動過程中uboot的作用

為什麼要有uboot?帶你全面分析嵌入式linux系統啟動過程中uboot的作用

2017-08-24 18:19作業系統

1.為什麼要有uboot

1.1、計算機系統的主要部件

(1)計算機系統就是以CPU為核心來執行的系統。典型的計算機系統有:PC機(桌上型電腦+筆記本)、嵌入式裝置(手機、平板電腦、遊戲機)、微控制器(家用電器像電飯鍋、空調)

(2)計算機系統的組成部件非常多,不同的計算機系統組成部件也不同。但是所有的計算機系統執行時需要的主要核心部件都是3個東西:

CPU + 外部儲存器(Flash/硬碟) + 內部儲存器DDR SDRAM/SDRAM/SRAM

1.2、PC機的啟動過程

(1)部署:典型的PC機的BIOS程式部署在PC機主機板上隨主機板出廠時已經預製了),作業系統部署在硬碟上,記憶體在掉電時無作用,CPU在掉電時不工作。

(2)啟動過程:PC上電後先執行BIOS程式(實際上PC的BIOS就是NorFlash),BIOS程式負責初始化DDR記憶體,負責初始化硬碟,然後從硬碟上將OS映象(是指作業系統)讀取到DDR中,然後跳轉到DDR中去執行OS直到啟動(OS啟動後BIOS就無用了)

1.3、典型嵌入式linux系統啟動過程

(1)典型嵌入式系統的部署:uboot程式部署在Flash能作為啟動裝置的Flash)上、OS(是指作業系統)部署在FLash(嵌入式系統中用Flash代替了硬碟)上、記憶體在掉電時無作用,CPU在掉電時不工作。

(2)啟動過程:嵌入式系統上電後先執行uboot、然後uboot負責初始化DDR,初始化Flash,然後將OS從Flash中讀取到DDR中,然後啟動OS(OS啟動後uboot就無用了)

總結:嵌入式系統和PC機的啟動過程幾乎沒有兩樣,只是BIOS成了uboot,硬碟成了Flash。

1.4、android系統啟動過程

(1)Android系統的啟動和Linux系統(前面講的典型的嵌入式系統啟動)幾乎一樣。幾乎一樣意思就是前面完全一樣,只是在核心啟動後加載根檔案系統後不同了。

(2)可以認為啟動分為2個階段:第一個階段是uboot到OS啟動;第二個階段是OS啟動後到rootfs載入到命令列執行;現在我們主要研究第一個階段,android的啟動和linux的差別在第二階段。

1.5、總結:uboot到底是幹嘛的

(1)uboot主要作用是用來啟動作業系統核心。

(2)uboot還要負責部署整個計算機系統。

(3)uboot中還有操作Flash等板子上硬碟的驅動。

(4)uboot還得提供一個命令列介面供人來操作。

2.為什麼是uboot

2.1、uboot從哪裡來的?

(1)uboot是SourceForge上的開源專案

(2)uboot專案的作者:一個德國人最早發起的專案

(3)uboot就是由一個人發起,然後由整個網路上所有感興趣的人共同維護髮展而來的一個bootloader。

2.2、uboot的發展歷程

(1)自己使用的小開源專案。

(2)被更多人認可使用

(3)被SoC廠商預設支援。

總結:uboot經過多年發展,已經成為事實上的業內bootloader標準。現在大部分的嵌入式裝置都會預設使用uboot來做為bootloader。

2.3、uboot的版本號問題

(1)早期的uboot的版本號類似於這樣:uboot1.3.4。後來版本號便成了類似於uboot-2010.06。

(2)uboot的核心部分幾乎沒怎麼變化,越新的版本支援的開發板越多而已,對於一個老版本的晶片來說,新舊版本的uboot並沒有差異。

2.4、uboot的可移植性的正確理解

(1)uboot就是universal bootloader(通用的啟動程式碼),通用的意思就是在各種地方都可以用。所以說uboot具有可移植性。

(2)uboot具有可移植性並不是說uboot在哪個開發板都可以隨便用,而是說uboot具有在原始碼級別的移植能力,可以針對多個開發板進行移植,移植後就可以在這個開發板上使用了。

3.uboot必須解決哪些問題

3.1、自身可開機直接啟動

(1)一般的SoC都支援多種啟動方式,譬如SD卡啟動、NorFlash啟動、NandFlash啟動等·····uboot要能夠開機啟動,必須根據具體的SoC的啟動設計來設計uboot。

(2)uboot必須進行和硬體相對應的程式碼級別的更改和移植,才能夠保證可以從相應的啟動介質啟動。uboot中第一階段的start.S檔案中具體處理了這一塊。

3.2、能夠引導作業系統核心啟動並給核心傳參

(1)uboot的終極目標就是啟動核心。

(2)linux核心在設計的時候,設計為可以被傳參。也就是說我們可以在uboot中事先給linux核心準備一些啟動引數放在記憶體中特定位置然後傳給核心,核心啟動後會到這個特定位置去取uboot傳給他的引數,然後在核心中解析這些引數,這些引數將被用來指導linux核心的啟動過程。

3.3、能提供系統部署功能

(1)uboot必須能夠被人藉助而完成整個系統(包括uboot、kernel、rootfs等的映象)在Flash上的燒錄下載工作。

(2)裸機教程中刷機(ARM裸機第三部分)就是利用uboot中的fastboot功能將各種映象燒錄到iNand中,然後從iNand啟動。

3.4能進行soc級和板級硬體管理

(1)uboot中實現了一部分硬體的控制能力(uboot中初始化了一部分硬體),因為uboot為了完成一些任務必須讓這些硬體工作。譬如uboot要實現刷機必須能驅動iNand,譬如uboot要在刷機時LCD上顯示進度條就必須能驅動LCD,譬如uboot能夠通過串列埠提供操作介面就必須驅動串列埠。譬如uboot要實現網路功能就必須驅動網絡卡晶片。

(2)SoC級(譬如串列埠)就是SoC內部外設,板級就是SoC外面開發板上面的硬體(譬如網絡卡、iNand)

3.5、uboot的“生命週期”

(1)uboot的生命週期就是指:uboot什麼時候開始執行,什麼時候結束執行。

(2)uboot本質上是一個裸機程式(不是作業系統),一旦uboot開始SoC就會單純執行uboot(意思就是uboot執行的時候別的程式是不可能同時執行的),一旦uboot結束執行則無法再回到uboot(所以uboot啟動了核心後uboot自己本身就死了,要想再次看到uboot介面只能重啟系統。重啟並不是復活了剛才的uboot,重啟只是uboot的另一生)

(3)uboot的入口和出口。uboot的入口就是開機自動啟動,uboot的唯一出口就是啟動核心。uboot還可以執行很多別的任務(譬如燒錄系統),但是其他任務執行完後都可以回到uboot的命令列繼續執行uboot命令,而啟動核心命令一旦執行就回不來了。

總結:一切都是為了啟動核心

4.uboot的工作方式

4.1、從裸機程式映象uboot.bin說起

(1)uboot的本質就是一個裸機程式,和我們裸機全集中寫的那些裸機程式xx.bin並沒有本質區別。如果非說要有區別,那就是:我們寫的大部分小於16KB,而uboot大於16KB(一般uboot在180k-400k之間)

(2)uboot本身是一個開源專案,由若干個.c檔案和.h檔案組成,配置編譯之後會生成一個uboot.bin,這就是uboot這個裸機程式的映象檔案。然後這個映象檔案被合理的燒錄到啟動介質中拿給SoC去啟動。也就是說uboot在沒有執行時表現為uboot.bin,一般躺在啟動介質中。

(3)uboot執行時會被載入到記憶體中然後一條指令一條指令的拿給CPU去執行。

4.2、uboot的命令式shell介面

(1)普通的裸機程式執行起來就直接執行了,執行時效果和程式碼有關。

(2)有些程式需要和人進行互動,於是乎程式中就實現了一個shell(shell就是提供人機互動的一個介面,回想ARM裸機全集第十六部分),uboot就實現了一個shell。

注意:shell並不是作業系統,和作業系統一點關係都沒有。linux中開啟一個終端後就得到了一個shell,可以輸入命令回車執行。uboot中的shell工作方式和linux中的終端shell非常像(其實幾乎是一樣的,只是命令集不一樣。譬如linux中可以ls,uboot中ls就不識別)

4.3、掌握uboot使用的2個關鍵點:命令和環境變數

(1)uboot啟動後大部分時間和工作都是在shell下完成的(譬如uboot要部署系統要在shell下輸命令、要設定環境變數也得在命令列地下,要啟動核心也要在命令列底下敲命令)

(2)命令就是uboot的shell中可以識別的各種命令。uboot中有幾十個命令,其中有一些常用另一些不常用(我們還可以自己給uboot新增命令),後面會用幾節課時間來依次學習uboot中常用命令。

(3)uboot的環境變數和作業系統的環境變數工作原理和方式幾乎完全相同。uboot在設計時藉助了作業系統的設計理念(命令列工作方式借鑑了linux終端命令列,環境變數借鑑了作業系統的環境變數,uboot的驅動管理幾乎完全照抄了linux的驅動框架)。

(4)環境變數可以被認為是系統的全域性變數,環境變數名都是系統內建的(認識就認識,不認識就不認識,這部分是系統自帶的預設的環境變數,譬如PATH;但是也有一部分環境變數是自己新增的,自己新增的系統就不認識但是我們自己認識)。系統或者我們自己的程式在執行時可以通過讀取環境變數來指導程式的執行。這樣設計的好處就是靈活,譬如我們要讓一個程式更改執行方法,不用去重新修改程式程式碼再重新編譯執行,而只要修改相應的環境變數就可以了。

(5)環境變數就是執行時的配置屬性。

5.uboot的常用命令1

5.1、類似linux終端的行緩衝命令列

(1)行緩衝的意思就是:當我們向終端命令列輸入命令的時候,這些命令沒有立即被系統識別,而是被緩衝到一個快取區(也就是系統認為我們還沒有輸入完),當我們按下回車鍵(換行)後系統就認為我們輸入完了,然後將緩衝區中所有剛才輸入的作為命令拿去分析處理。

(2)linux終端設計有3種緩衝機制:無緩衝、行緩衝、全緩衝

(3)有些命令有簡化的別名,譬如printenv命令可以簡化為print,譬如setenv可以簡化為set

(4)有些命令會帶引數(注意格式是固定的),uboot的每個命令都有事先規定好的各種格式。有些命令就是不帶引數的,譬如printenv/print命令;有些命令帶可選的引數(可以帶也可以不帶,當然帶不帶引數的執行結果是不同的);有些命令帶必須的引數(譬如setenv/set命令)

(5)採用“help+命令名”來查詢命令的詳細資訊,只輸入help時,則打印出命令列表。

5.2、命令中的特殊符號(譬如單引號)

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

(2)別的符號也許也有,而且有特定的意義。當碰到uboot的命令列有特殊符號時要注意不是弄錯了,而是可能有特別的含義。

5.3、有些命令是一個命令族(譬如movi)

(1)命令族意思就是好多個命令開頭都是用同一個命令關鍵字的,但是後面的引數不一樣,這些命令的功能和作用也不同。這就叫一個命令族。

(2)同一個命令族中所有的命令都有極大的關聯,譬如movi開頭的命令族都和moviNand(EMMC、iNand)操作有關。

5.4、第一個命令:printenv/print

(1)print命令不用帶引數,作用是打印出系統中所有的環境變數。

(2)環境變數就好像程式的全域性變數一樣。程式中任何地方都可以根據需要去呼叫或者更改環境變數(一般都是呼叫),環境變數和全域性變數不同之處在於:全域性變數的生命週期是在程式的一次運行當中,開始執行時誕生程式結束時死亡,下次執行程式時從頭開始;但是環境變數被儲存在Flash的另一塊專門區域(Flash上有一個環境變數分割槽),一旦我們在程式中儲存了該環境變數,那麼下次開機時該環境變數的值將維持上一次更改儲存後的值。

6.uboot的常用命令2

1、設定(新增/更改)環境變數:setenv/set

用法:set name value

2、儲存環境變數的更改:saveenv/save

saveenv/save命令不帶引數,直接執行,作用是將記憶體中的環境變數的值同步儲存到Flash中環境變數的分割槽。注意:環境變數的儲存是整體的覆蓋儲存,也就是說記憶體中所有的環境變數都會整體的將Flash中環境變數分割槽中原來的內容整體覆蓋。

總結:徹底更改一個環境變數的值,需要2步:

第一步:set命令來更改記憶體中的環境變數

第二步:用save命令將其同步到Flash中環境變數的分割槽。

有時候我們只是想測試下這個環境變數,不希望影響到下一次開機,那就只set不save,這樣set後當前本次執行的uboot已經起效果了,只不過沒save下一次開機還是會恢復到原來的狀況。

3、網路測試指令:ping

(1)命令用法: ping ip地址

注意:ping是測試開發板和主機之間的網路連結,注意以下步驟:

1)首先要插上網線。

2)先試圖ping通主機windows。注意Windows中有線網絡卡的地址設定(設定本地連線)。設定主機windows的本地連線IPv4地址為192.168.1.10

3)第三步確認開發板中uboot裡幾個網路相關的環境變數的值對不對。最重要的是ipaddr(這個環境變量表示當前開發板的IP地址),這個地址必須和主機windows的IP地址在同一個網段。

網段的概念:一個IP地址分為2部分,一部分是網段地址,另一部分是網段內的主機地址(由子網掩碼來區分哪一部分是網段地址,哪一部分是IP地址)。在子網掩碼是255.255.255.0的情況下,192.168.1.10這個IP地址的前三部分(192.168.1.)屬於網段地址,第4部分(10)屬於主機地址。

7.開發板和主機的ping通

上節課最後的結果是:uboot中的ipaddr和主機windows本地連線地址已經設定到一個網段,但是實際還ping不通。

還發現了這樣的現象:1、我把2個的網段都從192.168.1.x改到192.168.0.x時會ping通一次,第二次開始就ping不通了;2、有同學說ping不通可能是因為uboot中gatewayip沒設定,我就實際測試設定網管為同網段.1,再次測試結論是第一次ping通了,第二次開始又不通了。

7.1、開發板執行linux下和主機Windows的ping通

(1)先將開發板刷機成linux+QT映象(刷機見裸機教程第三部分),然後啟動進入linux命令列終端下。

(2)在linux下使用ifconfig命令將開發板中linux系統的IP地址設定為和主機windows同一網段(為了上課方便,以後就固定:主機windows地址192.168.1.10,開發板uboot或linux的地址為192.168.1.20,虛擬機器ubuntu地址為192.168.1.141)

(3)此時開發板端ping windows通的。

(4)windows中ping開發板也是通的。

說明:首先開發板和主機的網路部分硬體都是好的,網路連線也是好的,主機windows中的網路軟體設定是好的。

7.2、開發板執行linux下和虛擬機器ubuntu的ping通

(1)在linux基礎課中講過:虛擬機器的網絡卡設定可以選擇好幾種方式,常用的就是NAT和橋接(bridged)。

(2)虛擬機器要和開發板進行網路通訊,只能通過橋接方式連線。

(3)虛擬機器要想被開發板ping通,設定步驟如下:

第一步:虛擬機器設定成橋接方式。

第二步:虛擬機器的選單中有個“虛擬網路編輯器”,這裡面要設定為橋接到有線網絡卡。(預設是自動的,自動的一般會影響ping通。因為電腦現在一般都有2個網絡卡:一個有線的一個無線的。如果選了自動,那麼虛擬機器會自動橋接到無線網絡卡上,但是我們卻是通過有線網絡卡來連線開發板的,自然ping不通)

第三步:在虛擬機器ubuntu中設定IP地址為192.168.1.141(可以通過/etc/network/interfaces檔案來設定靜態的然後重啟;也可以直接命令列ifconfig去設定)

(4)此時開發板ping虛擬機器ubuntu應該就通了。

(5)此時虛擬機器ubuntu中ping開發板也是通的。

7.3、開發板執行uboot下和主機Windows的ping通

(1)剛才開發板執行linux時和主機windows、虛擬機器ubuntu都ping通了,說明硬體和連線和主機設定沒錯。

(2)此時開發板重啟進入uboot,設定好ipaddr、gatewayip,然後去ping windows發現還是不通。 懷疑uboot本身網路驅動有問題。

(3)然後同樣情況下嘗試去ping通虛擬機器ubuntu,理論分析應該也不通,但是實際發現是通的。

7.4、開發板執行uboot下和虛擬機器ubuntu的ping通

uboot和虛擬機器ubuntu互相ping通(前提是虛擬機器ubuntu設定為橋接,且橋接到有線網絡卡,且ip地址設定正確的情況下)

結論:開發板中執行的uboot有點小bug,ping windows就不通,ping虛擬機器ubuntu就通。

8.uboot常用命令3

8.1、tftp下載指令:tftp

(1)uboot本身主要目標是啟動核心,為了完成啟動核心必須要能夠部署核心,uboot為了部署核心就需要將核心映象從主機中下載過來然後燒錄到本地flash中。uboot如何從主機(windows或者虛擬機器ubuntu)下載映象到開發板上?有很多種方式,主流方式是:fastboot和tftp。

fastboot的方式是通過USB線進行資料傳輸。

tftp的方式是通過有線網路的。典型的方式就是通過網路,fastboot是近些年才新發展的。

(2)tftp方式下載時實際上uboot扮演的是tftp客戶端程式角色,主機windows或虛擬機器ubuntu中必須有一個tftp伺服器,然後將要下載的映象檔案放在伺服器的下載目錄中,然後開發板中使用uboot的tftp命令去下載即可。

(3)有些人習慣在windows中搭建tftp伺服器,一般是用一些軟體來搭建(譬如tftpd32,使用起來比較簡單);有些人習慣在linux下搭建tftp伺服器,可以參考網盤中的虛擬機器下載目錄下的一個教程《嵌入式開發環境搭建-基於14.04.pdf》,這裡面有ubuntu中搭建tftp伺服器的教程,也可以自己上網搜尋教程嘗試。(如果你直接就用我的虛擬機器,那就已經搭建好了,不用再搭建了;如果是自己新裝的那就參考文件搭建;如果你的版本和我的不一樣那搭建過程可能不一樣)

(4)我的虛擬機器搭建的時候設定的tftp下載目錄是/tftpboot,將要被下載的映象複製到這個目錄下。

(5)檢查開發板uboot的環境變數,注意serverip必須設定為虛擬機器ubuntu的ip地址。(serverip這個環境變數的意義就是主機tftp伺服器的ip地址)

(6)然後在開發板的uboot下先ping通虛擬機器ubuntu,然後再嘗試下載:tftp 0x30000000 zImage-qt(意思是將伺服器上名為zImage-qt的檔案下載到開發板記憶體的0x30000000地址處。)

(7)映象下載到開發板的DDR中後,uboot就可以用movi指令進行映象的燒寫了。

注意:

如果你是用的windows下的tftp伺服器,那uboot的serverip就要設定為和windwos下tftp伺服器的ip地址一樣(windows下的tftp伺服器軟體設定的時候就有個步驟是讓你設定伺服器的ip地址,這個ip地址和主機windows必須在一個網段)。

9.uboot的常用命令4

9.1、SD卡/iNand操作指令movi

(1)開發板如果用SD卡/EMMC/iNand等作為Flash,則在uboot中操作flash的指令為movi(或mmc)

(2)movi指令是一個命令集,有很多子命令,具體用法可以help movi檢視。

(3)movi的指令都是movi read和movi write一組的,movi read用來讀取iNand到DDR上,movi write用來將DDR中的內容寫入iNand中。理解這些指令時一定要注意涉及到的2個硬體:iNand和DDR記憶體。

(4)movi read {u-boot | kernel} {addr} 這個命令使用了一種通用型的描述方法來描述:movi 和read外面沒有任何標記說明每一次使用這個指令都是必選的;一對大括號{}括起來的部分必選1個;大括號中的豎線表是多選一;中括號[]表示可選引數

(5)指令有多種用法,譬如 movi read u-boot 0x30000000,意思就是把iNand中的u-boot分割槽讀出到DDR的0x30000000起始的位置處。(uboot程式碼中將iNand分成了很多個分割槽,每個分割槽有地址範圍和分割槽名,uboot程式操作中可以使用直接地址來操作iNand分割槽,也可以使用分割槽名來操作分割槽。);注意這裡的0x30000000也可以直接寫作30000000,意思是一樣的(uboot的命令列中所有數字都被預設當作十六進位制處理,不管你加不加0x都一樣)。

9.2、NandFlash操作指令nand

理解方法和操作方法完全類似於movi指令

9.3、記憶體操作指令:mm、mw、md

(1)DDR中是沒有分割槽的(只聽說過對硬碟、Flash進行分割槽,沒聽說過對記憶體進行分割槽····),但是記憶體使用時要注意,千萬不能越界踩到別人了。因為uboot是一個裸機程式,不像作業系統會由系統整體管理所有記憶體,系統負責分配和管理,系統會保證記憶體不會隨便越界。然後裸機程式中uboot並不管理所有記憶體,記憶體是散的隨便用的,所以如果程式設計師(使用uboot的人)自己不注意就可能出現自己把自己的資料給覆蓋了。(所以你思考下我們為什麼把uboot放在23E00000地址處)

(2)md就是memory display,用來顯示記憶體中的內容。

(3)mw就是memory write,將內容寫到記憶體中

(4)mm就是memory modify,修改記憶體中的某一塊,說白了還是寫記憶體(如果需要批量的逐個單元的修改記憶體,用mm最合適)

9.4、啟動核心指令:bootm、go

(1)uboot的終極目標就是啟動核心,啟動核心在uboot中表現為一個指令,uboot命令列中呼叫這個指令就會啟動核心(不管成功與否,所以這個指令是一條死路)。

(2)差別:bootm啟動核心同時給核心傳參,而Go命令啟動核心不傳參。bootm其實才是正宗的啟動核心的命令,一般情況下都用這個;go命令本來不是專為啟動核心設計的,go命令內部其實就是一個函式指標指向一個記憶體地址然後直接呼叫那個函式,go命令的實質就是PC直接跳轉到一個記憶體地址去執行而已。go命令可以用來在uboot中執行任何的裸機程式(有一種除錯裸機程式的方法就是事先啟動uboot,然後在uboot中去下載裸機程式,用go命令去執行裸機程式)

10.uboot的常用環境變數1

10.1、環境變數如何參與程式執行

(1)環境變數有2份,一份在Flash中,另一份在DDR中。uboot開機時一次性從Flash中讀取全部環境變數到DDR中作為環境變數的初始化值,然後使用過程中都是用DDR中這一份,使用者可以用saveenv指令將DDR中的環境變數重新寫入Flash中去更新Flash中環境變數。下次開機時又會從Flash中再讀一次。

(2)環境變數在uboot中是用字串表示的,也就是說uboot是按照字元匹配的方式來區分各個環境變數的。因此用的時候一定要注意不要打錯字了。

1、自動執行倒數時間:bootdelay

2、網路設定:ipaddr serverip

(1)ipaddr是開發板的本地IP地址

(2)serverip是開發板通過tftp指令去tftp伺服器下載東西時,tftp伺服器的IP地址。

(3)gatewayip是開發板的本地閘道器地址

(4)netmask是子網掩碼

(5)ethaddr是開發板的本地網絡卡的MAC地址。

11.uboot的常用環境變數2

11.1、自動執行命令設定:bootcmd

(1)uboot啟動後會開機自動倒數bootdelay秒,如果沒有人按下回車打斷啟動,則uboot會自動執行啟動命令來啟動核心。

(2)uboot開機自動啟動時實際就是在內部執行了bootcmd這個環境變數的值所對應的命令集:bootcmd=movi read kernel 30008000; bootm 30008000

意思是:將iNand的kernel分割槽讀取到DDR記憶體的0x30008000地址處,然後使用bootm啟動命令從記憶體0x30008000處去啟動核心。

(3)set bootcmd printenv,然後saveenv;然後重啟則會看到啟動倒數後自動執行printenv命令打印出環境變數。這個小實驗說明開機自動執行了bootcmd。

(4)設定bootcmd環境變數:set bootcmd 'movi read kernel 30008000; bootm 30008000'

11.2、uboot給kernel傳參:bootargs

(1)linux核心啟動時可以接收uboot給他傳遞的啟動引數,這些啟動引數是uboot和核心約定好的形式、內容,linux核心在這些啟動引數的指導下完成啟動過程。這樣的設計是為了靈活,為了核心在不重新編譯的情況下可以用不同的方式啟動。

(2)我們要做的事情就是:在uboot的環境變數中設定bootargs,然後bootm命令啟動核心時會自動將bootargs傳給核心。

(3)環境變數bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3

意義解釋:

console=ttySAC2,115200 控制檯使用串列埠2,波特率115200.

root=/dev/mmcblk0p2 rw 根檔案系統在SD卡埠0裝置(iNand)第2分割槽,根檔案系統是可讀可寫的

init=/linuxrc linux的程序1(init程序)的路徑

rootfstype=ext3 根檔案系統的型別是ext3

(4)核心傳參非常重要。在核心移植的時候,新手經常因為忘記給核心傳參,或者給核心傳遞的引數不對,造成核心啟動不起來。

11.3、新建、更改、刪除一個環境變數的方法

(1)新建一個環境變數,使用set var value

(2)更改一個環境變數,使用set var value

(3)刪除一個環境變數,使用set var

注意:修改完成環境變數後一定要儲存,否則下次開機更改就又沒了。

12.uboot中對Flash和DDR的管理

12.1、uboot階段Flash的分割槽

(1)所謂分割槽,就是說對Flash進行分塊管理。

(2)PC機等產品中,因為大家都是在作業系統下使用硬碟的,整個硬碟由作業系統統一管理,作業系統會使用檔案系統幫我們管理硬碟空間。(管理保證了檔案之間不會互相堆疊),於是乎使用者不用自己太過在意分割槽問題。

(3)在uboot中是沒有作業系統的,因此我們對Flash(相當於硬碟)的管理必須事先使用分割槽界定(實際上在uboot中和kernel中都有個分割槽表,分割槽表就是我們在做系統移植時對Flash的整體管理分配方法)。有了這個界定後,我們在部署系統時按照分割槽界定方法來部署,uboot和kernel的軟體中也是按照這個分割槽界定來工作,就不會錯。

(4)分割槽方法不是一定的,不是固定的,是可以變動的。但是在一個移植中必須事先設計好定死,一般在設計系統移植時就會定好,定的標準是:

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中使用同一個分割槽表。將來在系統部署時和系統程式碼中的分割槽方法也必須一樣。

12.2、uboot階段DDR的分割槽

(1)DDR的分割槽和Flash的分割槽不同,主要是因為Flash是掉電存在的,而DDR是掉電消失,因此可以說DDR是每次系統執行時才開始部署使用的。

(2)記憶體的分割槽主要是在linux核心啟動起來之前,linux核心啟動後核心的記憶體管理模組會接管整個記憶體空間,那時候就不用我們來管了。

(3)注意記憶體分割槽關鍵就在於記憶體中哪一塊用來幹什麼必須分配好,以避免各個不同功能使用了同一塊記憶體造成的互相踩踏。譬如說我們tftp 0x23E00000 zImage去下載zImage到記憶體的0x23E00000處就會出錯,因為這個記憶體處實際是uboot的映象所在。這樣下載會導致下載的zImage把記憶體中的uboot給沖掉。