<linux> linux与uboot添加新的nor flash支持

linux与uboot添加新的nor flash支持

linux

以3.18内核为例子

在内核源码中找到路径为drivers/mtd/spi-nor/spi-nor.c的文件

打开后找到flash支持表。 内核启动过程会对比表中的INFO()里面的参数,即flash JEDEC ID,匹配到后,按照后面的 64 * 1024等参数初始化flash的设置。

/* NOTE: double check command sets and memory organization when you add
 * more nor chips.  This current list focusses on newer chips, which
 * have been converging on command sets which including JEDEC ID.
 */
static const struct spi_device_id spi_nor_ids[] = {
        /* Atmel -- some are (confusingly) marketed as "DataFlash" */
        { "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
        { "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },

        { "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
        { "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
        { "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },

        { "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
        { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
        { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
        { "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },

        { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },

        /* EON -- en25xxx */
        { "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
        { "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
        { "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
        { "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
        { "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
        { "en25qh64a",  INFO(0x1c7017, 0, 64 * 1024,  128, SECT_4K) },
        { "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
        { "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },

        /* ESMT */
        { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },

        /* Everspin */
        { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
        { "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },

        .................... //省略部分代码
}

假设一款新的flash的JEDEC ID0x204017,大小与en25q64的参数一样。

则需要在表中添加如下代码

{ "newboard",    INFO(0x204017, 0, 64 * 1024,  128, SECT_4K) }, //只是修改了INFO()里面的第一个参数,即JEDEC ID

重新编译固件后,观看启动流程。

[    0.680000] m25p80 spi32766.0: found newboard, expected newboard
[    0.680000] m25p80 spi32766.0: newboard (8192 Kbytes)
[    0.690000] m25p80 spi32766.0: using chunked io
[    0.690000] 5 ofpart partitions found on MTD device spi32766.0
[    0.700000] Creating 5 MTD partitions on "spi32766.0":

配置正确。

详细的匹配过程可以搜索代码中spi_nor_ids的判断代码。

uboot

在uboot中也是有类似的机制,查看是否支持该flash。 若不支持,则烧写固件时候的参数都不正确。

焊接新款flash后,uboot启动过程显示如下log

flash manufacture id: 20, device id 40 17
Warning: un-recognized chip ID, please update bootloader!

烧写固件显示如下错误log

NetBootFileXferSize= 00640004
Abort: image size larger than 3866624!

在源码中定位错误的代码,通过image size larger than定位源码。

查找到uboot目录下drivers/spi_flash.c,查看源码,添加JEDEC ID的打印。

int raspi_erase_write(char *buf, unsigned int offs, int count)
{
        int blocksize = spi_chip_info->sector_size;
        int blockmask = blocksize - 1;

        ra_dbg("%s: offs:%x, count:%x\n", __func__, offs, count);

        if (count > (spi_chip_info->sector_size * spi_chip_info->n_sectors) -
                        (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE)) {
                printf("id=0x%x, jedec=0x%x, sector_size=%d, n_sectors=%d\n",  spi_chip_info->id, spi_chip_info->jedec_id, spi_chip_info->sector_size, spi_chip_info->n_sectors); //添加jedec id的打印。
                printf("Abort: image size larger than %d!\n\n", (spi_chip_info->sector_size * spi_chip_info->n_sectors) -
                                (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE));
                udelay(10*1000*1000);
                return -1;
        }

添加代码后,重新启动uboot,烧写固件,显示错误如下,可以看到jedec为0x40178331,这跟linux下读取的204017也是同一个,只不过uboot中,分开了ID 与 JEDEC。

NetBootFileXferSize= 00640004
id=0x20, jedec=0x40178331, sector_size=65536, n_sectors=64
Abort: image size larger than 3866624!

查看同文件下代码,是通过spi_chip_info来判断uboot是否支持该flash

struct chip_info {
        char            *name;
        u8              id;
        u32             jedec_id;
        unsigned long   sector_size;
        unsigned int    n_sectors;
        char            addr4b;
};
struct chip_info *spi_chip_info = NULL;

static struct chip_info chips_data [] = {
        /* REVISIT: fill in JEDEC ids, for parts that have them */
        { "AT25DF321",          0x1f, 0x47000000, 64 * 1024, 64,  0 },
        { "AT26DF161",          0x1f, 0x46000000, 64 * 1024, 32,  0 },
        { "FL016AIF",           0x01, 0x02140000, 64 * 1024, 32,  0 },
        { "FL064AIF",           0x01, 0x02160000, 64 * 1024, 128, 0 },
        { "MX25L1605D",         0xc2, 0x2015c220, 64 * 1024, 32,  0 },
        { "MX25L3205D",         0xc2, 0x2016c220, 64 * 1024, 64,  0 },
        { "MX25L6405D",         0xc2, 0x2017c220, 64 * 1024, 128, 0 },
        { "MX25L12805D",        0xc2, 0x2018c220, 64 * 1024, 256, 0 },
#ifndef NO_4B_ADDRESS_SUPPORT
        { "MX25L25635E",        0xc2, 0x2019c220, 64 * 1024, 512, 1 },
        { "S25FL256S",          0x01, 0x02194D01, 64 * 1024, 512, 1 },
        { "N25Q256A",           0x20, 0xba191000, 64 * 1024, 512, 1 },
        { "MT25QL512AB",        0x20, 0xba201044, 64 * 1024, 1024, 1 },
#endif
        { "S25FL128P",          0x01, 0x20180301, 64 * 1024, 256, 0 },
        { "S25FL129P",          0x01, 0x20184D01, 64 * 1024, 256, 0 },
        { "S25FL164K",          0x01, 0x40170140, 64 * 1024, 128, 0 },
        { "S25FL132K",          0x01, 0x40160140, 64 * 1024, 64, 0 },
        { "S25FL032P",          0x01, 0x02154D00, 64 * 1024, 64,  0 },
        { "S25FL064P",          0x01, 0x02164D00, 64 * 1024, 128, 0 },
        { "S25FL116K",          0x01, 0x40150140, 64 * 1024, 32,  0 },
        { "F25L64QA",           0x8c, 0x41170000, 64 * 1024, 128, 0 }, //ESMT
        { "F25L32QA",           0x8c, 0x41168c41, 64 * 1024, 64,  0 }, //ESMT
        { "EN25F16",            0x1c, 0x31151c31, 64 * 1024, 32,  0 },
        { "EN25Q32B",           0x1c, 0x30161c30, 64 * 1024, 64,  0 },
        { "EN25F32",            0x1c, 0x31161c31, 64 * 1024, 64,  0 },
        { "EN25F64",            0x1c, 0x20171c20, 64 * 1024, 128,  0 }, //EN25P64
        { "EN25Q64",            0x1c, 0x30171c30, 64 * 1024, 128,  0 },
        { "W25Q32BV",           0xef, 0x40160000, 64 * 1024, 64,  0 }, //S25FL032K //W25Q32FV
        { "W25Q64BV",           0xef, 0x40170000, 64 * 1024, 128,  0 }, //S25FL064K //W25Q64FV
        { "W25Q128BV",          0xef, 0x40180000, 64 * 1024, 256, 0 }, //W25Q128FV
        { "W25Q256FV",          0xef, 0x40190000, 64 * 1024, 512, 1 },
        { "N25Q032A13ESE40F",   0x20, 0xba161000, 64 * 1024, 64,  0 }

        .............................. //省略部分代码

}

同样添加JEDEC ID

{ "newboard",            0x1c, 0x40178331, 64 * 1024, 128,  0 }, //其他参数也是参考之前正确的flash参数,也可以看flash的参数pdf文档。

重新编译固件后,启动uboot,出现如下log

flash manufacture id: 20, device id 40 17
find flash: newboard

重新烧写固件也不提示固件超大的问题,即正常了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值