tiny6410的nand flash学的我实在是揪心,这个问题的引出主要是我读取内核并启动没有成功,2440的nand flash是2K读取,但我在查看Nand Flash的数据手册时,发现这块flash的page是8K每页,所以在我写的bootloader中来自己更改代码,而不是跟友善保持一致(以2K读),一开始以的是8K每页读,才发现前4页为2K,但当以前4页2K读,后面8K读(当然这里是我的错误认知),然后基于这样的一个考虑后,我发现以2K每页读取NandFlash,代码运行成功,我以8K每页读取NandFlash,代码运行一样成功,问题就在这里,如果这样考虑,代码到底是每页多少被写到NandFlash的?事实证明的是,这篇文章给了我答案,看来还真是。

以下文章转载自:

Tiny6410+K9GAG08U0E  http://blog.csdn.net/o0Avalon0o/article/details/49644553

友善采用这颗8K Page的Nand,在6410上面搭配使用,确实给用户添加了不少麻烦,再加上ecc部分使用软件实现,代码不开源,学到块驱动的时候确实揪心啊~~

内部SRAM的大小

先从启动说起,Tiny6410启动选用的是用户手册里面屏蔽掉的一种直接Nand启动方式,如下图,根据友善原理图的OM[4:0]电平,对应表中的RESERVED,这种启动方式就是上电后直接将Nand的前面一部分代码映射到片内SRAM中,开始启动。

而三星官方推荐的启动方式应该是从IROM中启动,然后通过IROM将NAND中的代码拷贝到片内SRAM,再跳转到SRAM中启动。

这里看了网上很多资料,有的人说SRAM是8K,有的说是4K,这里我看到用户手册里面是说有4K,但是我用Tiny6410调试裸板程序的时候,发现确实是拷贝了8K代码:

这里自己有个猜测:对于友善使用的这种隐藏的启动方式,就是直接将代码放到SRAM空间运行,此时当然就有8K RAM空间了;但是当使用三星推荐的从IROM中运行,那么IROM中运行的代码的临时变量都是保存在SRAM上面的,所以可能是官方想保留上半4K RAM用于IROM启动。

8K页大小问题

从上面启动选择那张图片可以看到,其实上6410最大仅支持4K页,并不支持8K页,而对于友善使用的被保留启动方式更是最多支持large page(2K)。

所以在开始的8K SRAM代码拷贝中需要注意,系统只会拷贝每个8K页中的前2K数据,而友善配套提供的superboot升级程序在烧写U-boot镜像的时候都只是操作每页中前2K空间。

而对应的在U-Boot源码中也可以看到拷贝U-boot到SDRAM中运行的函数,仅操作了前2K数据:

static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
uchar *buf = (uchar *)dst_addr;
int i;
uint page_shift = 9;
if (large_block)
page_shift = 11;
/* Read pages */
for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
nandll_read_page(buf, i, large_block);
}
return 0;
}

可以看到在整个启动到U-boot代码搬运过程中,都没有启动ecc,所以在这个过程中数据都是不可靠的,而在友善的论坛里面也看到过他们承认,有掉U-boot固件的可能性。这也不能全怪人家,硬件决定6410拷贝8K代码的时候已经不安全了,那么后面Uboot重定向的时候做不做ecc都不是太重要了。。。

在进入U-boot第二阶段start_armboot中之后,通过调用nand_scan()跟友善不开源的NAND_Init(),从这里之后即对K9GAG08U0E完成初始化,开启软件ECC,此后对Kernel、Rootfs的数据操作都是变为可靠了。

这里再吐槽一下,调用NAND_Init()竟然会改变U-Boot的环境变量,搞的我每次通过mini6410.h文件设置的环境变量都无效,这也是醉了。。。P.S.经过验证,友善应该是在Nand上面开辟了一段空间用于保存环境变量,调用NAND_Init之后,系统将直接从Nand的这段地址中还原环境参数,也就是说修改/include/configs/mini6410.h下面的环境变量屁用都没有,对于一块全新的开发板只要在Uboot中调用一次setenv、saveenv,保存到Nand中,下次如果仅更新Uboot固件时,则不需要再重新设置环境变量了(确保你用的Uboot是最新版,旧版本Uboot命令行下不支持saveenv保存参数)。

推荐解决方法可以在NAND_Init()后面使用void setenv (char *varname, char *varvalue)重新设置。

Tiny6410中的nand命令

友善提供的最新U-Boot终于支持对K9GAG08U0E进行写入操作了,分析cmd_nand.c中的do_nand():

    /* read write */
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
int read;
if (argc < 4)
goto usage;
addr = (ulong)simple_strtoul(argv[2], NULL, 16);
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
printf("\nNAND %s: ", read ? "read" : "write");
if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
return 1;
s = strchr(cmd, '.');
if (s != NULL &&
(!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
if (read) {
ret = FriendlyARMReadNand( (u_char*)addr, size, off);
if (ret == -1) {
puts("offset should be multiple of page size\n");
}
} else {
/* write */
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
/* opts.forcejffs2 = 1; */
opts.pad    = 1;
opts.blockalign = 1;
opts.quiet      = quiet;
if (NandIsMlc()) {
ret = -1;
puts("write.jffs2/write.e/write.i is not supported\n");
} else
ret = nand_write_opts(nand, &opts);
}
#ifdef CFG_NAND_YAFFS_WRITE
} else if (!read && s != NULL && + (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))) {
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
opts.pad = 0;
opts.blockalign = 1;
opts.quiet = quiet;
opts.writeoob = 1;
opts.autoplace = 1;
/* jsgood */
/* if (s[6] == '1')
opts.forceyaffs = 1; */
ret = nand_write_opts(nand, &opts);
#endif
} else {
if (read) {
if (!NandIsMlc()) {
ret = nand_read(nand, off, &size, (u_char *)addr);
} else {
ret = FriendlyARMReadNand( (u_char*)addr, size, off);
if (ret == -1) {
puts("offset should be multiple of page size\n");
}
}
} else {
if (NandIsMlc()) {
if (off % NandBlockSizeInByte != 0) {
puts("offset should be multiple of block size\n");
ret = -1;
} else {
unsigned int i;
ret = 0;
for (i = 0; i < size; i += NandBlockSizeInByte) {
int len = size - i;
if (len > NandBlockSizeInByte) {
len = NandBlockSizeInByte;
}
FriendlyARMWriteNand(((u_char *)addr) + i, len, off + i, NandBlockSizeInByte);
}
}
} else {
ret = nand_write(nand, off, &size, (u_char *)addr);
if (ret == 0) {
uint *magic = (uint*)(PHYS_SDRAM_1);
if ((0x24564236 == magic[0]) && (0x20764316 == magic[1]))
magic[0] = 0x27051956;
}
}
}
}

从代码可以看到,只有nand read.i == nand read可以完成K9GAG08U0E的读操作,且它们都要求操作地址必须是page对齐;

而nand write可以完成K9GAG08U0E的写操作,同样,操作地址需要page对齐(8K),且暂时还不支持带oob数据的文件系统镜像的烧写(yaffs)!!

Tiny6410 的NandFlash(K9GAG08U0E)相关推荐

  1. MTD,文件系统,存储器分区的个人理解

    MTD是 memory technology device的简称 (奇怪的中文译名内存技术设备) 个人理解:MTD实际上是跟VFS差不多的东西,VFS是虚拟文件系统,在VFS中有对各种具体文件系统的接 ...

  2. 关于s3c6410的SD卡启动

        要研究裸机程序的编写,必须要有一个"全裸"的环境.友善提供的superboot可以提供执行用户自定义程序的能力,但其实这样运行的程序环境还是依赖于superboot的, 那 ...

  3. s3c6410 开发板Linux系统支持 K9GAG08U0E的方法

    由于NandFlash硬件升级比较快,公司去年一直在使用三星的K9GAG08U0D,现在MLC NandFlash 升级到了第二代,K9GAG08U0D 很快就会处在停产的状态,未雨绸缪,公司选型了K ...

  4. 【开发板资讯】友善推出mini6410 之后不久再推出tiny6410(mini6410和tiny6410有何不同?市场定位如何?)...

          套餐简介   6410开发板面世已经2年多,但价格相比2440,一直高不可攀,最主要的原因之一就是软件极其不完善,学习资源缺乏,导致不良率高,用户使用困难. 但是,经过半年来的努力,友善之 ...

  5. MTD NANDFLASH驱动相关知识介绍

    转:http://blog.csdn.net/zhouzhuan2008/article/details/11053877 目录 MTD总概述 MTD数据结构 MTD相关层实现 MTD,Memory ...

  6. NandFlash系列之一:NorFlash与NandFlash对比

    NandFlash系列之一:NorFlash与NandFlash对比 作者:刘洪涛,华清远见嵌入式学院高级讲师. FLASH存储器又称闪存,主要有两种:NorFlash和NandFlash,下面我们从 ...

  7. NandFlash详述【转】

    NandFlash详述 转自:http://wenku.baidu.com/view/04d9330bb52acfc789ebc92f.html?re=view 1. 硬件特性: [Flash的硬件实 ...

  8. 简介nandflash、norflash、ram、sram、dram、rom、eeprom、flash的区别

    1.nandflash     Nandflash是IO设备,数据.地址.控制线都是共用的,需要软件区控制读取时序, 所以不能像nor flash.内存一样随机访问,不能EIP(片上运行),因此不能直 ...

  9. 移植uboot第六步:支持NANDFlash

    写在前面: 我的博客已迁移至自建服务器:博客传送门,CSDN博客暂时停止,如有机器学习方面的兴趣,欢迎来看一看. 此外目前我在gitHub上准备一些李航的<统计学习方法>的实现算法,目标将 ...

  10. WinCE开机Logo的实现(USB下载图片到nandflash)

    WinCE开机启动Logo使用Eboot读取NandFlash中的图片数据,然后显示的方式.对于开机logo的方式网友http://jazka.blog.51cto.com/809003/664131 ...

最新文章

  1. 前端知识点回顾之重点篇——JavaScript异步机制
  2. SQL SERVER2000教程-第四章 创建和维护表 第二节 数据完整性
  3. 使用SQL*PLUS构建完美excel或html输出
  4. 通过文件IO控制硬件设备的方法
  5. x的平方根—leetcode69
  6. Python爬虫人工智能大数据全栈视频史上最全合辑教程分享!
  7. 谷歌浏览器书签栏怎么隐藏 谷歌Chrome浏览器书签栏隐藏教程
  8. 新年礼物 总算有服务器了
  9. 下载加载linux下用vmware-mount挂载vmdk虚拟硬盘分区
  10. 网络编程之 字节序和深入理解bind()函数
  11. iOS项目开发实战——使用Xcode6设计自己定义控件与图形
  12. WebSocket和WebRtc的一些心得
  13. .fnt 字体不能正常显示
  14. 生信常用分析图形绘制02 -- 解锁火山图真谛!
  15. 计算机读不出光盘,光驱读不出光盘,小编教你电脑光盘不能被识别怎么解决
  16. 教室录播系统方案_校园录播教室搭建方案?
  17. Java服务器通过SCP连接Linux服务器上传、下载文件
  18. 2021SAAE上海第七届教育装备展览会
  19. db2检查什么表被锁住了,如何解锁
  20. [转贴]八岁女童墓志铭:我来过,我很乖~~~~~ (是个人就流泪)

热门文章

  1. 等什么君计算机音乐,等什么君歌曲大全_等什么君最新歌曲_九酷音乐
  2. 2020 dns排名_2020年新版全球/全国各地ISP的DNS服务器地址表
  3. 宽带运营商为什么限制上行带宽
  4. 《数据结构上机实验(C语言实现)》笔记(2 / 1)
  5. the7主题footer.php,【Drupal7主题】Repro 清爽杂志门户Drupal 主题
  6. docker容器—搭建LNMP
  7. python 汉字转拼音拼音转汉字
  8. AutoCAD中添加块和块参照(转载)
  9. 本地计算机如何使用代理服务器,自动设置代理ip
  10. MacBook蓝牙鼠标 自动断开问题