热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Tiny6410+K9GAG08U0E

Tiny6410(K9GAG08U0E)使用小记友善采用这颗8KPage的Nand,在6410上面搭配使用,确实给用户添加了不少麻烦,再

Tiny6410(K9GAG08U0E)使用小记

友善采用这颗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 &#61; (uchar *)dst_addr;int i;uint page_shift &#61; 9;if (large_block)page_shift &#61; 11;/* Read pages */for (i &#61; 0; i <(0x3c000>>page_shift); i&#43;&#43;, buf&#43;&#61;(1<return 0;
}

可以看到在整个启动到U-boot代码搬运过程中&#xff0c;都没有启动ecc&#xff0c;所以在这个过程中数据都是不可靠的&#xff0c;而在友善的论坛里面也看到过他们承认&#xff0c;有掉U-boot固件的可能性。这也不能全怪人家&#xff0c;硬件决定6410拷贝8K代码的时候已经不安全了&#xff0c;那么后面Uboot重定向的时候做不做ecc都不是太重要了。。。
在进入U-boot第二阶段start_armboot中之后&#xff0c;通过调用nand_scan()跟友善不开源的NAND_Init()&#xff0c;从这里之后即对K9GAG08U0E完成初始化&#xff0c;开启软件ECC&#xff0c;此后对Kernel、Rootfs的数据操作都是变为可靠了。
这里再吐槽一下&#xff0c;调用NAND_Init()竟然会改变U-Boot的环境变量&#xff0c;搞的我每次通过mini6410.h文件设置的环境变量都无效&#xff0c;这也是醉了。。。P.S.经过验证&#xff0c;友善应该是在Nand上面开辟了一段空间用于保存环境变量&#xff0c;调用NAND_Init之后&#xff0c;系统将直接从Nand的这段地址中还原环境参数&#xff0c;也就是说修改/include/configs/mini6410.h下面的环境变量屁用都没有&#xff0c;对于一块全新的开发板只要在Uboot中调用一次setenv、saveenv&#xff0c;保存到Nand中&#xff0c;下次如果仅更新Uboot固件时&#xff0c;则不需要再重新设置环境变量了(确保你用的Uboot是最新版&#xff0c;旧版本Uboot命令行下不支持saveenv保存参数)。
推荐解决方法可以在NAND_Init()后面使用void setenv (char *varname, char *varvalue)重新设置。


Tiny6410中的nand命令

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

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

从代码可以看到&#xff0c;只有nand read.i &#61;&#61; nand read可以完成K9GAG08U0E的读操作&#xff0c;且它们都要求操作地址必须是page对齐&#xff1b;
而nand write可以完成K9GAG08U0E的写操作&#xff0c;同样&#xff0c;操作地址需要page对齐(8K)&#xff0c;且暂时还不支持带oob数据的文件系统镜像的烧写(yaffs)&#xff01;&#xff01;


推荐阅读
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了在一个局域网内设置复印机共享的步骤和注意事项,包括固定IP地址的设置、打印机共享的操作、防火墙和杀毒软件的关闭、局域网访问权限的保证等。同时提醒用户要确保所有相连的电脑在同一个域。 ... [详细]
  • 本文介绍了win7系统休眠功能无法启动和关闭的解决方法,包括在控制面板中启用休眠功能、设置系统休眠的时间、通过命令行定时休眠、手动进入休眠状态等方法。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
author-avatar
sEn_森森森森森
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有