U-Boot 适配新型号 SPI Nor Flash 实战解析

U-Boot 适配新型号 SPI Nor Flash 实战解析 1. 从报错信息开始JEDEC ID无法识别的背后那天我拿到一块新开发板兴冲冲地把编译好的U-Boot镜像烧录进去结果串口终端突然蹦出一行刺眼的错误unrecognized JEDEC id bytes: 0b, 40, 18这个报错就像一盆冷水浇下来——系统根本不认识板载的SPI Nor Flash。这种情况在嵌入式开发中太常见了特别是当你用的Flash型号比较新或者比较冷门时。我手头这块板子用的XT25F128B就是个典型的生面孔。遇到这种问题先别慌报错信息其实已经给了关键线索。这串0b, 40, 18就是Flash的JEDEC ID相当于存储芯片的身份证号码。U-Boot启动时会通过SPI总线读取这个ID然后在它的内置数据库里查找匹配项。如果找不到就会抛出这个错误。提示JEDEC ID通常由3个字节组成第一个字节(0x0B)代表制造商后两个字节(0x4018)是设备编号。就像通过身份证号前几位能看出籍贯地一样老司机看到0x0B就知道是XTX厂家。2. 深入U-Boot源码寻找Flash信息数据库顺着报错信息我直接grep了U-Boot源码目录grep -rn unrecognized JEDEC *结果定位到drivers/mtd/spi/spi_flash.c文件的919行附近。这段代码就像个尽职的图书馆管理员拿着Flash的ID在图书目录spi_flash_ids数组里挨个比对。如果遍历完整个目录都找不到匹配项就会报错。真正的Flash信息库藏在spi_flash_ids.c里。打开这个文件你会看到一个巨大的数组里面用INFO宏定义了各种Flash型号的参数。以常见的W25Q128为例INFO(0xef4018, 0x00, 64*1024, 256, SECT_4K | SPI_NOR_DUAL_READ)这个结构体包含五个关键参数JEDEC ID0xef4018扩展ID0x00表示没有扇区大小64KB扇区数量256个特性标志支持4K擦除和双线读取3. 解读Flash手册获取正确的设备参数现在需要为XT25F128B添加支持。首先得找到它的数据手册一般在芯片官网或经销商处都能下载。在手册的Device Identification章节我找到了关键信息参数值Manufacturer ID0x0B (XTX)Device ID0x4018Page Size256 bytesSector Size4KB/64KBCapacity16MB (128Mbit)特别注意这个Flash支持两种扇区尺寸4KB的小扇区和64KB的大扇区。这在添加支持时需要特别声明否则擦除操作可能会出问题。4. 添加新Flash型号实战修改步骤在spi_flash_ids.c中找到合适的位置通常是按制造商ID排序添加我们的新设备INFO(0x0b4018, 0x00, 64*1024, 256, SECT_4K | SPI_NOR_QUAD_READ)这里有几个注意点JEDEC ID要转换成连续的3字节格式0x0b4018扇区数量计算总容量16MB除以64KB得到256特性标志要仔细核对手册这个型号支持四线读取(QSPI)修改后需要重新编译U-Boot。我习惯先清理旧编译结果make mrproper make defconfig make menuconfig # 检查SPI Nor支持是否开启 make -j8烧录新镜像后终于看到了期待已久的启动日志SF: Detected xt25f128b with page size 256 Bytes, erase size 64 KiB, total 16 MiB5. 设备树同步容易被忽略的关键步骤你以为到这里就结束了Too young我刚开始也这么想直到发现Linux系统下Flash无法正常访问。这是因为U-Boot和Linux内核的设备树描述需要保持一致。打开你的板级设备树文件比如arch/arm/dts/your_board.dts找到SPI控制器节点。确保兼容性字符串包含新Flash型号flash0 { compatible xtx,xt25f128b, jedec,spi-nor; reg 0; spi-max-frequency 50000000; #address-cells 1; #size-cells 1; };特别是这个spi-max-frequency一定要参考手册的最大时钟频率设置设高了会导致通信失败。6. 验证与调试确保万无一失硬件调试最怕的就是看起来能用。我习惯用这套组合拳验证Flash支持是否完整基础读写测试# U-Boot下测试 sf probe # 检测Flash sf read 80000000 0 1000 # 从0地址读取4KB到内存 md 80000000 # 查看读取内容 mw 80000000 12345678 # 修改内存数据 sf erase 0 1000 # 擦除前4KB sf write 80000000 0 1000 # 写回数据性能测试# 测试擦除速度 time sf erase 0 100000 # 测试写入速度 time sf write 80000000 0 100000特殊功能验证如果声称支持四线模式(QSPI)要实测读取速度是否确实提升检查4K扇区擦除是否正常工作验证写保护功能如果有7. 经验总结那些年我踩过的坑做完这个项目我整理了几个容易出错的地方字节序问题有些手册把JEDEC ID写成0x0B4018实际传输顺序可能是0x0B 0x40 0x18扇区大小混淆同一个Flash可能支持多种擦除粒度务必确认使用的具体模式电压配置3.3V和1.8V的Flash配置不同接错可能损坏芯片时钟频率手册标称的最大频率往往有裕量实际使用建议留20%余量有一次我遇到个特别诡异的问题Flash能识别但写入总是失败。折腾两天才发现是硬件设计时CS引脚没加上拉电阻导致片选信号不稳定。所以硬件设计审查也很重要