出处:http://blog.csdn.net/quannii/article/details/8861572
今天按照国嵌视频,进行uboot--nor flash驱动移植
难点:mini2440开发板子上的nor flash芯片是:SST39VF1601,我用的天嵌开发板子上nor flash芯片是:EN29LV160AB。不同的nor flash,芯片资料的介绍区别还是比较大,EN29LV160AB资料中,没有涉及到块擦除和块操作的本分,如果按照国嵌视频的移植,需要修改块操作和块擦除部分,所以移植难度还是挺大的,特别是对我这菜鸟级别的来说。
1、nor flash工作原理:其核心就是读、写、擦除操作,以及对应的命令操作时序,见数据手册。(但是EN29LV160AB没有块操作时序和命令,也没有提到有多少块)
2、SST39VF1601移植参考文件是SST39VF160,在uboot/board/dave/common/flash.c 文件,但是EN29LV160AB移植参考文件也是可以用这个文件吗??
3、国嵌中SST39VF1601,移植修改如下
(1)先读取nor flash ID,即要吻合software ID Entry命令操作序列。(在函数flash_init中,先修改函数flash_get_size())
(2)函数中不识别device ID为234BH的SST39VF1601的片子,所以在flash.c中添加相应的宏定义
(3)在函数flash_get_size()的device ID匹配中添加代码,使初始化时能够识别芯片
(4)建立flash的block分区的地址表,驱动按照每块64kb来建立分区的
(5)修改flash的擦除函数flash_erase(),实验时可以选择按块方式擦除
(6)修改法拉盛写函数write_word函数
(7)修改函数write_buff
(8)修改函数flash_print_info
(9)此时去编译uboot的时候会报一些错误,因为没有CFG_FLASH_ADDR0没有定义,参考include/configs/B2.h,在board/mini2440/flash.c添加宏定义的代码
(10)屏蔽原来flash有关的宏定义
(11)添加有关新的flash宏定义(CONFIG_ENV_ADDR定义了环境变量的起始地址为0x30000,环境变量的大小为64k)
解决:
由于我的nor flash芯片是EN29LV160AB,所以就不能按照国嵌视频上移植的方法进行移植。参考了网上的一个移植文件点击打开链接
文件大概如下:
EN29LV160AB 是TQ2440选的NOR FLASH芯片,定义的sector总数手册上的是35 。
通常,在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动。u-boot中默认是从Nor Flash启动的。翻开此芯片的datasheet看到:
TQ2440原理图上的第47脚 BYTE#是接高电平的,so 此芯片工作于16位模式(半字模式)
A0-A19是地址线,在半字模式下,D0-D15做为数据输入输出口。因为数据位是16位,A0-A19可以选择2^20 = 1M *2BYTE = 2Mbyte。正好是AM29LV160DB的容量。S3C2440的ADDR1要接AM29LV160DB的A0。上图中AM29LV160DB的A20,A21是空脚,分别接的是LADDR21,LADDR22。这应该是为了以后方便扩展NOR FLASH的容量。LADDR21,LADDR22对AM29LV160DB是没用的。<1>2048K * 8bit / 1024K * 16bit Flash Memory Boot Sector Flash Memory
<2>Flexible Sector Architecture:
-One 16-Kbyte, two 8-Kbyte, one 32-Kbyte, and thirty-one 64-Kbyte sectors(byte mode)
-One 8-Kword, two 4-Kword, one 16-Kword,and thirty-one 32-Kword sectors(word mode)
无论哪种模式总扇区是 35 sectors。1. 修改Norflash参数
vi include/configs/TQ2440.h
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#if 0 //注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif
#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
#ifdef CONFIG_AMD_LV800
#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
#define CONFIG_SYS_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of environment */
#endif
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
#define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
#endif
//第175行添加如下内容
#define CONFIG_EON_29LV160AB 1 //添加TQ2440开发板Nor Flash设置
#define PHYS_FLASH_SIZE 0x200000 //我们开发板的Nor Flash是2M
#define CONFIG_SYS_MAX_FLASH_SECT (35) //根据EN29LV160AB的芯片手册描述,共35个扇区// 注意:uboot其他文件中最大扇区的定义名字也不是“CONFIG_SYS_MAX_FLASH_SECT ”,所以要改成“CFG_MAX_FLASH_SECT”
#define CFG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x060000) //暂设置环境变量的首地址为0x060000(即:384Kb)// 注意:这里,uboot其他文件中定义flash_base基地址的名字不是“CONFIG_SYS_FLASH_BASE”,所以要修改成“CFG_FLASH_BASE ”
2. 添加Norflash的information
vi include/flash.h
第181行添加
#define EON_ID_LV160AB 0x22492249
#define EON_MANUFACT 0x001c001c
3. 修改norflash的驱动,在u-boot中对Nor Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、write_hword。
vi board/Tanatseng/TQ2440/flash.c
由-One 8-Kword, two 4-Kword, one 16-Kword,and thirty-one 32-Kword sectors(word mode)
可知主要扇区大小为32k,so修改第31行
#define MAIN_SECT_SIZE 0x8000 //定义为32k,主要扇区的大小
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
由于我们是把norflash连接到了s3c2440的bank0上,因此norflash中的地址相对于s3c2440来说基址为0x00000000,即CONFIG_SYS_FLASH_BASE = 0。
而之所以又把norflash中的地址向左移一位(即乘以2),是因为我们是把s3c2440的ADDR1连接到了norflash的A0上的缘故。
由数据手册可知EN29LV160AB第0扇区大小为8K,第1、2为4K,第3为16K,后面31扇区为32K。前面4个扇区加起来刚好是主要扇区的大小 = 32K, 所以修改87行下如下// 增加的代码
#elif defined(CONFIG_EON_29LV160AB)
(EON_MANUFACT & FLASH_VENDMASK) |
(EON_ID_LV160AB & FLASH_TYPEMASK);
#else
#error "Unknow flash configured"
#endif
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 3)
{
/* 1st one is 8 KB */
if (j == 0)
{
flash_info[i].start[j] = flashbase + 0;
}
/* 2nd and 3rd are both 4 KB */
if ((j == 1) || (j == 2))
{
flash_info[i].start[j] = flashbase + 0x2000 + (j - 1) * 0x1000;
}
/* 4th 16 KB */
if (j == 3)
{
flash_info[i].start[j] = flashbase + 0x4000;
}
}
else
{
flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;
修改flash_print_info,添加EN29LV160AB相关信息如下:
switch (info->flash_id & FLASH_VENDMASK) {
case (AMD_MANUFACT & FLASH_VENDMASK):
printf ("AMD: ");
break;
case (EON_MANUFACT & FLASH_VENDMASK):
printf ("EON: ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case (AMD_ID_LV400B & FLASH_TYPEMASK):
printf ("1x Amd29LV400BB (4Mbit)\n");
break;
case (AMD_ID_LV800B & FLASH_TYPEMASK):
printf ("1x Amd29LV800BB (8Mbit)\n");
break;
case (EON_ID_LV160AB & FLASH_TYPEMASK):
printf ("1x EN29LV160AB (16Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
}
修改int flash_erase (flash_info_t * info, int s_first, int s_last)
if ((info->flash_id & FLASH_VENDMASK) !=
(EON_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;4. 至此,uboot关于Norflash已经移植好.
参考:
http://blog.chinaunix.net/u3/117012/showart_2283549.html
http://bbs.embedsky.net/archiver/?tid-6373.html
遇到的问题:
参考上述的文件移植,在移植的过程中还是会有很多错误的,看报错的类型,经过一步步的修改,最终能够成功编译。移植到开发板子上后的结果如下:
U-Boot 2008.10 (Apr 29 2013 - 00:53:47)
DRAM: 64 MB
Flash: 2 MB // 大小对了
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Mini2440 # flinfo
Bank # 1: EON:lx EN29LV160AB(16Mbit)
Size: 2 MB in 35 Sectors
Sector Start Addresses:
00000000 (RO) 00002000 (RO) 00003000 (RO) 00004000 (RO) 00008000 (RO)
00010000 (RO) 00018000 00020000 00028000 00030000
00038000 00040000 00048000 00050000 00058000
00060000 00068000 00070000 00078000 00080000 (RO)
00088000 (RO) 00090000 00098000 000A0000 000A8000
000B0000 000B8000 000C0000 000C8000 000D0000
000D8000 000E0000 000E8000 000F0000 000F8000
Mini2440 #
上述 ,nor flash大小为2M,型号为EN29LV160AB,32个sectors扇区都对啦,说明移植成功!!