100ASK-T113 Pro 开发板 Bootloader 完全开发指南
本章基于 Tina-Linux SDK,深入讲解 Bootloader(U-Boot)的组成、编译、配置、修改及烧录方法。包含大量实战示例,从环境搭建到修改设备树、增加开机 Logo、使用 fastboot 更新分区,手把手带你掌握嵌入式 Linux 启动的第一阶段。学完本章,你将能独立对 T113 开发板的 U-Boot 进行定制和调试。
文章目录
- 100ASK-T113 Pro 开发板 Bootloader 完全开发指南
- 一、Tina-Linux Bootloader 简述
- 1.1 什么是 Bootloader?
- 1.2 Tina-Linux 启动流程(文字描述)
- 二、单独编译 Bootloader 部分
- 2.1 准备编译工具链
- 2.2 快速编译 boot0 及 U-Boot
- 2.3 单独编译 U-Boot
- 2.4 单独编译 BOOT0 / FES / SBOOT
- 三、单独配置 U-Boot
- 3.1 U-Boot 设备树与环境变量文件
- 3.2 U-Boot 源码所在位置
- 3.3 Tina 系统指定的配置文件
- 3.4 编译打包与更新
- 四、修改系统启动环境变量
- 4.1 查看 U-Boot 默认环境变量
- 4.2 修改启动等待时间
- 4.3 设置为默认配置(永久修改)
- 五、U-Boot 支持的命令(部分常用)
- 5.1 信息查询类
- 5.2 环境变量操作
- 5.3 内存操作
- 5.4 存储介质操作
- 5.5 网络命令
- 5.6 FAT 文件系统命令
- 六、示例:U-Boot 下查看并修改内核设备树节点
- 6.1 FDT 命令基本用法
- 6.2 查询配置(以 WiFi 节点为例)
- 6.3 修改整数属性
- 6.4 修改字符串属性
- 6.5 GPIO 或 PIN 配置特殊说明
- 七、示例:使用 fastboot 更新系统分区
- 7.1 进入 fastboot 模式
- 7.2 主机端安装 fastboot 工具
- 7.3 查看设备连接
- 7.4 更新 boot 分区
- 7.5 其他分区
- 八、示例:修改 U-Boot 支持 RGB 屏幕
- 8.1 修改 U-Boot 设备树
- 8.2 修改 U-Boot 配置
- 8.3 编译并烧录
- 九、示例:U-Boot 下增加启动 LOGO 图
- 9.1 准备合适尺寸的图片
- 9.2 转换图片格式(如需要)
- 9.3 拷贝到特定目录
- 9.4 编译打包使用
- 9.5 调整图像大小(可选)
- 十、示例:固化自己的 U‑Boot 配置(重启不丢失)
- 10.1 修改默认环境变量(推荐用于 bootcmd、bootargs 等)
- 10.2 修改 Kconfig 配置(用于开启/关闭命令、功能)
- 10.3 验证固化是否成功
- 十一、必须掌握 vs 了解即可
- ✅ 必须掌握(面试/工作中高频)
- 🔍 了解即可(能看懂、不要求独立完成)
- 十二、面试官提问环节
- 第1问:U-Boot 中如何修改启动等待时间?如何永久生效?
- 第2问:U-Boot 中如何从 SD 卡加载内核并启动?
- 第3问:如何单独编译 U-Boot 而不重新编译整个 Tina 系统?
- 第4问:在 U-Boot 中修改设备树节点后,如何使修改生效并传递给内核?
- 第5问:为什么修改了 `env.cfg` 后重新烧录固件,但开发板上的环境变量还是旧的?
- 十三、常见问题与调试技巧
- 13.1 U-Boot 无法进入命令行?
- 13.2 修改设备树后屏幕依然不亮?
- 13.3 fastboot 无法识别设备?
- 十四、总结
一、Tina-Linux Bootloader 简述
1.1 什么是 Bootloader?
Bootloader 是系统上电后第一个执行的程序,负责初始化硬件(时钟、DDR、存储控制器等),然后将 Linux 内核加载到内存并启动。在 Tina-Linux SDK 中,Bootloader 由两部分组成:
- 一级引导程序(BOOT0):固化在芯片内部 BootROM 之后的第一个可执行程序,用汇编编写,极小,负责初始化 DDR 并将完整 U-Boot 加载到内存。
- 二级引导程序(U-Boot):功能强大的引导器,提供命令行接口、支持多种文件系统、网络下载、环境变量管理等。
1.2 Tina-Linux 启动流程(文字描述)
text
上电 → 芯片内部 BootROM 根据启动引脚选择启动介质(NAND/SD卡/SPI Flash) → 加载 BOOT0 到内部 SRAM 并执行 → BOOT0 初始化 DDR 控制器,将 U-Boot 从 Flash 复制到 DDR → 跳转到 U-Boot 执行 → U-Boot 初始化更多外设,根据环境变量加载内核 → 启动 Linux 内核我们将在后续章节详细讲解如何单独编译 BOOT0 和 U-Boot,以及如何修改它们的配置。
二、单独编译 Bootloader 部分
2.1 准备编译工具链
Tina-SDK 中已经包含了交叉编译工具链,位于prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin。在编译之前需要确保环境变量已加载:
bash
cd ~/tina-d1-h source build/envsetup.sh lunch 4 # 选择 t113_100ask-tina2.2 快速编译 boot0 及 U-Boot
在 SDK 的lichee/brandy-2.0/目录下,执行./build.sh -p <平台名称>可以一键编译整个 Bootloader。平台名称对应LICHEE_CHIP变量,对于 T113 是sun8iw20p1。
示例:
bash
cd lichee/brandy-2.0/ ./build.sh -p sun8iw20p1该命令会自动编译 BOOT0(包含 nand、emmc、spinor 版本)和 U-Boot。编译完成后,生成的文件会被复制到device/config/chips/t113/bin/以及out/t113-100ask/目录。
2.3 单独编译 U-Boot
如果只需要编译 U-Boot(不重新编译 BOOT0),可以进入 U-Boot 源码目录手动配置并编译。
bash
cd lichee/brandy-2.0/u-boot-2018/ make sun8iw20p1_uart3_defconfig # 配置为 T113 百问网开发板配置 make -j$(nproc)sun8iw20p1_uart3_defconfig是专门为 T113 百问网开发板准备的默认配置(调试串口为 UART3)。编译成功后,会在当前目录生成u-boot.bin,并自动重命名并复制到device/config/chips/t113/bin/u-boot-sun8iw20p1.bin。
2.4 单独编译 BOOT0 / FES / SBOOT
BOOT0 的源码位于lichee/brandy-2.0/spl/目录。进入该目录后,可以通过make命令选择不同存储介质进行编译。
编译用于 NAND Flash 的 boot0:
bash
cd lichee/brandy-2.0/spl make distclean make p=sun8iw20p1 m=nand make boot0编译用于 SD/eMMC 的 boot0:
bash
make distclean make p=sun8iw20p1 m=emmc make boot0编译 FES(工厂烧录相关):
bash
make distclean make p=sun8iw20p1 m=fes make fes编译 SBOOT(安全启动相关):
bash
make distclean make p=sun8iw20p1 m=sboot make sboot编译输出的文件位于spl/nboot/或out/t113-100ask/目录下,例如boot0_sdcard_sun8iw20p1.bin、boot0_nand_sun8iw20p1.bin。
必须掌握:如何单独编译 U-Boot 和 BOOT0。这在实际开发中频繁用到,例如修改 U-Boot 源码后只需重新编译 U-Boot 而无需重编整个系统。
三、单独配置 U-Boot
3.1 U-Boot 设备树与环境变量文件
Tina SDK 将板级配置放在device/config/chips/t113/configs/100ask/目录下,其中与 U-Boot 相关的文件有:
| 文件名 | 作用 |
|---|---|
uboot-board.dts | U-Boot 专用的设备树源文件,描述引脚、时钟等 |
env.cfg | 默认 U-Boot 环境变量(如 bootdelay、bootcmd、console) |
sys_config.fex | 硬件引脚复用、时钟、电源等配置(会参与生成设备树) |
注意:U-Boot 的设备树与内核的设备树是分开的。U-Boot 的设备树主要用于驱动显示、存储、网络等,以便加载内核。
3.2 U-Boot 源码所在位置
完整的 U-Boot 源码位于:
text
~/tina-d1-h/lichee/brandy-2.0/u-boot-2018/该目录下包含常见的 U-Boot 子目录:arch/、board/、common/、configs/、drivers/、dts/等。你可以在configs/目录中找到所有预定义的配置文件:
bash
cd lichee/brandy-2.0/u-boot-2018/configs/ ls -1 *sun8iw20p1*输出:
text
sun8iw20p1_defconfig sun8iw20p1_nor_defconfig sun8iw20p1_uart3_defconfig # 我们使用的配置3.3 Tina 系统指定的配置文件
Tina SDK 通过device/config/chips/t113/configs/100ask/BoardConfig.mk来指定 U-Boot 使用的配置:
makefile
LICHEE_CHIP := sun8iw20p1 LICHEE_BRANDY_VER := 2.0 LICHEE_BRANDY_DEFCONF := sun8iw20p1_uart3_defconfig当执行 SDK 顶层make时,构建系统会读取BoardConfig.mk,自动调用 U-Boot 的make sun8iw20p1_uart3_defconfig。
3.4 编译打包与更新
在 SDK 顶层目录,执行以下命令即可重新编译整个系统(包括 U-Boot)并打包固件:
bash
mboot # 单独编译 Bootloader(等同于 cd lichee/brandy-2.0 && ./build.sh -p sun8iw20p1) make -j$(nproc) # 编译完整系统(包括内核、包等) pack # 打包生成最终烧录镜像如果只修改了 U-Boot 源码,可以只运行mboot,然后pack,最后烧录镜像。这样比完整编译节省大量时间。
四、修改系统启动环境变量
4.1 查看 U-Boot 默认环境变量
连接开发板串口(波特率 115200),上电后迅速按空格键进入 U-Boot 命令行。输入print命令即可查看所有环境变量:
bash
=> print bootdelay=1 console=ttyS3,115200 bootcmd=run setargs_nand_ubi boot_normal ...关键变量解释:
bootdelay:自动启动前的等待秒数,默认为 1。bootcmd:U-Boot 自动执行的命令,例如此处为run setargs_nand_ubi boot_normal。setargs_nand:定义传递给内核的启动参数(bootargs),包括根文件系统位置、控制台等。setargs_mmc:当从 SD 卡启动时使用的 bootargs。boot_normal:实际加载内核的命令(sunxi_flash read ...; bootm ...)。
4.2 修改启动等待时间
在 U-Boot 命令行中修改bootdelay并保存:
bash
=> setenv bootdelay 3 => saveenv => reset重启后会发现倒计时变成了 3 秒。
必须掌握:
printenv、setenv、saveenv是 U-Boot 最常用的调试命令。
4.3 设置为默认配置(永久修改)
如果你希望在编译固件时就内置新的环境变量(例如默认bootdelay=3或添加固定 MAC 地址),可以修改device/config/chips/t113/configs/100ask/env.cfg文件。
示例:添加 MAC 地址
原文件内容片段:
text
mac= wifi_mac= bt_mac=修改为:
text
mac=20:0D:B0:33:9D:7E wifi_mac= bt_mac=保存后,重新执行make && pack并烧录固件,MAC 地址就会成为默认值。进入 U-Boot 后输入print即可验证。
了解即可:
env.cfg中的变量会覆盖 U-Boot 源码中的默认环境变量。
五、U-Boot 支持的命令(部分常用)
在 U-Boot 提示符下输入?或help可以列出所有命令。以下列出最常用的几类:
5.1 信息查询类
| 命令 | 作用 |
|---|---|
bdinfo | 显示板级信息(内存地址、时钟等) |
mmcinfo | 显示 MMC/SD 卡信息 |
flinfo | 显示 NOR Flash 信息 |
5.2 环境变量操作
| 命令 | 作用 |
|---|---|
printenv | 打印所有环境变量 |
setenv | 设置环境变量 |
saveenv | 保存环境变量到存储介质 |
5.3 内存操作
| 命令 | 作用 |
|---|---|
md | 显示内存内容 |
mw | 填充内存 |
cp | 内存拷贝 |
cmp | 内存比较 |
md示例:md 0x42000000查看内存地址 0x42000000 处的数据。 |
5.4 存储介质操作
- MMC/SD 卡:
mmc dev <id>切换设备,mmc part显示分区,fatls mmc 0:1列出 FAT 分区文件。 - NAND Flash:
nand info显示 NAND 信息,nand read/nand write读写,nand erase擦除。 - UBI 卷:
ubi part sys挂载 UBI 分区,ubifsmount ubi0:rootfs挂载 UBIFS。
5.5 网络命令
| 命令 | 作用 |
|---|---|
dhcp | 自动获取 IP |
tftp <addr> <file> | 通过 TFTP 下载文件到内存 |
bootm <addr> | 启动内存中的内核镜像 |
5.6 FAT 文件系统命令
| 命令 | 作用 |
|---|---|
fatls <interface> <dev[:part]> [path] | 列出目录 |
fatload <interface> <dev[:part]> <addr> <file> | 加载文件到内存 |
fatinfo | 显示文件系统信息 |
示例:从 SD 卡的第一个分区加载内核镜像
bash
=> mmc dev 0 => fatload mmc 0:1 0x42000000 zImage => bootm 0x42000000六、示例:U-Boot 下查看并修改内核设备树节点
U-Boot 提供了fdt命令来操作设备树(Flattened Device Tree)。注意:操作的是当前内存中的设备树,通常内核的设备树会在启动时由 U-Boot 传递给内核。
6.1 FDT 命令基本用法
| 命令 | 作用 |
|---|---|
fdt addr <addr> | 设置设备树的内存地址 |
fdt list <path> | 列出节点或属性 |
fdt set <path> <prop> <val> | 修改属性值 |
fdt rm <path> [prop] | 删除节点或属性 |
fdt mknode <path> <node> | 创建新节点 |
示例:查看根节点
bash
=> fdt addr 0x43ec0e70 # 假设设备树在此地址 => fdt list /6.2 查询配置(以 WiFi 节点为例)
bash
=> fdt list /soc@3000000/rfkill@0/wlan@0 wlan@0 { compatible = "allwinner,sunxi-wlan"; wlan_busnum = <0x00000001>; wlan_regon = <0x00000013 0x00000006 0x0000000c 0x00000000>; wlan_hostwake = <0x00000013 0x00000006 0x0000000a 0x00000000>; };6.3 修改整数属性
例如将wlan_busnum从 1 改为 2:
bash
=> fdt set /soc@3000000/rfkill@0/wlan@0 wlan_busnum <0x2> => fdt list /soc@3000000/rfkill@0/wlan@0 wlan_busnum wlan_busnum = <0x00000002>;6.4 修改字符串属性
例如将 WiFi 状态从"okay"改为"disabled":
bash
=> fdt set /soc@3000000/rfkill@0/wlan@0 status "disabled"6.5 GPIO 或 PIN 配置特殊说明
在设备树中,GPIO 通常用一组数字描述:<phandle port pin func pull drive data>。对于全志芯片,GPIO 编号规则如下:
| 端口 | 宏定义 | 数值 |
|---|---|---|
| PA | #define PA 0 | 0 |
| PB | #define PB 1 | 1 |
| PC | #define PC 2 | 2 |
| … | … | … |
| PP | #define PP 15 | 15 |
示例:<0x00000013 0x00000006 0x0000000c 0x00000000>其中第二个数0x06表示 PG 端口,第三个数0x0c表示组内序号 12,即PG12。后面的数分别表示功能分配、内部电阻、驱动能力、输出电平。
修改 GPIO 配置可以使用fdt set,但要注意保持其他位的值不变。通常不建议手动修改,而是修改源码中的设备树文件。
必须掌握:
fdt list和fdt set是调试设备树的有力工具,特别适用于快速验证硬件配置。
七、示例:使用 fastboot 更新系统分区
当开发板通过 USB 连接到 PC 时,可以在 U-Boot 中进入 fastboot 模式,然后通过 PC 端的fastboot命令单独更新某个分区(如 boot、rootfs)。
7.1 进入 fastboot 模式
在 U-Boot 命令行中输入:
bash
=> fastboot开发板会进入 fastboot 模式,等待 USB 连接。
7.2 主机端安装 fastboot 工具
Ubuntu 下安装:
bash
sudo apt install android-tools-fastboot7.3 查看设备连接
bash
sudo fastboot devices Android Fastboot fastboot7.4 更新 boot 分区
先找到 boot 分区的镜像文件。在 SDKout/t113-100ask/目录下,boot.fex是一个软链接,指向实际的boot.img。
bash
cd out/t113-100ask ls -l image/boot.fex # lrwxrwxrwx ... -> /home/ubuntu/tina-d1-h/out/t113-100ask/boot.img使用 fastboot 烧写:
bash
sudo fastboot flash boot /home/ubuntu/tina-d1-h/out/t113-100ask/boot.img输出示例:
text
target reported max download size of 33554432 bytes sending 'boot' (3766 KB)... OKAY [ 0.212s] writing 'boot'... OKAY [ 1.152s] finished. total time: 1.364s7.5 其他分区
类似地,可以更新rootfs分区:
bash
sudo fastboot flash rootfs rootfs.img或者擦除分区:
bash
sudo fastboot erase private必须掌握:fastboot 是快速迭代开发的利器,避免反复插拔 SD 卡或重新烧录完整固件。
八、示例:修改 U-Boot 支持 RGB 屏幕
百问网 T113 开发板支持 7 寸 RGB 接口 LCD(1024×600)。我们需要修改 U-Boot 的设备树,增加 LCD 节点,使 U-Boot 能够初始化屏幕(以便显示开机 Logo)。
8.1 修改 U-Boot 设备树
设备树文件位于:
text
device/config/chips/t113/configs/100ask/uboot-board.dts找到&lcd0节点(如果不存在则添加)。以下是完整配置(重要参数已注释):
c
&lcd0 { lcd_used = <1>; // 启用 LCD lcd_driver_name = "default_lcd"; lcd_backlight = <100>; // 背光亮度 0-255 lcd_if = <0>; // 0: RGB 接口 lcd_hv_if = <0>; // 0: 水平垂直同步 lcd_x = <1024>; // 水平分辨率 lcd_y = <600>; // 垂直分辨率 lcd_width = <154>; // 屏幕物理宽度 (mm) lcd_height = <85>; // 屏幕物理高度 (mm) lcd_dclk_freq = <51>; // 像素时钟 51MHz lcd_hbp = <140>; // Horizontal Back Porch lcd_ht = <1344>; // Horizontal Total lcd_hspw = <20>; // Horizontal Sync Pulse Width lcd_vbp = <20>; // Vertical Back Porch lcd_vt = <635>; // Vertical Total lcd_vspw = <3>; // Vertical Sync Pulse Width lcd_pwm_used = <1>; // 使用 PWM 调背光 lcd_pwm_ch = <7>; // 使用 PWM 通道 7 lcd_pwm_freq = <500>; // PWM 频率 500Hz lcd_pwm_pol = <1>; // 极性 lcd_power = "vcc-lcd"; lcd_pin_power = "vcc-pd"; pinctrl-0 = <&rgb18_pins_a>; // 数据引脚组 pinctrl-1 = <&rgb18_pins_b>; };注意:如果原文件已有&lcd0但某些属性不同,需要删除原来的兼容节点,替换为本节内容。
8.2 修改 U-Boot 配置
进入 U-Boot 源码目录,编辑configs/sun8iw20p1_uart3_defconfig,在文件末尾添加以下配置(若没有):
kconfig
# 启用 LCD 驱动 CONFIG_VIDEO_LCD=y CONFIG_VIDEO_SUNXI=y CONFIG_VIDEO_SUNXI_DE_BE=y CONFIG_VIDEO_SUNXI_DE_FE=y CONFIG_VIDEO_SUNXI_HDMI=n CONFIG_DISPLAY_LOGO=y CONFIG_BMP_16BPP=y CONFIG_BMP_24BPP=y CONFIG_BMP_32BPP=y8.3 编译并烧录
回到 SDK 顶层,执行:
bash
mboot # 重新编译 U-Boot make -j$(nproc) # 完整编译(可选,因为只改了 U-Boot) pack # 打包然后烧录新固件。此时启动后,屏幕应该会亮起(但无图像,因为还未添加 Logo)。如果背光亮起,说明 LCD 初始化成功。
必须掌握:修改设备树是嵌入式开发的核心技能,学会添加 LCD 节点后,也可以类推添加其他外设。
九、示例:U-Boot 下增加启动 LOGO 图
9.1 准备合适尺寸的图片
以 7 寸屏(1024×600)为例,建议使用分辨率小于屏幕分辨率的 BMP 图片(例如 800×480)。为了加快加载速度,图片大小应控制在 200KB 以内。可以使用 GIMP 或画图工具将图片转换为 BMP 格式,颜色深度选择 24 位。
9.2 转换图片格式(如需要)
使用 ImageMagick 的convert命令:
bash
sudo apt install imagemagick convert original.jpg -resize 800x480 -colors 256 bootlogo.bmp或者使用 GIMP 导出为 BMP(不压缩、24 位)。
9.3 拷贝到特定目录
将bootlogo.bmp复制到 SDK 的boot-resource目录,该目录会被打包到启动分区。
bash
cp bootlogo.bmp ~/tina-d1-h/device/config/chips/t113/configs/100ask/configs/注意:路径可能因 SDK 版本而异。实际使用的目录是
device/config/chips/t113/configs/100ask/configs/,这个目录下的文件会被打包到boot-resource.fex中。
9.4 编译打包使用
重新编译并打包:
bash
make -j$(nproc) pack烧录固件后,上电即可看到开机 Logo。
9.5 调整图像大小(可选)
如果 Logo 显示不完全或拉伸,可以更换为更小尺寸的图片。推荐使用 512×300 黑色背景的图片,加载速度极快。
了解即可:开机 Logo 的显示由 U-Boot 中的
bmp_display函数实现。你也可以通过修改env.cfg中的bootlogo变量来更换 Logo 文件名(需要配合 U-Boot 源码修改)。
十、示例:固化自己的 U‑Boot 配置(重启不丢失)
直接修改运行时的环境变量(
setenv)只在当前启动生效,复位后就会恢复成默认值。
要想修改永久生效,必须修改U‑Boot 的默认配置(defconfig或env.cfg),然后重新编译并烧写。
10.1 修改默认环境变量(推荐用于 bootcmd、bootargs 等)
Tina SDK 中板级的环境变量默认值存放在device/config/chips/t113/configs/100ask/env.cfg。
bash
cd ~/tina-d1-h/device/config/chips/t113/configs/100ask vim env.cfg例如,将默认启动命令从boot_normal改为boot_recovery:
text
bootcmd=run setargs_nand_ubi boot_recovery保存后,重新完整编译 SDK(会自动重新打包 U‑Boot):
bash
cd ~/tina-d1-h make -j32 pack10.2 修改 Kconfig 配置(用于开启/关闭命令、功能)
如果你需要永久启用某个 U‑Boot 命令(比如config、cpu、license等),需要修改defconfig。
① 进入 U‑Boot 源码目录,打开 menuconfig:
bash
cd ~/tina-d1-h/lichee/brandy-2.0/u-boot-2018 make sun8iw20p1_uart3_defconfig # 加载当前板子的配置 make menuconfig② 在菜单中勾选你需要的功能(例如Command line interface → Info commands → [*] config)。
③ 保存并退出,然后生成新的 defconfig:
bash
make savedefconfig cp defconfig configs/sun8iw20p1_uart3_defconfig④ 回到 SDK 顶层重新编译:
bash
cd ~/tina-d1-h make -j3210.3 验证固化是否成功
烧写新生成的固件(例如tina_t113-100ask_uart3.img)到设备,重启后:
bash
# 进入 U‑Boot 命令行,查看环境变量是否为你修改的值 print bootcmd # 检查新增的命令是否存在 help config如果两者都符合预期,说明配置已永久固化。
核心原则:
- 不要在运行时用
setenv改完就重启(除非你执行了saveenv,但某些 NAND 或 SPI NOR 上saveenv可能不可靠)。- 生产环境必须通过修改defconfig或板级 env.cfg来固化配置。
- 备份你的修改:将
device/config/chips/t113/configs/100ask/和修改后的 defconfig 用 Git 管理。
十一、必须掌握 vs 了解即可
✅ 必须掌握(面试/工作中高频)
- U-Boot 源码位置:
lichee/brandy-2.0/u-boot-2018/,板级配置device/config/chips/t113/configs/100ask/。 - 常用 U-Boot 命令:
printenv、setenv、saveenv、md、mmcinfo、fatload、bootm、reset。 - 单独编译 U-Boot:
make sun8iw20p1_uart3_defconfig→make -jN。 - 修改环境变量:通过 U-Boot 命令行
setenv+saveenv,或修改env.cfg后重新编译。 - 使用 fastboot 更新分区:
fastboot flash boot boot.img。 - 修改设备树:编辑
uboot-board.dts后重新编译。 - 增加开机 Logo:放置 BMP 到
configs/目录,重新打包。
🔍 了解即可(能看懂、不要求独立完成)
- BOOT0 的详细编译命令(
make p= sun8iw20p1 m=nand等)。 - FDT 命令的高级用法(修改数组属性、添加节点)。
- U-Boot 源码的目录结构(
arch/arm/cpu/armv7/sunxi/等)。 - GPIO 编号与设备树中数字的转换规则。
- U-Boot 中的 SPI NAND 驱动细节。
十二、面试官提问环节
第1问:U-Boot 中如何修改启动等待时间?如何永久生效?
参考答案:
- 临时修改:在 U-Boot 命令行输入
setenv bootdelay 3,然后saveenv,下次启动生效。 - 永久固化:修改 SDK 中的
device/config/chips/t113/configs/100ask/env.cfg,将bootdelay=3写入,然后重新编译打包烧录。
第2问:U-Boot 中如何从 SD 卡加载内核并启动?
参考答案:
bash
=> mmc dev 0 => fatload mmc 0:1 0x42000000 zImage => fatload mmc 0:1 0x43000000 sun8iw20p1.dtb => bootz 0x42000000 - 0x43000000其中bootz用于 zImage,bootm用于 uImage。注意设备树地址与内核地址不能重叠。
第3问:如何单独编译 U-Boot 而不重新编译整个 Tina 系统?
参考答案:
bash
cd ~/tina-d1-h source build/envsetup.sh lunch 4 mboot # 单独编译 Bootloader或者手动进入 U-Boot 目录make,然后回到顶层执行pack重新打包。注意:mboot会自动将生成的u-boot.bin复制到正确位置。
第4问:在 U-Boot 中修改设备树节点后,如何使修改生效并传递给内核?
参考答案:
使用fdt set修改内存中的设备树,然后使用bootm或bootz启动内核时,U-Boot 会自动将修改后的设备树地址传给内核。示例:
bash
=> fdt addr 0x43ec0e70 => fdt set /soc@3000000/uart3 status "okay" => bootm 0x42000000 - 0x43ec0e70如果已经通过setenv bootargs设置了正确的设备树地址,也可以直接运行bootcmd。
第5问:为什么修改了env.cfg后重新烧录固件,但开发板上的环境变量还是旧的?
参考答案:
可能的原因:
- 没有执行
make clean或删除旧的out/目录,导致打包时仍使用了旧的env.fex。 - 开发板上的环境变量被保存到了存储介质(如 NAND 的 env 分区),U-Boot 启动时会优先使用已保存的环境变量而不是固件中的默认值。解决方法:在 U-Boot 命令行执行
env default -a恢复默认,然后saveenv。 - 确保修改的
env.cfg路径正确,且没有被其他板级配置文件覆盖。
十三、常见问题与调试技巧
13.1 U-Boot 无法进入命令行?
- 检查串口参数:波特率 115200,数据位 8,停止位 1,无流控。
- 确认开发板供电正常,且启动介质(SD 卡/NAND)有正确固件。
- 如果启动倒计时非常短(例如
bootdelay=0),可在上电前按住空格键或任意键,直到串口输出Hit any key to stop autoboot。
13.2 修改设备树后屏幕依然不亮?
- 确认
lcd_used = <1>;确认背光 PWM 通道和极性正确;检查硬件连接。 - 在 U-Boot 命令行执行
fdt list /soc/lcd0查看设备树节点是否生效。 - 可以暂时在
uboot-board.dts中直接写死lcd_backlight = <255>测试。
13.3 fastboot 无法识别设备?
- 确保在 U-Boot 中已输入
fastboot命令。 - 检查 USB 线是否连接正确(通常使用 OTG 口)。
- 主机端安装驱动(Windows 需要 Zadig 或全志 USB 驱动,Linux 无需额外驱动)。
- 执行
lsusb查看是否有1f3a:1000或类似的全志设备。
十四、总结
本章详细讲解了 Tina-Linux SDK 中 Bootloader 的组成、编译、配置与调试方法。通过一系列示例,你应当能够独立完成以下任务:
- 单独编译 U-Boot 和 BOOT0。
- 修改 U-Boot 环境变量和设备树。
- 增加开机 Logo 并调整显示。
- 使用 fastboot 快速更新内核或文件系统。
Bootloader 是嵌入式系统的地基,熟练掌握 U-Boot 将极大提升你的开发效率和调试能力。建议在实验板上反复练习本章所有示例,并尝试修改不同参数观察效果。