• U-Boot初始化及工作流程分析


    0. 概述

    U-Boot通常是从架构相关的汇编文件(尾缀为大写S的汇编文件意为可链接)中获取第一条执行的指令,例如:

    - arch/arm/cpu/armv7/start.S
    - arch/powerpc/cpu/mpc83xx/start.S
    - arch/mips/cpu/start.S
    
    • 1
    • 2
    • 3

    在以上所列出的汇编文件中,主要执行如下三个函数:

    lowlevel_init()
    board_init_f()
    board_init_r()
    
    • 1
    • 2
    • 3

    完整的执行流程如下图所示:

    U-Boot代码执行流程

    1. lowlevel_init()

    不同架构类型的处理器会单独定义lowlevel_init.S文件,例如:

    ./arch/arm/cpu/armv7/lowlevel_init.S
    ./arch/arm/cpu/armv8/lowlevel_init.S
    ./arch/mips/mach-ath79/ar933x/lowlevel_init.S
    
    • 1
    • 2
    • 3

    该函数的基本功能是使得CPU可以获取、执行到board_init_f()函数。在此函数中没有栈信息,不能设置SDRAM和控制台。

    .pushsection .text.lowlevel_init, "ax"
    WEAK(lowlevel_init)
    #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
    	ldr	sp, =CONFIG_SPL_STACK
    #else
    	ldr	sp, =CONFIG_SYS_INIT_SP_ADDR
    #endif
    	bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */
    #ifdef CONFIG_SPL_DM
    	mov	r9, #0
    #else
    #ifdef CONFIG_SPL_BUILD
    	ldr	r9, =gdata
    #else
    	sub	sp, sp, #GD_SIZE
    	bic	sp, sp, #7
    	mov	r9, sp
    #endif
    #endif
    	push	{ip, lr}
    	bl	s_init
    	pop	{ip, pc}
    ENDPROC(lowlevel_init)
    .popsection
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2. board_init_f()

    为执行board_init_r做准备,需要初始化两个关键功能:SDRAM和串口。
    在此阶段,global_data已经可以使用,栈信息位于SRAM中。由于BSS段仍然无法使用,因此,不可以使用全局/静态变量。

    若U-Boot中开启了SPL功能,则在common/spl.c代码中可以实现该函数,否则,通常以common/board_f.c中实现为准。

    board_init_f()中调用的函数在数组init_sequence_f[]中定义:

    static const init_fnc_t init_sequence_f[] = {
    	setup_mon_len,
    ......
    	env_init,		/* initialize environment */
    	init_baud_rate,		/* initialze baudrate settings */
    	serial_init,		/* serial communications setup */
    	console_init_f,		/* stage 1 init of console */
    	display_options,	/* say that we are here */
    	display_text_info,	/* show debugging info if required */
    	checkcpu,
    #if defined(CONFIG_SYSRESET)
    	print_resetinfo,
    #endif
    #if defined(CONFIG_DISPLAY_CPUINFO)
    	print_cpuinfo,		/* display cpu info (and speed) */
    #endif
    #if defined(CONFIG_DTB_RESELECT)
    	embedded_dtb_select,
    #endif
    #if defined(CONFIG_DISPLAY_BOARDINFO)
    	show_board_info,
    #endif
    	INIT_FUNC_WATCHDOG_INIT
    #if defined(CONFIG_MISC_INIT_F)
    	misc_init_f,
    #endif
    	INIT_FUNC_WATCHDOG_RESET
    #if defined(CONFIG_SYS_I2C)
    	init_func_i2c,
    #endif
    #if defined(CONFIG_VID) && !defined(CONFIG_SPL)
    	init_func_vid,
    #endif
    	announce_dram_init,
    	dram_init,		/* configure available RAM banks */
    #ifdef CONFIG_POST
    	post_init_f,
    #endif
    ......
    #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
    		!CONFIG_IS_ENABLED(X86_64)
    	jump_to_copy,
    #endif
    	NULL,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    3. board_init_r()

    U-Boot执行到此处,已经进入到正常的功能代码调用流程,例如设备驱动、命令行、镜像搬移加载等功能。

    若U-Boot中开启了SPL功能,则在common/spl.c代码中可以实现该函数,否则,通常以common/board_r.c中实现为准。

    board_init_r()中调用的函数在数组init_sequence_r[]中定义:

    static init_fnc_t init_sequence_r[] = {
    	initr_trace,
    	initr_reloc,
    ......
    #ifdef CONFIG_MMC
    	initr_mmc,
    #endif
    ......
    	run_main_loop,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    以上所有的功能相关的初始化中,CPU相关的初始化代码通常位于如下路径:

    linux@u-boot$ ls arch/arm/
    config.mk      lib           mach-davinci     mach-keystone  mach-orion5x   mach-snapdragon  mach-tegra      mach-zynqmp-r5
    cpu            mach-aspeed   mach-exynos      mach-kirkwood  mach-owl       mach-socfpga     mach-uniphier   Makefile
    dts            mach-at91     mach-highbank    mach-mediatek  ......
    linux@u-boot$
    
    • 1
    • 2
    • 3
    • 4
    • 5

    板级相关的初始化代码通常位于如下路径:

    linux@u-boot$ ls board/
    abilis          bluewater     corscience     ge           lg           qca             sifive             toradex
    advantech       bosch         creative       geekbuying   l+g          qemu-mips       silica             tplink
    alliedtelesis   boundary      cssi           google       liebherr     qualcomm        sks-kinkel         tqc
    altera          broadcom      CZ.NIC         grinn        logicpd      quipos          socrates           ucRobotics
    ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    SQL Server数据库查询优化
    Linux网络编程04
    你了解数据同步吗?
    怎么查看当前vue项目,要求的node.js版本
    中药配方专利申请时间有多久?
    在CDH的hue上的oozie出现,提交 Coordinator My Schedule 时出错
    Android Media Framework(三)OpenMAX API阅读与分析
    pyqt5:openpyxl 读取 Excel文件,显示在 QTableWidget 中
    Java8 Collectors.toMap() 的使用
    关于电影的HTML网页设计—— 电影小黄人6页 HTML+CSS+JavaScript
  • 原文地址:https://blog.csdn.net/weixin_43644245/article/details/125507767