0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

u-boot在汇编启动阶段的相关操作介绍

麦辣鸡腿堡 来源:CSDN博客 作者:内核新视界 2023-12-07 11:22 次阅读

u-boot在汇编启动阶段对系统的一些初始化

cpu交由u-boot接管进入u-boot后, 首先会到_start符号处开始执行初始化, 并在此期间完成一些必要的系统寄存器相关的初始化,包括保存boot参数进行地址无关fixed,系统寄存器复位,底层平台相关初始化等 ,启动代码位于arch/arm/cpu/armv8/start.S,入口地址为_start。

启动前为后续流程做的一些平台相关操作

从_start开始,u-boot会根据board定义做一些平台化相关的初始化工作或者是保存一些重要寄存器信息,代码如下:

/*************************************************************************
 *
 * Startup Code (reset vector)
 *
 *************************************************************************/

.globl _start
_start: ------------------------------------------------------------------------ (1)
#if defined(CONFIG_LINUX_KERNEL_IMAGE_HEADER) ---------------------------------- (2)
#include < asm/boot0-linux-kernel-header.h >
#elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) -------------------------------- (3)
/*
 * Various SoCs need something special and SoC-specific up front in
 * order to boot, allow them to set that in their boot0.h file and then
 * use it here.
 */
#include < asm/arch/boot0.h >
#else
    b reset ----------------------------------------------------------------- (4)
#endif

    .align 3

.globl _TEXT_BASE ------------------------------------------------------------ (5)
_TEXT_BASE:
    .quad CONFIG_SYS_TEXT_BASE

/*
 * These are defined in the linker script.
 */
.globl _end_ofs -------------------------------------------------------------- (5)
_end_ofs:
    .quad _end - _start

.globl _bss_start_ofs
_bss_start_ofs:
    .quad __bss_start - _start

.globl _bss_end_ofs
_bss_end_ofs:
    .quad __bss_end - _start

reset:
    /* Allow the board to save important registers */
    b save_boot_params ----------------------------------------------------- (6)
.globl save_boot_params_ret
save_boot_params_ret:

... /* 此处省略无关代码,待分析到时再展开代码 */
...
WEAK(save_boot_params)
    b save_boot_params_ret /* back to my caller */
ENDPROC(save_boot_params)

#endif
  • • (1)_start段标记为全局可见并在链接脚本中被声明为入口地址,表示u-boot的入口地址为_start;
  • • (2)首先进入入口后有两种可配置情况,一种就是定义了LINUX_KERNEL_IMAGE_HEADER,boot0-linux-kernel-header.h展开部分后如下:
.macro le64sym, sym
    .long sym()_lo32
    .long sym()_hi32
    .endm

.globl _start
_start:
    /*
     * DO NOT MODIFY. Image header expected by Linux boot-loaders.
     */
    b reset    /* branch to kernel start, magic */
    .long 0    /* reserved */
    le64sym _kernel_offset_le  /* Image load offset from start of RAM, little-endian */
    le64sym _kernel_size_le   /* Effective size of kernel image, little-endian */
    le64sym _kernel_flags_le  /* Informative flags, little-endian */
    .quad 0    /* reserved */
    .quad 0    /* reserved */
    .quad 0    /* reserved */
    .ascii "ARMx64"   /* Magic number */
    .long 0    /* reserved */

此处将与在链接脚本中定义的LINUX_KERNEL_IMAGE_HEADER对应起来,为u-boot头部添加一个类似与Linux arm64 的Image头部,首先是起始8字节, 如果没有定义efi相关的功能则是一个跳转指令,跳转到reset段继续执行启动流程 ,其他如链接脚本中解释一致;

  • • (3)第二种可能的配置,就是定义了ENABLE_ARM_SOC_BOOT0_HOOK配置,此处的头文件根据不同board会引用到不同头文件,如瑞芯微的最终会引用到如下部分代码头文件:
#ifdef CONFIG_SPL_BUILD
    /*
     * We need to add 4 bytes of space for the 'RK33' at the
     * beginning of the executable.  However, as we want to keep
     * this generic and make it applicable to builds that are like
     * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
     * TPL, but extra space needed in the SPL), we simply insert
     * a branch-to-next-instruction-word with the expectation that
     * the first one may be overwritten, if this is the first stage
     * contained in the final image created with mkimage)...
     */
    b 1f  /* if overwritten, entry-address is at the next word */
1:
#endif
#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM)
    adr     r3, entry_counter
    ldr r0, [r3]
    cmp r0, #1           /* check if entry_counter == 1 */
    beq reset            /* regular bootup */
    add     r0, #1
    str r0, [r3]         /* increment the entry_counter in memory */
    mov     r0, #0           /* return 0 to the BROM to signal 'OK' */
    bx lr               /* return control to the BROM */
entry_counter:
    .word   0
#endif

#if (defined(CONFIG_SPL_BUILD) || defined(CONFIG_ARM64))
    /* U-Boot proper of armv7 do not need this */
    b reset
#endif

#if !defined(CONFIG_ARM64)
    /*
     * For armv7, the addr '_start' will used as vector start address
     * and write to VBAR register, which needs to aligned to 0x20.
     */
    .align(5), 0x0
_start:
    ARM_VECTORS
#endif

#if !defined(CONFIG_TPL_BUILD) && defined(CONFIG_SPL_BUILD) && 
    (CONFIG_ROCKCHIP_SPL_RESERVE_IRAM > 0)
    .space CONFIG_ROCKCHIP_SPL_RESERVE_IRAM /* space for the ATF data */
#endif

因为有些设备boot到u-boot之前已经有安全固件了,

所以此时控制权交给u-boot时,其实是可能有一些传递参数信息的要求,比如这里瑞芯微芯片通过bootrom boot到tpl后,

后续在完成tpl初始化后会将控制权再交还给bootrom固件,由bootrom固件继续加载spl,

所以这里在进行u-boot流程之前保存了bootrom的返回地址,以便后续瑞芯微板级软件使用。

定义有可能也是arm32的模式,所以还可能在入口地址处保存异常向量表;

  • • (4)如果对应board没有上述两种需求,那么_start段则是一条最简单的跳转指令b reset跳转到reset处继续启动流程初始化;
  • • (5)在_start到reset之间,有一个.align 3用于8字节对齐,因为可能在读取常量地址之前各自平台做了自己代码逻辑导致当前地址并不是8字节对齐的, 这里不管是否对齐都强制对齐了一下,之后还保存了一些常量信息,其中包括_TEXT_BASE保存了链接地址,用于在启动地址无关功能时进行对运行时地址的偏移计算,其他几个偏移值目前未使用;
  • • (6)save_boot_params用于保存一些board相关的重要寄存器,此处定义为了一个弱函数,为直接跳转回save_boot_params_ret继续往下执行,如果某些board需要保存寄存器参数则可以在自己的lowlevel.S文件中实现此函数。 一般由atf,bl2或者rom跳转到spl或u-boot时厂商可能需要在两个固件之间传递参数,比如由bl2在寄存器x0,x1,x2中分别存入了一些固件的地址信息,那么u-boot则可以在早期通过此函数保存这些信息,并在后续某个时机中使用。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8651

    浏览量

    361816
  • 汇编
    +关注

    关注

    2

    文章

    214

    浏览量

    25735
  • Uboot
    +关注

    关注

    4

    文章

    123

    浏览量

    27873
收藏 人收藏

    评论

    相关推荐

    U-BootAT91RM9200上的移植及启动分析

    基于AT91RM9200的嵌入式目标板和U-Boot1.1.2源码资源,分析了U-Boot启动过程,介绍U-Boot的移植方法和具体
    发表于 03-16 11:00

    U-Boot介绍1

    U-Boot介绍1
    发表于 08-04 00:23

    【Z-turn Board试用体验】+ u-boot启动

    等信息。如果内核也被烧进QSPI Flash那么不做任何操作的话,内核就会在3s后(当然这个时间可以u-boot中自己设置成更长的时间)被自动加载,如果按下任何键,u-boot自动加
    发表于 07-12 17:24

    【OK210试用体验】u-boot篇 -- u-boot启动流程总结

    【OK210试用体验】u-boot篇 -- u-boot启动流程总结 u-boot跟其他的bootloader类似,启动有两个
    发表于 09-08 22:45

    【OK210试用体验】u-boot篇 -- u-boot命令tab补全功能

    /CommandLineParsing 。实现shell功能补全 实现u-boot的hush shell功能补全其实很简单,u-boot顶层README有对相关命令的
    发表于 09-10 17:56

    u-boot详解

    操作系统基本是2002年11月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boo
    发表于 07-04 04:56

    怎么对u-boot进行进行反汇编

    知道是makefile中加入ARM-Linux-objdump,但是很多目录下都有这个makefile文件,可不可以只反汇编start.S,如果可以是修改那个路径下的makefile?还有可不可对u-boot的全部源码进行反
    发表于 08-20 02:13

    最简单的u-boot

    说一下u-boot,它是一个嵌入式设备中相当于电脑bootloader的一个东西,能干啥:1.初始化硬件 2.启动内核只有内核启动了才能让一个系统
    发表于 01-15 20:49

    U-boot的特点是什么

    Bootloader的操作模式常用bootloader介绍U-boot介绍U-boot的特点:U-bo
    发表于 12-14 09:22

    U-BOOT启动流程分享

    Bootloader移植(下)U-BOOT 启动流程u-boot启动三个2启动步骤(重点)U-boot
    发表于 01-18 10:17

    u-boot编译的相关镜像是如何生成的

    u-boot编译的相关镜像是如何生成的?rk3399 u-boot启动基本过程是怎样的?
    发表于 03-08 06:13

    如何启动U-boot

    如何启动U-boot
    发表于 03-10 06:12

    OpenAMP u-boot启动问题求解

    超过 ~130KB(代码 + RAM,其中代码放置 MCU SRAM 1 中)时,我们可以重现该问题。低于该大小,M4 应用程序将从 u-boot 正确启动,并且 Linux 下跟
    发表于 12-26 08:36

    U-Boot启动及移植分析

    bootloader 开发是嵌入式系统必不可少而且十分重要的部分,U-Boot 为功能强大的bootloader 开发软件。本文详细分析了U-Boot启动流程,并结合其源码,阐述了U-Bo
    发表于 09-01 16:34 27次下载

    嵌入式U-BOOT启动流程及移植

    摘要:嵌入式系统一般没有通用的bootloader,u-boot是功能强大的bootloader开发软件,但相对也比较复杂。文中对u-boot启动流程作了介绍,详细给出了
    发表于 02-25 16:00 59次下载