分类: 嵌入式
2011-02-17 16:21:47
先是找相应的Nand Flash。由于对S3C2440的特性以及Nand Flash的情况不是非常清楚,当我终于低价从淘宝上买回了3颗1GB的Flash芯片(型号HY27UT088G2A)后,才知道,这个型号的Flash是MLC构架的,往往是做黑芯片的首选。为什么这么说呢?因为这种芯片价格特别便宜,用卖给我的那个人的话来说,就是从台湾内地等一些小厂出来的劣质芯片,打上Hynix公司的型号。网上这个型号的芯片的文档都下不到,Hynix公司的网站上更是查不到这个型号的相关信息。MLC又是什么东东呢?MLC即多层式储存(Multi Level Cell),与此相对的是单层式储存(Single Level Cell),即SLC。本来本人以MLC是没有什么偏见的,但看到网上评测说MLC的寿命更短,可靠性要求更高,心里就不太爽,最糟糕的就是S3C2440硬件设计是不支持MLC的Nand Flash。有网友讨论过在S3C2440的MLC方案,讲到软件ECC,提到一些复杂的算法,恕目前本人水平有限,就此打住。总之,这几个MLC的芯片算是买亏了。
当然,本人一度把这个Flash芯片装到我的核心板上去了,用风枪吹掉原来的芯片,再用恒温烙铁换上新的芯片。本人在自己的核心板上已经弄过几次了,每次都提心吊胆的,不过目前还没有出问题,经过这么一番锻炼,我的拆焊技术得到了不少提升啊!MLC的Flash换上去之后,用SJF2440能够检测得到芯片的ID(具体没有记下来),但是没法烧写它。我再换了一个老128MU盘里面的HY27UA081G1M(除了128M容量之外,其他参数和核心板自带的K9F1208U0B是一样的)的芯片上去再试,还是不行。这时,我确信了阳初盘里面的那个SJF不支持除K9x1208之外的其他任何Nand Flash芯片的编程。这个SJF是三星公司提供给SMDK2440开发板用的烧写程序,估计由于市场和开发的原因吧,完全没有支持更多的芯片。其实其他公司同类型和同容量的Flash芯片,仅仅只是产品ID不同而已,其他都是兼容的,为什么不能够提供支持呢?好在有这个东东的源码,用VS60打开一看,果然看到sjf2440.c的145行处调用了K9S1208_Menu()函数,定位到k9S12028.c文件中这个函数的定义处,58行处有:
id=NF_CheckId();
if(id!=0xec76)
{
printf("ERROR: K9S1208 is not detected. Detected ID=0x%x.\n",id);
return;
}
else
{
printf("K9S1208 is detected. ID=0x%x\n",id);
}
由些可见,这个程序对于id非0xec76的芯片完全不理会。网上查到,实际上这个id的高字节表示的是生产厂商,这里的0xec表示的就是Samsung公司,可查到Hynix的为0xad。低字节是容量等相关参数的标识,这里的0x76可以认为表示了64M的nand flash,而128M的为0x79。鉴于没有时间去研究NAND的操作的细节,本人仅仅想添加对HY27UA081G1M芯片的支持,于是对k9S12028.c文件从58起做了如下修改:
id=NF_CheckId();
if(id==0xad79)
{
printf("HY27UA081G is detected. Detected ID=0x%x.\n",id);
}
else if(id==0xec76)
{
printf("K9S1208 is detected. ID=0x%x\n",id);
}
else
{
printf("ERROR: K9S1208 is not detected. Detected ID=0x%x.\n",id);
return;
}
然后用VS60编译。运行新的SJF2440,在第一步时依旧选择0,这时能够顺利进入第二步,并且显示:
HY27UA081G is detected. Detected ID=0xad79
第二步依旧选择0,可以进入第三步,这一步是选择扇区,这里,程序只提供了对0-4095编号的扇区号的选择,实际上,HY27UA081G1M有8192个扇区,感兴趣的同仁可以修改SJF2440的源码,来提供对足够多的芯片的支持。选择下载到扇区0,然而就只可以成功下载vivi了。
vivi下载之后,拔掉JTAG,重启,串口上显示vivi已经运行了,按空格键就能进入vivi。这时我注意到vivi提示:
"No NAND device found!!!“
见鬼,肯定是vivi也不支持K9x12028之外的Flash。于是又去看vivi的源码。vivi的源码没有SJF的那么好看,主是脱离像VS那种工具,不太熟悉在Linux上看源代码。好不容易找着了drivers\mtd\nand\smc_core_2440.c的smc_scan()函数中1097行包含了上面的字符串。再往上看,在1053行有一个for循环,一看,就是匹配id。再就是到包含文件中去找nand_flash_ids这个数组。从文件名就能看出应该就是include\mtd\nand_ids.h文件了,打开一看,除了37行起:
{"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0x12, 3, 0x4000}, // 64Mb
{"Samsung K9D1G08V0M", NAND_MFR_SAMSUNG, 0x79, 27, 0x12, 3, 0x4000}, // 128Mb
// >>> Add new device
{"Samsung K9F2G08U0M", NAND_MFR_SAMSUNG, 0xDA, 28, 0, 0, 0 }, // 256Mb
{"Samsung K9F4G08U0M", NAND_MFR_SAMSUNG, 0xDC, 29, 0, 0, 0 }, // 512Mb
这四种Flash外,其他的芯片全部给注释掉了。仿照38行(我的芯片也是128M,注意注释标注的是Mb应该是MB,因为表示的中字节容量),在下面添加一行:
{"Hyinix HY27HA081G1M", NAND_MFR_HYNIX, 0x79, 27, 0x12, 3, 0x4000}, // 128Mb
然后还要在include\mtd\nand.h文件的204行下面添加定义:
#define NAND_MFR_HYNIX 0xad
Hynix对应的ID在上面有提到过。这样,重新编译vivi,下载新的vivi到我芯片中,重启就能成功检测NAND Flash芯片了。顺便提一句,阳初内核运行起来后,同样不能正确识别这个芯片的厂商ID,但能够通过检测,能够得到正确容量,能正确分区并挂载。可见,nand的驱动里面也没有记录Hynix的厂商ID。这个驱动应该也是出自Samsung之手吧,看来他们还真不厚道,SJF,VIVI,NAND驱动,始终见不到Hynix的身影,好歹Hynix也是世界级的芯片厂商,Samsung不会自家兄弟反而不认识了吧!
vivi起来之后,就应该分区装系统了。bon命令还是不能用,现在想来,这个bon命令还是真没有多少用,网上查到,它的分区信息和mtd是不太一样的,所以分完区,一旦当作mtd分区来用,肯定又会被破坏掉。我之前希望能用bon命令是因为bon命令分区完成后会擦除分区内容并检查坏块,后来发现vivi带的Flash命令可以完成这些功能。这比较有用,因为新下载的vivi总是使用param区(如果存在的话)里面的mtd分区信息,而不会使用默认的分区信息。因为它不会破坏分区内容,这样,重新下载的vivi它就可能继续使用上一次保存在param分区里面的参数信息。但问题出现了,part add命令不能成功设置分区的flag,它总是设置成0。所以我一旦调整root分区的信息,它的flag就变成了0,但root分区必须将flag设为16以指明内核以yaffs格式挂载该分区,否则就会导致启动过程中根目录挂载不成功的问题。如:
FAT: bogus logical sector size 42986
yaffs: dev is 7936 name is "1f:00"
yaffs: Attempting MTD mount on 31.0, "1f:00"
VFS: Mounted root (yaffs filesystem).
Warning: unable to mount devfs, err: -2
另外,检测mtd的坏块也是一件很重要的事情。网上资料说,要从NAND Flash启动,须保证NAND Flash的第一个block是好的,这样硬件才能在reset之后自动产生的一个Nand Flash读取时序后成功将bootloader的第一部分读取到内部SRAM中,通过执行这一部分bootloader,再将bootloader的其余部分读取到SRAM中,这跟PC机启动过程很类似。另外,本人发现,kernel分区(被用到部分)一旦出现了坏块,会导致内核无法运行,通过修改kernel分区的起点和大小,避开坏块之后,问题就会消失。本人并不清楚vivi分区中出现坏块(不是第一个block)会不会产生问题,而我的param分区中也有坏块,但没有发现问题。呵呵,这个从老U盘上拆下来的芯片坏块还真的,在前2M的三个分区中,就出现了2个坏块,而root分区中的前30几兆共发现了5个坏块(后面部分可能还存在坏块,没有检测),大致坏块分布在前面10M以内。本人发现在用load flash或者net flash命令写flash时,程序有时会提示跳过一些坏块,但却并不是所有。不知道这是不是表示一些内容被写进了坏块的位置?这会不会出现问题呢?看来这些问题都得从vivi的源码中去找答案。