那曲檬骨新材料有限公司

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

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

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

uboot開啟地址無關(guān)后的重定位地址操作

麥辣雞腿堡 ? 來源:CSDN博客 ? 作者:內(nèi)核新視界 ? 2023-12-07 11:25 ? 次閱讀

開啟地址無關(guān)后的重定位地址操作

在由save_boot_params跳轉(zhuǎn)回save_boot_params_ret后啟動流程繼續(xù)往下執(zhí)行來到下面代碼段:

save_boot_params_ret:

#if CONFIG_POSITION_INDEPENDENT
    /* Verify that we're 4K aligned.  */
    adr x0, _start
    ands x0, x0, #0xfff --------------------------------------------------------- (1)
    b.eq 1f
0:
    /*
     * FATAL, can't continue.
     * U-Boot needs to be loaded at a 4K aligned address.
     *
     * We use ADRP and ADD to load some symbol addresses during startup.
     * The ADD uses an absolute (non pc-relative) lo12 relocation
     * thus requiring 4K alignment.
     */
    wfi
    b 0b
1:

    /*
     * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
     * executed at a different address than it was linked at.
     */
pie_fixup:
    adr x0, _start  /* x0 < - Runtime value of _start */
    ldr x1, _TEXT_BASE  /* x1 < - Linked value of _start */
    subs x9, x0, x1  /* x9 < - Run-vs-link offset */
    beq pie_fixup_done ------------------------------------------------------------- (2)
    adrp    x2, __rel_dyn_start     /* x2 < - Runtime &__rel_dyn_start */ ----------- (3)
    add     x2, x2, #:lo12:__rel_dyn_start
    adrp    x3, __rel_dyn_end       /* x3 < - Runtime &__rel_dyn_end */
    add     x3, x3, #:lo12:__rel_dyn_end
pie_fix_loop: ---------------------------------------------------------------------- (4)
    ldp x0, x1, [x2], #16 /* (x0, x1) < - (Link location, fixup) */
    ldr x4, [x2], #8  /* x4 < - addend */
    cmp w1, #1027  /* relative fixup? */
    bne pie_skip_reloc
    /* relative fix: store addend plus offset at dest location */
    add x0, x0, x9
    add x4, x4, x9
    str x4, [x0]
pie_skip_reloc:
    cmp x2, x3
    b.lo pie_fix_loop
pie_fixup_done:
#endif

此部分的功能主要是在定義POSITION_INDEPENDENT后,進(jìn)行地址無關(guān)的相對地址修復(fù),以此保證后續(xù)在跳入c語言部分時可正常執(zhí)行,一般不定義此配置則是繼續(xù)往下執(zhí)行boot流程。

  • ? (1)正如在鏈接腳本中說的,地址無關(guān)功能最基本需要保證加載地址是4K對齊的,經(jīng)過一些測試發(fā)現(xiàn)某些情況需要64K對齊,這里不展開說明。此處使用adr指令獲取_start的運(yùn)行時地址并檢驗(yàn)是否是4K對齊,如果是則繼續(xù)往下執(zhí)行,如果不是則調(diào)用wfi指令掛死在此處。wfi為等待中斷指令,只有在接收到中斷事件是才會喚醒cpu繼續(xù)往下執(zhí)行。(補(bǔ)充一個知識點(diǎn):wfi指令只能被中斷喚醒,wfe指令可以被sev指令喚醒也可以被中斷喚醒)
  • ? (2)通過對運(yùn)行時地址和加載地址相減得到一個地址偏移值,如果偏移值等于0,說明加載地址和運(yùn)行時地址是一致的不需要進(jìn)行地址修復(fù),則直接跳pie_fixup_done繼續(xù)下面流程初始化,否則就進(jìn)入地址修復(fù)邏輯。
  • ? (3)首先需要說明為什么不使用adr指令而是adrp指令,adr指令是一個小范圍讀相對pc指針地址內(nèi)存的指令,可以使用adr說明讀取的地址一定是離pc指針很近的位置,而當(dāng)讀取__rel_dyn_start這種并不能確定實(shí)際地址在哪里的地址時則只能使用大范圍讀地址指令的adrp指令,不過adrp指令是以頁為單位進(jìn)行讀取的,所以add x2, x2, #:lo12:__rel_dyn_start的作用就是將__rel_dyn_start地址的頁內(nèi)偏移讀取出來并與頁對齊的運(yùn)行地址相加得到實(shí)際的運(yùn)行地址。(此操作指令在Linux上被封裝為adr_l指令)
  • ? (4)在對地址修復(fù)分析時,首先需要了解一個elf動態(tài)庫重定位的知識點(diǎn),先來看一個結(jié)構(gòu)體定義:
typedef struct {
        Elf64_Addr      r_offset;
        Elf64_Xword     r_info;
        Elf64_Sxword    r_addend;
} Elf64_Rela;

當(dāng)對動態(tài)庫進(jìn)行地址重定向時首先會去查找rela.dyn段中的信息,此段中每一組信息就是上面結(jié)構(gòu)體定義的信息,對于64為系統(tǒng)的elf則是24字節(jié)為一個表,r_offset保存需要重定位作用的地址位置,r_info描述此表重定位類型此類型特定于處理器,如arm64位則是:

/* AArch64 relocs */
#define R_AARCH64_NONE  0 /* No relocation */
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base */

r_addend是一個常量加數(shù),用于計(jì)算存儲在可重定位字段中的值。 對表進(jìn)行重定位有以下公式:

重定位為值 = *(r_offset + 實(shí)際偏移值) = 實(shí)際偏移值 + r_addend。

根據(jù)此公式則可以重定向每一個需要重定向的地址值。

因此在此處同樣是如此,x0保存r_offset值,x1保存r_info值,x4保存r_addend,并通過x1與R_AARCH64_RELATIVE比較看是否屬于aarch64相對地址類型,如果不是則不是需要重定向的一組表則跳到pie_skip_reloc判斷是否完成所有rela.dyn段重定向,如果是則繼續(xù)往下執(zhí)行啟動流程初始化,如果不是則跳回pie_fix_loop繼續(xù)下一組表的重定向。

當(dāng)判斷屬于aarch64相對地址類型時進(jìn)入重定向邏輯,首先需要知道x9是運(yùn)行地址減去鏈接地址得到的偏移地址,那么實(shí)際運(yùn)行地址也等于鏈接地址加上x9,所以add x0, x0, x9,add x4, x4, x9,x0是需要修復(fù)的重定位運(yùn)行地址,x4是實(shí)際運(yùn)行時需要附加的常量值,根據(jù)上面的公式,將x4這個由附加常量值加偏移值得到的運(yùn)行時附加常量值寫入到x0這個運(yùn)行時重定向地址即可完成整個重定向修復(fù)功能。

此處沒有實(shí)際代碼或者流程圖展示,邏輯比較繞,大致邏輯就是根據(jù)重定向段中每24個字節(jié)組成的一個表讀取出實(shí)際需要進(jìn)行重定向的地址,將這個地址的運(yùn)行地址找出來并往這個地址寫入附加常量值加偏移值即可完成一次重定向。在完成段中所有重定向后此時地址已經(jīng)被修復(fù)好了,后續(xù)調(diào)用任何絕對地址引用的指令也不會出問題了。當(dāng)然這個操作是耗時的,一般也不會有board會開啟此功能。

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

    關(guān)注

    134

    文章

    9169

    瀏覽量

    369247
  • Uboot
    +關(guān)注

    關(guān)注

    4

    文章

    125

    瀏覽量

    28350
  • ARMv8
    +關(guān)注

    關(guān)注

    1

    文章

    35

    瀏覽量

    14195
收藏 人收藏

    評論

    相關(guān)推薦

    操作系統(tǒng)中的邏輯地址和物理地址

    本文是關(guān)于操作系統(tǒng)中邏輯地址和物理地址之間的區(qū)別。計(jì)算機(jī)操作系統(tǒng)中的內(nèi)存使用兩種不同類型的地址;物理地址
    發(fā)表于 09-14 14:26 ?4143次閱讀

    uboot定位與搬移地址沖突

    是在板子目錄下的config.mk中定義的,也就是說程序在sdram中的運(yùn)行地址應(yīng)該就是CONFIG_SYS_TEXT_BASE中指定的數(shù)字,但board_init_f程序執(zhí)行的搬移地址
    發(fā)表于 07-08 05:45

    定位與鏈接腳本的使用方法

    嵌入式知識-ARM裸機(jī)-學(xué)習(xí)筆記(4):定位與鏈接腳本的使用一、定位1. 一些基本概念的引入位置有關(guān)編碼: 匯編源碼編碼成二進(jìn)制可執(zhí)行程序
    發(fā)表于 12-23 07:12

    ARM裸機(jī)篇(三)——定位地址無關(guān)

    1、ARM定位地址無關(guān)碼在上一節(jié)中,我們將第一個裸機(jī)程序編譯,然后將映像文件
    發(fā)表于 04-15 17:56

    ARM裸機(jī)定位的目的是什么?如何實(shí)現(xiàn)

    腳本中加入AT()來指定加載地址,以防止編譯出的代碼過大。 鏈接腳本中,指定程序運(yùn)行地址位于SDRAM,上電從片內(nèi)0地址開始運(yùn)行,所以
    發(fā)表于 05-16 14:32

    ARM為什么需要定位?如何去實(shí)現(xiàn)呢

    的// 匯編最后的這個死循環(huán)不能丟 b . 總結(jié):由上面我們可以看到:定位的時候,先使用一段位置無關(guān)碼來對重定位地址那里的內(nèi)存進(jìn)行一些
    發(fā)表于 05-18 16:42

    IP地址及網(wǎng)卡MAC地址操作指南

      為便于各分公司及部門統(tǒng)計(jì)IP地址及網(wǎng)卡MAC地址,請按照以下步驟操作:   1、 點(diǎn)擊“開始”,選擇運(yùn)行。   2、在“運(yùn)行”中輸入“cmd”,并點(diǎn)擊
    發(fā)表于 09-03 16:12 ?0次下載

    IP地址,IP地址是什么意思

    IP地址,IP地址是什么意思 基本定義 IP地址都是一個十分要的概念,INTERNET的許多服務(wù)和特點(diǎn)都是通過IP地址體現(xiàn)出來的。
    發(fā)表于 04-03 15:12 ?1684次閱讀

    ATM地址,ATM地址是什么意思

    ATM地址,ATM地址是什么意思 異 步傳輸模式(ATM)使用地址來確定和定位ATM設(shè)備。在ATM中,地址是呼叫建立過程中通過UNI信令確
    發(fā)表于 04-06 16:00 ?1535次閱讀

    stm32位帶操作及內(nèi)存地址

    位待操作地址STM32地址地址、總線地址、寄存器地址是什么基
    發(fā)表于 01-12 18:21 ?1次下載
    stm32位帶<b class='flag-5'>操作</b>及內(nèi)存<b class='flag-5'>地址</b>

    伺服定位時如何切換定位地址

    在使用伺服的定位功能是,通常會有多個不同的定位地址,常用的處理方法是只寫一個定位指令,然后把地址數(shù)據(jù)做成參數(shù),每次要用時先傳輸
    的頭像 發(fā)表于 05-23 10:03 ?1025次閱讀
    伺服<b class='flag-5'>定位</b>時如何切換<b class='flag-5'>定位</b><b class='flag-5'>地址</b>?

    虛擬地址翻譯物理地址的流程有哪些呢?

    現(xiàn)代的操作系統(tǒng)將可執(zhí)行文件加載,創(chuàng)建了進(jìn)程,進(jìn)程中每一條指令和數(shù)據(jù)都被分配了一個虛擬地址,CPU獲取到這個虛擬地址,需要翻譯成內(nèi)存的物理
    的頭像 發(fā)表于 08-14 10:30 ?1379次閱讀
    虛擬<b class='flag-5'>地址</b>翻譯物理<b class='flag-5'>地址</b>的流程有哪些呢?

    RA Flash地址絕對定位

    RA Flash地址絕對定位
    的頭像 發(fā)表于 10-26 18:24 ?867次閱讀
    RA Flash<b class='flag-5'>地址</b>絕對<b class='flag-5'>定位</b>

    IP地址定位與GPS定位:技術(shù)解析與應(yīng)用比較

    IP地址定位和GPS定位是比較常見的定位技術(shù)。本文將與大家探討這兩種技術(shù)的工作原理、優(yōu)缺點(diǎn)及其在實(shí)際應(yīng)用中的比較和融合。 IP地址
    的頭像 發(fā)表于 07-16 13:50 ?688次閱讀

    MAC地址的作用范圍,MAC地址怎么申請?

    物理地址(PhysicalAddress),用于在網(wǎng)絡(luò)中唯一標(biāo)示一個網(wǎng)卡。以下是英利檢測針對其作用范圍及申請方式的詳細(xì)解答:MAC地址的作用范圍局域網(wǎng)內(nèi)的設(shè)備定位
    的頭像 發(fā)表于 12-19 17:44 ?648次閱讀
    MAC<b class='flag-5'>地址</b>的作用范圍,MAC<b class='flag-5'>地址</b>怎么申請?
    百家乐官网详解| 百家乐投注平台导航网| 大赢家即时比分| 百家乐筹码方形筹码| 超级百家乐官网2龙虎斗| 二八杠语音报牌器| 百家乐官网园有限公司| 澳门百家乐官网游戏说明| 太阳城娱乐城下载| 百家乐凯时娱乐网| 运城百家乐官网的玩法技巧和规则| 搏天堂| 威尼斯人娱乐棋牌是真的吗| 百家乐庄闲和概率| 网上百家乐官网作弊法| 奔驰百家乐官网可信吗| 现金游戏网| 威尼斯人娱乐城网址多少| 百家乐单机版游戏下载| 坐乾向巽24山向择吉| 娱乐城百家乐规则| 吕百家乐官网赢钱律| 百家乐官网技巧微笑心法| 百家乐官网庄闲规则| 百家乐筹码| 大发888娱乐在线客服| 百家乐怎么玩请指教| 百家乐讲坛汉献| 澳门百家乐官网打法精华| 保德县| 韩城市| 澳门博彩公司| 沙龙百家乐代理| 威尼斯人娱乐789399| 威尼斯人娱乐城吃饭| 怎么看百家乐的路| 百家乐网上投注文章| 网上百家乐导航| 最新百家乐双面数字筹码| 百家乐庄闲和的倍数| 广发百家乐的玩法技巧和规则|