在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

3天內不再提示

u-boot armv8鏈接腳本

麥辣雞腿堡 ? 來源:CSDN博客 ? 作者:內核新視界 ? 2023-12-07 11:19 ? 次閱讀

u-boot armv8鏈接腳本

在進行源碼分析之前,首先看看u-boot的鏈接腳本,通過鏈接腳本可以從整體了解一個u-boot的組成,并且可以在啟動分析中知道某些邏輯是在完成什么工作。

在armv8中,u-boot使用arch/arm/cpu/armv8/u-boot.lds進行鏈接。

u-boot-spl和u-boot-tpl使用arch/arm/cpu/armv8/u-boot-spl.lds進行鏈接,因為每個board的情況可能不同,所以u-boot可以通過Kconfig來自定義u-boot-spl.lds和u-boot-tpl.lds。

4.1 u-boot.lds

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * (C) Copyright 2013
 * David Feng < fenghua@phytium.com.cn >
 *
 * (C) Copyright 2002
 * Gary Jennejohn, DENX Software Engineering, < garyj@denx.de >
 */

#include < config.h >
#include < asm/psci.h >

OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start) -------------------------------------------------------------------- (1)
/*
 *(1)首先定義了二進制程序的輸出格式為"elf64-littleaarch64",
 *    架構是"aarch64",程序入口為"_start"符號;
 */
SECTIONS
{
#ifdef CONFIG_ARMV8_SECURE_BASE -------------------------------------------------- (2)
/*
 *(2)ARMV8_SECURE_BASE是u-boot對PSCI的支持,在定義時可以將PSCI的文本段,
 *    數據段,堆棧段重定向到指定的內存,而不是內嵌到u-boot中。
 *    不過一般廠商實現會使用atf方式使其與bootloader分離,這個功能不常用;
 */
 /DISCARD/ : { *(.rela._secure*) }
#endif
 . = 0x00000000; -------------------------------------------------------------- (3)
/*
 *(3)定義了程序鏈接的基地址,默認是0,通過配置CONFIG_SYS_TEXT_BASE可修改
 *    這個默認值。
 */
 . = ALIGN(8);
 .text :
 {
  *(.__image_copy_start) --------------------------------------------------- (4)
/*
 *(4)__image_copy_start和__image_copy_end用于定義需要重定向的段,
 *    u-boot是一個分為重定向前初始化和重定向后初始化的bootloader,
 *    所以此處會定義在完成重定向前初始化后需要搬運到ddr中數據的起始地址和結束地址;
 *
 *    大多數時候u-boot是運行在受限的sram或者只讀的flash上,
 *    u-boot為了啟動流程統一會在ddr未初始化和重定位之前不去訪問全局變量,
 *    但是又為了保證u-boot能夠正常讀寫全局變量,內存,調用各類驅動能力,
 *    所以u-boot將啟動初始化分為了兩個部分,重定向前初始化board_f和
 *    重定向后初始化  board_r,在重定向之前完成一些必要初始化,
 *    包括可能的ddr初始化,然后通過__image_copy_start和__image_copy_end
 *    將u-boot搬運到ddr中,并在ddr中進行重定向后初始化,這個時候的u-boot就可以
 *    正常訪問全局變量等信息了。
 * 
 *    如果想要在board_f過程中讀寫一些全局變量信息該怎么辦呢?
 *    u-boot通過定義global_data(gd)來完成此功能,
 *    后續在分析到時會詳細講解實現方式。
 */
  CPUDIR/start.o (.text*) -------------------------------------------------- (5)
/*
 *(5)定義了鏈接程序的頭部文本段,armv8就是
 *    arch/arm/cpu/armv8/start.S, 
 *    start.S中所有文本段將會鏈接到此段中并且段入口符號就是_start;
 */
 }

 /* This needs to come before *(.text*) */
 .efi_runtime : { ------------------------------------------------------------ (6)
/*
 *(6)在定義了efi運行時相關支持時才會出現使用的段,一般不用關心;
 */
        __efi_runtime_start = .;
  *(.text.efi_runtime*)
  *(.rodata.efi_runtime*)
  *(.data.efi_runtime*)
        __efi_runtime_stop = .;
 }

 .text_rest : ---------------------------------------------------------------- (7)
/*
 *(7)除了start.o,其他的所有文本段將會鏈接到此段中;
 */
 {
  *(.text*)
 }

#ifdef CONFIG_ARMV8_PSCI -------------------------------------------------------- (8)
/*
 *(8)同(2),是PSCI相關功能的支持,一般不會使用;
 */
 .__secure_start :
#ifndef CONFIG_ARMV8_SECURE_BASE
  ALIGN(CONSTANT(COMMONPAGESIZE))
#endif
 {
  KEEP(*(.__secure_start))
 }

#ifndef CONFIG_ARMV8_SECURE_BASE
#define CONFIG_ARMV8_SECURE_BASE
#define __ARMV8_PSCI_STACK_IN_RAM
#endif
 .secure_text CONFIG_ARMV8_SECURE_BASE :
  AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
 {
  *(._secure.text)
  . = ALIGN(8);
  __secure_svc_tbl_start = .;
  KEEP(*(._secure_svc_tbl_entries))
  __secure_svc_tbl_end = .;
 }

 .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
 {
  *(._secure.data)
 }

 .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
       CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
#ifdef __ARMV8_PSCI_STACK_IN_RAM
  AT(ADDR(.secure_stack))
#else
  AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
#endif
 {
  KEEP(*(.__secure_stack_start))

  . = . + CONFIG_ARMV8_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;

  . = ALIGN(CONSTANT(COMMONPAGESIZE));

  KEEP(*(.__secure_stack_end))
 }

#ifndef __ARMV8_PSCI_STACK_IN_RAM
 . = LOADADDR(.secure_stack);
#endif

 .__secure_end : AT(ADDR(.__secure_end)) {
  KEEP(*(.__secure_end))
  LONG(0x1d1071c); /* Must output something to reset LMA */
 }
#endif

 . = ALIGN(8);
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } ------------------- (9)
/*
 *(9)所有僅讀數據將會在這個段中對齊排序存放好;
 */

 . = ALIGN(8);
 .data : { -------------------------------------------------------------------- (10)
/*
 *(10)所有數據段將會鏈接到此段中;
 */
  *(.data*)
 }

 . = ALIGN(8);

 . = .;

 . = ALIGN(8);
 .u_boot_list : { ------------------------------------------------------------- (11)
/*
 *(11)u_boot_list段定義了系統中當前支持的所有命令和設備驅動,此段把散落在各個文件中
 *     通過U_BOOT_CMD的一系列拓展宏定義的命令和U_BOOT_DRIVER的拓展宏定義的設備驅動收集到一起,
 *     并按照名字排序存放,以便后續在命令行快速檢索到命令并執行和檢測注冊的設備和設備樹匹配
 *     probe設備驅動初始化;(設備驅動的probe只在定義了dm模塊化驅動時有效)
 */
  KEEP(*(SORT(.u_boot_list*)));
 }

 . = ALIGN(8);

 .efi_runtime_rel : {
                __efi_runtime_rel_start = .;
  *(.rel*.efi_runtime)
  *(.rel*.efi_runtime.*)
                __efi_runtime_rel_stop = .;
 }

 . = ALIGN(8);

 .image_copy_end :
 {
  *(.__image_copy_end)
 }

 . = ALIGN(8);

 .rel_dyn_start : -------------------------------------------------------- (12)
/*
 *(12)一般u-boot運行時是根據定義的基地址開始執行,如果加載地址和鏈接地址
 *     不一致則會出現不能執行u-boot的問題。通過一個
 *     配置CONFIG_POSITION_INDEPENDENT即可打開地址無關功能,
 *     此選項會在鏈接u-boot時添加-PIE參數。此參數會在u-boot ELF文件中
 *     生成rela*段,u-boot通過讀取此段中表的相對地址值與實際運行時地址值
 *     依次遍歷進行修復當前所有需要重定向地址,使其可以實現地址無關運行;
 *     即無論鏈接基地址如何定義,u-boot也可以在任意ram地址
 *     運行(一般需要滿足最低4K或者64K地址對齊);
 * 
 *     注意此功能只能在sram上實現,因為此功能會在運行時修改文本段數據段中的地址,
 *     如果此時運行在片上flash,則不能寫flash,導致功能失效無法實現地址無關;
 */
 {
  *(.__rel_dyn_start)
 }

 .rela.dyn : {
  *(.rela*)
 }

 .rel_dyn_end :
 {
  *(.__rel_dyn_end)
 }

 _end = .;

 . = ALIGN(8);

 .bss_start : { -------------------------------------------------------- (13)
/*
 *(13)眾所周知的bbs段;
 */
  KEEP(*(.__bss_start));
 }

 .bss : {
  *(.bss*)
   . = ALIGN(8);
 }

 .bss_end : {
  KEEP(*(.__bss_end));
 }

 /DISCARD/ : { *(.dynsym) } -------------------------------------------- (14)
/*
 *(14)一些在鏈接時無用需要丟棄的段;
 */
 /DISCARD/ : { *(.dynstr*) }
 /DISCARD/ : { *(.dynamic*) }
 /DISCARD/ : { *(.plt*) }
 /DISCARD/ : { *(.interp*) }
 /DISCARD/ : { *(.gnu*) }

#ifdef CONFIG_LINUX_KERNEL_IMAGE_HEADER ----------------------------------- (15)
/*
 *(15)在efi加載時會很有用,主要在u-boot的二進制頭部添加了一些頭部信息,
 *     包括大小端,數據段文本段大小等,以便于efi相關的加載器讀取信息,
 *     此頭部信息來自于Linux arm64的Image的頭部信息;該頭部也不屬于u-boot的
 *     一部分只是被附加上去的;
 */
#include "linux-kernel-image-header-vars.h"
#endif
}

4.2 u-boot-spl.lds

此鏈接腳本是標準的spl鏈接腳本,還包含了u_boot_list段,如果對應自己board不需要命令行或者模塊化驅動設備,只作為一個加載器則可以自定義更簡略的鏈接腳本。

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * (C) Copyright 2013
 * David Feng < fenghua@phytium.com.cn >
 *
 * (C) Copyright 2002
 * Gary Jennejohn, DENX Software Engineering, < garyj@denx.de >
 *
 * (C) Copyright 2010
 * Texas Instruments, < www.ti.com >
 * Aneesh V < aneesh@ti.com >
 */

MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE, ---------------------------------------- (1)
/*
 *(1) >XXX 的形式可以將指定段放入XXX規定的內存中;一般u-boot-spl只有
 *    很小的可運行內存塊,所以spl中會舍去大量不需要用的段只保留關鍵的
 *    文本段數據段等,并且通過 >.sram的形式將不在ddr初始化前用到的段定義到sdram中,
 *    后續只需在完成ddr初始化后將這些段搬運到ddr中即可,而不需要額外的
 *    地址修復邏輯,如下:有一個sram 0x18000-0x19000,
 *    一個sdram 0x80000000 - 0x90000000,
 *    那么通過 >.sram方式則map文件可能如下:
 *       0x18000 stext
 *       ...
 *       0x18100 sdata
 *       ...
 *       0x80000000 sbss
 *       ...
 */
  LENGTH = IMAGE_MAX_SIZE }
MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
  LENGTH = CONFIG_SPL_BSS_MAX_SIZE }

OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start) -------------------------------------------------------------------- (2)
/*
 *(2)同u-boot.lds一致,共用一套邏輯入口_start;
 */
SECTIONS
{
 .text : {
  . = ALIGN(8);
  *(.__image_copy_start) -------------------------------------------------- (3)
/*
 *(3)同樣的,如果spl需要重定向則會使用此段定義,大多數情況下spl中會用上重定向;
 */
  CPUDIR/start.o (.text*)
  *(.text*)
 } >.sram

 .rodata : {
  . = ALIGN(8);
  *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
 } >.sram

 .data : {
  . = ALIGN(8);
  *(.data*)
 } >.sram

#ifdef CONFIG_SPL_RECOVER_DATA_SECTION ---------------------------------------- (4)
/*
 *(4)SPL_RECOVER_DATA_SECTION段用于保存數據段數據,
 *    一些board在初始化時修改data段數據,并在后續某個階段
 *    從此段中恢復data的原始數據;
 */
 .data_save : {
  *(.__data_save_start)
  . = SIZEOF(.data);
  *(.__data_save_end)
 } >.sram
#endif

 .u_boot_list : {
  . = ALIGN(8);
  KEEP(*(SORT(.u_boot_list*)));
 } >.sram

 .image_copy_end : {
  . = ALIGN(8);
  *(.__image_copy_end)
 } >.sram

 .end : {
  . = ALIGN(8);
  *(.__end)
 } >.sram

 _image_binary_end = .;

 .bss_start (NOLOAD) : {
  . = ALIGN(8);
  KEEP(*(.__bss_start));
 } >.sdram -------------------------------------------------------------- (5)
/*
 *(5)將bss段數據定義到 >.sdram中,即可在初始化ddr后直接對此段地址清零
 *    即可使用全局未初始化變量,并且不會帶來副作用。
 */

 .bss (NOLOAD) : {
  *(.bss*)
   . = ALIGN(8);
 } >.sdram

 .bss_end (NOLOAD) : {
  KEEP(*(.__bss_end));
 } >.sdram

 /DISCARD/ : { *(.rela*) }
 /DISCARD/ : { *(.dynsym) }
 /DISCARD/ : { *(.dynstr*) }
 /DISCARD/ : { *(.dynamic*) }
 /DISCARD/ : { *(.plt*) }
 /DISCARD/ : { *(.interp*) }
 /DISCARD/ : { *(.gnu*) }
}

從上述的鏈接腳本可以看出,armv8的u-boot的啟動是從arch/arm/cpu/armv8/start.S中的_start開始的 ,并在后續初始化中調用了很多鏈接腳本中定義的地址符號表。

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

    關注

    134

    文章

    9097

    瀏覽量

    367583
  • Uboot
    +關注

    關注

    4

    文章

    125

    瀏覽量

    28233
  • ARMv8
    +關注

    關注

    1

    文章

    35

    瀏覽量

    14158
收藏 人收藏

    評論

    相關推薦

    U-boot的基本介紹

    從本文開始,將陸續推送“手把手教你移植U-boot”系列文章,目標是由淺入深地講解U-boot的工作流程、原理、配置方法和移植方法,手把手教你完成U-boot的移植工作,默認硬件開發平臺為ARM,操作系統為Linux。
    發表于 07-14 16:52 ?2908次閱讀
    <b class='flag-5'>U-boot</b>的基本介紹

    U-boot的執行流程

    本文主要講述了U-boot的執行流程。
    發表于 07-14 16:58 ?708次閱讀
    <b class='flag-5'>U-boot</b>的執行流程

    我的U-Boot鏈接腳本筆記

    以下是我學習u-boot鏈接腳本時做的筆記,歡迎指正錯誤。/* 指明輸出的可執行文件格式為elf,即小端模式的32位ARM指令 */OUTPUT_FORMAT("
    發表于 07-22 10:04

    SDK下使用make u-boot編譯NXP官方下載的u-boot編譯不成功怎么辦?

    .imgMKIMAGE u-boot-dtb.imgCATu-boot-dtb.binCOPY u-boot.binLDu-boot.elfCCspl/common/spl/spl.oCCspl/arch/arm/cpu/armv8
    發表于 12-31 06:24

    基于armv8架構對u-boot進行啟動流程分析(一)

    ,比如mkimage的實現代碼在此處;4 u-boot armv8鏈接腳本在進行源碼分析之前,首先看看u-boot
    發表于 05-23 15:59

    基于armv8架構對u-boot進行啟動流程分析(二)

    為全局可見并在鏈接腳本中被聲明為入口地址,表示u-boot的入口地址為_start;(2)首先進入入口后有兩種可配置情況,一種就是定義了LINUX_KERNEL_IMAGE_HEADER
    發表于 05-23 16:05

    Porting U-Boot to the Control

    In this paper, the way of porting U-Boot to Control Computer Based MPC8349 will beintroduced
    發表于 01-25 15:45 ?13次下載

    u-boot的Makefile分析

    u-boot的Makefile分析 U-BOOT是一個LINUX下的工程,在編譯之前必須已經安裝對應體系結構的交叉編譯環境,這里只針對ARM,編譯器系列軟件為arm-linux-*。 U-BOOT的下載
    發表于 05-17 09:16 ?2067次閱讀

    u-boot簡介

    U-Boot,全稱 Universal Boot Loader,是遵循GPL條款的開放源碼項目。U-Boot的作用是系統引導。U-Boot從FADSROM、
    發表于 10-14 11:17 ?3564次閱讀

    u-boot中Hush shell的功能及編寫腳本的方法介紹

    了解u-boot中Hush shell的功能,以及如何為其編寫腳本。 說明了存儲和檢索腳本的方法。
    的頭像 發表于 11-22 07:00 ?5687次閱讀

    U-Boot架構淺析

    導讀:嵌入式Linux系統搭建,bootloader是必不可少的一環,而U-Boot已成嵌入式Linux事實標準。所以較為深入的分析U-Boot的設計,對于更...
    發表于 02-07 11:56 ?7次下載
    <b class='flag-5'>U-Boot</b>架構淺析

    Linux U-Boot開發指南

    介紹 U-Boot 的編譯打包、基本配置、常用命令的使用、基本調試方法等, 為 U-BOOT 的移植及應用開發提供了基礎。
    的頭像 發表于 03-06 10:28 ?1323次閱讀
    Linux <b class='flag-5'>U-Boot</b>開發指南

    基于armv8架構來對u-boot進行啟動流程分析

    首先引用wiki上的簡介:u-boot 是一個主要用于嵌入式系統的引導加載程序,可以支持多種不同的計算機系統結構。
    發表于 06-09 09:39 ?864次閱讀
    基于<b class='flag-5'>armv8</b>架構來對<b class='flag-5'>u-boot</b>進行啟動流程分析

    armv8 u-boot的啟動介紹

    先看arm官網提供的一張圖: 上圖詳細概括了arm官方推薦的armv8的啟動層次結構: 官方將啟動分為了BL1,BL2,BL31,BL32,BL33階段,根據順序,芯片啟動后首先執行BL1階段代碼
    的頭像 發表于 12-07 11:09 ?2217次閱讀
    <b class='flag-5'>armv8</b> <b class='flag-5'>u-boot</b>的啟動介紹

    u-boot在匯編啟動階段的相關操作介紹

    boot參數, 進行地址無關fixed,系統寄存器復位,底層平臺相關初始化等 ,啟動代碼位于arch/arm/cpu/armv8/start.S, 入口地址為_start。 啟動前為后續流程做的一些平臺
    的頭像 發表于 12-07 11:22 ?638次閱讀
    主站蜘蛛池模板: 操女人视频网站| 亚洲精品免费视频| 高h乱肉辣文辣书阁| 日本午夜三级| 夜夜爽天天狠狠九月婷婷| 最近最新免费视频| 亚洲国产精品网站久久| 美剧免费在线观看| 深夜久久| 国语一区| 黄色一级a毛片| 国产香蕉在线精彩视频| 爱爱免费视频网站| 亚洲 另类色区 欧美日韩| 亚洲a影院| bt天堂在线www种子搜索| 黄频网| 日韩毛片高清免费| 天天爱夜夜爽| 被cao到合不拢腿腐男男| 国产一区二区三区影院 | 57pao强力打造免费高清高速| 四虎4hu影库永久地址| 亚洲午夜一级毛片| 欧美精品人爱a欧美精品| 久青草国产高清在线视频| 国产午夜精品福利| 天堂影院在线| 天天视频色| 在线观看免费午夜大片| 天堂中文资源在线观看| 无毒不卡在线播放| 国产精品久久久久久久久免费观看| 经典三级第一页| 人人揉揉香蕉大青草| 日本大片免aaa费观看视频| 99色婷婷| 女人的逼毛片| 不卡精品国产_亚洲人成在线| baoyu污污网站入口免费| 免费能直接在线观看黄的视频|