Hi3556v200 u-boot+Liteos方案启动流程分析--3.通用uboot分析之board_init_f

1.前言

本文主要就Hi3556v200的U-boot+Liteos方案的启动流程做简要介绍, 前面主要分析了Hi3556v200下的start.S文件,在这之后它将解压通用uboot的代码执行,执行的入口位于通用uboot的start.S文件。
通过_main最终调用到board_init_f函数,board_init_f将遍历执行init_sequence_f函数数组。
U-boot版本:u-boot-2016.11

2.init_sequence_f函数数组

位于/u-boot-2016.11/common/board_f.c
board_init_f主要是调用了init_sequence_f函数数组,下面简要说明一下init_sequence_f的关键函数:

  • setup_mon_len
    设置 gd->mon_len 成员变量,此处为_bss_end -start,也就是整个代码的长度
    注意:此时gd变量地址主要是在board_init_f中分配,由于是局部变量,因此主要保存在栈里,栈指针为0x04014000-0x2000, 此位于sram的空间,如下类同。

  • fdtdec_setup
    fdt相关配置,主要获取了fdt的地址
    /* Get a pointer to the FDT */
    gd->fdt_blob = __dtb_dt_begin;

  • trace_early_init

  • trace buffer的初始化

  • initf_malloc
    设置 malloc相关变量:
    gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
    堆大小为CONFIG_SYS_MALLOC_F_LEN

  • arch_cpu_init
    basic arch cpu dependent setup,Hi3556未实现

  • mach_cpu_init,
    SoC/machine dependent CPU setup,Hi3556未实现

  • initf_dm
    驱动模型的一些初始化

  • initf_console_record
    如 果 定 义 了宏 CONFIG_CONSOLE_RECORD 和 宏CONFIG_SYS_MALLOC_F_LEN 的话此函数就会调用函数 console_record_init,但是 Hi3556v200的 uboot 没有定义宏 CONFIG_CONSOLE_RECORD,所以此函数直接返回 0

  • arch_cpu_init
    basic arch cpu dependent setup

  • mach_cpu_init, /* SoC/machine dependent CPU setup */

  • timer_init
    初始化定时器,Cortex-A7 内核有一个定时器,这里初始化的就是 Cortex-A 内核的那个定时器。通过这个定时器来为 uboot 提供时间。就跟 Cortex-M 内核 Systick 定时器一样

  • board_early_init_f
    板子相关的早期的一些初始化设置
    osdrv/opensource/uboot/u-boot-2016.11/board/hisilicon/hi3556v200/hi3556v200.c中,返回0.

  • env_init
    初始化环境变量地址
    gd->env_addr = (ulong)&default_environment[0]
    设置 gd 的成员变量 env_addr,也就是环境变量的保存地址。

  • init_baud_rate,
    /* initialze baudrate settings */

  • serial_init,
    /* serial communications setup */

  • console_init_f,
    /* stage 1 init of console */

  • show_board_info
    If the root node of the DTB has a “model” property, show it

  • INIT_FUNC_WATCHDOG_INIT

  • dram_init
    只是设置了ddr大小
    gd->ram_size += gd->bd->bi_dram[i].size

  • testdram
    dram测试程序

  • display_options, /* say that we are here */

  • display_text_info, /* show debugging info if required */

  • setup_dest_addr
    /*
    * Now that we have DRAM mapped and working, we can
    * relocate the code and continue running from DRAM.
    *
    * Reserve memory at end of RAM for (top down in that order):
    * - area that won’t get touched by U-Boot and Linux (optional)
    * - kernel log buffer
    * - protected RAM
    * - LCD framebuffer
    * - monitor code
    * - board info struct
    */
    如上为setup_dest_addr的注释,setup_dest_addr将设置uboot的重定位地址,后面就可以执行重定位并转向重定位后的地址执行
    编译阶段osdrv_mem_cfg.sh脚本按照soc来进行修改位于osdrv/opensource/uboot/u-boot-2016.11/tools/include/configs/hi3559v200.h中的宏,包括:
    #define PHYS_SDRAM_1 0x80000000
    #define PHYS_SDRAM_1_SIZE 0x10000000
    #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
    setup_dest_addr主要初始化了gd的如下成员变量
    gd->ram_top = CONFIG_SYS_SDRAM_BASE//DRAM基地址
    gd->ram_top += get_effective_memsize();//gd->ram_top被初始化为DRAM的最顶端地址
    gd->ram_top = board_get_usable_ram_top(gd->mon_len);
    gd->relocaddr = gd->ram_top;//uboot的重定位地址,当前为DRAM最顶端地址,会根据预留空间逐步调整

  • reserve_logbuffer
    为logbuffer预留空间,同时下调gd->relocaddr
    gd->relocaddr -= LOGBUFF_RESERVE

  • reserve_pram
    参数预留,同时下调gd->relocaddr
    reg = getenv_ulong(“pram”, 10, CONFIG_PRAM);
    gd->relocaddr -= (reg << 10); /* size is in kB */

  • reserve_mmu
    为mmu预留空间,同时下调gd->relocaddr
    gd->arch.tlb_size = PGTABLE_SIZE;
    gd->relocaddr -= gd->arch.tlb_size;

  • reserve_lcd
    gd->fb_base = CONFIG_FB_ADDR;
    gd->relocaddr = lcd_setmem(gd->relocaddr);
    gd->fb_base = gd->relocaddr;

  • reserve_uboot
    gd->relocaddr -= gd->mon_len;//为uboot预留空间,同时下调gd->relocaddr
    gd->relocaddr &= ~(4096 - 1);
    debug(“Reserving %ldk for U-Boot at: %08lx\n”, gd->mon_len >> 10,
    gd->relocaddr);
    gd->start_addr_sp = gd->relocaddr;
    留出重定位后的 uboot 所占用的内存区域,uboot 所占用大小由gd->mon_len 所指定
    留出 uboot 的空间以后还要对 gd->relocaddr 做 4K 字节对齐,并且重新设置
    gd->start_addr_sp = gd->relocaddr;
    从上面的预留方法可以看出,是通过dram的最高地址开始,一直递减来为各部分预留空间
    到此处已经确认出

  • reserve_malloc
    为malloc预留空间
    gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;

  • reserve_board
    为bd_t结构体预留空间

  • setup_machine
    gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */

  • reserve_global_data
    设置新的global data空间
    gd->start_addr_sp -= sizeof(gd_t);
    gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
    debug(“Reserving %zu Bytes for Global Data at: %08lx\n”,
    sizeof(gd_t), gd->start_addr_sp);

  • reserve_fdt
    为fdt预留空间
    gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
    gd->start_addr_sp -= gd->fdt_size;
    gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
    debug(“Reserving %lu Bytes for FDT at: %08lx\n”,
    gd->fdt_size, gd->start_addr_sp);

  • reserve_stacks
    为栈预留16字节

int arch_reserve_stacks(void)
{

        /* setup stack pointer for exceptions */
        gd->irq_sp = gd->start_addr_sp;

# if !defined(CONFIG_ARM64)
#  ifdef CONFIG_USE_IRQ
        gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
        debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
              CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp);

        /* 8-byte alignment for ARM ABI compliance */
        gd->start_addr_sp &= ~0x07;
#  endif
        /* leave 3 words for abort-stack, plus 1 for alignment */
        gd->start_addr_sp -= 16;
# endif
        return 0;
}
  • setup_dram_config

  • show_dram_config
    显示RAM信息

  • display_new_sp
    debug(“New Stack Pointer is: %08lx\n”, gd->start_addr_sp);

  • setup_reloc
    gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
    获取当前uboot代码与重定位后的uboot代码之间的偏移,其中
    osdrv/opensource/uboot/u-boot-2016.11/include/configs/hi3556v200.h中有如下的定义:
    #define CONFIG_SYS_TEXT_BASE 0x80800000
    memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
    将global data从sram重定位到dram中的reloc addr
    也就是说setup_reloc首先计算重定位的偏移,并完成global data的重定位

3. 总结

综上所述,可以画出如下的内存布局
Hi3556v200 u-boot+Liteos方案启动流程分析--3.通用uboot分析之board_init_f_第1张图片

你可能感兴趣的:(Hi3556,uboot)