i.MX6ULL终结者Uboot编译及移植u-boot启动流程

本文详细解析了U-boot在i.MX6ULL平台上的编译和启动流程,从链接脚本u-boot.lds开始,经过汇编阶段(包括异常向量表初始化、CPU设置等),再到C语言阶段(board_init_f和board_init_r函数),最终实现硬件初始化和命令行交互。整个启动过程涉及异常处理、内存管理、硬件配置等多个关键步骤。
摘要由CSDN通过智能技术生成

U-boot编译成功后会在源码目录下生成链接脚本u-boot.lds,本文档从链接脚本开始逐步分析启动u-boot的过程。
vi u-boot.lds
在这里插入图片描述

图 1

ENTRY(_start):程序的入口点为_start_start定义在了arch/arm/lib/vectors.S:
SECTIONS中的对象按顺序依次存放在内存中。
.text: 代码段。
*(.__image_copy_start)标签不占内存空间,
*(.vectors)初始化异常向量表,存放在开始位置,
arch/arm/cpu/armv7/start.o (.text*)存放start.o
*(.text*) 最后存放其他的可执行文件。
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }只读数据段,使用SORT_BY_ALIGNMENT将rodata里的对象文件相应段对齐排列。
data:data存储已经初始化的全局变量。
u_boot_list存放了一些命令,在System.map中搜索“u_boot_list”可以看到。
后面的标签在u-boot.map和System.map中可以看到。

1 汇编阶段

从链接脚本可以知道,程序首先执行arch/arm/lib/vectors.S 的内容,
在这里插入图片描述

图 1

在vectors.S中使用“.globl _start”声明“_start”是全局变量,外部可访问,然后初始化异常向量表,54行跳转到reset函数,reset函数在arch/arm/cpu/armv7/start.S中声明,
在这里插入图片描述

图 2

在reset函数中跳转到save_boot_params ,save_boot_params定义在100行,功能是跳转到save_boot_params_ret,
在这里插入图片描述

图 3

save_boot_params_ret主要功能是保证 CPU在SVC模式,并禁止FIQ和IRQ中断。
往下是向量表重定位和SPL相关的设置,然后依次跳转到cpu_init_cp15,cpu_init_crit,_main。
在这里插入图片描述

图 4

在113行定义了cpu_init_cp15函数,此函数主要功能是关闭cache,MMU,TLB等,这些都是虚拟内存转化相关功能,uboot阶段使用的是物理内存。
在这里插入图片描述

图 5

关闭虚拟内存映射后跳转到cpu_init_crit函数,
在这里插入图片描述

图 6

cpu_init_crit跳转到lowlevel_init,查找函数”lowlevel_init”
在这里插入图片描述

图 7

lowlevel_init定义在arch/arm/cpu/armv7/lowlevel_init.S文件,
在这里插入图片描述

图 8

在这里插入图片描述

图 9

在lowlevel_init.S中,设置栈顶指针,CONFIG_SYS_INIT_SP_ADDR 加载Uboot第二阶段(C语言阶段)代码代码到RAM,文件头部写着如下信息,说明设置堆栈,为调用C函数进行进一步初始化,:
在这里插入图片描述

图10

s_init为空函数
cpu_init_cp15和cpu_init_crit函数执行完后,开始执行_main函数,通过在u-boot.map找到查找,_main函数在arch/arm/lib/crt0.S
在这里插入图片描述

图 11

在这里插入图片描述

图 12

打开crt0.S:
在这里插入图片描述

图 13

函数_main中清除bss段,跳转到board_init_f,
在这里插入图片描述

图 14

然后跳转到board_init_r
在这里插入图片描述

图 15

2 C语言阶段

uboot程序在汇编阶段跳转到board_init_f函数,此函数在common/board_f.c 中有如下定义:

void board_init_f(ulong boot_flags)
{
   
#ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
    /*
     * For some archtectures, global data is initialized and used before
     * calling this function. The data should be preserved. For others,
     * CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack
     * here to host global data until relocation.
     */
    gd_t data;
    gd = &data;
    /*
     * Clear global data before it is accessed at debug print
     * in initcall_run_list. Otherwise the debug print probably
     * get the wrong vaule of gd->have_console.
     */
    zero_global_data();
#endif
 
    gd->flags = boot_flags;
    gd->have_console = 0;
 
    if (initcall_run_list(init_sequence_f))//调用初始化一些初始化函数列表
        hang();
 
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
        !defined(CONFIG_EFI_APP)
    /* NOTREACHED - jump_to_copy() does not return */
    hang();
#endif
}

在函数board_init_f中依次调用init_sequence[]中的函数,init_sequence[],此数组存放着一些初始化函数,在common/board_f.c中定义:

static init_fnc_t init_sequence_f[] = {
   
#ifdef CONFIG_SANDBOX
    setup_ram_buf,
#endif
    setup_mon_len,
#ifdef CONFIG_OF_CONTROL
    fdtdec_setup,
#endif
#ifdef CONFIG_TRACE
    trace_early_init,
#endif
    initf_malloc,
    initf_console_record,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
    /* TODO: can this go into arch_cpu_init()? */
    probecpu,
........
#endif
    setup_machine,
    reserve_global_data,
    reserve_fdt,
    reserve_arch,
    reserve_stacks,
    setup_dram_config,
    show_dram_config,
    display_new_sp,
#ifdef CONFIG_SYS_EXTBDINFO
    setup_board_extra,
#endif
    INIT_FUNC_WATCHDOG_RESET
    reloc_fdt,
    setup_reloc,
.............................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值