u-boot支持yaffs映像烧写的补丁

u-boot的nand flash驱动有两个版本,似乎是以u-boot1.1.5为分界点的,之前的版本使用的是自己写的nand flash驱动,而后面的版本使用的是linux内核中nand flash的驱动。这两个版本有可能在同一个u-boot中存在,都存放在
driver目录下面,一个为nand,一个为nand_legacy,意思为传统的nand flash驱动。两者使用一个宏开关
CFG_NAND_LEGACY来打开,如果定义这个宏的话,将使用传统的nand flash驱动,否则使用最新的flash驱动。
关于传统的flash驱动中的yaffs文件映像的下载问题,我已经解决,可以看我的另外的一篇文章,使用的内核版本是2.6.15,你去看内核的yaffs代码,2.6.17是内核中yaffs的一个分界点,所以你2.6.17的内核可能可以使用我说的方法,2.618的内核可能就不能用我说的那个方法,2.6.18以上的内核没有验证过,热心的朋友可以帮忙使用2.6.18以上的内核帮忙验证一下,然后在这里告诉一下在下。
最新的flash中的yaffs文件映像烧写的问题,我放出一个老外的驱动,我验证过映像下载是没有问题,但是产生了一些其他的问题,我一直没有解决,所以这篇文章也拖到现在。

                diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index b011b5e..2760874 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -351,6 +351,23 @@ #endif
                 opts.quiet      = quiet;
                 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;
+            if (s[6] == ‘1‘)
+                opts.forceyaffs = 1;
+            ret = nand_write_opts(nand, &opts);
+#endif
         } else {
             if (read)
                 ret = nand_read(nand, off, &size, (u_char *)addr);
@@ -462,6 +479,10 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
     "nand read[.jffs2]     - addr off|partition size\n"
     "nand write[.jffs2]    - addr off|partiton size - read/write `size‘ bytes starting\n"
     "    at offset `off‘ to/from memory address `addr‘\n"
+#ifdef CFG_NAND_YAFFS_WRITE
+    "nand write[.yaffs[1]] - addr off|partition size - write `size‘ byte yaffs image\n"
+    "    starting at offset `off‘ from memory address `addr‘ (.yaffs1 for 512+16 NAND)\n"
+#endif
     "nand erase [clean] [off size] - erase `size‘ bytes from\n"
     "    offset `off‘ (entire device if not specified)\n"
     "nand bad - show bad blocks\n"
diff --git a/drivers/nand/nand_util.c b/drivers/nand/nand_util.c
index 10bf036..bea5c1e 100644
--- a/drivers/nand/nand_util.c
+++ b/drivers/nand/nand_util.c
@@ -343,6 +343,10 @@ int nand_write_opts(nand_info_t *meminfo
         struct nand_oobinfo *oobsel =
             opts->forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo;

+#ifdef CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
+        /* jffs2_oobinfo matches 2.6.18+ MTD nand_oob_16 ecclayout */
+        oobsel = &jffs2_oobinfo;
+#endif
         if (meminfo->oobsize == 8) {
             if (opts->forceyaffs) {
                 printf("YAFSS cannot operate on "
@@ -443,6 +447,28 @@ int nand_write_opts(nand_info_t *meminfo
             memcpy(oob_buf, buffer, meminfo->oobsize);
             buffer += meminfo->oobsize;

+            if (opts->forceyaffs) {
+#ifdef CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
+                /* translate OOB for yaffs1 on Linux 2.6.18+ */
+                oob_buf[15] = oob_buf[12];
+                oob_buf[14] = oob_buf[11];
+                oob_buf[13] = (oob_buf[7] & 0x3f)
+                    | (oob_buf[5] == ‘Y‘ ? 0 : 0x80)
+                    | (oob_buf[4] == 0 ? 0 : 0x40);
+                oob_buf[12] = oob_buf[6];
+                oob_buf[11] = oob_buf[3];
+                oob_buf[10] = oob_buf[2];
+                oob_buf[9]  = oob_buf[1];
+                oob_buf[8]  = oob_buf[0];
+                memset(oob_buf, 0xff, 8);
+#else
+                /* set the ECC bytes to 0xff so MTD will
+                   calculate it */
+                int i;
+                for (i = 0; i  meminfo->oobinfo.eccbytes; i++)
+                    oob_buf[meminfo->oobinfo.eccpos[i]] = 0xff;
+#endif
+            }
             /* write OOB data first, as ecc will be placed
              * in there*/
             result = meminfo->write_oob(meminfo,

自己选择性的添加吧。

这个补丁主要完成了一个oob字节顺序的改变。

注意同时要查看一下你的mkyaffsimage命令的源文件里面的oob的字节的顺序!

这样制作的u-boot下载yaffs文件系统映像没有问题,但是垃圾回收(garbage collection)机制有问题,对该文件系统进行写入操作(mkdir、 touch)时,系统提示:

page 1302 in gc has no object: 0 0 0
.
.
.
page 1311 in gc has no object : 0 0 0

具体原因待查!

内核的一个编译选项的意义:
Device Drivers->Memory Technolovy Devices->FTL(Flash Translation Layer) Support
这个选项的意义在于?
由于无法重复的在flash的同一块存储位置上做写入的操作(必须事先擦除该快之后才能写入),因此一般在硬盘上使用的文件系统,如:fat16,fat32,ntfs,ext2,ext3等将无法直接用到flash上,为了沿用这些文件系统,则必须透过一层转换层来将逻辑地址对应到flash的存储器的物理位置上,使系统能把flash当作普通的硬盘来使用,我们将这一层称之为ftl(flash translation layer),flash主要用于nor flash上,而nftl则应用于nand flash上。
最简单的ftl的实现方法就是一对一的映射,那么当上层的文件系统要写一个块设备的扇区的时候,闪存做下面的操作来完成这个请求。
1、将这个扇区的所在的擦处块读到内存中,放入缓冲
2、按照写要求更新该缓冲块
3、对该快进行擦除
4、回写
存在的问题:
1、效率低,一个chunk更新要对整个block进行擦除
2、没有磨损均衡策略
3、非常不安全!容易引起数据的丢失,如果3步与第4步之间,数据将全部丢失

所以闪存转换层采用的算法比这个复杂一点

在flash上,尽量避免使用传统的依赖闪存转换层的文件系统,最好采用专门的针对flash的文件系统,如
jffs3和yaffs2

问题:加载cramfs文件系统分区(mount -t cramfs /dev/mtdblock1 /mnt/flash1)的时候,报出如下的错误:
end_request: I/O error, dev mtdblock2, sector 0
Buffer I/O error on device mtdblock2, logical block 0
end_request: I/O error, dev mtdblock2, sector 0
Buffer I/O error on device mtdblock2, logical block 0
end_request: I/O error, dev mtdblock2, sector 8
Buffer I/O error on device mtdblock2, logical block 1
end_request: I/O error, dev mtdblock2, sector 8
Buffer I/O error on device mtdblock2, logical block 1
end_request: I/O error, dev mtdblock2, sector 16
Buffer I/O error on device mtdblock2, logical block 2
end_request: I/O error, dev mtdblock2, sector 16
开始以为是硬件错误,后来仔细一检查发现:其实是uboot写入cramfs文件系统映像时使用的ecc校验算法和内核使用的校验算法不一致导致的,如果我们将内核中的mtd层ecc校验NAND_ECC_SOFT关掉,在/drivers/mtd/at91_nand.c文件中有定义。则系统在加载的时候将不再报错,验证了这是校验的问题,解觉的办法是什么?
首先在uboot中,使用nand erase 将cramfs分区擦除干净,以nfs的方式启动linux,然后使用
cp root_fs_cramfs.img /dev/mtd1
将cramfs映像文件拷贝到相应的字符设备中。
然后使用mount -t cramfs /dev/mtdblock1 /mnt/flash1。
则cramfs文件系统加载正常。

这样我们可以不使用ramdisk技术来加载根文件系统,可以省去读内存的时间,加快启动速度。
这时的内核启动参数为:
noinitrd init=/linuxrc root=/dev/mtdblock1 ro console=ttyS0,115200 mem=64M ip=192.168.0.11 netmask=255.255.255.0
修改u-boot的bootcmd ,就可以加快启动速度,同时节省ram的空间!直接从cramfs的nandflash上启动
时间: 2024-10-14 13:03:31

u-boot支持yaffs映像烧写的补丁的相关文章

s3c2440 移值u-boot-2016.03 第6篇 支持mtd yaffs 烧写

1, 解决启动时的错误 Warning - bad CRC, using default environment 搜索发现 在 /tools/env/fw_env.c 中 /* 放在NAND FLASH 中 大小 128K 开始地址 */ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) #define CONFIG_ENV_OFFSET (256<<10) #define CONF

u-boot-2016.03 支持yaffs2文件系统烧写之添加nand write.yaffs2命令

我们进入nand的命令文件cmd/nand.c,在do_nand函数里,有nand read或write的代码,而其中有对jffs2的支持,却并没有对yaffs2的支持.以前的老版本uboot是有对yaffs文件系统烧写的支持的,于是我们参考老版本的uboot代码,在do_nand函数里的nand write/read部分加上一段代码,如下: 1 #ifdef CONFIG_CMD_NAND_TRIMFFS 2 } else if (!strcmp(s, ".trimffs")) {

向开发板中烧写Linux系统-型号S3C6410

作者 : 万境绝尘 转载请著名出处 终于拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧写内容 : BootLoader, Linux Kernel, File System; 烧写流程 : -- sd卡烧写u-boot并启动 : 首先将 u-boot 烧写到 sd 卡中, 使用 sd 卡的bootloader启动; -- 擦出nand flash : 之后将开发板的闪存 nand f

Jlink烧写图文教程

,点击安装          , 插上jlink,安装驱动后,红灯一直亮                                                                     (mini2440为例) (jz2440v2为例) 2. 打开jflash(安装好驱动就有) 3.打开百问网提供的配置文件s3c2440.jflash 打开后是这样         的 点target->connect,成功出现 4. 打开u-boot. bin ,打开后是这样的 5. 点

【海东青电子-简书】touchgfx 之 《IAR-hex文件的烧写方法》

IAR ---- 跟KEIL一样,TouchGFX自动生成的工程项目,在IAR中同样不能正确烧写片外flash!不过,经过适当的手动配置,IAR是可以烧写片外flash的,只是要费些周折.下面以Clock例程为例说明配置过程. 以STM32F769I-DISCO板子为例,创建一个TouchGFX工程,并使用系统自带的Clock例程: 图一 不需要编写任何代码,使用Clock例程就行,先运行VS.看看在仿真器上是否能正确跑起来这个Clock.然后,进入IAR,因为使用的是目前最新的IAR版本V8.

用uboot 烧写uboot linux内核 文件系统到nandflash的 过程以及bootm go命令启动与区别

原文:http://blog.sina.com.cn/s/blog_6b94d5680100nd48.html 文章结构结构顺序有变化-1:烧写uboot0: bootargs bootcmd 命令参数的设置1:制作yaffs2的过程2:烧写yaffs2的过程3:制作uimage 的过程4: 烧写uiamge的过程5:uimage zimage vmlinux 的区别6: uboot传递给内核的参数结构 tag7:bootm go 的 启动过程 以及区别8:加载地址 入口地址 等 ///////

嵌入式Linux之旅——环境搭建篇之烧写整个系统

上一小结我们已经烧写完u-boot,我烧写的u-boot是板子厂家定制的,本小节将利用这个u-boot烧写整个系统.当然,在系统移植篇的时候也会涉及到如何定制一个u-boot. 烧写整个系统我们一个叫dnw的工具,dnw是一个USB工具,通过USB发送文件给具有USB下载功能的bootloader.也就说我用的厂家定制的u-boot已经具备了USB下载功能.我需要先安装一些库: sudo apt-get install libncurses5:i386 libstdc++6:i386 zlib1

三星RP6818开发板添加应用后分区烧写问题分析

当用三星RP6818开发板添加应用后分区烧写出现问题,可以将应用去掉再烧写测试,可能是应用.环境配置等出了问题. Q:烧写时,partmap我可以改吗?system.img有些大,超过500M了. 但我看这个长度也是足够的,为什么烧写出现unknownerror? 400m烧写的时候没问题. A:未知错误不是长度的问题.system分区足够大的了. Q:应该是什么问题?现在我烧写以前成功过的映像,也不行了,歇菜了. A:清除分区. Q:我看system分区,0x2f200000大约742M左右,

走进STM32世界之Hex程序烧写

多数51单片机(STC系列单片机)的初学者都知道,在51单片机初上电时,可以通过PC机上位机软件将程序引导至bootloader,从而将新程序的hex文件下载至单片机中,完成程序的升级或是更新.在32位Cortex-M3内核下的STM32单片机也是可以做到的.这个上位机软件叫做"Flash loader demonstrator":短接boot0与VCC后,再次复位即进入到升级模式(System memory boot loader). 我们需要先下载芯片烧录工具软件Flash loa