嵌入式软件平台/芯片确认与驱动来源追踪研究 1. uclass_first_device_err 函数归属 框架 : U-Boot Driver Model (DM) 驱动程序模型
头文件位置 : include/dm/uclass.h
实现文件 : drivers/core/uclass.c
函数原型 :
/**
* uclass_first_device_err() - Get the first device in a uclass
*
* The device returned is probed if necessary, and ready for use if no error is
* returned
*
* @id: Uclass ID to look up
* @devp: Returns pointer to the first device in that uclass, or NULL if none
* Return: 0 if found, -ENODEV if not found, other -ve on error
*/
int uclass_first_device_err ( enum uclass_id id , struct udevice ** devp );
功能说明 : - 获取指定 uclass 中的第一个设备 - 自动探测设备(如果需要) - 返回错误码:0 表示成功,-ENODEV 表示未找到设备,其他负值表示错误 - 与 uclass_first_device() 的区别:后者跳过探测失败的设备,而 _err 版本会返回探测错误
相关函数 : - uclass_first_device() - 获取第一个设备(跳过探测失败的) - uclass_next_device_err() - 获取下一个设备(带错误处理) - uclass_first_device_check() - 获取第一个设备(检查模式) - uclass_get() - 获取 uclass 实例
2. 嵌入式项目中确认目标平台和芯片的方法 2.1 编译时确定(Kconfig 系统) U-Boot 使用 Kconfig 系统进行架构和板级选择:
架构选择文件 : arch/Kconfig
choice
prompt "Architecture select"
default SANDBOX
config ARC
bool "ARC architecture"
select DM
select CLK
select SUPPORT_OF_CONTROL
...
config ARM
bool "ARM architecture"
select DM
select SUPPORT_OF_CONTROL
...
config ARM64
bool "ARM 64-bit architecture"
...
板级配置 : configs/<board>_defconfig
每个支持的板子都有对应的 defconfig 文件,例如: - configs/TQM823L_defconfig - configs/rk3399_defconfig
编译命令 :
make <board>_defconfig
make
2.2 运行时确定 方法 1: 通过设备树(Device Tree)
// 读取设备树中的 compatible 字符串
ofnode_get_compatible_list ( dev_ofnode ( dev ), compat , ARRAY_SIZE ( compat ));
方法 2: 通过 U-Boot 命令
# 在 U-Boot 命令行中
= > bdinfo # 显示板级信息
= > cpu info # 显示 CPU 信息
= > dm tree # 显示驱动模型设备树
= > dm class # 按 uclass 显示设备
方法 3: 通过代码查询
// 获取 CPU 信息
struct udevice * cpu ;
uclass_first_device_err ( UCLASS_CPU , & cpu );
// 获取板级信息
struct udevice * board ;
uclass_first_device_err ( UCLASS_BOARD , & board );
2.3 维护者查询工具 使用 scripts/get_maintainer.pl 查询特定板子/子系统的维护者:
# 查询文件的维护者
perl scripts/get_maintainer.pl -f drivers/mtd/nand/spi/core.c
# 查询补丁的维护者
perl scripts/get_maintainer.pl <patch_file>
3. SPI/QSPI NAND Flash 驱动代码来源追踪 3.1 驱动目录结构 drivers/mtd/nand/spi/
├── core.c # 核心驱动框架
├── otp.c # OTP (One-Time Programmable) 支持
├── alliancememory.c # Alliance Memory 芯片支持
├── ato.c # ATO 芯片支持
├── esmt.c # ESMC 芯片支持
├── fmsh.c # 飞索半导体支持
├── foresee.c # Foresee 芯片支持
├── gigadevice.c # 兆易创新 (GigaDevice) 支持
├── macronix.c # Macronix 支持
├── micron.c # 美光 (Micron) 支持
├── paragon.c # Paragon 支持
├── skyhigh.c # SkyHigh 支持
├── toshiba.c # 东芝支持
├── winbond.c # 华邦支持
└── xtx.c # 芯天下支持
3.2 核心驱动文件分析 drivers/mtd/nand/spi/core.c
关键特性: - 同时支持 Linux 内核和 U-Boot(通过 #ifndef __UBOOT__ 条件编译) - 使用 SPI MEM 操作框架 - 支持多种 SPI 传输模式(1S-1S-1S, 1S-2S-2S, 1S-4S-4S 等)
U-Boot 特定包含 :
#else
#include <errno.h>
#include <watchdog.h>
#include <spi.h>
#include <spi-mem.h>
#include <ubi_uboot.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/mtd/spinand.h>
#include <linux/printk.h>
#include <linux/delay.h>
#endif
3.3 厂商标识定义 各厂商 SPI NAND 的制造商 ID 定义:
// GigaDevice (兆易创新)
#define SPINAND_MFR_GIGADEVICE 0xC8
// Micron (美光)
#define SPINAND_MFR_MICRON 0x2c
// Macronix
#define SPINAND_MFR_MACRONIX 0xC2
// Winbond (华邦)
#define SPINAND_MFR_WINBOND 0xEF
// Toshiba (东芝)
#define SPINAND_MFR_TOSHIBA 0x98
3.4 驱动维护信息 子系统维护者 (来自 MAINTAINERS 文件):
SPI NAND
M: Dario Binacchi <dario.binacchi@amarulasolutions.com>
M: Michael Trimarchi <michael@amarulasolutions.com>
R: Frieder Schrempf <frieder.schrempf@kontron.de>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-nand-flash.git
相关子系统 : - SPI : drivers/spi/ (Orphaned, custodian: u-boot-spi) - SPI-NOR : drivers/mtd/spi/ (Maintained by Vignesh R) - RAW NAND : drivers/mtd/nand/raw/ (Maintained by Dario Binacchi)
3.5 代码来源追踪方法 方法 1: Git 历史查询
# 查看文件的提交历史
git log --oneline drivers/mtd/nand/spi/core.c
# 查看特定行的作者
git blame drivers/mtd/nand/spi/core.c
# 查找引入特定函数的提交
git log -S "uclass_first_device_err" --oneline
方法 2: 查看 Kconfig 配置
# 搜索 SPI NAND 相关配置
grep -r "MTD_SPI_NAND" drivers/mtd/nand/spi/Kconfig
# 查看哪些板子启用了 SPI NAND
grep -r "MTD_SPI_NAND" configs/
方法 3: 查看设备树绑定
# 设备树中 SPI NAND 节点示例
& spi0 {
flash@0 {
compatible = "gigadevice,gd5f1gq4uf90" , "spi-nand" ;
reg = <0 >;
spi-max-frequency = <104000000 >;
} ;
} ;
3.6 Makefile 构建配置 drivers/mtd/nand/spi/Makefile :
spinand-objs := core.o otp.o
spinand-objs += alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o
spinand-objs += micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
4. 实用命令汇总 4.1 U-Boot 编译配置 # 列出所有支持的板子
make | grep defconfig
# 配置特定板子
make rk3399_defconfig
# 查看当前配置
grep CONFIG_ .config | head -50
# 编译
make -j$( nproc)
4.2 驱动模型调试 # 在 U-Boot 命令行
= > dm tree # 显示设备树
= > dm class spi # 显示 SPI 设备
= > dm class mtd # 显示 MTD 设备
= > dm info # 显示设备详细信息
= > dm uclass # 列出所有 uclass
4.3 代码搜索 # 搜索函数定义
grep -rn "uclass_first_device_err" drivers/
# 搜索特定芯片支持
grep -rn "SPINAND_MFR_" drivers/mtd/nand/spi/
# 搜索设备树兼容字符串
grep -rn "compatible.*spi-nand" arch/*/dts/
5. 参考资源 研究完成时间:2026-03-12