Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831199
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2015-07-21 22:47:22

u-boot支不支持烧写文件系统?

1. 分区如何设置?

参考内核打印出来的分区信息
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"

2. 烧写JFFS2

tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand      write.jffs2     30000000   0x00260000        5b89a8
          烧写jffs2文件    内存地址    rootfs起始地址    jffs2文件大小
SMDK2410 # tftp 30000000 fs_mini_mdev.jffs2
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'fs_mini_mdev.jffs2'.
Load address: 0x30000000
Loading: T T T T T T T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###################
done
Bytes transferred = 5999016 (5b89a8 hex)
SMDK2410 # nand erase.part rootfs

NAND erase.part: device 0 offset 0x240000, size 0xfdc0000
Skipping bad block at  0x01500000                                          
Skipping bad block at  0x04760000                                          
Skipping bad block at  0x05cc0000                                          
Skipping bad block at  0x07c80000                                          
Skipping bad block at  0x0cc60000                                          
Erasing at 0xffe0000 -- 100% complete.
OK
SMDK2410 # nand write.jffs2 30000000 0x00260000 5b89a8

NAND write: device 0 offset 0x260000, size 0x5b89a8
 5999016 bytes written: OK
SMDK2410 #



jffs2文件系统启动,需要修改启动参数:
set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

SMDK2410 # set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2
SMDK2410 # boot

NAND read: device 0 offset 0x60000, size 0x1e0000
 1966080 bytes read: OK
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-2.6.22.6
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1848656 Bytes = 1.8 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux...................................................................................................................... done, booting the kernel.
.......... 
一连串打印信息
..................
...................
VFS: Mounted root (jffs2 filesystem).           挂接上了文件系统。
Freeing init memory: 140K
init started: BusyBox v1.7.0 (2008-01-22 10:04:09 EST)
starting pid 765, tty '': '/etc/init.d/rcS'

Please press Enter to activate this console.
starting pid 771, tty '/dev/s3c2410_serial0': '/bin/sh'
#

3. 烧写YAFFS

tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000  889bc0

SMDK2410 # tftp 30000000 fs_mini_mdev.yaffs2
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'fs_mini_mdev.yaffs2'.
Load address: 0x30000000
Loading: T T T T T T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #########################
done
Bytes transferred = 8952768 (889bc0 hex)
SMDK2410 # nand erase.part rootfs

NAND erase.part: device 0 offset 0x240000, size 0xfdc0000
Skipping bad block at  0x01500000                                          
Skipping bad block at  0x04760000                                          
Skipping bad block at  0x05cc0000                                          
Skipping bad block at  0x07c80000                                          
Skipping bad block at  0x0cc60000                                          
Erasing at 0xffe0000 -- 100% complete.
OK
SMDK2410 # nand write.yaffs 30000000 260000  889bc0

NAND write: device 0 offset 0x260000, size 0x889bc0
Unknown nand command suffix '.yaffs'.
SMDK2410 #


发现错误,打印信息:Unknown nand command suffix '.yaffs'. 
分析源码:
定位到这句话:

#ifdef CONFIG_CMD_NAND_YAFFS
        } else if (!strcmp(s, ".yaffs")) {
            if (read) {
                printf("Unknown nand command suffix '%s'.\n", s);
                return 1;
            }
            ret = nand_write_skip_bad(nand, off, &rwsize,
                        (u_char *)addr, WITH_YAFFS_OOB);
#endif

在配置文件中加入这个宏定义:
#define CONFIG_CMD_NAND_YAFFS

重新编译,下载:
(1)更新UBOOT:
    tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
(2)重启:
    reset
(3)重新烧写yaffs
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000  889bc0
SMDK2410 # tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: T T T T T T ###############
done
Bytes transferred = 217520 (351b0 hex)
Un-Protect Flash Bank # 1

....... done
Erased 7 sectors
Copy to Flash... 9....8....7....6....5....4....3....2....1....done
SMDK2410 # reset
resetting ...


U-Boot 2012.04.01 (Jul 21 2015 - 00:18:15)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0
SMDK2410 # tftp 30000000 fs_mini_mdev.yaffs2
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'fs_mini_mdev.yaffs2'.
Load address: 0x30000000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #########################
done
Bytes transferred = 8952768 (889bc0 hex)
SMDK2410 # nand erase.part rootfs

NAND erase.part: device 0 offset 0x240000, size 0xfdc0000
Skipping bad block at  0x01500000                                          
Skipping bad block at  0x04760000                                          
Skipping bad block at  0x05cc0000                                          
Skipping bad block at  0x07c80000                                          
Skipping bad block at  0x0cc60000                                          
Erasing at 0xffe0000 -- 100% complete.
OK


SMDK2410 # nand write.yaffs 30000000 260000  889bc0
// 这里写的特别的快。
NAND write: device 0 offset 0x260000, size 0x889bc0
 8952768 bytes written: OK
SMDK2410 #


启动板子
SMDK2410 # reset
resetting ...


U-Boot 2012.04.01 (Jul 21 2015 - 00:18:15)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0

NAND read: device 0 offset 0x60000, size 0x1e0000
 1966080 bytes read: OK
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-2.6.22.6
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1848656 Bytes = 1.8 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux...................................................................................................................... done, booting the kernel.
Linux version 2.6.22.6 (book@book-desktop) (gcc version 3.4.5) #1 Thu Jan 27 22:22:51 CST 2011
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。
打印一串串信息
。。。。。。。。。。。。。。。。。。。

yaffs: auto selecting yaffs2
block 150 is bad
block 553 is bad
block 724 is bad
block 978 is bad
block 1617 is bad
VFS: Mounted root (yaffs filesystem).   文件挂接上去了。
Freeing init memory: 140K
Warning: unable to open an initial console.
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.  某些文件找不到。。

这说明u-boot有问题,怎么解决这个问题呢?
对比:烧写进nand flash的文件系统和原始的文件系统。看看原始的文件系统是不是真的完全拷贝到flash上去了。

查找源代码:
common/cmd_nand.c:606:          } else if (!strcmp(s, ".yaffs")) {

还是这句话:

#ifdef CONFIG_CMD_NAND_YAFFS
        } else if (!strcmp(s, ".yaffs")) {
            if (read) {
                printf("Unknown nand command suffix '%s'.\n", s);
                return 1;
            }
            // 如果是 yaffs文件,就执行 nand_write_skip_bad 函数

            ret = nand_write_skip_bad(nand, off, &rwsize,
                        (u_char *)addr, WITH_YAFFS_OOB);
#endif


点击(此处)折叠或打开

  1. /**
  2.  * nand_write_skip_bad:
  3.  *
  4.  * Write image to NAND flash.
  5.  * Blocks that are marked bad are skipped and the is written to the next
  6.  * block instead as long as the image is short enough to fit even after
  7.  * skipping the bad blocks.
  8.  *
  9.  * @param nand     NAND device
  10.  * @param offset    offset in flash
  11.  * @param length    buffer length
  12.  * @param buffer buffer to read from
  13.  * @param flags        flags modifying the behaviour of the write to NAND
  14.  * @return        0 in case of success
  15.  */
  16. int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
  17.             u_char *buffer, int flags)
  18. {
  19.     int rval = 0, blocksize;
  20.     size_t left_to_write = *length;
  21.     u_char *p_buffer = buffer;
  22.     int need_skip;

  23. #ifdef CONFIG_CMD_NAND_YAFFS
  24.     if (flags & WITH_YAFFS_OOB) {
  25.         if (flags & ~WITH_YAFFS_OOB)
  26.             return -EINVAL;

  27.         int pages;
  28.         pages = nand->erasesize / nand->writesize;
  29.         blocksize = (pages * nand->oobsize) + nand->erasesize;
  30.         if (*length % (nand->writesize + nand->oobsize)) {
  31.             printf ("Attempt to write incomplete page"
  32.                 " in yaffs mode\n");
  33.             return -EINVAL;
  34.         }
  35.     } else
  36. #endif
  37.     {
  38.         blocksize = nand->erasesize;
  39.     }

  40.     /*
  41.      * nand_write() handles unaligned, partial page writes.
  42.      *
  43.      * We allow length to be unaligned, for convenience in
  44.      * using the $filesize variable.
  45.      *
  46.      * However, starting at an unaligned offset makes the
  47.      * semantics of bad block skipping ambiguous (really,
  48.      * you should only start a block skipping access at a
  49.      * partition boundary). So don't try to handle that.
  50.      */
  51.     if ((offset & (nand->writesize - 1)) != 0) {
  52.         printf ("Attempt to write non page aligned data\n");
  53.         *length = 0;
  54.         return -EINVAL;
  55.     }

  56.     need_skip = check_skip_len(nand, offset, *length);
  57.     if (need_skip < 0) {
  58.         printf ("Attempt to write outside the flash area\n");
  59.         *length = 0;
  60.         return -EINVAL;
  61.     }

  62.     if (!need_skip && !(flags & WITH_DROP_FFS)) {
  63.         rval = nand_write (nand, offset, length, buffer);
  64.         if (rval == 0)
  65.             return 0;

  66.         *length = 0;
  67.         printf ("NAND write to offset %llx failed %d\n",
  68.             offset, rval);
  69.         return rval;
  70.     }

  71.    // 这里while循环进行拷贝
  72.     while (left_to_write > 0) {
  73.         size_t block_offset = offset & (nand->erasesize - 1);
  74.         size_t write_size, truncated_write_size;

  75.         WATCHDOG_RESET ();

  76.         if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
  77.             printf ("Skip bad block 0x%08llx\n",
  78.                 offset & ~(nand->erasesize - 1));
  79.             offset += nand->erasesize - block_offset;
  80.             continue;
  81.         }

  82.         if (left_to_write < (blocksize - block_offset))
  83.             write_size = left_to_write;
  84.         else
  85.             write_size = blocksize - block_offset;

  86. #ifdef CONFIG_CMD_NAND_YAFFS
  87.         if (flags & WITH_YAFFS_OOB) {
  88.             int page, pages;
  89.             size_t pagesize = nand->writesize;
  90.             size_t pagesize_oob = pagesize + nand->oobsize;
  91.             struct mtd_oob_ops ops;

  92.             ops.len = pagesize;
  93.             ops.ooblen = nand->oobsize;
  94.            //ops.mode = MTD_OOB_AUTO; 这里改为:
  95.         ops.mode = MTD_OOB_RAW;    数据不改动拷贝
  96.             ops.ooboffs = 0;

  97.             pages = write_size / pagesize_oob;
  98.             for (page = 0; page < pages; page++) {
  99.                 WATCHDOG_RESET();

  100.                 ops.datbuf = p_buffer;
  101.                 ops.oobbuf = ops.datbuf + pagesize;

  102.            rval = nand->write_oob(nand, offset, &ops);
  103.            // if (!rval) 这句话改为:
  104.            if (rval)
  105.                break;

  106.                 offset += pagesize;
  107.                 p_buffer += pagesize_oob;
  108.             }
  109.         }
  110.         else
  111. #endif
  112.         {
  113.             truncated_write_size = write_size;
  114. #ifdef CONFIG_CMD_NAND_TRIMFFS
  115.             if (flags & WITH_DROP_FFS)
  116.                 truncated_write_size = drop_ffs(nand, p_buffer,
  117.                         &write_size);
  118. #endif

  119.             rval = nand_write(nand, offset, &truncated_write_size,
  120.                     p_buffer);
  121.             offset += write_size;
  122.             p_buffer += write_size;
  123.         }

  124.         if (rval != 0) {
  125.             printf ("NAND write to offset %llx failed %d\n",
  126.                 offset, rval);
  127.             *length -= left_to_write;
  128.             return rval;
  129.         }

  130.         left_to_write -= write_size;
  131.     }

  132.     return 0;
  133. }
重新编译,烧写:
这里启动还是有问题,不知道为什么???下次再来好好研究一下。
其实这里的uboot并没有完全移植成功,这个uboot是有bug的。在移植新内核的章节可以找到答案。

YAFFS2启动参数需要配置吗?
set bootargs console=ttySAC0 root=/dev/mtdblock3
save

4. 制作补丁

                   源码      修改后的代码       生成的patch文件
        diff -urN u-boot-2012.04.01  u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch

5. 给源码打补丁

$patch  -p1  < ../u-boot-2012.04.01_100ask.patch


总结:

1. 加入jffs2以及yaffs2文件系统的读写操作的支持
2. 如何制作补丁文件
3. 如何给源码打补丁文件


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