S3C6410学习——Nand flash陷阱
我的开发板式Tiny6410,配置的Nand flash是K9GAG08U0E,块空间1M,页空间8K。于是可以实现nand_read函数:
- intnand_read(unsignedintnand_start,unsignedintddr_start,unsignedintlen)
- {
- unsignedlongrest=len;
- unsignedlongaddr=nand_start;
- unsignedlongpage;
- unsignedchar*dest=(unsignedchar*)ddr_start;
- inti;
- nand_select();
- while(rest>0){
- nand_cmd(0x00);
- nand_addr(addr);
- nand_cmd(0x30);
- nand_ready();
- page=rest>PAGE_SIZE?PAGE_SIZE:rest;
- for(i=0;i!=page;++i){
- *dest++=NFDATA;
- }
- rest-=page;
- addr+=page;
- }
- nand_deselect();
- return0;
- }
如上,我们可以完成必要的硬件初始化后用nand_read(0, 0x50000000, __bss_start-_start)来将完整的代码从Nand搬移到DDR中,开始我也是这样想的,但是发现代码根本无法运行,后来调试了一下发现,这样只将代码的前2K拷贝到DDR中,接下来的6K代码丢失了,而再接下来的代码是正确的!这很奇怪啊,手册中明却指出,该Nand的页大小为8KB,但为何我实际读取时却只能读取到2KB呢?原来S3C6410启动时拷贝的8K代码不是存储在Nand flash的第一页上,而是存储在Nand flash的前4页上,每页2K,总共8K,这是S3C6410芯片的硬件结构决定的!也就是说,虽然我们的Nand flash的页大小是8K,但是S3C6410为了适应各种型号的Nand flash并保证硬件能正确的拷贝Nand flash中的前8K到SRAM中,硬性的加上这一规定。因此,nand2ddr函数应该这样写:
- voidcopy2ddr(unsignedlonglength){
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_read(PAGE_SIZE*i,0x50000000+i*2048,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_read(PAGE_SIZE*4,0x50000000+PAGE_SIZE,rest);
- }
对应还有写操作,原理一样,逆着写回去,这里就不分析原理了,nand_write函数:
- voidnand_write(unsignedintnand_start,unsignedchar*buf,unsignedintlen)
- {
- unsignedlongcount=0;
- unsignedlongaddr=nand_start;
- inti=nand_start%PAGE_SIZE;
- nand_select();
- while(count
- {
- nand_cmd(0x80);
- nand_addr(addr);
- for(;i
- {
- NFDATA=buf[count++];
- addr++;
- }
- nand_cmd(0x10);
- nand_ready();
- i=0;
- }
- nand_deselect();
- }
store2nand函数应该这样写:
- voidstore2nand(unsignedlongddr_start,unsignedlonglength){
- unsignedchar*src=(unsignedchar*)ddr_start;
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_write(PAGE_SIZE*i,src+2048*i,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_write(PAGE_SIZE*4,src+2048*4,rest);
- }
store2nand函数可以用来下载程序时写nand用,如果不按照这种方式将程序写入nand,硬件就无法正确加载Nand flash的前8K代码,程序也就无法正常运行。
下面是我自己写的Tiny6410裸机程序,arm-linux-gcc环境,如果需要可以下载了看看,代码实现了系统时钟、DDR、Nand flash还有串口的初始化,下面是链接地址,以后还会继续完善:
下载地址:(前段时间忘了改了)
http://download.csdn.net/detail/girlkoo/4690705
S3C641Nandflash陷 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)