接着上一节,板子开始做前期初始化工作。

8.1 board_init_f

  board_f.c (common)

 /* 板子初次初始化。boot_flags = 0 */
void board_init_f(ulong boot_flags)
{
gd->flags = boot_flags;
gd->have_console = ; if (initcall_run_list(init_sequence_f))
hang(); #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
!defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64)
/* NOTREACHED - jump_to_copy() does not return */
hang();
#endif
}

  boot_flags 标志位0,且终端标志位也为0,在 initcall_run_list(init_sequence_f) 链表中执行板子初始化过程

8.2 init_sequence_f 函数数组

 static init_fnc_t init_sequence_f[] = {
setup_mon_len, ///< 设置gd->mon_len为编译出来的u-boot.bin+bss段的大小
initf_malloc, ///< 设置内存池的大小 gd->malloc_limit = 0x400, gd->malloc_ptr = 0
initf_console_record, ///< 为空,直接返回 0
arch_cpu_init, ///< 基本arch cpu相关设置, 未做初始化
mach_cpu_init, ///< SoC/machine 相关CPU设置, 未作设置
initf_dm, ///< 驱动模型的初始化, 未开宏
arch_cpu_init_dm, ///< 驱动模型相关的 CPU 初始化, 未开宏
mark_bootstage, /* need timer, go after init dm */
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f, ///< 时钟和 GPIO 的初始化
#endif #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \
defined(CONFIG_SH) || defined(CONFIG_SPARC)
timer_init, ///< 定时器初始化
#endif env_init, ///< initialize environment, 初始化环境变量结构体 default_environment
///< env_dataflash.c 中是此时的实际调用
init_baud_rate, /* 波特率设置 */
serial_init, /* 串行通信初始化 */
console_init_f, /* 在重定位之前使能串口功能 */
display_options, /* 打印 uboot 版本信息 */
display_text_info, /* 打印 uboot 配置信息 */
print_cpuinfo, /* 显示 CPU 信息 */
#if defined(CONFIG_DISPLAY_BOARDINFO)
show_board_info, ///< 显示板子信息,需要复写函数
#endif
announce_dram_init, ///< 打印了一个 DRAM: 字符串
/* TODO: unify all these dram functions? */
#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_NDS32) || \
defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || \
defined(CONFIG_SH)
dram_init, /* 配置 DRAM 大小, gd->ram_size = 0x04000000 , 即 64MB*/
#endif
/*
* 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, ///< 重定位地址设置 gd->relocaddr = gd->ram_top = 0x3400 0000
reserve_round_4k,
reserve_trace, ///< trace 设置,移动gd->relocaddr,未配置,不动
#if !defined(CONFIG_BLACKFIN) && !defined(CONFIG_XTENSA)
reserve_uboot, ///< 留出 uboot.bin 的空间 gd->relocaddr 下移后, gd->start_addr_sp = gd->relocaddr
#endif
#ifndef CONFIG_SPL_BUILD
reserve_malloc,
reserve_board,
#endif
setup_machine, ///< 不做初始化
reserve_global_data, ///< 初始化 global_data 的空间,gd->start_addr_sp -= sizeof(gd_t);
reserve_fdt, ///< 未开特性
reserve_arch, ///< 未做任务
reserve_stacks, ///< gd->start_addr_sp 16字节对齐
setup_dram_config, ///< DRAM配置前面已经做了
show_dram_config, ///< 显示 DRAM 的大小 64M
display_new_sp, ///< 打印当前栈
reloc_fdt, ///< 未作配置
setup_reloc, ///< gd->reloc_off = gd->relocaddr reloc_off 设置为栈顶
NULL,
};

8.2.1 setup_mon_len

 /* 设置gd->mon_len为编译出来的u-boot.bin+bss段的大小 */
static int setup_mon_len(void)
{
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
return ;
}

  _start 的地址为 0

8.2.2 initf_malloc

 /* 设置内存池的大小 */
int initf_malloc(void)
{
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
assert(gd->malloc_base); /* Set up by crt0.S */
gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
gd->malloc_ptr = ;
#endif return ;
}

8.2.3 设置重定位地址---setup_dest_addr

 /* 设置重定位地址 */
static int setup_dest_addr(void)
{
debug("Monitor len: %08lX\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
*/
debug("Ram size: %08lX\n", (ulong)gd->ram_size);
#ifdef CONFIG_SYS_SDRAM_BASE /* JZ2440 = CONFIG_SYS_SDRAM_BASE = 0x30000000 */
gd->ram_top = CONFIG_SYS_SDRAM_BASE;
#endif
gd->ram_top += get_effective_memsize(); /* gd->ram_top = 0x30000000 + 0x400 0000 = 0x3400 0000 */
/* 此段依然返回 SDRAM 顶端地址 0x3400 0000 */
gd->ram_top = board_get_usable_ram_top(gd->mon_len);
gd->relocaddr = gd->ram_top; /* 重定位地址为 0x3400 0000 */
debug("Ram top: %08lX\n", (ulong)gd->ram_top);
return ;
}

  gd->relocaddr = 0x34000000 指向 SDRAM 的顶端

8.2.4 uboot 和 bss段---reserve_uboot

 /* 预留 uboot 区,gd->start_addr_sp = gd->relocaddr -= gd->mon_len  */
static int reserve_uboot(void)
{
/*
* reserve memory for U-Boot code, data & bss
* round down to next 4 kB limit
*/
gd->relocaddr -= gd->mon_len;
gd->relocaddr &= ~( - );
#if defined(CONFIG_E500) || defined(CONFIG_MIPS)
/* round down to next 64 kB limit so that IVPR stays aligned */
gd->relocaddr &= ~( - );
#endif debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> ,
gd->relocaddr); gd->start_addr_sp = gd->relocaddr; return ;
}

  栈 gd->start_addr_sp 指向 uboot 段 基地址

8.2.5 堆区---reserve_malloc

 /* malloc 堆区预留大小 */
static int reserve_malloc(void)
{
/* PHYS_FLASH_1 = 0x00000000
CONFIG_SYS_FLASH_BASE = PHYS_FLASH_1
CONFIG_ENV_ADDR = CONFIG_SYS_FLASH_BASE + 0x070000 = 0x070000
CONFIG_ENV_IS_IN_FLASH
CONFIG_ENV_SIZE = 0x10000 */
/* CONFIG_SYS_MALLOC_LEN = 4 * 1024 * 1024 = 0x40 0000 */
/* TOTAL_MALLOC_LEN = CONFIG_SYS_MALLOC_LEN */
gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
debug("Reserving %dk for malloc() at: %08lx\n",
TOTAL_MALLOC_LEN >> , gd->start_addr_sp);
return ;
}

  栈 gd->start_addr_sp 指向 malloc 段 基地址

8.2.6 预留 bd 区域 --- reserve_board

 /* board 信息结构体分配区域 */
static int reserve_board(void)
{
if (!gd->bd) {
gd->start_addr_sp -= sizeof(bd_t);
gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));
memset(gd->bd, '\0', sizeof(bd_t));
debug("Reserving %zu Bytes for Board Info at: %08lx\n",
sizeof(bd_t), gd->start_addr_sp);
}
return ;
}

  栈 gd->start_addr_sp 指向 bd 段 基地址

8.2.7 预留全局数据区域---reserve_global_data

 /* 预留 GD 区域 */
static int reserve_global_data(void)
{
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);
return ;
}

  栈 gd->start_addr_sp 指向 gd 段 基地址

8.2.8 栈区预留区---reserve_stacks

 /* 栈区预留区,gd->start_addr_sp 指向 栈底基地址 */
static int reserve_stacks(void)
{
/* make stack pointer 16-byte aligned */
gd->start_addr_sp -= ;
gd->start_addr_sp &= ~0xf; /*
* let the architecture-specific code tailor gd->start_addr_sp and
* gd->irq_sp
*/
return arch_reserve_stacks();
}

  gd->start_addr_sp 指向 栈底基地址

8.3 小节

  代码执行完后,则返回,当前栈地址指向栈处,依然有大部分区域未分配。

  当前分配的区域如下:

  

八、uboot 代码流程分析---board_init_f的更多相关文章

  1. 六、uboot 代码流程分析---start.S

    6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...

  2. 七、uboot 代码流程分析---C环境建立

    7.1 start.S 修改 在上一节中的流程中,发现初始化的过程并没由设置看门狗,也未进行中断屏蔽 如果看门狗不禁用,会导致系统反复重启,因此需要在初始化的时候禁用看门狗:中断屏蔽保证启动过程中不出 ...

  3. 十、uboot 代码流程分析---run_main_loop

    调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr void board_init_r(gd_t *new_gd, ulong dest_ ...

  4. 九、uboot 代码流程分析---relloc_code

    执行完 board_init_f 后,重新跳转回 _main 中执行. 9.1 relloc_code 前 9.1.1 gd 设置 在调用board_init_f()完成板卡与全局结构体变量 gd 的 ...

  5. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  6. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  7. Uboot启动流程分析(三)

    1.前言 在前面的文章Uboot启动流程分析(二)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12002764.html 已经对_main函数的整个大体调用流程 ...

  8. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...

  9. Uboot启动流程分析(一)

    1.前言 Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从flash中拷贝到DDR中,最后启动Linux内核,uboot的 ...

随机推荐

  1. 智能制造(MES)四大阶段

    智能制造的发展会经历标准化.自动化.信息化.智能化四个阶段标准化,对于生产流程.业务流程.生产制造多方面的标准化.质量检测标准化.企业管理.供应链等.标准化是组织现代化生产的重要组成部分,对于生产专业 ...

  2. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):3. 随机颜色及清除按钮

    1. 随机颜色 通过前面的教程,咪博士已经带大家实现了画板的绘图功能.但是,现在画板只能画出黄色的图案,还十分单调,接下来咪博士就教大家,如何使用随机颜色,让画板变得五彩斑斓. 改进后的代码如下: f ...

  3. BZOJ2588Count on a tree——LCA+主席树

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  4. LightOJ 1030 【概率DP求期望】

    借鉴自:https://www.cnblogs.com/keyboarder-zsq/p/6216762.html 题意:n个格子,每个格子有一个值.从1开始,每次扔6个面的骰子,扔出几点就往前几步, ...

  5. day24 新三级菜单

    china = { "shandong":{ "linyi":["lanshan","nanfang","he ...

  6. 洛谷 P4074 [WC2013]糖果公园 解题报告

    P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...

  7. 洛谷 P2812 校园网络【[USACO]Network of Schools加强版】 解题报告

    P2812 校园网络[[USACO]Network of Schools加强版] 题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是 ...

  8. JAVA过滤器的使用(Filter)

    request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf ...

  9. max,min,Zip函数(十一)

    zip函数,拉链,传两个有序的参数,将他们一一对应为元祖形式 max,min比较默认比较一个元素,处理的是可迭代对象,相当于for循环取出每个元素进行比较,注意:不同类型之间不可比较 #!/usr/b ...

  10. NCBI上查看SNP位点在哪个基因座上(locus)

    首先,进入NCBI的主页网站:https://www.ncbi.nlm.nih.gov/variation/view/ 进入后,在下图红色框框位置输入目的SNP,比如rs608139 输完后,出现如下 ...