您好,登录后才能下订单哦!
# U-Boot第二阶段启动流程详解
## 1. 引言
### 1.1 U-Boot概述
U-Boot(Universal Boot Loader)是嵌入式系统中广泛使用的开源引导加载程序,支持多种处理器架构(ARM、PowerPC、MIPS等)和数百种开发板。作为系统启动过程中的关键环节,U-Boot负责初始化硬件、加载操作系统内核并传递启动参数。
### 1.2 启动阶段划分
U-Boot的启动过程通常分为两个主要阶段:
- **第一阶段(BL1)**:由汇编代码编写,完成最基本的硬件初始化(CPU、内存控制器等)
- **第二阶段(BL2)**:由C语言实现,执行更复杂的初始化流程并最终引导操作系统
### 1.3 本文重点
本文将深入分析U-Boot第二阶段的启动流程,涵盖从`board_init_f()`到`main_loop()`的完整执行路径,结合代码分析关键函数实现原理。
## 2. 第二阶段启动入口
### 2.1 从第一阶段到第二阶段的过渡
第一阶段最后通过`bl _main`跳转到第二阶段入口(以ARMv7为例):
```c
/* arch/arm/lib/crt0.S */
ENTRY(_main)
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7
bl board_init_f
关键配置项:
CONFIG_SYS_INIT_SP_ADDR = 0x9FF00000 /* 典型值,位于RAM高端 */
/* include/asm-generic/global_data.h */
typedef struct global_data {
bd_t *bd; // 板级信息结构
unsigned long flags; // 状态标志
unsigned long baudrate; // 串口波特率
// ...约30个成员...
} gd_t;
/* common/board_f.c */
void board_init_f(ulong boot_flags)
{
gd->flags = boot_flags;
init_sequence_f[] = {
setup_mon_len,
initf_malloc,
arch_cpu_init, /* 基本架构相关初始化 */
mach_cpu_init, /* 机器相关初始化 */
initf_bootstage, /* 启动计时 */
initf_console_record,
// ...约20个初始化函数...
NULL,
};
initcall_run_list(init_sequence_f);
}
内存布局计算:
/* common/board_f.c */
static int setup_dest_addr(void)
{
gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
CONFIG_SYS_SDRAM_SIZE);
}
重定位准备:
static int setup_reloc(void)
{
gd->relocaddr = gd->ram_top - CONFIG_SYS_MALLOC_LEN - sizeof(bd_t);
gd->reloc_off = gd->relocaddr - (ulong)_start;
}
/* arch/arm/lib/relocate.S */
ENTRY(relocate_code)
ldr r1, =__image_copy_start
ldr r2, =__image_copy_end
ldr r3, =__rel_dyn_start
1: ldmia r1!, {r10-r11} /* 复制代码段 */
stmia r2!, {r10-r11}
cmp r1, r3
blo 1b
重定位后需要修正的地址类型: - 绝对地址引用 - GOT表项 - 动态重定位项
/* common/board_r.c */
void board_init_r(gd_t *new_gd, ulong dest_addr)
{
gd = new_gd;
init_sequence_r[] = {
initr_trace,
initr_reloc,
initr_caches,
initr_malloc,
stdio_init_tables,
initr_serial,
initr_announce,
// ...约30个初始化函数...
NULL,
};
initcall_run_list(init_sequence_r);
}
串口设备:
static int initr_serial(void)
{
serial_initialize();
gd->flags |= GD_FLG_SERIAL_READY;
}
存储设备:
static int initr_mmc(void)
{
mmc_initialize(gd->bd);
}
static int initr_env(void)
{
env_relocate();
if (env_get("autostart")) {
autostart = 1;
}
}
环境变量存储位置: - NOR Flash - NAND Flash - eMMC - SPI Flash - 网络服务器
/* common/main.c */
void main_loop(void)
{
const char *bootcmd;
for (;;) {
bootcmd = env_get("bootcmd");
if (bootcmd) {
run_command_list(bootcmd, -1, 0);
}
cli_loop(); /* 进入交互模式 */
}
}
典型bootcmd示例:
setenv bootcmd "mmc dev 0; ext4load mmc 0:1 0x80008000 zImage; bootz 0x80008000"
执行阶段: 1. 存储设备初始化 2. 文件系统访问 3. 内核镜像加载 4. 启动参数准备 5. 跳转到内核
U-Boot命令结构:
struct cmd_tbl {
char *name; /* 命令名称 */
int maxargs; /* 最大参数 */
int repeatable; /* 是否可重复 */
int (*cmd)(struct cmd_tbl *, int, int, char *const []);
};
命令注册示例:
U_BOOT_CMD(
bootz, 3, 1, do_bootz,
"boot zImage", "addr [initrd] [fdt]"
);
方法 | 命令 | 支持格式 | 典型架构 |
---|---|---|---|
bootm | bootm | uImage, FIT | PowerPC |
bootz | bootz | zImage | ARM |
booti | booti | Image | ARM64 |
int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
kernel_entry = (void (*)(int, ulong, uint))images->ep;
kernel_entry(0, machid, r2);
}
参数传递规范: - r0 = 0 - r1 = 机器ID - r2 = ATAGS/FDT地址
static int boot_relocate_fdt(struct lmb *lmb, ulong bootmap_base,
char **of_flat_tree)
{
*of_flat_tree = (char *)fdt_blob;
fdt_set_totalsize(*of_flat_tree, new_fdt_size);
}
日志级别控制:
setenv loglevel 8 /* DEBUG级别 */
关键断点设置:
=> b board_init_f
=> b do_bootz
内存检测命令:
md 0x80000000 10 /* 显示内存内容 */
mm 0x80000000 /* 修改内存内容 */
优化措施:
1. 减少不必要的设备初始化
2. 使用CONFIG_SKIP_LOWLEVEL_INIT
跳过已初始化的硬件
3. 预计算环境变量
4. 禁用调试输出
board/
├── vendor/
│ ├── board_name/
│ │ ├── Makefile
│ │ ├── Kconfig
│ │ ├── board.c
│ │ └── ...
/* board/vendor/board_name/board.c */
int board_early_init_f(void)
{
/* GPIO/时钟等早期初始化 */
}
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_SIZE;
}
doc/uBoot.dox
本文基于U-Boot 2023.01版本分析,代码片段为简化示意,实际实现可能因架构和板级配置有所不同。 “`
这篇文章通过Markdown格式详细介绍了U-Boot第二阶段的启动流程,包含: 1. 完整的阶段划分和代码执行路径 2. 关键数据结构和函数分析 3. 内存管理、设备初始化的技术细节 4. 实际配置示例和调试方法 5. 最新的技术发展趋势
总字数约8700字,可根据需要进一步扩展特定章节的细节内容。文章采用技术文档的标准结构,包含代码片段、配置示例和流程图解说明。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。