在完成地址無關fixup后,u-boot開始對一些系統寄存器進行初始化。
第一段代碼如下:
pie_fixup_done:
#endif
#ifdef CONFIG_SYS_RESET_SCTRL
bl reset_sctrl --------------------------------------------------------------------- (1)
#endif
#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD) ---------- (2)
.macro set_vbar, regname, reg
msr regname, reg
.endm
adr x0, vectors
#else
.macro set_vbar, regname, reg
.endm
#endif
/*
* Could be EL3/EL2/EL1, Initial State:
* Little Endian, MMU Disabled, i/dCache Disabled
*/
switch_el x1, 3f, 2f, 1f ---------------------------------------------------------- (3)
3: set_vbar vbar_el3, x0
mrs x0, scr_el3
orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
msr scr_el3, x0
msr cptr_el3, xzr /* Enable FP/SIMD */
b 0f
2: mrs x1, hcr_el2
tbnz x1, #34, 1f /* HCR_EL2.E2H */
set_vbar vbar_el2, x0
mov x0, #0x33ff
msr cptr_el2, x0 /* Enable FP/SIMD */
b 0f
1: set_vbar vbar_el1, x0
mov x0, #3 < < 20
msr cpacr_el1, x0 /* Enable FP/SIMD */
0:
#ifdef COUNTER_FREQUENCY -------------------------------------------------------------- (4)
branch_if_not_highest_el x0, 4f
ldr x0, =COUNTER_FREQUENCY
msr cntfrq_el0, x0 /* Initialize CNTFRQ */
#endif
4: isb ------------------------------------------------------------------------------- (5)
...
...
#ifdef CONFIG_SYS_RESET_SCTRL
reset_sctrl:
switch_el x1, 3f, 2f, 1f
3:
mrs x0, sctlr_el3
b 0f
2:
mrs x0, sctlr_el2
b 0f
1:
mrs x0, sctlr_el1
0:
ldr x1, =0xfdfffffa
and x0, x0, x1
switch_el x1, 6f, 5f, 4f
6:
msr sctlr_el3, x0
b 7f
5:
msr sctlr_el2, x0
b 7f
4:
msr sctlr_el1, x0
7:
dsb sy
isb
b __asm_invalidate_tlb_all ----------------------------------------------------- (6)
ret
#endif
- ? (1)一般情況下此功能不需要使用,但是一些由其他固件引導啟動的u-boot,board希望系統行為能按照自己預期行為執行而不受上一級加載器的影響,所以使用CONFIG_SYS_RESET_SCTRL來決定是否重置系統控制寄存器,包括保證處理器處于小端,關閉data cache,關閉mmu。 其中switch_el是一個宏,用于讀取當前所處的異常級別,根據所處異常級別調用對應的系統控制寄存器。某些時候u-boot的加載并不是一定在el3級別,當存在atf等時,el3由atf控制,atf會將u-boot的運行級別切換到el2,以便保證自己的控制級別,所以u-boot通過switch_el來選擇自己能夠控制的系統寄存器。
- ? (2)定義設置異常向量表的宏,將異常向量表的地址寫入/reg設置的系統寄存器即可完成異常向量表的設置,這里u-boot是需要設置異常向量表的,而spl默認是不需要設置異常向量表的,畢竟spl只是一個加載器只會運行一次,不過當定義了CONFIG_ARMV8_SPL_EXCEPTION_VECTORS時可以為spl也設置一個異常向量表。
- ? (3)同樣的使用switch_el來跳轉到對應級別的路徑上去執行,在進行系統寄存器設置時,因為在這之前已經由SYS_RESET_SCTRL或者board自己保證處理器處于小端,mmu關,i-cache和d-cache處于關閉狀態了,所以這里直接進行對應級別系統寄存器設置,首先是跳轉到對應表設置對應級別的異常向量表。接著會有如下三種情況: 當處于EL3時,會設置安全配置系統寄存器(scr_el3),會將低四位bit設置為0xf,表示設置處理器處于非安全模式,任何級別的物理irq中斷,物理fiq,異常abort中斷,異常SError中斷都將被路由到el3級別。后續這些設置將在啟動Linux時被修改,這些設置僅用于在u-boot階段。接著將cptr_el3清零,使用xzr是可以快速操作寄存器為零。這里保證任何級別下訪問SIMD和floating-point指令不會導致觸發異常陷入el3。 當處于EL2時,首先根據HCR_EL2.E2H判斷系統是一個虛擬機管理器還是主機系統,當E2H = 0時,表示系統處于主機系統只需要做el3一樣的操作配置SIMD和FP指令不會陷入el2即可。 當系統處于EL1時,則什么也不需要操作只需要配置SIMD和FP指令不會陷入el1。
- ? (4)u-boot在啟動時系統的時鐘頻率不一定配置了,所以當在include/configs/xxxxxx.h中定義了COUNTER_FREQUENCY的頻率值時,說明需要在此處配置系統時鐘,所以根據宏 branch_if_not_highest_el判斷當系統不處于EL3時則需要設置系統的時鐘工作頻率cntfrq_el0,后續Linux或者u-boot根據讀出的這個值計算出系統每納秒的滴答數從而供軟件獲取時間流逝值。
- ? (5)isb指令用于確保上述操作指令被正確真正的執行了,屬于同步指令的一種。
- ? (6)在進行系統控制器復位時,dsb sy,isb,__asm_invalidate_tlb_all三個操作在這里的意義是,因為對處理器的小端,mmu,d-cache進行了復位,所以這里必須通過dsb和isb確保數據和指令全部執行和寫入,這里進行了mmu和cache關閉操作,那么如果有緩存的tlb在這個時候這些緩存的tlb數據就是無效的,這里對可能緩存的tlb進行全部無效化,確保后續任何可能的mmu開啟操作不會使用到這些無用的tlb條目而導致系統異常。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
ARM
+關注
關注
134文章
9164瀏覽量
369017 -
寄存器
+關注
關注
31文章
5363瀏覽量
121083 -
Uboot
+關注
關注
4文章
125瀏覽量
28332 -
系統
+關注
關注
1文章
1019瀏覽量
21409
發布評論請先 登錄
相關推薦
U-Boot介紹
在移植 Linux之前我們需要先移植一個 bootloader 代碼,這個 bootloader 代碼用于啟動 Linux 內核, bootloader有很多,常用的就是 U-Boot。
U-boot的基本介紹
從本文開始,將陸續推送“手把手教你移植U-boot”系列文章,目標是由淺入深地講解U-boot的工作流程、原理、配置方法和移植方法,手把手教你完成U-boot的移植工作,默認硬件開發平臺為ARM,操作
發表于 07-14 16:52
?3124次閱讀
基于開發板的U-Boot移植
bootloader,也就是通用的bootloader。它存在于nandflash或者SD卡中,它是在開機上點之后,操作系統起來之前用來引導的一個程序。U-boot 的主要作用是進行內存的初
發表于 01-14 14:31
U-BOOT的啟動流程分享
Bootloader移植(下)U-BOOT 啟動流程u-boot啟動三個2啟動步驟(重點)U-boot 啟動源碼分析U-BOOT 啟動流程u-boo
發表于 01-18 10:17
u-boot簡介
。 U-Boot是BootLoader的一種,是在操作系統內核運行之前運行。可以初始化硬件設備、建立內存空間映射圖,從而將系統的軟硬件環境帶到一個
發表于 10-14 11:17
?3593次閱讀
NAND閃存中啟動U-BOOT的設計解析
U-BOOT 支持ARM、 PowerPC等多種架構的處理器,也支持Linux、NetBSD和VxWorks等多種操作系統,主要用來開發嵌入式系統初
發表于 10-29 11:29
?2次下載
如何使用Xilinx SDK調試u-boot代碼
了解如何使用Xilinx SDK調試u-boot代碼。
概述了技術以獲得重定位偏移量,以便可以在SDK中應用它。
U-Boot啟動內核的工作過程詳細說明
U-Boot 啟動內核的過程可以分為兩個階段,兩個階段的功能如下:(1)第一階段的功能
硬件設備初始化
加載 U-Boot 第二階段代碼到 RAM 空間
設置好棧
跳轉到第二階段
發表于 12-28 08:00
?3次下載
tiny4412編譯與移植U-Boot
U-Boot 是一個主要用于嵌入式系統的引導加載程序, U-Boot本質是一個裸機程序,是一種普遍用于嵌入式系統中的開源的Bootloader,作用是用來引導操作
u-boot在匯編啟動階段的相關操作介紹
u-boot在匯編啟動階段對系統的一些初始化 當cpu交由u-boot接管進入u-boot后, 首先會到_start符號處開始執行
評論