u-boot第一階段啓動流程分析


對於uboot中的start.S主要做的事情就是系統各個方面的初始化,大致可以分爲以下6個部分:

1、設置CPU模式

2、關閉看門狗

3、關閉中斷

4、設置堆棧SP指針

5、清除bss段

6、異常中斷處理

下面按照start.S源碼逐個分析以上部分

1、設置CPU模式


41行,globl相當於,相當於C語言的extern,全局變量,外部可以訪問;而_start是整個文件的開始執行的入口

42行,進入_start之後跳轉到reset的位置。我們跟蹤reset看看做了什麼東西:


113行,將cpsr的值賦給R0寄存器

114行,清除r0的bit[4:0]位

115行,將r0和0xd3進行或運算,然後將結果給r0,即把r0的bit[7:6]和bit[4]和bit[2:0]置爲1

116行,將r0的值賦給cpsr

功能:

首先來看一下cpsr的結構


r0中的值經過幾條語句的運算之後,r0的bit[7:6]和bit[4]和bit[2:0]置爲1,將r0的值賦給cpsr也就是將cpsr對應的位也置爲1,從上面的結構中我們可以看到,置位之後,將CPU設置爲SVC模式,也就是管理模式,並且屏蔽外部中斷(IRQ)和快速中斷(FIQ)。

好了,分析完reset那我們回到最開始的地方

43-49行以及51-57行,也就是將各個步驟的地址存到pc中,pc是程序計數器,相關消息請查閱ARM彙編的相關知識,此處不再贅述。

43-57行分別對應着在發生“未定義指令”、“軟件中斷”、“預取指錯誤”、“數據錯誤”、“未定義”、“普通中斷”、“快速中斷”時,跳轉到對應的位置執行相應的代碼。

59行,說明接下來的代碼都要16字節對齊,不足之處要用0xdeadbeef補充,嘿嘿~壞牛肉



_bss_start和_bss_end的定義則是在腳本文件中,目的是保存命令參數。

小結:第一步驟要做的事情主要就是設置CPU爲SVC模式,並且關閉中斷。


2、關閉看門狗


我就直接看對應的板子,就是往WTCON中寫0就能關閉看門狗。有興趣可以去查看datasheet中的描述,如下:



3、關閉中斷


關中斷也很簡單,直接置起中斷屏蔽位就可以了,因爲我用的是2440的板子,所以直接看對應的代碼吧

嘿嘿,說到mask,我倒是想到我高中同桌了,一直叫他mask,許久不見,不知道他最近怎麼樣了......

說白了就是屏蔽下面這些中斷,有興趣還是去看datasheet,如下:


4、設置堆棧SP指針


注意,前面說到TEXT_BASE 的定義爲TEXT_BASE = 0x33D00000,而我們也能找到192和193行的兩個立即數的定義

#define CFG_MALLOC_LEN  (CFG_ENV_SIZE + 128*1024)
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */

194-196行,如果用到中斷的話,那麼再把r0的值減去IRQ 和FIQ的堆棧值

197行,再減去終止異常所用到的堆棧的大小,也就是12個字節,最後存入sp

說了那麼多,還是直接上圖:


5、清理bss


200-201把bss_start和bss_end的地址分別存入r0和r1,然後開始清理。

206行,比較當前地址是否到了bss段結束位置

207行,如果小於或者等於,就重新開始,直到地址超過bss的_end位置,即實現了整個bss段都清零

5、設置異常中斷


這部分代碼最讓語句看上去並不難,但是irq_save_user_regs和bad_save_user_regs具體實現的流程是怎麼樣的,還是弄得不太清楚,日後再說吧。


總結


最後再說一下,第一階段拼死拼活做了那麼多準備工作,最最最重要的就是調用start_armboot這個C語言函數,這也就是第二階段的入口。具體start_armboot如何工作的,請看第二階段的分析。

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