uboot學習之三-----uboot啟動第一階段--start.S之一


uboot分為兩個階段:start.S是uboot的第一階段。

  一:引入start.S

    u-boot.s找到start.S的入口

      ①首先在C語言中整個項目的入口就是main函數(這是C語言規定的),所以如果要去了解C語言的項目,從main函數開始,這樣才能分析,如果隨便拿一個文件就開始看,最后看得一頭霧水,對自己沒有信心。怎么來找呢?可以使用souceinsight的搜索功能來查找。

      ②在uboot中因為有匯編階段參與,因此不能直接找main.c。整個程序的入口取決於連接腳本中ENTRY聲明的地方。ENTRY(_start)因此 _start符號是整個程序的入口,_start所在的代碼就是整個程序的起始代碼。

 

  二:分析start.S

    1、頭文件包含

      ①#include <config.h> config.h是在include文件下,這個文件不是源碼中的文件,是配置時自動生成的文件。詳見mkconfig腳本,在mkcofig腳本最后 發現 

      

      包含了一個#include <configs/x210_sd.h>

      最后分析發現,最終包含的是/include/configs/x210_sd.h,這個文件是整個uboot移植時的配置文件,里面有很多宏。這樣就將兩個文件關聯了起來。所以分析start.S時,要考慮configs/x210_sd.h。

       ②#include <version.h>

        /include/version.h中包含了#include "version_autogenerated.h"這個頭文件是編譯時自動生成的,這里面定義的宏define U_BOOT_VERSION "U-Boot1.3.4Joran"來自於makefile的配置值。這個宏在我們的程序中會被調用,在我們uboot啟動過程中串口打印出uboot的版本號,那個版本號信息就來自於這          里。
       ③#if defined(CONFIG_ENABLE_MMU)
        #include <asm/proc/domain.h>
        #endif

        asm目錄不是uboot中的原生目錄,uboot中本來是沒有這個目錄的。asm目錄是配置時創建的一個符號鏈接,實際指向的是就是asm-arm(詳解上一章節分析mkconfig腳本時).經過分析后發現,實際文件是:include/asm-arm/proc-armv/domain.h從這里可以看出之前配置時創建的符號鏈接的作用,如果沒有這些符號鏈接則編譯時根本通不過,因為找不到頭文件。(所以uboot不能在windows的共享文件夾下配置編譯,因為windows中沒有符號鏈接)
        

        思考為什么start.S不直接包含asm-arm/proc-armv/domain.h,而要用asm/proc/domain.h?這樣的設計主要是為了可移植性。因為如果直接包含,則start.S文件和CPU架構(和硬件)有關了,可移植性就差了。譬如我要把uboot移植到mips架構下,則start.S源代碼中所有的頭文件包含全部要修改。我們用了符號鏈接之后,則start.S中源代碼不用改,只需要在具體的硬件移植時配置不同,創建的符號鏈接指向的不同,則可以具有可移植性。

        ④啟動代碼的16字節頭部

        

從代碼讀出:如果定義了CONFIG_EVT1並且沒有定義CONFIG_FUSED,那么就定義4個4字節的空間。從sourceinsight部分可以看出紅色是已經定義的,黑色是未定義的,所以條件滿足,定義出16字節的空間,並且填充起來。

裸機中講過,從SD卡和nand啟動是需要16字節校驗頭(mkv210image.c就是為了計算這個校驗頭),以前做裸機實驗時,dnw下載方式不需要校驗頭,做SD卡啟動,mkv210image.c會給原鏡像210.bin加上16字節的校驗頭。

uboot中,這里的start.S中在開頭位置放了16字節的填充占位,這個占位的16字節只是保證正式的image的頭部確實有16字節,但是這個16字節內容是不對的,還需要后面去計算校驗和然后重新去填充的,uboot下有一個sd_fusing文件夾下C110-EVT1-mkbl1.c這個文件幾乎就是我們之前的mkv210image.c。

C110-EVT1-mkbl1.c中:

這里和star.S是相互聯系的。

      ⑤異常向量表構建

這個異常表順序是CPU設計時決定的,是硬件決定的。這些異常應該被處理,如果不處理這些這些異常,程序會跑飛。   

  復位異常處理:復位異常的代碼是 b reset ,因此在CPU復位后真正去執行的有效代碼是reset處的代碼,因此reset符號處,才是真正有意義代碼的開始處。

    ⑥有意思的deadbeef

    .balignl 16,0xdeadbeef  .balignl 16 是以16字節對齊,如果沒有對齊,用0xdeadbeef這個數字來填充,這個填充沒有什么特別的意義,只是剛好組成一個有意思的英語單詞----壞牛肉

 

 

為什么要對齊呢?有時候是為了提高訪問效率,有時候是硬件的要求。

 

    ⑦TEXT_BASE等

 

第100行的TEXT_BASE在整個代碼里都是被引用,它是在makefile里配置階段時的TEXT_BASE,其實就是我們鏈接時,指定的程序的鏈接地址,它的值就是c3e00000,我們在源代碼中和配置的makefile中很多變量是互相關聯的,有些符號的值可以從makefile中傳遞到源代碼中.

  ⑧CFG_PHY_UBOOT_BASE  33e00000  uboot在DDR中的物理地址。虛擬地址就是之前的ce3e00000。

 

.globl _armboot_start
_armboot_start:
    .word _start

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start
_bss_start:
    .word __bss_start

.globl _bss_end
_bss_end:
    .word _end

 armboot_start是后面重定位時用到的,bss_start這些是后面清bss段時會使用到的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM