100ASK-T113 Pro 开发板 Bootloader 完全开发指南

100ASK-T113 Pro 开发板 Bootloader 完全开发指南

本章基于 Tina-Linux SDK,深入讲解 Bootloader(U-Boot)的组成、编译、配置、修改及烧录方法。包含大量实战示例,从环境搭建到修改设备树、增加开机 Logo、使用 fastboot 更新分区,手把手带你掌握嵌入式 Linux 启动的第一阶段。学完本章,你将能独立对 T113 开发板的 U-Boot 进行定制和调试。


文章目录

    • [100ASK-T113 Pro 开发板 Bootloader 完全开发指南](#100ASK-T113 Pro 开发板 Bootloader 完全开发指南)
    • [一、Tina-Linux Bootloader 简述](#一、Tina-Linux Bootloader 简述)
      • [1.1 什么是 Bootloader?](#1.1 什么是 Bootloader?)
      • [1.2 Tina-Linux 启动流程(文字描述)](#1.2 Tina-Linux 启动流程(文字描述))
    • [二、单独编译 Bootloader 部分](#二、单独编译 Bootloader 部分)
      • [2.1 准备编译工具链](#2.1 准备编译工具链)
      • [2.2 快速编译 boot0 及 U-Boot](#2.2 快速编译 boot0 及 U-Boot)
      • [2.3 单独编译 U-Boot](#2.3 单独编译 U-Boot)
      • [2.4 单独编译 BOOT0 / FES / SBOOT](#2.4 单独编译 BOOT0 / FES / SBOOT)
    • [三、单独配置 U-Boot](#三、单独配置 U-Boot)
      • [3.1 U-Boot 设备树与环境变量文件](#3.1 U-Boot 设备树与环境变量文件)
      • [3.2 U-Boot 源码所在位置](#3.2 U-Boot 源码所在位置)
      • [3.3 Tina 系统指定的配置文件](#3.3 Tina 系统指定的配置文件)
      • [3.4 编译打包与更新](#3.4 编译打包与更新)
    • 四、修改系统启动环境变量
      • [4.1 查看 U-Boot 默认环境变量](#4.1 查看 U-Boot 默认环境变量)
      • [4.2 修改启动等待时间](#4.2 修改启动等待时间)
      • [4.3 设置为默认配置(永久修改)](#4.3 设置为默认配置(永久修改))
    • [五、U-Boot 支持的命令(部分常用)](#五、U-Boot 支持的命令(部分常用))
      • [5.1 信息查询类](#5.1 信息查询类)
      • [5.2 环境变量操作](#5.2 环境变量操作)
      • [5.3 内存操作](#5.3 内存操作)
      • [5.4 存储介质操作](#5.4 存储介质操作)
      • [5.5 网络命令](#5.5 网络命令)
      • [5.6 FAT 文件系统命令](#5.6 FAT 文件系统命令)
    • [六、示例:U-Boot 下查看并修改内核设备树节点](#六、示例:U-Boot 下查看并修改内核设备树节点)
      • [6.1 FDT 命令基本用法](#6.1 FDT 命令基本用法)
      • [6.2 查询配置(以 WiFi 节点为例)](#6.2 查询配置(以 WiFi 节点为例))
      • [6.3 修改整数属性](#6.3 修改整数属性)
      • [6.4 修改字符串属性](#6.4 修改字符串属性)
      • [6.5 GPIO 或 PIN 配置特殊说明](#6.5 GPIO 或 PIN 配置特殊说明)
    • [七、示例:使用 fastboot 更新系统分区](#七、示例:使用 fastboot 更新系统分区)
      • [7.1 进入 fastboot 模式](#7.1 进入 fastboot 模式)
      • [7.2 主机端安装 fastboot 工具](#7.2 主机端安装 fastboot 工具)
      • [7.3 查看设备连接](#7.3 查看设备连接)
      • [7.4 更新 boot 分区](#7.4 更新 boot 分区)
      • [7.5 其他分区](#7.5 其他分区)
    • [八、示例:修改 U-Boot 支持 RGB 屏幕](#八、示例:修改 U-Boot 支持 RGB 屏幕)
      • [8.1 修改 U-Boot 设备树](#8.1 修改 U-Boot 设备树)
      • [8.2 修改 U-Boot 配置](#8.2 修改 U-Boot 配置)
      • [8.3 编译并烧录](#8.3 编译并烧录)
    • [九、示例:U-Boot 下增加启动 LOGO 图](#九、示例:U-Boot 下增加启动 LOGO 图)
      • [9.1 准备合适尺寸的图片](#9.1 准备合适尺寸的图片)
      • [9.2 转换图片格式(如需要)](#9.2 转换图片格式(如需要))
      • [9.3 拷贝到特定目录](#9.3 拷贝到特定目录)
      • [9.4 编译打包使用](#9.4 编译打包使用)
      • [9.5 调整图像大小(可选)](#9.5 调整图像大小(可选))
    • [十、示例:固化自己的 U‑Boot 配置(重启不丢失)](#十、示例:固化自己的 U‑Boot 配置(重启不丢失))
      • [10.1 修改默认环境变量(推荐用于 bootcmd、bootargs 等)](#10.1 修改默认环境变量(推荐用于 bootcmd、bootargs 等))
      • [10.2 修改 Kconfig 配置(用于开启/关闭命令、功能)](#10.2 修改 Kconfig 配置(用于开启/关闭命令、功能))
      • [10.3 验证固化是否成功](#10.3 验证固化是否成功)
    • [十一、必须掌握 vs 了解即可](#十一、必须掌握 vs 了解即可)
      • [✅ 必须掌握(面试/工作中高频)](#✅ 必须掌握(面试/工作中高频))
      • [🔍 了解即可(能看懂、不要求独立完成)](#🔍 了解即可(能看懂、不要求独立完成))
    • 十二、面试官提问环节
      • [第1问:U-Boot 中如何修改启动等待时间?如何永久生效?](#第1问:U-Boot 中如何修改启动等待时间?如何永久生效?)
      • [第2问:U-Boot 中如何从 SD 卡加载内核并启动?](#第2问:U-Boot 中如何从 SD 卡加载内核并启动?)
      • [第3问:如何单独编译 U-Boot 而不重新编译整个 Tina 系统?](#第3问:如何单独编译 U-Boot 而不重新编译整个 Tina 系统?)
      • [第4问:在 U-Boot 中修改设备树节点后,如何使修改生效并传递给内核?](#第4问:在 U-Boot 中修改设备树节点后,如何使修改生效并传递给内核?)
      • [第5问:为什么修改了 `env.cfg` 后重新烧录固件,但开发板上的环境变量还是旧的?](#第5问:为什么修改了 env.cfg 后重新烧录固件,但开发板上的环境变量还是旧的?)
    • 十三、常见问题与调试技巧
      • [13.1 U-Boot 无法进入命令行?](#13.1 U-Boot 无法进入命令行?)
      • [13.2 修改设备树后屏幕依然不亮?](#13.2 修改设备树后屏幕依然不亮?)
      • [13.3 fastboot 无法识别设备?](#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-tina

2.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.binboot0_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 秒。

必须掌握printenvsetenvsaveenv 是 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 Flashnand 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 listfdt 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-fastboot

7.3 查看设备连接

bash

复制代码
sudo fastboot devices
Android Fastboot   fastboot

7.4 更新 boot 分区

先找到 boot 分区的镜像文件。在 SDK out/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.364s

7.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=y

8.3 编译并烧录

回到 SDK 顶层,执行:

bash

复制代码
mboot          # 重新编译 U-Boot
make -j$(nproc) # 完整编译(可选,因为只改了 U-Boot)
pack           # 打包

然后烧录新固件。此时启动后,屏幕应该会亮起(但无图像,因为还未添加 Logo)。如果背光亮起,说明 LCD 初始化成功。

必须掌握:修改设备树是嵌入式开发的核心技能,学会添加 LCD 节点后,也可以类推添加其他外设。


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 的默认配置defconfigenv.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
pack

10.2 修改 Kconfig 配置(用于开启/关闭命令、功能)

如果你需要永久启用某个 U‑Boot 命令(比如 configcpulicense 等),需要修改 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 -j32

10.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 了解即可

✅ 必须掌握(面试/工作中高频)

  1. U-Boot 源码位置lichee/brandy-2.0/u-boot-2018/,板级配置 device/config/chips/t113/configs/100ask/
  2. 常用 U-Boot 命令printenvsetenvsaveenvmdmmcinfofatloadbootmreset
  3. 单独编译 U-Bootmake sun8iw20p1_uart3_defconfigmake -jN
  4. 修改环境变量 :通过 U-Boot 命令行 setenv + saveenv,或修改 env.cfg 后重新编译。
  5. 使用 fastboot 更新分区fastboot flash boot boot.img
  6. 修改设备树 :编辑 uboot-board.dts 后重新编译。
  7. 增加开机 Logo :放置 BMP 到 configs/ 目录,重新打包。

🔍 了解即可(能看懂、不要求独立完成)

  1. BOOT0 的详细编译命令(make p= sun8iw20p1 m=nand 等)。
  2. FDT 命令的高级用法(修改数组属性、添加节点)。
  3. U-Boot 源码的目录结构(arch/arm/cpu/armv7/sunxi/ 等)。
  4. GPIO 编号与设备树中数字的转换规则。
  5. 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 修改内存中的设备树,然后使用 bootmbootz 启动内核时,U-Boot 会自动将修改后的设备树地址传给内核。示例:

bash

复制代码
=> fdt addr 0x43ec0e70
=> fdt set /soc@3000000/uart3 status "okay"
=> bootm 0x42000000 - 0x43ec0e70

如果已经通过 setenv bootargs 设置了正确的设备树地址,也可以直接运行 bootcmd


第5问:为什么修改了 env.cfg 后重新烧录固件,但开发板上的环境变量还是旧的?

参考答案

可能的原因:

  1. 没有执行 make clean 或删除旧的 out/ 目录,导致打包时仍使用了旧的 env.fex
  2. 开发板上的环境变量被保存到了存储介质(如 NAND 的 env 分区),U-Boot 启动时会优先使用已保存的环境变量而不是固件中的默认值。解决方法:在 U-Boot 命令行执行 env default -a 恢复默认,然后 saveenv
  3. 确保修改的 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 将极大提升你的开发效率和调试能力。建议在实验板上反复练习本章所有示例,并尝试修改不同参数观察效果。

相关推荐
charlie1145141912 小时前
Linux 字符设备驱动:cdev、设备号与设备模型
linux·开发语言·驱动开发·c
handler013 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy1133 小时前
Linux进程与线程编程详解
linux·c++
我星期八休息3 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
切糕师学AI3 小时前
深入解析 Zsh 与 Oh-My-Zsh:打造高效现代化终端
linux·终端·zsh
切糕师学AI4 小时前
Ubuntu 下 Git 完全使用指南
linux·git·ubuntu
老黄编程5 小时前
大型工地实时数据处理与三维重构系统方案
人工智能·ubuntu·信息可视化·重构·入侵检测·大型数据集中处理
浪客灿心5 小时前
Linux网络传输层协议
linux·运维·网络
舟遥遥娓飘飘5 小时前
Nexus4CC 手机电脑同步claude code对话部署教程(基于linux系统)
linux·智能手机·电脑