嵌入式開發丨瞭解系統中的Uboot功能

ningmengzier發表於2020-12-15

Uboot全稱 Universal Boot Loader ,一個遵循GPL協議的的開源專案,其作用是引導作業系統,支援引導Linux、VxWorks、Solaris等作業系統;其原始碼組織形式和Linux原始碼很相似,編譯也可參照Linux原始碼編譯,且包含許多Linux原始碼中的驅動原始碼,所以Uboot實際上可以算作一個微型的作業系統,可以做一些簡單工作。

01
Uboot完成的工作


Uboot需要完成的工作有:讀Flash、初始化sdram、啟動核心。 總結起來的話就是:

Uboot主要作用是用來啟動作業系統核心;

Uboot還要負責部署整個計算機系統;

Uboot中還要操作Flash等板子上硬碟的驅動;
Uboot還得提供一個命令列介面供人來操作。


注意: 在從Flash讀出核心寫到sdram之前,需要先關閉看門狗,再初始化sdram、初始化系統時鐘。


為了完成這個工作,且便於除錯,還要開發一下其他功能:例如設定Uboot的一些引數,再把設定好的引數寫入到Flash,還需要用到網路卡、usb及串列埠等以便除錯。



02
Uboot的工作模式


大多數的Uboot都包含兩種不同的操作模式:“下載模式”和“啟動模式”。


下載模式 是指Uboot將透過串列埠或網路等通訊手段從主機下載檔案,然後控制啟動流程。

啟動模式 是指Uboot從目標機上的某個固態儲存裝置上將作業系統自動載入到RAM中執行。


在典型的嵌入式Linux系統中


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

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


在Android系統中


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

  • 可以認為啟動分為2個階段:第一個階段是Uboot到OS啟動;第二個階段是OS啟動後到rootfs載入到命令列執行;現在我們說的是第一個階段,Android的啟動和Linux的差別在第二階段。




03
命令和環境變數


Uboot在使用中的兩個關鍵點:命令和環境變數


命令 就是Uboot的shell中可以識別的各種命令。

Uboot中有幾十個命令,其中有一些常用另一些不常用(我們還可以自己給Uboot新增命令)。


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


環境變數 就是執行時的配置屬性。
Uboot的環境變數和作業系統的環境變數工作原理和方式幾乎完全相同。Uboot在設計時藉助了作業系統的設計理念(命令列工作方式借鑑了Linux終端命令列,環境變數借鑑了作業系統的環境變數,Uboot的驅動管理幾乎完全照抄了Linux的驅動框架)。


環境變數可以被認為是系統的全域性變數,環境變數名都是系統內建的(譬如PATH;但是也有一部分環境變數是自己新增的)。


系統或者我們自己的程式在執行時可以透過讀取環境變數來指導程式的執行。這樣設計的好處就是靈活,譬如我們要讓一個程式更改執行方法,不用去重新修改程式程式碼再重新編譯執行,而只要修改相應的環境變數就可以了。


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


04
Uboot常用命令



Uboot的每個命令都有事先規定好的各種格式。

  • 有些命令是 帶引數(注意格式是固定的);

  • 有些命令是 不帶引數的(譬如printenv/print命令);

  • 有些命令帶 可選的引數(既可帶也可不帶,帶不帶引數的執行結果是不同的);

  • 有些命令帶 必須的引數(譬如setenv/set命令)

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

  • 有些命令是一個 命令族(譬如movi);

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


第一個命令: print

該命令不用帶引數,作用是列印出系統中所有的環境變數。

注意: 環境變數和全域性變數不同之處在於:

  • 全域性變數的生命週期是在程式的一次執行當中,開始執行時誕生程式結束時死亡,下次執行程式時從頭開始;

  • 環境變數被儲存在Flash的另一塊專門區域(Flash上有一個環境變數分割槽),一旦我們在程式中儲存了該環境變數,那麼下次開機時該環境變數的值將維持上一次更改儲存後的值。


第二個命令: set、save

  • setenv/set 設定(新增/更改)環境變數,

      用法:set name value

  • saveenv/save   儲存環境變數的更改,該命令不帶引數,直接執行

注意: 想要徹底更改一個環境變數的值,需要2步:
1、set命令來更改記憶體中的環境變數;
2、用save命令將其同步到Flash中環境變數的分割槽。


第三個命令: ping
 網路測試指令, 用法: ping IP地址
注意: ping是測試開發板和主機之間的網路連結。先要插上網線,試圖ping通主機windows,再確認開發板中uboot裡幾個網路相關的環境變數的值對不對。


第四個命令: Tftp

透過網路下載檔案

Uboot> setenv ethaddr

Uboot> setenv ipaddr

Uboot> setenv serverip (tftp伺服器的地址)

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


第五個命令: Flinfo

檢視Flash扇區資訊, 用法:uboot>flinfo


第六個命令: SD卡/iNand操作指令movi

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

movi的指令都是movi read和movi write一組的,movi read用來讀取iNand到DDR上,movi write用來將DDR中的內容寫入iNand中。


第七個命令: 啟動核心指令bootm、go

bootm啟動核心同時給核心傳參,而Go命令啟動核心不傳參。

U boot的終極目標就是啟動核心,啟動核心在Uboot中表現為一個指令,Uboot命令列中呼叫這個指令就會啟動核心(不管成功與否)。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69989353/viewspace-2742399/,如需轉載,請註明出處,否則將追究法律責任。

相關文章