u-boot-2016.5启动流程

本文详细解析了U-Boot 2016.05的启动流程,从_start入口开始,经过reset、cpu_init_crit、lowlevel_init、_main等步骤,逐步进行板级初始化、代码重定位,最后执行命令,启动操作系统。主要涉及的文件包括start.S、crt0.S、board_f.c、relocate.S、board_r.c、main.c、cmd/bootm.c等,详述了bootcmd参数获取、run_command_list函数的调用以及do_bootm函数执行启动OS的过程。
摘要由CSDN通过智能技术生成

0、由u-boot-2016.05\arch\arm\cpu\u-boot.lds链接文件中ENTRY(_start) 可知程序的入口在_start,在SourceInsight中查找可发现程序的入口_start在u-boot-2016.05\arch\arm\lib\vectors.S中。

...

ENTRY(_start)
SECTIONS
{
    ...

    . = 0x00000000;

    . = ALIGN(4);
    .text :
    {
        *(.__image_copy_start)
        *(.vectors)
        CPUDIR/start.o (.text*)
        *(.text*)
    }

    ...

    . = ALIGN(4);
    .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

    . = ALIGN(4);
    .data : {
        *(.data*)
    }

    . = ALIGN(4);

    . = .;

    ...

    .bss_start __rel_dyn_start (OVERLAY) : {
        KEEP(*(.__bss_start));
        __bss_base = .;
    }

    .bss __bss_base (OVERLAY) : {
        *(.bss*)
         . = ALIGN(4);
         __bss_limit = .;
    }

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

    ...
}

进入boot-2016.05\arch\arm\lib\vectors.S中,可以看到从_start开始后就跳转到reset去执行:

...

.globl _start

...

_start:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
    .word   CONFIG_SYS_DV_NOR_BOOT_CFG
#endif

    b   reset
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq
    ldr pc, _fiq

...

1、从u-boot-2016.05\arch\arm\cpu\arm920t\start.S中reset执行
主要执行流程:reset -> cpu_init_crit -> lowlevel_init -> _main

reset:

...

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl  cpu_init_crit
#endif

    bl  _main

...

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:

...

    bl  lowlevel_init

...

#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

2、由bl _main跳转到u-boot-2016.05\arch\arm\lib\crt0.S中从入口_main开始执行
主要执行流程:board_init_f -> relocate_code -> board_init_r

ENTRY(_main)

        ...

    bl  board_init_f_alloc_reserve
        ...
    bl  board_init_f_init_reserve
        ...
    bl  board_init_f

#if ! defined(CONFIG_SPL_BUILD)

        ...

    b   relocate_code

        ...

#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)

         ...

#if defined(CONFIG_SYS_THUMB_BUILD)

        ...

#else
    ldr pc, =board_init_r   
#endif
#endif

ENDPROC(_main)

这部分有三点说明:
⑴、u-boot-2016.05\common\board_f.c:board_init_f通过initcall_run_list(init_sequence_f)函数执行一系列初始化函数以实现前半部分板级初始化。全局结构体gd在u-boot-2016.05\arch\arm\include\asm\global_data.h中声明:

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r9")

⑵、u-boot-2016.05\arch\arm\lib\relocate.S:relocate_code实现uboot代码的重定位,此部分如果觉得源代码不是简单明了可自己改写。
⑶、去重定位uboot有两种路径:
一种是将gd->flags设为0,在初始化函数序列init_sequence_f中的jump_to_copy函数中去跳转到relocate_code:

static int jump_to_copy(void)
{
    if (gd->flags & GD_FLG_SKIP_RELOC)
        return 0;
    ...

#if defined(CONFIG_X86) || defined(CONFIG_ARC)
    ...
#else
    relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);
#endif

    return 0;
}

另一种就是不宏定义CONFIG_SPL_BUILD,然后在u-boot-2016.05\arch\arm\lib\crt0.S中通过

#if ! defined(CONFIG_SPL_BUILD)

        ...

    b   relocate_code

        ...

#endif

来跳转到relocate_code。以上两种方法选其一,另一种就得去掉。
3、在上一步通过ldr pc, =board_init_r指令进入u-boot-2016.05\common\board_r.c:board_init_r函数,进而调用initcall_run_list(init_sequence_r)函数执行一系列初始化函数以实现后半部分板级初始化,并在initcall_run_list函数里进入run_main_loop不再返回。

void board_init_r(gd_t *new_gd, ulong dest_addr)
{
    ...

    if (initcall_run_list(init_sequence_r))
        hang();

    /* NOTREACHED - run_main_loop() does not return */
    hang();
}

init_sequence_r是一个函数指针数组,里面存放了很多初始化函数指针,里面有两个重要的函数指针initr_announce和run_main_loop:

init_fnc_t init_sequence_r[] = {

    ...

    initr_announce,

    ...

    run_main_loop,
};

initr_announce函数声明从此处开始程序就将跳转到RAM中运行:

static int initr_announce(void)
{
    debug("Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr);
    return 0;
}

最后一项是run_main_loop ,进入run_main_

u-boot-2016.11.tar.bz2是一个开源软件项目的压缩文件。该压缩文件是u-boot引导加载程序的源代码和相关文件的打包形式。u-boot(Universal Bootloader)是一款用于嵌入式系统的开源引导加载程序,用于初始化硬件并启动操作系统。 u-boot-2016.11.tar.bz2文件的扩展名.tar.bz2表示它是使用tar和bzip2两种工具进行压缩的。.tar是一个常用的文件打包工具,它可以将多个文件和目录打包成一个文件。.bz2是一个压缩工具,可以将文件进行高效压缩。 要使用u-boot-2016.11.tar.bz2文件,首先需要将其解压缩。可以使用tar命令进行解压缩,命令为tar -xjf u-boot-2016.11.tar.bz2。这将解压缩文件,并将源代码和其他相关文件提取到当前目录下。 解压缩后,可以在提取出的文件中找到u-boot引导加载程序的源代码和相关文件。可以根据需要进行定制和编译,生成适合特定硬件平台的引导加载程序。u-boot支持多种处理器架构和开发板,可以根据需要进行配置。 根据u-boot-2016.11.tar.bz2文件的版本号来看,它是2016年11月发布的版本。这意味着该版本已经存在一段时间,并可能具有稳定性和经过验证的特性。对于需要使用u-boot的开发者和嵌入式系统制造商,这个版本可以作为一个可靠的基础进行开发和定制。 总之,u-boot-2016.11.tar.bz2是u-boot引导加载程序的源代码和相关文件的压缩包。解压缩后,可以通过定制和编译源代码,生成适合特定硬件平台的引导加载程序。这个版本已经存在一段时间,并可能具有可靠的特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值