uboot啟動流程詳解(2)-reset
1、原始碼及註釋
reset是uboot最先執行的程式碼,接下來我們來看看reset的具體流程。
reset:
/*如果沒有重新定義save_boot_params,則使用<arch/arm/cpu/armv7/start.S>
中的save_boot_params。其不做任何事情,直接返回。*/
bl save_boot_params
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr /*將cpsr暫存器的內容傳送到r0暫存器*/
and r1, r0, #0x1f /*標誌位清零*/
teq r1, #0x1a /*測試處理器是否處於HYP模式,
HYP是armv-7a為cortex-A15處理器提供硬體虛擬化引進的管理模式。*/
bicne r0, r0, #0x1f /*工作模式位清零*/
orrne r0, r0, #0x13 /*設定成SVC管理模式*/
orr r0, r0, #0xc0 /*關閉FIQ和IRQ中斷*/
msr cpsr,r0 /*將r0的值賦給cpsr*/
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/****************************************************************
設定異常向量的基地址,正常異常模式下異常向量的基地址為0x00000000,高異常模式下
異常向量的基地址為0xffff0000,這裡V=0設定成正常異常模式。CP15協處理器的操作及
相關知識可以看另一篇文章。
*****************************************************************/
/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register
/*********************************************
重新設定異常向量的基地址,只有上面V=0的情況下,這裡才能去重新
配置異常向量表的基地址!
**********************************************/
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15 //初始化協處理器,具體流程請看另一篇文章
bl cpu_init_crit //初始化記憶體和鎖相環,具體流程請看另一篇文章
#endif
bl _main //呼叫c程式碼,具體流程請看另一篇文章。
2、CPSR暫存器介紹
通過向模式位M[4:0]裡寫入相應的資料切換到不同的模式,在對CPSR,SPSR暫存器進行操作不能使用mov,ldr等通用指令,只能使用特權指令msr和mrs。
在ARM處理器中,只有MRS(Move to Register from State register)指令可以對狀態暫存器CPSR和SPSR進行讀操作。通過讀CPSR可以獲得當前處理器的工作狀態。讀SPSR暫存器可以獲得進入異常前的處理器狀態(因為只有異常模式下有SPSR暫存器)。
除了使用者模式和系統模式,其餘模式下都有一個私有SPSR儲存狀態暫存器,用來儲存切換到該模式之前的執行狀態,之所以使用者模式和系統模式沒有SPSR是因為,通常CPU大部分時間執行在使用者模式下,當產生異常或系統呼叫時會分別切換進入另外幾種模式,儲存使用者模式下的狀態,當切換回原先模式時,直接回復SPSR的值到CPSR就可以了,因此,使用者模式和系統模式下不需要SPSR。
3、相關彙編指令介紹
- mrs
將狀態暫存器的內容傳送至通用暫存器。 - teq
TEQ R1,R2 ;將暫存器R1的值與暫存器R2的值按位異或,並根據結果設定CPSR的標誌位。該指令通常用於比較運算元1和運算元2是否相等。常與EQ和NE條件碼配合使用,當兩個資料相等時,條件碼EQ有效,否則條件碼NE有效。 - bic
指令格式:BIC{cond}{S} Rd,Rn,operand2
BIC指令將Rn 的值與運算元operand2 的反碼按位邏輯”與”,結果存放到目的暫存器Rd 中。
指令示例:BIC R0,R0,#0x0F ;將R0最低4位清零,其餘位不變。 - orr
指令格式:orr {cond}{S} Rd,Rn,operand2
orr指令將運算元operand2 與Rn 的值按位邏輯"或",結果存放到目的暫存器Rd 中。
指令示例:orrs R1,R1,R2 ;R1=R1|R2,並根據運算的結果更新標誌位。
orr R0,R0,#0x0F ;R0=R0|0x0F,將R0最低4位置1,其餘位不變。
4、處理器模式介紹
5、ARM通用暫存器介紹
在ARM處理器內部有37個使用者可見的暫存器:30個通用暫存器,6個狀態暫存器(1個專用於記錄當前狀態,5個專用於記錄模式切換前的狀態),1個程式計數器PC。在不同的工作模式和處理器狀態下,程式設計師可以訪問的暫存器也不盡相同。
-31個通用暫存器:
R0~R15;
R13_svc、R14_svc;
R13_abt、R14_abt;
R13_und;R14_und;
R13_irq、R14_irq;
R8_fiq-R14_fiq
-6 個狀態暫存器:
CPSR、SPSR_svc、SPSR_abt、SPSR_und、SPSR_irq和SPSR_fiq
5.1 通用暫存器
通用暫存器包括R0~R15,可以分為三類:
─ 未分組暫存器R0~R7
─ 分組暫存器R8~R14
─ 程式計數器PC(R15)
(1)未分組暫存器R0~R7
在所有的執行模式下,未分組暫存器都指向同一個物理暫存器,他們未被系統用作特殊的用途,是真正的通用暫存器。因此,在中斷或異常處理進行執行模式轉換時,由於不同的處理器執行模式均使用相同的物理暫存器,可能會造成暫存器中資料的破壞,這一點在進行程式設計時應引起注意。
(2)分組的暫存器R8~R14
對於R8~R12,每一次所訪問的物理暫存器,與處理器當前的工作模式有關。
一、R8~R12
當處理器工作於fiq模式時,訪問的暫存器為R8_fiq~R12_fiq;
除fiq模式以外的其他模式,訪問的暫存器為R8_usr~R12_usr。
二、R13和R14:
每個暫存器對應6個不同的物理暫存器,其中的一個是使用者模式與系統模式共用,另外5個物理暫存器,對應於其他5種不同的異常模式。
R13:暫存器R13在ARM指令中常用作堆疊指標SP。但這只是一種習慣用法,使用者也可使用其他的暫存器作為堆疊指標。而在Thumb指令集中,某些指令強制性的要求使用R13作為堆疊指標。
R14:暫存器R14也稱作子程式連結暫存器(Subroutine Link Register)或連結暫存器LR。當執行BL子程式呼叫指令時,R14中得到R15(程式計數器PC)的備份。其他情況下,R14用作通用暫存器。與之類似,當發生中斷或異常時,對應的分組暫存器R14_svc、R14_irq、R14_fiq、R14_abt和R14_und用來儲存R15的返回值。
(3)程式計數器PC(R15)
暫存器R15用作程式計數器(PC)。在ARM狀態下,位[1:0]為0,位[31:2]用於儲存PC;在Thumb狀態下,位[0]為0,位[31:1]用於儲存PC。
使用R15時注意:雖然R15可以用作通用暫存器,但是有一些指令在使用R15時有一些特殊限制,若不注意,執行的結果將是不可預料的。所以,一般不這麼使用。
關於PC的值:由於ARM採用多級流水線技術,所以PC總是指向正在取指的指令,而不是正在執行的指令。也即PC總是指向當前指令的下兩條指令的地址。因此,對於ARM指令集而言,PC的值為當前指令的地址值加8個位元組。
5.2 狀態暫存器
在ARM微處理器中,有CPSR和SPSR兩種程式狀態暫存器。
1、當前程式狀態暫存器 CPSR (Current Program Status Register)用來儲存當前程式狀態的暫存器。所有處理器模式下都可以訪問當前程式狀態暫存器CPSR。僅一個CPSR。
2、儲存程式狀態暫存器SPSR_mode (Saved Program Status Register)SPSR_mode用來進行異常處理,其功能包括:
─ 儲存ALU中的當前操作資訊,當異常發生時, 用來儲存CPSR的值,從異常返回時,將 SPSR_mode複製到CPSR中,恢復CPSR的值。
─ 控制允許和禁止中斷 修改SPSR的值
─ 設定處理器的執行模式 修改SPSR的值
問題:一共有多少個SPSR?為什麼?
ARM狀態暫存器的格式
1、條件碼標誌位(儲存ALU中的當前操作資訊)
N:正負號/大小 標誌位
0表示:正數/大於;1表示:負數/小於
Z:零標誌位
0表示:結果不為零;1表示:結果為零
C:進位/借位/移出位
0表示:未進位/借位/移出0;1表示:進位/未借位/移出1
V:溢位標誌位
0表示:結果未溢位;1表示:結果溢位
2、控制位
I、F中斷控制位——控制允許和禁止中斷
I=1 禁止IRQ中斷 I=0 允許IRQ中斷
F=1 禁止FIQ中斷 F=0 允許FIQ中斷
T控制(標誌)位——反映處理器的執行狀態
T=1時,程式運行於Thumb狀態
T=0時,程式運行於ARM狀態
M控制位——決定了處理器的執行模式
當發生異常時這些位被改變。如果處理器執行在特權模式,這些位也可以由程式修改。