今天按照国嵌视频,进行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,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 Typen");
??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扇区都对啦,说明移植成功!!