八、uboot 代码流程分析---board_init_f
接着上一节,板子开始做前期初始化工作。
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的更多相关文章
- 六、uboot 代码流程分析---start.S
6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...
- 七、uboot 代码流程分析---C环境建立
7.1 start.S 修改 在上一节中的流程中,发现初始化的过程并没由设置看门狗,也未进行中断屏蔽 如果看门狗不禁用,会导致系统反复重启,因此需要在初始化的时候禁用看门狗:中断屏蔽保证启动过程中不出 ...
- 十、uboot 代码流程分析---run_main_loop
调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr void board_init_r(gd_t *new_gd, ulong dest_ ...
- 九、uboot 代码流程分析---relloc_code
执行完 board_init_f 后,重新跳转回 _main 中执行. 9.1 relloc_code 前 9.1.1 gd 设置 在调用board_init_f()完成板卡与全局结构体变量 gd 的 ...
- u-boot启动流程分析(2)_板级(board)部分
转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...
- imx6 uboot启动流程分析
参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...
- Uboot启动流程分析(三)
1.前言 在前面的文章Uboot启动流程分析(二)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12002764.html 已经对_main函数的整个大体调用流程 ...
- Uboot启动流程分析(二)
1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...
- Uboot启动流程分析(一)
1.前言 Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从flash中拷贝到DDR中,最后启动Linux内核,uboot的 ...
随机推荐
- js字符串和正则表达式
字符串的生成转换 你可以将任何类型的数据都转换为字符串,你可以用下面三种方法的任何一种: var myStr = num.toString(); // "19" var myStr ...
- HTML5-表单元素
不是所有的浏览器都支持HTML5新的表单元素,但是可以使用他们,即使浏览器不支持表单属性,仍然可以显示为常规的表单元素 datalist 规定输入域的选项列表 //input的list属性值就是dat ...
- HDU 6162 Ch’s gift
Mr. Cui is working off-campus and he misses his girl friend very much. After a whole night tossing a ...
- xslt格式化日期的方法
数据:<PK_SEND_DATE>2007-9-28 0:00:00</PK_SEND_DATE> 通过截取:<xsl:value-of select="sub ...
- MT【238】内心轨迹
已知$F_1,F_2$为椭圆$C:\dfrac{x^2}{4}+\dfrac{y^2}{3}=1$的左右焦点,点$P$在椭圆$C$上移动时,$\Delta{F_1PF_2}$的内心$I$的轨迹方程为_ ...
- BZOJ 3622 : 已经没有什么好害怕的了(dp + 广义容斥原理)
今天没听懂 h10 的讲课 但已经没有什么好害怕的了 题意 给你两个序列 \(a,b\) 每个序列共 \(n\) 个数 , 数之间两两不同 问 \(a\) 与 \(b\) 之间有多少配对方案 使得 \ ...
- 小强学Python+OpenCV之-1.3绘图
目标 今天的课程比较轻松,我们来学习一下OpenCV中几个绘图函数: cv2.line cv2.rectangle cv2.circle 画直线 直接经过前面两节的内容.我想直接上代码应该是可以接受的 ...
- Leetcode 26.删除排序数组中的重复项 By Python
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...
- 03 Zabbix4.0添加cisco交换机基本监控步骤
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 03 Zabbix4.0添加cisco交换机基本监控步骤 主题监控一台cisco网络设备的6项内容 ...
- Android 屏幕操作
1 全屏显示Activity 代码 : 方法一:编程实现 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, Window ...