U-boot-1:编译已有的uboot

针对uboot2016

一、编译U-boot的用到的基本命令

1、make  xxx_config

    在根目录下生成.config

CONFIG_SYS_ARCH="arm"
CONFIG_SYS_CPU="arm920t"
CONFIG_SYS_SOC="s3c24x0"
CONFIG_SYS_VENDOR="samsung"
CONFIG_SYS_BOARD="smdk2410"
CONFIG_SYS_CONFIG_NAME="smdk2410"
CONFIG_CPU_ARM920T=y
CONFIG_SYS_ARM_ARCH=4
CONFIG_SYS_CACHE_SHIFT_5=y
CONFIG_SYS_CACHELINE_SIZE=32
CONFIG_TARGET_SMDK2410=y

2、指定架构和编译器

export ARCH=arm      

export CROSS_COMPILE=/xxx/xxx/arm-none-linux-gnueabi-2014-05/bin/arm-none-linux-gnueabi-

3、make

二、移植uboot2016需要修改的内容

    以三星2410为例

  •       board/samsung/smdk2410/
  •       include/configs/smdk2410.h
  •       configs/smdk2410_defconfig

三、Uboot程序执行大体流程

1、arch/arm/cpu/arm920t/start.S 

    程序执行入口,设置CPU模式,关闭MMU,Cache;跳到board/vender_name/board_name/lowlevel_init.S执行cpu_init_crit.

reset:
        /*
         * set the cpu to SVC32 mode
         */
        mrs     r0, cpsr
        bic     r0, r0, #0x1f
        orr     r0, r0, #0xd3
        msr     cpsr, r0
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl      cpu_init_crit
#endif
        bl      _main
cpu_init_crit:
        /*
         * disable MMU stuff and caches
         */
        mrc     p15, 0, r0, c1, c0, 0
        bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
        bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
        orr     r0, r0, #0x00000002     @ set bit 1 (A) Align
        orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
        mcr     p15, 0, r0, c1, c0, 0
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
        /*
         * before relocating, we have to setup RAM timing
         * because memory timing is board-dependend, you will
         * find a lowlevel_init.S in your board directory.
         */
        mov     ip, lr
        ......
        bl      lowlevel_init
        mov     lr, ip
#endif

2、board/vender_name/board_name/lowlevel_init.S

    start.S中cpu_init_crit调用lowlevel_init完成板子初始化工作包括时钟,内存,串口等(这些初始化函数实体定义在其他文件中,会继续调用)

.globl lowlevel_init
lowlevel_init:
        /* memory control configuration */
        /* make r0 relative the current location so that it */
        /* reads SMRDATA out of FLASH rather than memory ! */
        ldr     r0, =SMRDATA
        ldr     r1, =CONFIG_SYS_TEXT_BASE
        sub     r0, r0, r1
        ldr     r1, =BWSCON     /* Bus Width Status Controller */
        add     r2, r0, #13*4

3、cpu_init_crit执行完返回start.S, start.S继续调用arch/arm/lib/crt0.S中的 _main

    _main设置栈,初始化C运行环境,继续调用uboot/common/board_f.c/board_init_f()  和board_init_r()

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
        ldr     sp, =(CONFIG_SPL_STACK)
#else
        ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
#else
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
#endif
        mov     r0, sp
        bl      board_init_f_alloc_reserve
        mov     sp, r0
        /* set up gd here, outside any C code */
        mov     r9, r0
        bl      board_init_f_init_reserve

        mov     r0, #0
        bl      board_init_f
#if defined(CONFIG_SYS_THUMB_BUILD)
        ldr     lr, =board_init_r       /* this is auto-relocated! */
        bx      lr
#else
        ldr     pc, =board_init_r       /* this is auto-relocated! */
#endif
        /* we should not return here. */
#endif


ENDPROC(_main)

4、uboot/common/board_f.c 和board_r.c

    board_init_f是uboot初始化过程中执行的第一个C函数,可以看作这个文件的入口函数。其中最重要的就是准备全局信息GD结构体, 内核启动参数就是来自于这个结构体。board_init_t完成代码重定位工作。board_init_t()不会再返回,它调用自身的run_main_loop函数,run_main_loop进入无限循环,已知调用common/mian.c下的main_loop

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;
void board_init_r(gd_t *new_gd, ulong dest_addr)
{
#ifdef CONFIG_NEEDS_MANUAL_RELOC
        int i;
#endif


#ifdef CONFIG_AVR32
        mmu_init_r(dest_addr);
#endif
static int run_main_loop(void)
{
#ifdef CONFIG_SANDBOX
        sandbox_main_loop_init();
#endif
        /* main_loop() can return to retry autoboot, if so just run it again */
        for (;;)
                main_loop();
        return 0;
}

5、最后执行uboot/common/mian.c下的main_loop

    读取命令,再执行命令

void main_loop(void)
{
        const char *s;

        bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifdef CONFIG_VERSION_VARIABLE
        setenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */

        cli_init();

        run_preboot_environment_command();

#if defined(CONFIG_UPDATE_TFTP)
        update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP */

        s = bootdelay_process();
        if (cli_process_fdt(&s))
                cli_secure_boot_cmd(s);

        autoboot_command(s);

        cli_loop();
        panic("No CLI available");
}

猜你喜欢

转载自blog.csdn.net/qq_23084801/article/details/80724518