Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1207971
  • 博文数量: 322
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 3276
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-17 09:21
文章分类

全部博文(322)

文章存档

2010年(155)

2009年(167)

我的朋友

分类: 嵌入式

2009-12-24 17:15:12

之前在制作yaffs根文件系统的时候失败了,Failed to execute /linuxrc.Attempting defaults...现象是第一个文件都不能解析实行,原因是u-boot还不支持yaffs格式的读写,也不知道用nfs启动内核,本文实现u-boot烧写yaffs根文件系统映象,摘自《嵌入式Linux应用开发完全手册》韦东山著。
    在上一篇笔记中,增加了NAND Flash 功能的 u-boot-1.1.6已经可以通过"nand write..."、"nand write.jffs2..."等命令来烧写cramfs、jffs2文件系统映象文件,下面增加"nand write.yaffs..."命令实现yaffs文件系统映象的烧写。
   "nand write.yaffs..."命令中,"nand"是具体命令,"write.yaffs..."是参数。nand命令在 commom/cmd_nand.c中实现,在其中增加"nand write.yaffs..." 的使用说明,我们可以在 u-boot 下通过 ?nand 命令查看到所加信息,代码添加如下:

U_BOOT_CMD(nand, 5, 1, do_nand,
    "nand    - NAND sub-system\n",
    "info                  - show available NAND devices\n"
    "nand device [dev]     - show or set current device\n"
    "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"
    "nand read.yaffs addr off size - read the `size' byte yaffs image starting\n"
    "    at offset `off' to memory address `addr'\n"
    "nand write.yaffs addr off size - write the `size' byte yaffs image starting\n"
    "    at offset `off' from memory address `addr'\n"
    "nand erase [clean] [off size] - erase `size' bytes from\n"
    "    offset `off' (entire device if not specified)\n"
    "nand bad - show bad blocks\n"
    "nand dump[.oob] off - dump page\n"
    "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
    "nand markbad off - mark bad block at offset (UNSAFE)\n"
    "nand biterr off - make a bit error at offset (UNSAFE)\n"
    "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
    "nand unlock [offset] [size] - unlock section\n");
 
 
   然后,在 nand 命令的处理函数 do_nand 中增加对"nand yaffs..."的支持。do_nand 函数仍在 commom/cmd_nand.c 中实现,代码修改如下:

else if (  s != NULL && !strcmp(s, ".yaffs")){     /*354*/
            if (read) {
                /* read */
                nand_read_options_t opts;
                memset(&opts, 0, sizeof(opts));
                opts.buffer = (u_char*) addr;
                opts.length = size;
                opts.offset = off;
                opts.readoob = 1;
                opts.quiet      = quiet;
                ret = nand_read_opts(nand, &opts);
            } else {
                /* write */
                nand_write_options_t opts;
                memset(&opts, 0, sizeof(opts));
                opts.buffer = (u_char*) addr;
                opts.length = size;
                opts.offset = off;
                /* opts.forceyaffs = 1; */
                opts.noecc = 1;
                opts.writeoob = 1;
                opts.blockalign = 1;
                opts.quiet      = quiet;
                opts.skipfirstblk = 1;
                ret = nand_write_opts(nand, &opts);
            }    /*379*/
 
   NAND Flash 每一页大小为 (512+16)字节 (还有其他格式的NAND Flash ,比如每页大小为(256+8)、(2048+64)等,SAMSUNG_K9F1G08U0B就是(2048+64)),其中512字节就是数据存储区,16字节称为OOB(Out Of Band)区,在OBB区存放坏块标记、前面512字节的ECC校验码等。
 
 
   上述代码中,opts.skipfirstblk是新增加的项,表示烧写时跳过第一个可用的逻辑块,这是由 yaffs 文件系统的特性决定的。下面给opts.skipfirstblk 新增加项重新定义 nand_write_options_t 结构,并在下面调用的 nand_write_opts 函数中对他进行处理。
 
a) 在 include/nand.h 中进行如下修改,增加 skipfirstblk 成员:

    struct nand_write_options {
    u_char *buffer;        /* memory block containing image to write */
    ulong length;        /* number of bytes to write */
    ulong offset;        /* start address in NAND */
    int quiet;        /* don't display progress messages */
    int autoplace;        /* if true use auto oob layout */
    int forcejffs2;        /* force jffs2 oob layout */
    int forceyaffs;        /* force yaffs oob layout */
    int noecc;        /* write without ecc */
    int writeoob;        /* image contains oob data */
    int pad;        /* pad to page size */
    int blockalign;        /* 1|2|4 set multiple of eraseblocks
                 * to align to */
    int skipfirstblk;   /* if true, skip the first good block, 
                         * set true when write the yaffs image,
                         * add by
                         */                   
};
 
b) 在 drivers/nand/nand_util.c 修改 nand_write_opts 函数,增加对 skipfirstblk 成员的支持:

    /* skip the first good block when wirte yaffs image, by */
        if (skipfirstblk) {      /*431行*/
            mtdoffset += erasesize_blockalign;
            skipfirstblk = 0;
            continue;
        }
 
进行上面移植后,u-boot 已经支持 yaffs 文件系统映象的烧写,由于前面设置"opts.noecc=1" 不使用ECC校验码,烧写时会提示很多提示信息,可以修改 drivers/nand/nand_base.c 文件918行的 nand_write_page 函数,将其注释掉。
    case NAND_ECC_NONE:
        //printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
 
在图二中的错误是由于size不是(512+16)*N 的缘故。

阅读(883) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~