在全志V3/V3s和索智S3/S3L上调试32MB NorFlash
Posted ka布
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在全志V3/V3s和索智S3/S3L上调试32MB NorFlash相关的知识,希望对你有一定的参考价值。
选取MX25L25635F作为调试对象,其他型号的NorFlash开发调试原理基本一致。为了使V3/V3s/S3/S3L识别32MB NorFlash并正常工作,主要针对以下三个部分进行开发和调试。下文将针对这三个部分的开发进行说明。
- U-Boot
- Linux Kernel
- System Configuration
第一部分,U-boot
原始的SDK包支持3线模式,但没有支持4线模式,因此,必须在引导过程中加入4线模式。简单解释一下,3线模式是指NorFlash支持3x8位地址线,可以访问的地址空间是16MB(2^24/1024/1024),4线模式支持4x8位地址线,可以访问比16MB大的地址空间。找到源码文件drivers/spinor/sunxi_spinor.c,增加4线模式的使能函数。
static void spinor_enter_4bytes_addr(int enable) { int command = 0; if(spinor_4bytes_addr_mode == 1 && enable == 1) command = 0xB7; else if(spinor_4bytes_addr_mode == 1 && enable == 0) command = 0xE9;
else return ;
#ifdef CONFIG_ARCH_SUN8IW8P1 spic_config_dual_mode(0, 0, 0, 1); #endif spic_rw(1, (void*)&command, 0, 0); return; }
需要注意的是,0xB7和0xE9不代码所有32MB NorFlash的4线模式进入/退出命令,应从datasheet中获取相应的命令值。接下来,找到spinor_init函数,回复flash size大于16MB的处理。
if(spi_size > 16*1024*1024/512) { spinor_4bytes_addr_mode = 1; spinor_enter_4bytes_addr(ENABLE_4BYTES); }
找到NorFlash读写函数__spinor_pp和__spinor_sector_normal_read,增加4线模式的数据读写代码片段。
------------写 if(spinor_4bytes_addr_mode == 0) { txnum = len+4; sdata[0] = SPINOR_PP; sdata[1] = (page_addr >> 16) & 0xff; sdata[2] = (page_addr >> 8 ) & 0xff; sdata[3] = page_addr & 0xff; memcpy((void *)(sdata+4), buf, len); } else if(spinor_4bytes_addr_mode == 1) { txnum = len+5; sdata[0] = SPINOR_PP; sdata[1] = (page_addr >> 24) & 0xff; sdata[2] = (page_addr >> 16) & 0xff; sdata[3] = (page_addr >> 8 ) & 0xff; sdata[4] = page_addr & 0xff; memcpy((void *)(sdata+5), buf, len); } ------------读 if(spinor_4bytes_addr_mode == 0) { txnum = 4; sdata[0] = SPINOR_READ; sdata[1] = (page_addr >> 16) & 0xff; sdata[2] = (page_addr >> 8 ) & 0xff; sdata[3] = page_addr & 0xff; } else if(spinor_4bytes_addr_mode == 1) { txnum = 5; sdata[0] = SPINOR_READ; sdata[1] = (page_addr >> 24) & 0xff; sdata[2] = (page_addr >> 16) & 0xff; sdata[3] = (page_addr >> 8 ) & 0xff; sdata[4] = page_addr & 0xff; }
最后需要在spinor_datafinish_card函数最后退出4线模式,这样做,刷机结束后,系统启动时才可以正确得到boot0,否则会重复刷机。
第二部分,Linux Kernel
内核部分的修改比较简单,在NorFlash设备驱动drivers/mtd/devices/m25p80.c中加入针对MX25L25635F这款32MB NorFlash的支持,如下:
--- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -724,7 +724,7 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, + { "mx25l12805f", INFO(0xc22018, 0, 64 * 1024, 512, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, @@ -1136,6 +1136,22 @@ static int __devexit m25p_remove(struct spi_device *spi) } +static int m25p_shutdown(struct spi_device *spi) +{ + struct m25p *flash = dev_get_drvdata(&spi->dev); + const struct spi_device_id *id = spi_get_device_id(spi); + struct flash_info *info; + printk("m25p: spinor shutdown\n"); + + if(flash->addr_width == 4) + { + info = (void *)id->driver_data; + set_4byte(flash, info->jedec_id, 0); + } + return 0; +} + + static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", @@ -1144,6 +1160,7 @@ static struct spi_driver m25p80_driver = { .id_table = m25p_ids, .probe = m25p_probe, .remove = __devexit_p(m25p_remove), + .shutdown = m25p_shutdown, /* REVISIT: many of these chips have deep power-down modes, which * should clearly be entered on suspend() to minimize power use.
第三部分,System Configuration
V3/V3s/S3/S3L这4个平台的SDK里面,U-Boot和Kernel都会调用sys_config.fex的Nor配置,需要将Nor Flash的大小修改成32,意思是32MB。
@@ -301,7 +298,8 @@ max_speed_hz = 50000000 bus_num = 0 chip_select = 0 mode = 0 -sflash_size = 16 +sflash_size = 32
完成上述三个环节的修改以后,依次编译U-Boot,Linux Kernel,最后打包Firmware,烧录到设备。
以上是关于在全志V3/V3s和索智S3/S3L上调试32MB NorFlash的主要内容,如果未能解决你的问题,请参考以下文章
全志 Tina Linux 系统调试 使用指南 GDB gdbserver coredump perf strace valgind