10. uboot 开发
本节简单介绍 U-Boot 基本概念和编译的注意事项,帮助客户了解 RK 平台 U-Boot 框架,具体 U-Boot开发细节可参考:<SDK>/docs/cn/Common/U-Boot/Rockchip-Developer-Guide-UBoot-*.pdf
小技巧
使用我司的XNIUPI-小牛派R系列产品,您可以直接使用我们提供的Bootloader源码,无需自行开发。以下内容,仅供需要深度二次开发的用户参考!
10.1 U-Boot 简介
v2017(next-dev) 是 RK 从 U-Boot 官方的 v2017.09 正式版本中切出来进行开发的版本,目前已经支持 RK 所有主流在售芯片。支持的功能主要有:
支持RK Android固件启动;
支持Android AOSP固件启动;
支持Linux Distro固件启动;
支持Rockchip miniloader和SPL/TPL两种Pre - loader引导;
支持LVDS、EDP、MIPI、HDMI、CVBS、RGB等显示设备;
支持eMMC、Nand Flash、SPI Nand flash、SPI NOR flash、SD卡、U盘等存储设备启动;
支持FAT、EXT2、EXT4文件系统;
支持GPT、RK parameter分区表;
支持开机LOGO、充电动画、低电管理、电源管理;
支持I2C、PMIC、CHARGE、FUEL GUAGE、USB、GPIO、PWM、GMAC、eMMC、NAND、Interrupt等;
支持Vendor storage保存用户的数据和配置;
支持RockUSB和Google Fastboot两种USB gadget烧写eMMC;
支持Mass storage、ethernet、HID等USB设备;
支持通过硬件状态动态选择kernel DTB;
注解
v2017已开源且定期更新到Github:rk-uboot_v2017
10.2 前期准备
下载rkbin 这是一个工具包仓库,用于存放RK不开源的bin、脚本、打包工具。U-Boot编译时会从该仓库索引相关文件,打包生成loader、trust、uboot固件。rkbin和U-Boot工程必须保持同级目录关系。
下载GCC GCC编译器使用gcc-linaro-6.3.1,放置于prebuilds目录之内。prebuilds和U-Boot保持同级目录关系。如下:
// 32 位 :prebuilds/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf// 64 位: prebuilds/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/
选择defconfig
"[芯片]_defconfig"或"[芯片].config"通常都是全功能版本,其余为特定feature版本。
10.3 启动流程
RK平台的U-Boot启动流程如下,仅列出一些重要步骤:
start.s
// 汇编环境
=> IRQ/FIQ/lowlevel/vbar/errata/cp15/gic // ARM 架构相关的 lowlevel 初始化
=> _main
=> stack // 准备好 C 环境需要的栈
// 【第一阶段】C 环境初始化,发起一系列的函数调用
=> board_init_f: init_sequence_f []
initf_malloc
arch_cpu_init // 【SoC 的 lowlevel 初始化】
serial_init // 串口初始化
dram_init // 获取 ddr 容量信息
reserve_mmu // 从 ddr 末尾开始往低地址 reserve 内存
reserve_video
reserve_uboot
reserve_malloc
reserve_global_data
reserve_fdt
reserve_stacks
dram_init_banksize
sysmem_init
setup_reloc // 确定 U-Boot 自身要 reloc 的地址
// 汇编环境
=> relocate_code // 汇编实现 U-Boot 代码的 relocation
// 【第二阶段】C 环境初始化,发起一系列的函数调用
=> board_init_r: init_sequence_r []
initr_caches // 使能 MMU 和 I/Dcache
initr_malloc
bidram_initr
sysmem_initr
initr_of_live // 初始化 of_live
initr_dm // 初始化 dm 框架
board_init // 【平台初始化,最核心部分】
board_debug_uart_init // 串口 iomux、clk 配置
init_kernel_dtb // 【切到 kernel dtb】!
clks_probe // 初始化系统频率
regulators_enable_boot_on // 初始化电源系统
io_domain_init //io-domain 初始化
set_armclk_rate //__weak, ARM 提到 (平台有需求才实现)
dvfs_init // 宽温芯片的调频调压
rk_board_init //__weak, 由各个具体平台进行实现
console_init_r
board_late_init // 【平台 late 初始化】
rockchip_set_ethaddr // 设置 Mac 地址
rockchip_set_serialno // 设置 Serialno
setup_boot_mode // 解析 "reboot xxx" 命令、
// 识别按键和 loader 烧写模式、recovery
charge_display // U-Boot 充电
rockchip_show_logo // 显示开机 logo
soc_clk_dump // 打印 clk tree
rk_board_late_init //__weak, 由各个具体平台进行实现
run_main_loop // 【进入命令行模式,或执行启动命令】
10.4 快捷键
RK平台提供串口组合键触发一些事件用于调试、烧写(如果无法触发,请多尝试几次;启用secure-boot时无效)。开机时长按:
ctrl+c
:进入U-Boot命令行模式;ctrl+d
:进入loader烧写模式;ctrl+b
:进入maskrom烧写模式;ctrl+f
:进入fastboot模式;ctrl+m
:打印bidram/system信息;ctrl+i
:使能内核initcall_debug;ctrl+p
:打印cmdline信息;ctrl+s
:"Starting kernel..."之后进入U-Boot命令行;