Winbond W25Q02JV擦除MTD分区致引导区丢失,Linux容量使用异常求助
问题根源
你的推测完全正确:Winbond W25Q02JV是4-die(每die 64Mb)的SPI NOR闪存,总容量256MB。这类多die设备需要驱动在访问超过第一个die的地址空间时,发送**bank切换指令(0xB9/0xC2)**来切换到对应die。Linux 6.6.40的spi-nor驱动大概率没正确识别该型号的多die特性,导致擦除mtd3时,没有切换到后续die,而是在第一个die内循环寻址,直接擦除了低地址的U-Boot和系统分区。
排查步骤
- 查驱动识别日志:执行
dmesg | grep spi-nor,看是否有"multi-die"、"bank switching"这类关键词。如果完全无相关输出,说明驱动根本没认出这是多die闪存。 - 验证分区地址:用
flash_info /dev/mtd3(需安装mtd-utils工具)查看mtd3的起始地址是0xB00000,已经超过第一个die的最大地址0x800000(64Mb),确认分区规划本身没问题,必须切换die才能访问该区域。 - 手动测试die切换:通过spidev工具直接发送指令测试——先发送0xB9指令切换到bank 1,再读取0x800000地址的数据,对比bank 0的0x0地址数据,若两者不同则硬件层面支持切换,问题出在驱动逻辑。
修复方案
1. 设备树补全配置(优先尝试)
给flash节点添加两个属性,强制驱动启用多die支持:
&qspi { u-boot,dm-pre-reloc; status = "okay"; is-dual = <0>; num-cs = <1>; flash@0 { compatible = "jedec,spi-nor", "winbond,w25q02jv"; reg = <0x0>; spi-tx-bus-width = <1>; spi-rx-bus-width = <4>; spi-max-frequency = <50000000>; spi-nor,addr-mode = <4>; #address-cells = <1>; #size-cells = <1>; // 新增以下两行配置 spi-nor,multi-die; spi-nor,bank-width = <2>; // 2位bank地址对应4个die(2^2=4) partition@0 { label = "qspi-fsbl-uboot"; reg = <0x0 0xE0000>; }; partition@E0000 { label = "uboot-env"; reg = <0xE0000 0x20000>; }; partition@100000 { label = "linux-with-rootfs"; reg = <0x100000 0xA00000>; }; partition@B00000 { label = "any-data"; reg = <0xB00000 0xF500000>; }; }; };
重新编译设备树并烧录,重启后再查内核日志确认驱动是否识别多die特性。
2. 内核驱动补丁(设备树无效时使用)
如果设备树修改后仍无效果,说明内核的winbond驱动未给W25Q02JV添加多die标记。找到drivers/mtd/spi-nor/winbond.c中的winbond_parts数组,添加对应型号的配置:
static const struct flash_info winbond_parts[] = { // ... 其他已有条目 ... { .name = "w25q02jv", .id = SNOR_ID(0xEF, 0x70, 0x19), .size = SZ_256M, .flags = SPI_NOR_HAS_4K_SECT | SPI_NOR_HAS_BP | SPI_NOR_HAS_QPI | SPI_NOR_HAS_WRR | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_MULTI_DIE, .n_dies = 4, .bank_width = 2, }, // ... 其他条目 ... };
重新编译内核并烧录,确保驱动加载时能正确识别4个die的结构。
3. 修复验证
完成修复后按以下步骤确认:
- 重启系统,执行
dmesg | grep multi-die,应能看到类似"winbond,w25q02jv: 4 x 64 MiB dies, total 256 MiB"的日志。 - 执行
flash_eraseall /dev/mtd3,重启后确认U-Boot和Linux仍能正常启动。 - 用
ubiformat /dev/mtd3格式化分区,挂载后写入测试数据,断电重启验证数据不丢失。
额外提醒
- U-Boot也需要支持该闪存的多die特性,否则启动时无法访问高地址分区,需确保U-Boot的spi-nor驱动同样处理了W25Q02JV的bank切换逻辑。
- 避免使用老旧版本的mtd-utils工具,确保
flash_eraseall和ubiformat支持多die设备的擦除与格式化操作。
内容的提问来源于stack exchange,提问作者Dementev Ivan
相关产品推荐
相关产品推荐

