91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

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

jf_44130326 ? 來源:Linux1024 ? 作者:Linux1024 ? 2025-11-28 07:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式系統(tǒng)中,U-Boot作為引導加載程序,其啟動流程的核心環(huán)節(jié)之一就是重定位(Relocation)。對于RK3506這類基于ARM Cortex-A架構的芯片,重定位的本質是將U-Boot代碼從初始加載地址(通常是片內(nèi)ROM或Flash)復制到運行效率更高的片外RAM,再切換執(zhí)行環(huán)境到RAM中運行。

本文將結合U-Boot源碼中ARM Cortex核心的啟動代碼,拆解RK3506平臺U-Boot重定位的實現(xiàn)邏輯、關鍵步驟與底層原理。

路徑:u-boot/arch/arm/cpu/armv7/start.S

wKgZPGko2kqAGNWAAAck-TkUqlU013.png

一、重定位的核心目的:為何需要“搬家”?

RK3506的U-Boot啟動初期,代碼通常從片內(nèi)BootROMSPI Flash加載到片內(nèi)SRAM(小容量高速內(nèi)存)執(zhí)行。但SRAM容量有限(通常僅幾十KB),無法容納完整的U-Boot鏡像(包含驅動、命令、文件系統(tǒng)等模塊),也無法滿足后續(xù)加載Linux內(nèi)核的需求。

重定位的核心目標:

1.釋放存儲空間:將U-Boot完整鏡像從Flash/SRAM遷移到大容量片外DDR內(nèi)存;

2.提升執(zhí)行效率:DDR內(nèi)存帶寬更高、容量更大,支持U-Boot運行復雜邏輯(如設備初始化、內(nèi)核加載);

3.預留內(nèi)存空間:為Linux內(nèi)核、設備樹等后續(xù)加載的鏡像預留連續(xù)內(nèi)存區(qū)域。

二、重定位的前提:啟動初期的關鍵初始化

在執(zhí)行重定位前,U-Boot必須完成一系列底層初始化,為“搬家”做好準備。結合本文提供的ARM Cortex啟動代碼,這些準備工作主要集中在reset入口函數(shù)中:

1.模式與中斷初始化

reset:  b  save_boot_paramssave_boot_params_ret:  /* 切換到 SVC32 模式,禁用 FIQ/IRQ */  mrs r0, cpsr  and r1, r0,#0x1f    @ 掩碼模式位  teq r1,#0x1a       @ 檢查是否為 HYP 模式  bicne r0, r0,#0x1f    @ 清除模式位  orrne r0, r0,#0x13    @ 設置為 SVC 模式(管理模式)  orr r0, r0,#0xc0     @ 禁用 FIQ (0x80) 和 IRQ (0x40)  msr cpsr, r0

?切換到ARM特權模式(SVC32):確保U-Boot擁有訪問系統(tǒng)寄存器、修改內(nèi)存配置的權限;

?禁用中斷:避免初始化過程中被外部中斷打斷,導致系統(tǒng)異常。

2.向量表初始化

/* 設置 VBAR 寄存器,指向 U-Boot 向量表 */ldr r0, =_startmcr p15,0, r0, c12, c0,0 @ 寫入VBAR(向量表基地址寄存器)

?ARMv7架構通過VBAR寄存器指定異常向量表地址;

?重定位前,向量表位于初始加載地址(如SRAM),后續(xù)重定位后需確保向量表地址同步更新(由鏈接腳本配合處理)。

3.緩存與MMU初始化(cpu_init_cp15

重定位前需禁用MMU(內(nèi)存管理單元)和緩存,避免地址映射干擾內(nèi)存復制:

ENTRY(cpu_init_cp15) /* invalidate L1 I/D 緩存、TLB */  mov r0,#0  mcr p15,0, r0, c8, c7,0 @ invalidate TLBs  mcr p15,0, r0, c7, c5,0 @ invalidate I-cache /* 禁用 MMU、緩存相關配置 */  mrc p15,0, r0, c1, c0,0  bic r0, r0,#0x00002000  @ 清除 V 位(向量表地址偏移)  bic r0, r0,#0x00000007  @ 清除 CAM 位(緩存相關)  orr r0, r0,#0x00000800  @ 啟用 BTB(分支預測)#ifdef CONFIG_SYS_ICACHE_OFF  bic r0, r0,#0x00001000  @ 禁用 I-cache#else  orr r0, r0,#0x00001000  @ 啟用 I-cache(重定位后生效)#endif  mcr p15,0, r0, c1, c0,0

?初始化CP15寄存器(ARM系統(tǒng)控制寄存器),清空緩存和TLB(地址轉換緩存);

?禁用MMU:此時CPU訪問的是物理地址,確保內(nèi)存復制過程中地址無映射偏差;

?按需啟用I-cache(指令緩存):重定位后代碼在DDR中運行時,緩存可提升執(zhí)行效率。

4.板級底層初始化(cpu_init_crit

ENTRY(cpu_init_crit) b lowlevel_init    @ 跳轉到板級初始化ENDPROC(cpu_init_crit)

?lowlevel_init是RK3506平臺的板級初始化函數(shù)(由瑞芯微適配);

?核心任務:初始化DDR內(nèi)存控制器、配置PLL時鐘(提升DDR帶寬)、初始化SPI Flash等外設;

?關鍵:只有完成DDR初始化,U-Boot才能將自身復制到DDR中,這是重定位的硬件基礎。

三、重定位的核心實現(xiàn):_main函數(shù)的“搬家”邏輯

當?shù)讓映跏蓟ㄓ绕涫荄DR初始化)完成后,代碼通過bl _main跳轉到U-Boot核心初始化流程,重定位的核心邏輯就在_main函數(shù)中(位于common/main.c)。

結合RK3506的平臺特性,_main函數(shù)中重定位的關鍵步驟如下:

1.確定重定位地址(鏈接腳本定義)

U-Boot的重定位目標地址由鏈接腳本(如arch/arm/cpu/armv7/rk3506/u-boot.lds)定義,核心符號:

?_start:U-Boot初始加載地址(SRAM或Flash地址);

?__image_copy_start:鏡像復制起始地址(初始加載地址的代碼段起始);

?__image_copy_end:鏡像復制結束地址;

?__bss_start/__bss_end:BSS段起始/結束地址(重定位后需清零);

?CONFIG_SYS_TEXT_BASE:重定位目標地址(RK3506通常配置為DDR起始地址,如0x80000000)。

2.內(nèi)存復制:從初始地址到DDR

重定位的核心操作是逐字節(jié)復制U-Boot鏡像到DDR目標地址,代碼邏輯簡化如下:

// 簡化自 common/main.cvoid_main(void) { // 1. 獲取鏈接腳本定義的地址符號 externulong__image_copy_start, __image_copy_end; externulong__bss_start, __bss_end; ulongdst = CONFIG_SYS_TEXT_BASE; // 重定位目標地址(DDR) ulongsrc = (ulong)&__image_copy_start; // 源地址(SRAM/Flash) // 2. 只有當源地址 != 目標地址時,才需要復制(避免自身覆蓋) if(src != dst) {    memcpy((void*)dst, (void*)src, &__image_copy_end - &__image_copy_start);  } // 3. 清零 BSS 段(未初始化全局變量)  memset((void*)&__bss_start,0, &__bss_end - &__bss_start); // 4. 跳轉到 DDR 中的 U-Boot 繼續(xù)執(zhí)行  board_init_f_r_trampoline(dst);}

?復制范圍:從__image_copy_start到__image_copy_end,包含代碼段(.text)、數(shù)據(jù)段(.data)等已初始化部分;

?避免自身覆蓋:若源地址與目標地址重疊(如部分SRAM與DDR地址重疊),U-Boot會先復制不重疊部分,再處理重疊區(qū)域,防止復制過程中覆蓋未復制的代碼;

?BSS段清零:BSS段存儲未初始化全局變量,C語言標準要求其初始值為0,因此重定位后需手動清零。

3.跳轉至DDR執(zhí)行:地址切換

復制完成后,通過board_init_f_r_trampoline函數(shù)跳轉到DDR中的U-Boot代碼繼續(xù)執(zhí)行。此時CPU執(zhí)行的指令已從DDR讀取,重定位完成。

4.棧指針更新

重定位后,棧指針(SP)也需更新到DDR中的安全地址(避免使用SRAM棧導致溢出),由board_init_f函數(shù)初始化:

// 簡化自 common/board_f.cvoidboard_init_f(ulongboot_flags){ ulongsp = CONFIG_SYS_INIT_SP_ADDR; // DDR 中的棧地址  sp -=sizeof(structglobal_data); // 預留全局數(shù)據(jù)結構空間  gd = (structglobal_data *)sp;  memset(gd,0,sizeof(structglobal_data)); // 初始化棧指針 asmvolatile("mov sp, %0": :"r"(sp) : "memory"); // 后續(xù)初始化:設備樹加載、命令初始化、內(nèi)核引導等}

?CONFIG_SYS_INIT_SP_ADDR:RK3506配置為DDR中的一段連續(xù)地址,確保??臻g足夠;

?global_data:U-Boot全局數(shù)據(jù)結構,存儲系統(tǒng)狀態(tài)(如內(nèi)存布局、設備信息),重定位后需在DDR中重新初始化。

四、重定位后的關鍵處理

1.向量表同步更新

重定位后,向量表地址需同步更新到DDR中的新地址,避免異常處理時跳轉到舊地址(SRAM/Flash)。由于之前已通過VBAR寄存器設置向量表基地址為_start,而_start在重定位后指向DDR地址,因此無需額外修改(鏈接腳本確保_start對應DDR目標地址)。

2.緩存重新配置

重定位完成后,U-Boot會重新啟用I-cache/D-cache(若配置),提升執(zhí)行效率。此時MMU仍處于禁用狀態(tài)(直到Linux內(nèi)核啟動時啟用),CPU直接訪問DDR物理地址。

3.避免重定位后的地址錯誤

?所有全局變量、函數(shù)指針均使用位置無關代碼(PIC)編譯,確保重定位后地址正確映射;

?鏈接腳本通過TEXT_BASE強制指定目標地址,確保復制后的鏡像在DDR中地址對齊。

五、RK3506重定位的特殊注意事項

1.DDR初始化優(yōu)先級:RK3506的DDR控制器初始化是重定位的前提,需通過lowlevel_init配置DDR時序、電壓,確保DDR穩(wěn)定工作;

2.Flash訪問兼容性:若初始加載地址為SPI Flash(如0x10000000),復制時需通過RK3506的SPI控制器驅動讀取Flash數(shù)據(jù),再寫入DDR;

3.內(nèi)存布局優(yōu)化:RK3506的DDR起始地址通常為0x80000000,U-Boot重定位后,會在DDR中預留后續(xù)加載Linux內(nèi)核(如0x80200000)和設備樹(如0x80100000)的空間,避免地址沖突。

六、總結:重定位的完整流程

RK3506 U-Boot重定位的核心是“初始化硬件→復制鏡像→切換執(zhí)行環(huán)境”,完整流程可概括為:

1.復位入口(reset):切換SVC模式、禁用中斷、初始化向量表;

2.底層初始化:初始化CP15寄存器(緩存/ MMU)、板級硬件(DDR/PLL);

3.確定地址:通過鏈接腳本獲取源地址、目標地址(DDR);

4.鏡像復制:memcpy復制代碼段/數(shù)據(jù)段到DDR,清零BSS段;

5.切換執(zhí)行:更新棧指針,跳轉到DDR中的U-Boot繼續(xù)執(zhí)行;

6.后續(xù)初始化:加載設備樹、初始化外設、引導Linux內(nèi)核。

重定位是U-Boot從“小容量初始環(huán)境”到“大容量運行環(huán)境”的關鍵一步,理解其原理不僅能幫助排查啟動故障(如DDR初始化失敗導致重定位失?。?,也能為定制化U-Boot(如調(diào)整內(nèi)存布局、優(yōu)化啟動速度)提供基礎。

對于RK3506開發(fā)者,建議結合鏈接腳本和lowlevel_init代碼,重點關注CONFIG_SYS_TEXT_BASE和DDR初始化參數(shù),確保重定位地址與硬件配置一致。

審核編輯 黃宇

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

    關注

    0

    文章

    135

    瀏覽量

    39738
  • RK3506
    +關注

    關注

    0

    文章

    94

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

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

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

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

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

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

    知識點、調(diào)試關注點和開發(fā)意義三方面展開分析,并通過流程圖展示它們的協(xié)作機制,幫助開發(fā)者深入理解 U-Boot 的命令系統(tǒng)。
    的頭像 發(fā)表于 02-03 15:44 ?871次閱讀
    <b class='flag-5'>深入</b>解析<b class='flag-5'>U-Boot</b>命令處理核心文件:功能、調(diào)試與開發(fā)價值

    深入解析rk平臺Android Bootloader核心代碼啟動流程AVB驗證

    下android_bootloader.c的核心代碼,帶你讀懂Android設備Bootloader內(nèi)核的完整啟動邏輯,以及開發(fā)者關注這些代碼的核心價值。 一、
    的頭像 發(fā)表于 01-22 07:06 ?237次閱讀
    <b class='flag-5'>深入</b>解析<b class='flag-5'>rk</b>平臺Android Bootloader核心<b class='flag-5'>代碼</b>:<b class='flag-5'>從</b>啟動流程<b class='flag-5'>到</b>AVB驗證

    RK3506 MIPI轉HDMI顯示開發(fā)實戰(zhàn):硬件驅動全解析

    0 入門 Linux 嵌入式開發(fā)!RK3506 開發(fā)板實戰(zhàn)教程系列開篇 在嵌入式設備開發(fā)中,MIPI DSI接口(移動行業(yè)處理器接口)廣泛用于連接LCD屏,而HDMI則是高清顯示輸出的主流標準
    的頭像 發(fā)表于 01-06 07:09 ?521次閱讀
    <b class='flag-5'>RK3506</b> MIPI轉HDMI顯示開發(fā)實戰(zhàn):<b class='flag-5'>從</b>硬件<b class='flag-5'>到</b>驅動全解析

    技術分享 | RK3506如何交叉編譯frp wireguard

    RK3506擁有著不錯的性價比以及與之相匹配的性能優(yōu)勢,非常適合用來做邊緣計算網(wǎng)關、小型數(shù)據(jù)收集端點等。今天給大家?guī)韮煽顑?nèi)網(wǎng)穿透工具的交叉編譯移植,方便在RK3506上搭建相關應用。在編譯兩個工具
    的頭像 發(fā)表于 12-25 17:29 ?576次閱讀
    技術分享 | <b class='flag-5'>RK3506</b>如何交叉編譯frp wireguard

    米爾RK3506核心板SDK重磅升級,解鎖三核A7實時控制新架構

    在工業(yè)控制與邊緣智能領域,開發(fā)者的核心需求始終明確:在可控的成本內(nèi),實現(xiàn)可靠的實時響應、穩(wěn)定的通信與高效的開發(fā)部署。米爾電子基于RK3506處理器打造的MYC-YR3506核心板平臺,近期完成了一次
    發(fā)表于 12-19 20:35

    如何讓RK3506流暢刷圖,用好RGA?

    本文基于觸覺智能RK3506核心板/開發(fā)板,介紹RGAIM2D進行圖像處理,包括相關編譯與測試方法。
    的頭像 發(fā)表于 10-29 10:00 ?1059次閱讀
    如何讓<b class='flag-5'>RK3506</b>流暢刷圖,用好RGA?

    RK3506開發(fā)板Linux開發(fā)板極致性價比之選

    RK3506開發(fā)板Linux開發(fā)板極致性價比之選瑞芯微RK3506開發(fā)板,3核Cortex-A7@1.5GHz+Cortex-M0,Linux+RT-Thread系統(tǒng)支持,128MB超大
    的頭像 發(fā)表于 09-11 16:26 ?3440次閱讀
    <b class='flag-5'>RK3506</b>開發(fā)板Linux開發(fā)板極致性價比之選

    【米爾RK3506國產(chǎn)開發(fā)板評測試用】開箱體體驗

    很高興今天收到了米爾科技的RK3506開發(fā)板,下面是開箱體驗,后期的測試使用中將會做詳細的測試和試用。 1.開箱,包含以下: RK3506開發(fā)板1 USB_TYPEC1 10Pin連接端子1 快速
    發(fā)表于 07-30 01:06

    有獎丨米爾 瑞芯微RK3506開發(fā)板免費試用來啦!

    米爾與瑞芯微合作發(fā)布的新品基于瑞芯微RK3506應用處理器的MYD-YR3506開發(fā)板免費試用名額增加啦
    的頭像 發(fā)表于 07-10 08:03 ?890次閱讀
    有獎丨米爾 瑞芯微<b class='flag-5'>RK3506</b>開發(fā)板免費試用來啦!

    瑞芯微RK3506 vs NXP i.MX6ULL

    在關鍵技術國產(chǎn)化浪潮中,國產(chǎn)芯片正以更高性能、更優(yōu)成本及自主可控優(yōu)勢實現(xiàn)對海外方案的成功替代。今天觸覺智能拿出自家新品瑞芯微RK3506核心板(IDO-SOM3506-S1),與線上某款熱銷
    的頭像 發(fā)表于 06-19 16:26 ?1232次閱讀
    瑞芯微<b class='flag-5'>RK3506</b> vs NXP i.MX6ULL

    米爾瑞芯微多核異構低功耗RK3506核心板重磅發(fā)布

    近日,米爾電子發(fā)布MYC-YR3506核心板和開發(fā)板,基于國產(chǎn)新一代入門級工業(yè)處理器瑞芯微RK3506,這款芯片采用三核Cortex-A7+單核Cortex-M0多核異構設計,不僅擁有豐富的工業(yè)接口
    發(fā)表于 05-16 17:20

    觸覺智能RK3506核心板,工業(yè)應用之RK3506 RT-Linux實時性測試

    觸覺智能RK3506核心板,工業(yè)應用方案分享之RT-Linux實時性測試
    的頭像 發(fā)表于 04-27 19:27 ?1928次閱讀
    觸覺智能<b class='flag-5'>RK3506</b>核心板,工業(yè)應用之<b class='flag-5'>RK3506</b> RT-Linux實時性測試

    如何用RK3506核心板自研一款嵌入式工業(yè)網(wǎng)關?

    飛凌嵌入式RK3506核心板做工業(yè)網(wǎng)關
    的頭像 發(fā)表于 03-19 16:32 ?2077次閱讀
    如何用<b class='flag-5'>RK3506</b>核心板自研一款嵌入式工業(yè)網(wǎng)關?