You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 修复验证

完成修复后按以下步骤确认:

  1. 重启系统,执行dmesg | grep multi-die,应能看到类似"winbond,w25q02jv: 4 x 64 MiB dies, total 256 MiB"的日志。
  2. 执行flash_eraseall /dev/mtd3,重启后确认U-Boot和Linux仍能正常启动。
  3. 用ubiformat /dev/mtd3格式化分区,挂载后写入测试数据,断电重启验证数据不丢失。
额外提醒
  • U-Boot也需要支持该闪存的多die特性,否则启动时无法访问高地址分区,需确保U-Boot的spi-nor驱动同样处理了W25Q02JV的bank切换逻辑。
  • 避免使用老旧版本的mtd-utils工具,确保flash_eraseall和ubiformat支持多die设备的擦除与格式化操作。

内容的提问来源于stack exchange,提问作者Dementev Ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:05:08