【嵌入式移植】8、U-Boot源碼分析5—啟動過程分析start.S

U-Boot源碼分析5—啟動過程分析start.S

  • 1、`boot0.h`
  • 2、`reset`
    • 2.1、`vectors`
    • 2.2、`ELn`
      • 2.2.1 EL3
      • 2.2.2、EL2、EL1
    • 2.3、`SMPEN`
    • 2.3、`core errate`
    • 2.4、`lowlevel_init`

前面從U-Boot編譯的角度分析了其Makefile、鏈接腳本等,本章開始正式分析U-Boot啟動過程

從上一篇文章7、U-Boot源碼分析4—鏈接腳本分析,可知U-Boot啟動入口_startarch/arm/cpu/armv8/start.S

1、boot0.h

start.S中找到啟動入口`_start:
請添加圖片描述

這里針對匯編文件的結尾*.s*.S進行說明:其中小寫的s表示文件中僅包含匯編代碼,編譯器將不進行預編譯操作;而大寫的S表示文件中包含相關預編譯代碼,編譯器將進行預編譯操作,即判斷#ifdef#ifndef#if defined(xxx)等語句的條件是否成立并保留相關代碼,或將#include指令包含的文件內容替換到對應位置,等等的預編譯操作

這里搜索CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK,發現存在定義:
請添加圖片描述
因此將執行第28行的語句,即#include <asm/arch/boot0.h>,對于某些芯片需要特殊的一些初始配置的話,可以通過配置CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK并執行相應boot0.h中的代碼來進行一些boot之前的操作,內容如下
請添加圖片描述

可知其語句和其它啟動文件基本一樣,都是跳轉至reset標號,但是增加了與AArch64切換有關的代碼,查看arch/arm/mach-sunxi/rmr_switch.S中的說明,其實是本例所使用芯片的特殊屬性,因為該芯片在復位后會進入AArch32狀態,所以在一些時刻需要切換到AArch64狀態,這里涉及ARMv8的Reset Management Register,暫時先不分析

隨后進行 2 3 = 8 2^3=8 23=8字節對齊(.align 3),并定義了一些符號:_end_ofs_bss_start_ofs_bss_end_ofs,是一些關鍵段與代碼段起始位置的偏移

2、reset

跳轉進入reset后,首先跳轉進入save_boot_params,這里save_boot_params通過WEAK關鍵字定義為save_boot_params_retstart.S文件最后);
因為使用了WEAK關鍵字,當然也可以直接在其它文件中定義自己的save_boot_params函數(需使用頭文件引用或在已有的頭文件中進行聲明)
請添加圖片描述
這里搜索CONFIG_SYS_RESET_SCTRL,發現沒有定義,因此不進行跳轉,繼續向下執行。
其實跳轉到reset_sctrl中主要是根據當前異常等級執行對應操作:設置小端,關MMU,關I/D-cache

2.1、vectors

接下來,第67行首先將中斷向量vectors的地址保存在x0寄存器中,中斷向量的定義在arch/arm/cpu/armv8/excetions.S中:
請添加圖片描述

這里首先進行 2 1 1 = 2048 2^11=2048 211=2048字節即2K對齊(.align 11),且各個中斷向量地址均以 2 7 = 128 2^7=128 27=128字節對齊;

每個中斷向量都對應其跳轉指令,比如b _do_bad_sync,先用bl指令跳轉到do_bad_sync函數執行,然后再跳轉到中斷退出函數exception_exit;而do_bad_sync函數最終將輸出各個關鍵寄存器的值,最后調用panic函數終止正在運行的程序并進行復位

/** do_bad_sync handles the impossible case in the Synchronous Abort vector.*/
void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr)
{efi_restore_gd();printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr);show_regs(pt_regs);panic("Resetting CPU ...\n");
}

當然這里所有中斷都沒有打開,目前不會進入任何中斷向量,另外現在沒有初始化堆棧等,也無法執行C函數

2.2、ELn

然后第68行判斷異常等級,并根據判斷結果從不同分支開始執行
請添加圖片描述
其中switch_elarch/arm/include/asm/macro.h中定義

/** Branch according to exception level*/
.macro	switch_el, xreg, el3_label, el2_label, el1_labelmrs	\xreg, CurrentELcmp	\xreg, 0xcb.eq	\el3_labelcmp	\xreg, 0x8b.eq	\el2_labelcmp	\xreg, 0x4b.eq	\el1_label
.endm

其中xreg即為傳入的x1寄存器,這里將CurrentEL寄存器的值放入x1寄存器中,并依次和0xc0x80x4進行比較,根據比較結果進入不同的分支標號

CurrentEL寄存器即為Current Exception Level寄存器,根據ARMv8的手冊,其定義如下:
請添加圖片描述
因此0xc0x80x4即分別對應EL3、EL2、EL1

2.2.1 EL3

可知當復位后CPU處于EL3時,執行如下代碼

3:	msr	vbar_el3, x0mrs	x0, scr_el3orr	x0, x0, #0xf			/* SCR_EL3.NS|IRQ|FIQ|EA */msr	scr_el3, x0msr	cptr_el3, xzr			/* Enable FP/SIMD */
#ifdef COUNTER_FREQUENCYldr	x0, =COUNTER_FREQUENCYmsr	cntfrq_el0, x0			/* Initialize CNTFRQ */
#endifb	0f

首先將x0寄存器中的中斷向量vectors的地址放入vbar_el3寄存器:Vector Base Address Register (EL3)
請添加圖片描述
其中低11位(0~10)保留為0,對應前面中斷向量最開始的2K字節對齊(.align 11

隨后的3行語句,首先將scr_el3寄存器的值保存到x0寄存器中,然后將x0寄存器或操作上0xF即將低4位置1,然后保存到x0寄存器中,最后將x0寄存器的值再賦給scr_el3寄存器,scr_el3寄存器低4為置1
請添加圖片描述
scr_el3寄存器bit3對應EA,即任何異常等級下發生的External Abort 和 SError 中斷都由EL3進行處理;bit2對應FIQ,即任何異常等級下發生的硬件上的FIQ (快速中斷請求)都由EL3進行處理;bit1對應IRQ,即任何異常等級下發生的硬件上的IRQ (中斷請求)都由EL3進行處理;bit0對應NS,置1表示任何低于EL3的異常等級(EL0、EL1等)都是非安全狀態,無法訪問安全內存空間

然后使用xzr(64位全零寄存器)將cptr_el3寄存器清零,
請添加圖片描述
即(TCPAC)打開EL2訪問CPTR_EL2HCPTR寄存器的權限,打開EL2、EL1訪問CPACR_EL1CPACR寄存器的權限;(TAM)打開EL2、EL1訪問Activity Monitor registers的權限;(TTA)打開系統寄存器訪問trace寄存器的權限;(TFP)使能SVE、SIMD和浮點運算;但(EZ)又把SVE關了

因此這一行代碼的功能也就是注釋說的使能SIMD和FP運算

然后由于在include/configs/sunxi-common.h中定義了COUNTER_FREQUENCY的值為24000000,因此將此值由x0寄存器賦給cntfrq_el0寄存器,即配置系統計數器的時鐘值,此系統計數器一般用于精確計時

結合上述分析,EL3等級對應的操作即為將中斷向量地址放入vbar_el3寄存器,設置相關中斷請求僅由EL3實現,使能SIMD和FP運算,設置系統計數器的時鐘值

2.2.2、EL2、EL1

對應執行的代碼為,均為將中斷向量地址放入對應的vbar_eln寄存器,使能SIMD和FP運算等,這里不再詳細分析

2:	msr	vbar_el2, x0mov	x0, #0x33ffmsr	cptr_el2, x0			/* Enable FP/SIMD */b	0f
1:	msr	vbar_el1, x0mov	x0, #3 << 20msr	cpacr_el1, x0			/* Enable FP/SIMD */

2.3、SMPEN

接下來的語句是開啟多核相關的操作,這里雖然沒有定義CONFIG_ARMV8_SET_SMPEN,但注釋里建立用于Cortex-A53時使能,因此這里也分析一下

	/** Enable SMPEN bit for coherency.* This register is not architectural but at the moment* this bit should be set for A53/A57/A72.*/
#ifdef CONFIG_ARMV8_SET_SMPENswitch_el x1, 3f, 1f, 1f
3:mrs     x0, S3_1_c15_c2_1               /* cpuectlr_el1 */orr     x0, x0, #0x40msr     S3_1_c15_c2_1, x0
1:
#endif

這里的操作也一樣,首先判斷所處的異常等級,僅在EL3時進行操作:首先將S3_1_c15_c2_1也即cpuectlr_el1寄存器的值放入x0寄存器,然后通過orr指令將第6位置1;這里cpuectlr_el1寄存器在Cortex-A53手冊中(ARMv8架構定義了一些必須實現的寄存器,同時預留一些空間給不同處理器來實現各自的特色功能等)
請添加圖片描述
第6位即SMPEN置1,表示使能各核心之間的數據一致性功能(主要與cache有關,對于多核系統來說,一般各個核具有自己的L1-cache,簇內共享L2-cache,還有外部的L3-cache,這樣不同核心上的cache或ram對于同一個數據可能有多個副本,會導致數據觀察者(CPU/GPU/DMA等)能看到的數據不一致,因此設置會再處理器中設置硬件來維護數據的一致性,具體內容可參考【Cache篇】一文總結ARMv8架構中關于Cache的知識點)

2.3、core errate

隨后進行核心勘誤,目前僅支持Cortex-A57進行核心勘誤表的設置,這里跳過

	/* Apply ARM core specific erratas */bl	apply_core_errata
....
WEAK(apply_core_errata)mov	x29, lr			/* Save LR *//* For now, we support Cortex-A57 specific errata only *//* Check if we are running on a Cortex-A57 core */branch_if_a57_core x0, apply_a57_core_errata
0:mov	lr, x29			/* Restore LR */retapply_a57_core_errata:#ifdef CONFIG_ARM_ERRATA_828024mrs	x0, S3_1_c15_c2_0	/* cpuactlr_el1 *//* Disable non-allocate hint of w-b-n-a memory type */orr	x0, x0, #1 << 49/* Disable write streaming no L1-allocate threshold */orr	x0, x0, #3 << 25/* Disable write streaming no-allocate threshold */orr	x0, x0, #3 << 27msr	S3_1_c15_c2_0, x0	/* cpuactlr_el1 */
#endif#ifdef CONFIG_ARM_ERRATA_826974mrs	x0, S3_1_c15_c2_0	/* cpuactlr_el1 *//* Disable speculative load execution ahead of a DMB */orr	x0, x0, #1 << 59msr	S3_1_c15_c2_0, x0	/* cpuactlr_el1 */
#endif#ifdef CONFIG_ARM_ERRATA_833471mrs	x0, S3_1_c15_c2_0	/* cpuactlr_el1 *//* FPSCR write flush.* Note that in some cases where a flush is unnecessary thiscould impact performance. */orr	x0, x0, #1 << 38msr	S3_1_c15_c2_0, x0	/* cpuactlr_el1 */
#endif#ifdef CONFIG_ARM_ERRATA_829520mrs	x0, S3_1_c15_c2_0	/* cpuactlr_el1 *//* Disable Indirect Predictor bit will prevent this erratumfrom occurring* Note that in some cases where a flush is unnecessary thiscould impact performance. */orr	x0, x0, #1 << 4msr	S3_1_c15_c2_0, x0	/* cpuactlr_el1 */
#endif#ifdef CONFIG_ARM_ERRATA_833069mrs	x0, S3_1_c15_c2_0	/* cpuactlr_el1 *//* Disable Enable Invalidates of BTB bit */and	x0, x0, #0xEmsr	S3_1_c15_c2_0, x0	/* cpuactlr_el1 */
#endifb 0b
ENDPROC(apply_core_errata)

2.4、lowlevel_init

接下來就到了大名鼎鼎的lowlevel_init,本章先不分析,留待下章

本章分析完畢~
完結撒花??ヽ(°▽°)ノ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719822.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719822.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719822.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ClickHouse SQL Reference (四)數據類型

Tuple(T1, T2, …) 元素元組&#xff0c;每個元素都有一個單獨的類型。元組必須至少包含一個元素。 元組用于臨時列分組。在查詢中使用IN表達式時&#xff0c;以及指定lambda函數的某些形式參數時&#xff0c;可以對列進行分組。有關更多信息&#xff0c;請參閱IN操作符和高階…

u-boot 基礎學習:板級配置 Kconfig 的包含

前言 u-boot 與 Linux 內核在嵌入式Linux開發中占有重要的地位&#xff0c;掌握 u-boot 的基礎開發&#xff0c;可以大大提升開發能力&#xff0c;并提高開發的效率。 u-boot 下 如何配置 板級的Kconfig 呢&#xff1f;u-boot 下板級的 Kconfig 是怎么包含到 主目錄下 Kconfig…

【代碼隨想錄算法訓練營Day34】860.檸檬水找零;406.根據身高重建隊列;452.用最少數量的箭引爆氣球

??Day 34 第八章 貪心算法 part04 ??今日任務 860.檸檬水找零406.根據身高重建隊列452.用最少數量的箭引爆氣球 ??860.檸檬水找零 本題看上好像挺難&#xff0c;其實挺簡單的&#xff0c;大家先嘗試自己做一做。題目鏈接&#xff1a;https://leetcode.cn/problems/lem…

【計算機網絡】IO多路轉接之poll

文章目錄 一、poll函數接口二、socket就緒條件三、poll的優點四、poll的缺點五、poll使用案例--只讀取數據的server服務器1.err.hpp2.log.hpp3.sock.hpp4.pollServer.hpp5.main.cc 一、poll函數接口 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int t…

2024.3.3 訓練記錄(7)

這幾天又忘記每天復習了&#xff0c;以后在實驗室復習完再回去好了 最近做1800的題目好多dp啊太ex了 文章目錄 牛客 練習賽122D 圓CF 1396B Stoned GameCF 1355C Count TrianglesCF 1437C Chef MonocarpCF 271D Good SubstringsCF 1475D Cleaning the PhoneCF 1362D2 Prefix-…

“羊駝“入侵CV,美團浙大沈春華團隊將LLaMA向CV擴展,構建全新基礎模型VisionLLaMA

本文首發:AIWalker https://arxiv.org/abs/2403.00522 https://github.com/Meituan-AutoML/VisionLLaMA 本文概述 大型語言模型構建在基于Transformer的架構之上來處理文本輸入, LLaMA 系列模型在眾多開源實現中脫穎而出。類似LLaMa的Transformer可以用來處理2D圖像嗎&#xf…

Python繪制不同形狀詞云圖

目錄 1.基本詞云圖1.1 導入所需庫1.2 準備詞匯1.3 配置參數并生成詞云圖1.4 在Python窗口中顯示圖片1.5 效果展示1.6 完整代碼 2. 不同形狀詞云圖2.1 找到自己所需形狀圖片2.2 利用PS將圖片設置為黑白色2.3 在代碼中設置背景2.4 效果展示 1.基本詞云圖 1.1 導入所需庫 import…

遠程調用--webClient

遠程調用webClient 前言1、創建webClient2、準備數據3、執行請求4、接收返回響應到的數據整體代碼 前言 非阻塞、響應式HTTP客戶端 1、創建webClient WebClient client WebClient.create();2、準備數據 Map<String,String> params new HashMap<>();params.pu…

貪心算法(區間問題)

452. 用最少數量的箭引爆氣球 題目(求無重復區間) 有一些球形氣球貼在一堵用 XY 平面表示的墻面上。墻面上的氣球記錄在整數數組 points &#xff0c;其中points[i] [xstart, xend] 表示水平直徑在 xstart 和 xend之間的氣球。你不知道氣球的確切 y 坐標。 一支弓箭可以沿著…

利用Python爬取8684公交路線查詢網站中全國公交站點信息

利用python語言結合requests、BeautifulSoup等類庫爬取https://api.8684.cn/v3/api.php?docitys&actprovince對應接口中所有城市公交路線信息以及公交站點信息。 import time import requests import json, re from bs4 import BeautifulSoup# 定義一個函數&#xff0c;傳…

“祖傳代碼“的是是非非

程序員眼中的“祖傳代碼”&#xff0c;就像一本古老而神秘的魔法書&#xff0c;藏著無窮的智慧和技巧&#xff0c;有些代碼像家傳寶貝&#xff0c;有些像祖傳秘方。快來分享一下你遇到的“祖傳代碼”吧~ 祖傳代碼的歷史與文化價值 祖傳代碼通常指的是經過長時間使用和傳承的代…

【DUSt3R】2張圖2秒鐘3D重建

【DUSt3R】2張圖2秒鐘3D重建 1. DUSt3R是一種用于稠密和無約束立體三維重建的方法,其實現步驟如下:2. 實際運行效果3. 運行結果4. 自問自答4.1 為社么這里要是使用transform模型呢?4.2 CroCo(通過跨視圖完成3D視覺任務的自我監督預訓練的一個研究)在DUSt3R的作用是什么,為…

打家劫舍(java版)

&#x1f4d1;前言 本文主要是【動態規劃】——打家劫舍(java版)的文章&#xff0c;如果有什么需要改進的地方還請大佬指出?? &#x1f3ac;作者簡介&#xff1a;大家好&#xff0c;我是聽風與他&#x1f947; ??博客首頁&#xff1a;CSDN主頁聽風與他 &#x1f304;每日一…

17 easy 290. 單詞規律

//給定一種規律 pattern 和一個字符串 s &#xff0c;判斷 s 是否遵循相同的規律。 // // 這里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每個字母和字符串 s 中的每個非空單詞之間存在著雙向連接的對應規律。 // // // // 示例1: // // //輸入: patte…

24計算機考研調劑 | 西安工大

西安工大 考研調劑招生信息 學校:西安工大 專業:- 年級:2024 招生人數:4 招生狀態:正在招生中 聯系方式:********* (為保護個人隱私,聯系方式僅限APP查看) 補充內容 歡迎化工、材料、環工等專業[或有計算機相關專業&#xff08;智能科學和軟件工程方向&#xff09;、機…

一款不錯的多端SSH工具:Xterminal

1、不僅是強大的SSH工具&#xff0c;更提供本地控制臺&#xff0c;以及更多即將推出的開發相關功能&#xff0c;讓您專注于創造卓越的代碼 2、AI賦能&#xff0c;智能命令提示&#xff0c;為大腦解壓 AI解答&#xff0c;讓你的疑問得到即時解答 AI智能提示&#xff0c;讓每一…

CodeFlying 和 aixcoder兩大免費軟開平臺,孰強孰弱?

今天為大家帶來碼上飛CodeFlying和aixcoder兩款免費的軟件開發平臺效果的測評 一、產品介紹 首先簡單介紹一下這兩個平臺 碼上飛CodeFlying&#xff1a;碼上飛 CodeFlying | AI 智能軟件開發平臺&#xff01; 是一款革命性的軟件開發平臺&#xff0c;它通過將軟件工程和大模…

Redis是AP的還是CP的?

redis是一個開源的內存數據庫&#xff0c;那么他到底是AP的還是CP的呢&#xff1f; 有人說&#xff1a;單機的是redis是cp的&#xff0c;而集群的redis是ap的&#xff1f; 但是我不這么認為&#xff0c;我覺得redis就是ap的&#xff0c;雖然在單機redis中&#xff0c;因為只有…

Git 基本操作 ?作區、暫存區、版本庫

創建本地倉庫&#xff1a; 創建 Git 本地倉庫 要提前說的是&#xff0c;倉庫是進行版本控制的?個文件目錄。我們要想對文件進行版本控制&#xff0c;就必須先創建?個倉庫出來。 首先touch 一個文件&#xff1a; 初始化倉庫&#xff1a; 創建完成后&#xff0c;我們會發現當前…

行列式錯題本

《1800》 1 階數和轉置 A是三階,B是4階,還有2這個系數 2 怎么啥也不會呀,委屈 行列式的拆分+提取系數 3