首頁 > 軟體

u-boot 1.3.4原始碼分析詳細教學

2020-06-16 17:10:50

每款MCU上電之後,並不是立即執行到主程式的,而是最先初始化整個系統資源,俗稱“Boot loader”。所以,u-boot是一種普遍用於嵌入式系統中的Boot loader,Boot loader是在作業系統執行之前執行的一小段程式,通過它,可以初始化硬體裝置、建立記憶體空間的對映表,從而建立適當的軟硬體環境,為最終呼叫作業系統核心做好準備。Boot loader的主要執行任務就是將核心映象從硬碟上讀到RAM中,然後跳轉到核心的入口點去執行,即開始啟動作業系統。系統在上電或復位時通常都從地址0x00000000處開始執行,而在這個地址處安排的通常就是系統的Boot Loader程式;所以了解了u-boot的啟動流程,就可以清楚知道linux啟動時列印的資訊是什麼意思。

那麼在介紹u-boot之前,先來認識一款軟體Source insight;由於從u-boot官網下載的u-boot1.3.4安裝包,它支援各大硬體平台,而且程式資料極多,在學習時,需要挑重點,找出符合位元組硬體的程式;所以source insight是一款相當不錯的軟體,當然像Slick edit也是一款很好的編輯器。

1 . Source Insight 使用

1.1 Source Insight工程建立

新建工程選單

工程設定介面

工程設定完成

工程檔案儲存路徑設定介面(預設)

原始碼新增介面

設定為新增子目錄檔案

新增檔案完成介面

關閉原始碼新增介面

檔案同步選單

同步設定

同步進行中

同步完成後介面

1.2常用操作介紹:

過濾檔案(輸入要檢視的檔名)

檢視目標檔案

檢視檔案中函數,變數,宏定義:

對於整個工程中只一個一份程式碼的函數或變數或宏,導航視窗會直接列出其定義,如下所示

對於有多個同名目標,則會以列表形式出現,讓使用者選擇:

搜尋功能:

給工程新增非預設型別檔案:

刪除檔案:

反向刪除:

同樣方法刪除CPU目錄下無關檔案。

2.  u-boot目錄結構

board:存放資料夾的是具體開發板相關資料夾,有的目錄是公司名,裡面存放具體開發板的資料夾。有的直接開發板資料夾。其中存放的是板級相關檔案。

common:通用檔案,存放的是所有CPU共用的檔案,大部分是u-boot命令支援檔案。

像bootm, go,tftpboot ,help 等命令就是在這些檔案中實現。

CPU:存放晶片構架相關的檔案,一個資料夾代表一個型別的CPU核心。其中的資料夾存放整個核心通用的程式碼檔案以及具體的SOC資料夾。

Disk              :硬體相關的支援程式碼。不用修改。

Doc        :u-boot的使用說明書。不用修改。

Drivers  :u-boot裝置驅動程式碼。

Fs          :檔案系統程式碼,不用修改。

include:u-boot標頭檔案,包含有公用標頭檔案,裝置驅動相關標頭檔案,以及分體系構架相關的標頭檔案。

其中有一個資料夾是configs,比較重要,存放開發板設定標頭檔案,每個開發板對應一個標頭檔案,標頭檔案的名字就是開發板的名字。

lib_generic:通用庫檔案程式碼,整個u-boot共用檔案。不用修改。

lib*:    其他以lib開頭的是具體體系架構相關的庫檔案,整個個晶片構架共用的檔案。不用修改。

nand_spl:nand 驅動。

net:網路協定程式碼,一般不用修改。

post:一些開發板上電檢測程式碼,一般不用修改。

tool:編譯u-boot需要的一些工具程式碼,不用修改。

README:文字文件,u-boot的編譯,設定說明。

Makefile: 管理u-boot的Makefile檔案—移植u-boot時候要在這個檔案 新增一個自己的開發板設定選項。

3. u-boot 的啟動過程

3.1  u-boot 啟動階段

      分兩部分:

1)組合部分—啟動程式碼;入口: cpu/構架資料夾/start.S

2) C語言程式碼部分。u-boot複雜功能都是這個階段實現。

入口:lib_*/board.c 中void start_armboot (void)函數。

任何一個開發板的u-boot都是從cpu/構架資料夾/start.S 檔案開始執行。

start.S:啟動程式碼,負責異常向量表定義,初始化CPU時鐘,記憶體設定,堆疊設定,複製程式碼到記憶體中,跳到到C程式碼階段。

3.2 start.S分析

以xyd2440為例子分析

入口檔案:start.S (cpuarm920t)  。

工作內容:

1.        異常向量表定義

2.        關看門狗

3.        關中斷

4.        設定時鐘

5.        設定記憶體控制器

6.        設定棧

7.        複製程式碼到記憶體

8.        清BSS段

9.        跳轉到C程式碼執行。

3.2.1 補充:GNU 組合知識

1)可以使用C的方法包含C語言標頭檔案,例如:

2).globl 關鍵字:宣告一個全域性的標號,全域性標號,其他可見,可以使用這個標誌。
.globl _start  :把_start標號宣告為全域性的,其他的檔案 ,C,連結檔案,其他組合檔案都可見。
 
3)標號定義: “標號:” ,如: _start: ,定義一個_start標號。一個標號代表一個地址。

4).balignl關鍵字:在當前位置以指定對齊方式存放數位。
  .balignl 16,0xdeadbeef  在當前程式碼所在的地址開始找到第一個16的整數倍地址存放0xdeadbeef
5).word關鍵字:在當前位置存放一個數值。如:
_TEXT_BASE:
 .word TEXT_BASE
代表在當前地址存放 TEXT_BASE 所代表的數值。
6)可以使用C語言的預處理功能。
#if defined(CONFIG_xyd2440_LED_DEBUG)
…..
#endif
上面程式碼意思是如果定義了CONFIG_xyd2440_LED_DEBUG宏,就編譯其中包含的程式碼段。

#define S_FRAME_SIZE 72
#define S_OLD_R0 68
上面使用C語言的宏定義功能定義數值。
7)  注釋:和C語言一樣。同時支援使用@注釋。  可用:// ,  /*  */,  @
8)組合程式碼專用宏定義:以 .macro 開頭 後接宏名,中間宏程式碼,最後是 .endm 做為結束。
 .macro bad_save_user_regs
 sub sp, sp, #S_FRAME_SIZE
 stmia sp, {r0 - r12}   @ Calling r0-r12
 ldr r2, _armboot_start
 sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
 sub r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
 ldmia r2, {r2 - r3}   @ get pc, cpsr
 add r0, sp, #S_FRAME_SIZE  @ restore sp_SVC

 add r5, sp, #S_SP
 mov r1, lr
 stmia r5, {r0 - r3}   @ save sp_SVC, lr_SVC, pc, cpsr
 mov r0, sp
 .endm
9) .align關鍵字: 控制程式碼對齊方式
ARM的.align 5就是2的5次方對齊,也就是4位元組對齊,

3.3 分析 :
//異常向量表定義
.globl _start  //把 _start 宣告為全域性標號               
_start: b  start_code            //第1條指令,復位異常
 ldr pc, _undefined_instruction //未定義異常
 ldr pc, _software_interrupt    //軟中斷異常
 ldr pc, _prefetch_abort        //預取指中止異常
 ldr pc, _data_abort            //資料中止異常
 ldr pc, _not_used
 ldr pc, _irq                  //IRQ中斷異常
 ldr pc, _fiq                  //FIQ中斷異常

_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort:  .word data_abort
_not_used:  .word not_used
_irq:   .word irq
_fiq:   .word fiq

當整個u-boot流程走完之後,就真正進入linux的啟動系統了。

所以,如果對u-boot整理流程通過軟體來認識一邊的話,就完全知道linux在啟動時,幹了哪些事。就像window啟動時,會出現一些資訊,告訴你當前執行到哪裡,執行了什麼事,一目了然。

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-07/145435.htm


IT145.com E-mail:sddin#qq.com