日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

硬核拆解:U-Boot?的第一條指令到底做了什么?

jf_44130326 ? 來源:Linux1024 ? 作者:Linux1024 ? 2026-04-26 07:08 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式Linux的朋友,大概率都有過這樣的體驗:燒錄完U-Boot,插上串口,看著屏幕上彈出U-Boot 202x.xx的打印信息,心里就踏實了——系統(tǒng)活了。

但很少有人想過,從芯片通電到這句打印出現(xiàn),背后已經(jīng)悄悄跑過了成千上萬條指令。而這一切的起點,也是最神秘、最底層的那一步,就藏在arch/arm/cpu/armv8/start.S這個文件里。

今天,我們就逐幀拆解這份ARMv8架構(gòu)下U-Boot的“啟動基因”,搞懂從通電到進入C語言世界(_main函數(shù))之前,CPU到底在忙些什么。

(建議收藏,調(diào)試啟動問題時,這篇就是你的“救命指南”)

wKgZO2ntScqATmouAAFMQICUmDU771.png

一、一切的起點:_start標(biāo)號

整個U-Boot的啟動,始于一個全局標(biāo)號_start,這是芯片上電/復(fù)位后,PC指針(程序計數(shù)器)指向的第一個地址,相當(dāng)于U-Boot的“出生證明”。

在_start開頭,有一段非常關(guān)鍵的條件編譯,給SoC廠商留足了“自定義空間”:

#ifdefCONFIG_ENABLE_ARM_SOC_BOOT0_HOOK#include#else  b  reset#endif

簡單說:有些芯片要求引導(dǎo)頭必須包含特殊簽名或頭部結(jié)構(gòu),廠商就可以在boot0.h里做定制化操作;如果不需要,就直接跳轉(zhuǎn)到reset標(biāo)號,進入下一步。

這一步看似簡單,卻是U-Boot適配不同芯片的關(guān)鍵“后門”。

二、位置無關(guān):U-Boot能“隨處運行”的秘密

現(xiàn)代U-Boot有個很強大的特性——位置無關(guān)代碼(PIC),也就是說,它的鏈接地址(編譯時指定的地址)和實際加載地址(燒錄到芯片的地址)可以不一樣,怎么燒錄都能正常啟動。

這個特性的核心,就藏在pie_fixup這段代碼里:

pie_fixup:  adr x0, _start     // 讀取 _start 的運行時實際地址  ldr x1, _TEXT_BASE   // 讀取編譯時指定的鏈接地址  sub x9, x0, x1     // 計算實際地址與鏈接地址的偏移量  ...pie_fix_loop: // 遍歷重定位表,給所有需要修正的地址加上偏移量

邏輯很直白:先算出“實際地址”和“預(yù)期地址”的差值(偏移量),再遍歷整個重定位表,把所有需要重定位的位置都加上這個偏移量。

正是這幾步操作,讓U-Boot實現(xiàn)了“任意地址加載,隨處運行”,極大降低了燒錄和調(diào)試的門檻。

三、異常級別切換:從EL3降到EL1的“降權(quán)”操作

ARMv8架構(gòu)的CPU有4個異常級別(EL0~EL3),級別越高,權(quán)限越大。芯片上電時,通常會處于最高權(quán)限的EL3,但Linux內(nèi)核一般只需要運行在EL1(或EL2,用于虛擬化)。

所以,start.S要做的關(guān)鍵一步,就是把CPU的異常級別“降下來”,用一個精妙的宏就能完成統(tǒng)一設(shè)置:

adrx0, vectorsswitch_elx1,3f,2f,1f

這段代碼的作用是:判斷當(dāng)前CPU的異常級別,然后執(zhí)行對應(yīng)級別的初始化:

?EL3(最高級別):設(shè)置向量表基地址(vbar_el3),配置SCR_EL3寄存器,開啟FP/SIMD功能(浮點/向量運算)。

?EL2(虛擬化級別):設(shè)置vbar_el2,同樣開啟FP/SIMD。

?EL1(內(nèi)核級別):設(shè)置vbar_el1。

無論從哪個級別啟動,最后都會統(tǒng)一落到同一個入口,同時初始化通用定時器頻率(cntfrq_el0),為后續(xù)的驅(qū)動和計時功能提供精準(zhǔn)時鐘

四、開啟緩存+多核“喚醒”:讓系統(tǒng)“跑起來”

芯片上電時,緩存(ICache/DCache)是默認(rèn)關(guān)閉的——緩存雖能提升性能,但啟動初期系統(tǒng)狀態(tài)混亂,開啟緩存會導(dǎo)致數(shù)據(jù)異常。所以U-Boot會在這里手動開啟緩存:

#ifndefCONFIG_SYS_ICACHE_OFF  mov x1, #CR_I // 開啟 ICache#else  mov x1, #0  // 關(guān)閉 ICache#endif

然后根據(jù)當(dāng)前異常級別,將配置寫入對應(yīng)的SCTLR_ELx寄存器,同時清除中斷掩碼(DAIF),讓系統(tǒng)能響應(yīng)SError(系統(tǒng)錯誤)。

如果是多核處理器(比如Cortex-A53/A57),還要開啟SMP一致性(多核協(xié)同工作的關(guān)鍵):

mrsx0, S3_1_c15_c2_1orr x0, x0,#0x40 // 置位 SMPEN 位msr S3_1_c15_c2_1, x0

這一步,就是讓多核CPU從“各自為戰(zhàn)”變成“協(xié)同工作”的基礎(chǔ)。

五、硬件“補丁”:修復(fù)ARM處理器的Errata

哪怕是ARM這樣的巨頭,其處理器也可能存在一些底層bug(行業(yè)內(nèi)叫Errata),這些bug可能導(dǎo)致特定場景下的數(shù)據(jù)不一致、死鎖或性能異常,需要通過固件補丁來修復(fù)。

start.S中的apply_core_errata函數(shù),就是干這個活的,由Kconfig中的CONFIG_ARM_ERRATA_*選項控制,針對Cortex-A57等處理器的經(jīng)典Errata打補?。?/p>

?Errata 828024:關(guān)閉write-back no-allocate的non-allocate hint,避免數(shù)據(jù)緩存異常。

?Errata 826974:關(guān)掉DMB指令前的投機執(zhí)行,防止指令執(zhí)行順序錯亂。

?Errata 833471 / 829520 / 833069:調(diào)整分支預(yù)測器、FPSCR寄存器刷新等行為,提升穩(wěn)定性。

這些看似晦澀的寄存器操作,每一步都是為了讓處理器更穩(wěn)定、更可靠。

六、多核“點名”:主CPU喚醒所有副CPU

完成底層配置后,就到了板級初始化的第一站——lowlevel_init,主要干三件核心事:

1.主CPU初始化GIC中斷控制器(Distributor和CPU Interface),相當(dāng)于給系統(tǒng)“裝中斷管家”。

2.如果開啟了MULTIENTRY(多核啟動),副CPU會先等待主CPU釋放“自旋表”地址,然后切換到對應(yīng)異常級別,等待主CPU調(diào)度。

3.主CPU繼續(xù)執(zhí)行,走向master_cpu標(biāo)號。

這里有個很巧妙的設(shè)計:smp_kick_all_cpus函數(shù)會通過GIC分發(fā)SGI 0號軟中斷,把所有副CPU“踢醒”,讓它們進入U-Boot啟動流程。副CPU則在slave_cpu標(biāo)號下“待命”,一旦檢測到CPU_RELEASE_ADDR非零,就立即跳轉(zhuǎn)執(zhí)行。

這就是U-Boot多核啟動的核心邏輯——主CPU “點名”,副CPU “應(yīng)答”,協(xié)同啟動。

七、終章:跳入C語言世界,奔向_main

當(dāng)所有底層配置、多核喚醒都完成后,主CPU就會執(zhí)行關(guān)鍵的一步,跳入C語言的世界:

master_cpu:  bl _main

至此,start.S的使命就暫告一段落了。

接下來的工作,就交給arch/arm/lib/crt0.S和board_init_f/board_init_r完成:重定位U-Boot代碼、清除BSS段、初始化串口、DRAM(內(nèi)存)、外設(shè),最終才能看到我們熟悉的U-Boot打印信息。

寫在最后

回看這份start.S,它就像一顆經(jīng)過精密雕琢的鉆石——沒有多余的指令,每一個條件編譯、每一次寄存器操作,都是為了把上電時混亂的系統(tǒng)初態(tài),梳理成一個干凈、穩(wěn)定的運行環(huán)境。

它不僅是U-Boot的啟動起點,更是理解整個ARMv8系統(tǒng)啟動流程的“最佳教科書”。

如果你在調(diào)試嵌入式系統(tǒng)時,遇到“卡在啟動早期”“多核不同步”“打開緩存就掛死”等問題,不妨回到這份代碼里找找答案——真正的寶藏,往往就藏在最開始的地方。

最后,留言區(qū)聊聊:你在調(diào)試U-Boot啟動時,遇到過最頭疼的問題是什么?

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • u-boot
    +關(guān)注

    關(guān)注

    0

    文章

    140

    瀏覽量

    39964
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    深度解析?RK?平臺?U-Boot?環(huán)境變量(env):原理、配置與實戰(zhàn)

    環(huán)境變量(env)是?U-Boot?的核心配置機制,無需重新編譯即可靈活調(diào)整啟動參數(shù)。在?Rockchip(RK)平臺上,環(huán)境變量不僅繼承了?U-Boot?的通用特性,還針對?RK?芯片架構(gòu)做了大量
    的頭像 發(fā)表于 04-27 07:11 ?536次閱讀
    深度解析?RK?平臺?<b class='flag-5'>U-Boot</b>?環(huán)境變量(env):原理、配置與實戰(zhàn)

    深度剖析U-Boot ADC Uclass:從架構(gòu)到實戰(zhàn)的全維度解析

    、數(shù)據(jù)流到實戰(zhàn)開發(fā),全方位拆解?U-Boot ADC Uclass?的設(shè)計精髓,幫你吃透這核心子系統(tǒng)。 、架構(gòu)概覽:三層架構(gòu),職責(zé)分明 U-Bo
    的頭像 發(fā)表于 04-26 07:08 ?57次閱讀
    深度剖析<b class='flag-5'>U-Boot</b> ADC Uclass:從架構(gòu)到實戰(zhàn)的全維度解析

    S32G398 u-boot OCOTP 編程保險絲僅在復(fù)位后激活是為什么?

    cmp\' 失敗,但在\'reset\'后成功。 有沒有另種方法可以在同 u-boot 會話中更新 efuse 值?
    發(fā)表于 04-08 06:05

    更新 U-boot 時出現(xiàn)的問題求解

    我在嘗試更新 U-boot 時遇到問題。最初我無法啟動 Fedora,但后來我讀到了這并嘗試更新 U-boot。但是,當(dāng)我按照官方文檔我卡在迷你機屏幕上,什么也做不了。我擔(dān)心董事會來了 DOA......
    發(fā)表于 04-01 07:20

    更新固件后 U-boot 不運行怎么解決?

    該如何修復(fù)它?我正在使用 screen 和 sx 通過 xmodem 對 u-boot 固件進行編程。傳輸完成后,我看到打印了堆點。這正常嗎?xmodem 是否對數(shù)據(jù)進行校驗和以確保正確接收數(shù)據(jù)? 這里有些圖片:
    發(fā)表于 03-25 08:17

    更新 SPL 和 U-Boot的提示和技巧

    U-Boot 和 SPL 文件并將它們加載到 U 盤上 7 連接將 USB 記憶棒連接到 VF2 板并將其安裝在文件夾中 8 更新來自終端的固件 9 驗證使用命令 cat /proc/mtd 并檢查如下
    發(fā)表于 03-20 08:15

    深入解析U-Boot image.c:RK平臺鏡像處理核心邏輯

    的SD/NAND/SPI等啟動方式做了專屬適配。本文將拆解image.c的核心邏輯,梳理RK平臺鏡像處理的關(guān)鍵流程,幫助開發(fā)者理解和調(diào)試啟動相關(guān)問題。 、文件定位與核心作用 image.c是
    的頭像 發(fā)表于 02-24 16:46 ?1853次閱讀
    深入解析<b class='flag-5'>U-Boot</b> image.c:RK平臺鏡像處理核心邏輯

    深入解析RK3588 U-Boot板級文件:evb_rk3588.c核心邏輯拆解

    在嵌入式開發(fā)領(lǐng)域,瑞芯微RK3588憑借超強的算力、豐富的接口和廣泛的場景適配性,成為高端邊緣計算、消費電子項目的熱門選擇。而U-Boot作為嵌入式系統(tǒng)的“第一道門”,負(fù)責(zé)硬件初始化、引導(dǎo)內(nèi)核啟動,其板級適配代碼直接決定了芯片硬件能力的落地。
    的頭像 發(fā)表于 02-24 15:24 ?1003次閱讀
    深入解析RK3588 <b class='flag-5'>U-Boot</b>板級文件:evb_rk3588.c核心邏輯<b class='flag-5'>拆解</b>

    U-Boot SPL核心文件spl.c深度解析:從啟動流程到調(diào)試優(yōu)化

    在嵌入式系統(tǒng)開發(fā)中,U-Boot 的 SPL(Secondary Program Loader)扮演著至關(guān)重要的角色,它是系統(tǒng)上電后執(zhí)行的第一個軟件組件之,負(fù)責(zé)為后續(xù)啟動過程鋪平道路。本文將深入
    的頭像 發(fā)表于 02-05 14:08 ?538次閱讀
    <b class='flag-5'>U-Boot</b> SPL核心文件spl.c深度解析:從啟動流程到調(diào)試優(yōu)化

    深入解析U-Boot TPL代碼:嵌入式啟動的“第一棒”背后的秘密

    在嵌入式系統(tǒng)啟動過程中,從按下電源鍵到操作系統(tǒng)開始運行,中間藏著系列精密的初始化步驟。今天我們就來拆解 Rockchip 平臺 U-Boot 中的 TPL(Tiny Program Loader)階段核心代碼tpl.c,看看這
    的頭像 發(fā)表于 02-05 14:07 ?1320次閱讀
    深入解析<b class='flag-5'>U-Boot</b> TPL代碼:嵌入式啟動的“<b class='flag-5'>第一</b>棒”背后的秘密

    深入解析U-Boot命令處理核心文件:功能、調(diào)試與開發(fā)價值

    在嵌入式系統(tǒng)開發(fā)中,U-Boot 作為主流的引導(dǎo)加載程序,其命令處理、交互邏輯和自動啟動流程是核心功能模塊。本文將圍繞command.c、cli.c和autoboot.c三個關(guān)鍵文件,從核心
    的頭像 發(fā)表于 02-03 15:44 ?1016次閱讀
    深入解析<b class='flag-5'>U-Boot</b>命令處理核心文件:功能、調(diào)試與開發(fā)價值

    深入解析U-Boot核心文件board_f.c:知識點、調(diào)試要點與開發(fā)價值

    在嵌入式系統(tǒng)開發(fā)中,U-Boot 作為應(yīng)用最廣泛的引導(dǎo)程序,其底層初始化邏輯直接決定了硬件啟動的穩(wěn)定性與可靠性。
    的頭像 發(fā)表于 02-03 15:38 ?878次閱讀
    深入解析<b class='flag-5'>U-Boot</b>核心文件board_f.c:知識點、調(diào)試要點與開發(fā)價值

    解析Rockchip平臺U-Boot核心文件:boot_rkimg.c到底做了什么?

    在嵌入式開發(fā)中,U-Boot 作為引導(dǎo)程序的 “中流砥柱”,負(fù)責(zé)初始化硬件、加載內(nèi)核并啟動系統(tǒng)。對于 Rockchip 平臺的設(shè)備(如常見的開發(fā)板、智能終端),boot_rkimg.c 是 U-Boot 中專門處理啟動流程的核心
    的頭像 發(fā)表于 02-03 15:29 ?993次閱讀
    解析Rockchip平臺<b class='flag-5'>U-Boot</b>核心文件:<b class='flag-5'>boot</b>_rkimg.c<b class='flag-5'>到底</b><b class='flag-5'>做了</b>什么?

    深入理解?RK3506 U-Boot?重定位:從代碼到原理

    的啟動代碼,拆解?RK3506?平臺?U-Boot?重定位的實現(xiàn)邏輯、關(guān)鍵步驟與底層原理。 路徑:u-boot/arch/arm/cpu/armv7/start.S 、重定位的
    的頭像 發(fā)表于 11-28 07:05 ?1027次閱讀
    深入理解?RK3506 <b class='flag-5'>U-Boot</b>?重定位:從代碼到原理

    U-Boot 無法識別 NAND怎么解決?

    U-Boot 無法識別 NAND
    發(fā)表于 09-03 06:37
    潢川县| 内江市| 柘荣县| 中牟县| 三穗县| 延川县| 新和县| 武鸣县| 宁城县| 齐齐哈尔市| 潜山县| 新余市| 莱西市| 古田县| 邛崃市| 靖州| 阿巴嘎旗| 安新县| 阳信县| 邢台县| 兴义市| 鄂托克旗| 元阳县| 收藏| 广汉市| 绥阳县| 尖扎县| 洛南县| 夏河县| 武威市| 威信县| 温泉县| 沁水县| 镇江市| 平陆县| 余庆县| 呼伦贝尔市| 灵台县| 奉化市| 沁水县| 鹤峰县|