U-Boot DFU (Device Firmware Upgrade) 技术分析
文档说明
- 硬件平台: 瑞芯微 RK3588
- 软件版本: U-Boot
- 文档目的: 系统梳理 DFU 功能的实现原理和使用方法
目录
1. DFU 功能概述
1.1 什么是 DFU?
DFU (Device Firmware Upgrade) 是 USB 实现者论坛制定的一种标准协议,用于通过 USB 接口升级设备固件。它将 USB 设备分为两种模式:
| 模式 | 说明 | 典型用途 |
|---|---|---|
| 运行时模式 | 设备正常运行时的固件 | 设备正常工作 |
| DFU 模式 | 固件升级专用模式 | 刷写固件 |
1.2 U-Boot DFU 的优势
传统固件升级方式:
┌─────────┐ SD卡拆装 ┌─────────┐
│ 开发机 │ ──────────────> │ 目标板 │
└─────────┘ └─────────┘
DFU 升级方式:
┌─────────┐ USB线缆 ┌─────────┐
│ 开发机 │ ══════════════> │ 目标板 │
└─────────┘ └─────────┘
主要优势:
- 无需拆装 SD 卡或连接串口
- 支持 USB 2.0/3.0 高速传输
- 支持多种存储介质(eMMC、NAND、SPI Flash 等)
- 支持分区级别的精确刷写
- 支持 TFTP 网络传输
- 可在 SPL 阶段使用
1.3 源码结构
u-boot/
├── drivers/dfu/ # DFU 后端驱动
│ ├── dfu.c # 核心逻辑
│ ├── dfu_mmc.c # MMC/eMMC 支持
│ ├── dfu_mtd.c # MTD 支持(Rockchip 专用)
│ ├── dfu_nand.c # NAND 支持
│ ├── dfu_ram.c # RAM 支持
│ ├── dfu_sf.c # SPI Flash 支持
│ └── dfu_tftp.c # TFTP 网络传输
│
├── drivers/usb/gadget/ # USB Gadget 层
│ ├── f_dfu.c # USB DFU 函数驱动
│ └── f_dfu.h # USB DFU 协议定义
│
├── cmd/ # 命令实现
│ └── dfu.c # dfu 命令
│
├── common/ # 通用功能
│ ├── dfu.c # 运行时支持
│ └── spl/spl_dfu.c # SPL 阶段支持
│
└── arch/arm/mach-rockchip/ # Rockchip 平台
├── dfu_alt_info.c # Alt info 配置
└── boot_mode.c # 启动模式集成
2. DFU 架构设计
2.1 分层架构
┌─────────────────────────────────────────────────────────────┐
│ USB Host (PC) │
│ (dfu-util 工具) │
└────────────────────────────┬────────────────────────────────┘
│ USB 协议
┌────────────────────────────▼────────────────────────────────┐
│ USB Gadget Driver │
│ (drivers/usb/gadget/f_dfu.c) │
│ - USB 请求处理 │
│ - 状态机管理 │
│ - 数据传输控制 │
└────────────────────────────┬────────────────────────────────┘
│ DFU 核心接口
┌────────────────────────────▼────────────────────────────────┐
│ DFU Core Layer │
│ (drivers/dfu/dfu.c) │
│ - 实体管理 │
│ - 缓冲区管理 │
│ - CRC 校验 │
└────────────────────────────┬────────────────────────────────┘
│ 设备操作接口
┌────────────────────────────▼────────────────────────────────┐
│ Device Backend Layer │
│ (dfu_mmc.c | dfu_mtd.c | dfu_nand.c | ...) │
│ - get_medium_size() 获取介质大小 │
│ - read_medium() 读取介质数据 │
│ - write_medium() 写入介质数据 │
│ - flush_medium() 刷新介质 │
└────────────────────────────┬────────────────────────────────┘
│ 块设备接口
┌────────────────────────────▼────────────────────────────────┐
│ Storage Device │
│ (eMMC | NAND | SPI Flash | RAM) │
└─────────────────────────────────────────────────────────────┘
2.2 关键概念
DFU Entity(实体)
DFU 实体代表一个可升级的单元,可以是:
- 原始分区(raw partition)
- 文件系统分区(FAT、EXT4)
- UBI 卷(MTD 设备)
- 内存区域
示例: U-Boot 分区、Boot 分区、RootFS 分区都是独立的 DFU 实体
Alternate Setting(Alt Setting)
USB DFU 使用 Alternate Setting 机制来区分不同的实体:
- 每个实体有一个唯一的 alt 编号
- 主机通过 alt 编号选择要操作的分区
DFU Layout(布局)
定义数据如何存储到介质:
| Layout 类型 | 说明 | 典型应用 |
|---|---|---|
DFU_RAW_ADDR |
原始地址访问 | 引导加载程序、GPT 分区表 |
DFU_FS_FAT |
FAT 文件系统 | 内核镜像、设备树 |
DFU_FS_EXT4 |
EXT4 文件系统 | 根文件系统 |
DFU_RAM_ADDR |
内存地址 | 内存加载 |
3. 核心数据结构
3.1 dfu_entity 结构体
位置: include/dfu.h
struct dfu_entity {
/* 基本信息 */
char name[DFU_NAME_SIZE]; // 实体名称(如 "uboot"、"boot")
int alt; // alternate setting 编号
void *dev_private; // 设备私有数据指针
enum dfu_device_type dev_type; // 设备类型(MMC/MTD/NAND/RAM/SF)
enum dfu_layout layout; // 数据布局类型
/* 设备特定数据(联合体) */
union {
struct mmc_internal_data mmc;
struct nand_internal_data nand;
struct ram_internal_data ram;
struct sf_internal_data sf;
struct mtd_internal_data mtd;
} data;
/* 操作函数指针(多态实现) */
int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
int (*read_medium)(struct dfu_entity *dfu, u64 offset,
void *buf, long *len);
int (*write_medium)(struct dfu_entity *dfu, u64 offset,
void *buf, long *len);
int (*flush_medium)(struct dfu_entity *dfu);
unsigned int (*poll_timeout)(struct dfu_entity *dfu);
void (*free_entity)(struct dfu_entity *dfu);
/* 运行时状态 */
u32 crc; // CRC32 校验值
u64 offset; // 当前写入偏移
int i_blk_seq_num; // 块序列号(0-65535,支持回绕)
u8 *i_buf; // 当前缓冲区位置
u8 *i_buf_start; // 缓冲区起始地址
u8 *i_buf_end; // 缓冲区结束地址
u64 r_left; // 剩余待读取量
long b_left; // 缓冲区剩余空间
u32 bad_skip; // 跳过的坏块数量
unsigned int inited:1; // 初始化标志
};
设计要点:
- 使用函数指针实现多态,不同设备类型有不同实现
- 联合体
data节省内存空间 - 支持块序列号回绕(0xffff → 0x0000),符合 DFU 规范
3.2 设备类型枚举
enum dfu_device_type {
DFU_DEV_MMC = 1, // MMC/eMMC 设备
DFU_DEV_ONENAND, // OneNAND Flash
DFU_DEV_NAND, // NAND Flash
DFU_DEV_RAM, // 内存设备
DFU_DEV_SF, // SPI Flash
DFU_DEV_MTD, // MTD 设备(包括 SPI NAND/NOR)
};
3.3 布局类型枚举
enum dfu_layout {
DFU_RAW_ADDR = 1, // 原始地址访问(直接读写扇区)
DFU_FS_FAT, // FAT 文件系统
DFU_FS_EXT2, // EXT2 文件系统
DFU_FS_EXT3, // EXT3 文件系统
DFU_FS_EXT4


551

被折叠的 条评论
为什么被折叠?



