文章目录
- 一、目录结构
- 二、uboot修改
-
- (一)uboot启动阶段:
-
- [阶段一 SPL](#阶段一 SPL)
- [阶段二 U-boot main](#阶段二 U-boot main)
- [阶段三 启动OS](#阶段三 启动OS)
- [(二)板级初始化函数 uboot main阶段](#(二)板级初始化函数 uboot main阶段)
- (三)后期初始化函数
- (四)修改uboot配置
一、目录结构
bash
u-boot/
├── arch/arm/mach-rockchip/ # SoC 公共代码(如 rk3576)
├── board/rockchip/ # 各开发板实现
│ └── evb_rk3576/
├── include/dt-bindings/ # 设备树绑定头文件
└── configs/ # defconfig 配置文件
- 补充:3576的gpio定义的头文件 u-boot/arch/arm/include/asm/arch-rockchip/gpio.h
二、uboot修改
3576的板子,主要修改文件就是 board/rockchip/evb_rk3576/evb_rk3576.c
(一)uboot启动阶段:
uboot启动流程:
采用 SPL + U-Boot 架构
uboot的板级初始化函数是可选的,如果不定义board_early_init_f() ,uboot就会跳过
如果定义了,就会在DRAM初始化后,环境变量加载前被调用。
阶段一 SPL
最小初始化,初始化时钟和DRAM,拷贝uboot main到DRAM 此时无DRAM(仅用SRAM/Cache),极简的C运行环境
阶段二 U-boot main
完整初始化(DRAM、外设、网络等),DRAM可用,完整的C环境,malloc、printf等可用
阶段三 启动OS
加载kernel,传递参数
(二)板级初始化函数 uboot main阶段
Generic Board / DM 驱动模型
将启动流程标准化为 board_f.c(前期) + board_r.c(后期);
所有板子共用同一套初始化框架,通过 钩子函数(如 board_early_init_f) 实现差异化。
入口:arch/arm/lib/crt0_64.S(或 crt0.S) → 跳转到 board_init_f
主流程:common/board_f.c → board_init_f()
调用点:
c
// u-boot/common/board_f.c
static const init_fnc_t init_sequence_f[] = {
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
#endif
#ifdef CONFIG_TRACE
trace_early_init,
#endif
initf_malloc,
log_init,
initf_bootstage, /* uses its own timer, so does not need DM */
initf_console_record,
#if defined(CONFIG_HAVE_FSP)
arch_fsp_init,
#endif
arch_cpu_init, /* basic arch cpu dependent setup */
mach_cpu_init, /* SoC/machine dependent CPU setup */
initf_dm,
arch_cpu_init_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
......
dram_init, /* configure available RAM banks */
......
NULL,
};
- 补充:DRAM 由 SPL 初始化,在早期通过initf_dm来初始化DM子系统,并非通过dram_init初始化DRAM,dram_init只是告诉uboot哪些内存可用
CONFIG_BOARD_EARLY_INIT_F 需要显式开启
(三)后期初始化函数
c
// u-boot/common/board_r.c
static init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
......
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
......
};
c
// arch/arm/mach-rockchip/board.c
__weak int rk_board_late_init(void)
{
return 0;
}
......
int board_late_init(void)
{
......
return rk_board_late_init();
}
CONFIG_BOARD_LATE_INIT需要开启
板级覆盖函数名应该为rk_board_late_init,而不是_board_late_init
要覆盖一个__weak函数,必须使用完全相同的函数名
(四)修改uboot配置
bash
# 进入菜单后修改配置并保存
make menuconfig
# 保存defconfig
make savedefconfig
# 保存配置到defconfig
cp defconfig ./configs/rk3576_defconfig