JZ2440:yaffs2 格式根檔案系統製作
阿新 • • 發佈:2019-02-15
YAFFS目前有yaffs、yaffs2兩個版本,一般來說,yaffs對小頁(512B+16B/頁)的NandFlash(68M)有很好的支援,yaffs2對大頁(2K+64B/頁)的NandFlash(128M、256M或者更大)支援更好。
我的 nandflash 型號是:K9F2G08U0C
大小是:256M
因此採用 mkyaffs2image 工具:
<*> yaffs2 file system support
其他配置也要配置好
make uImage
重新生成uImage
+ WITH_DROP_FFS | WITH_WR_VERIFY);
+#endif
+#ifdef CONFIG_CMD_NAND_YAFFS
+ } else if (!strcmp(s, ".yaffs2")) {
+ if (read) {
+ printf("Unknown nand command suffix '%s'\n", s);
+ return 1;
+ }
+ ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
+ maxsize, (u_char *)addr,
+ WITH_YAFFS_OOB);
#endif
} else if (!strcmp(s, ".oob")) {
/* out-of-band data */
@@ -765,6 +775,11 @@ static char nand_help_text[] =
" 'addr', skipping bad blocks and dropping any pages at the end\n"
" of eraseblocks that contain only 0xFF\n"
#endif
+#ifdef CONFIG_CMD_NAND_YAFFS
+ "nand write.yaffs2 - addr off|partition size\n"
+ " write 'size' bytes starting at offset 'off' with yaffs format\n"
+ " from memory address 'addr', skipping bad blocks\n"
+#endif
"nand erase[.spread] [clean] off size - erase 'size' bytes "
"from offset 'off'\n"
" With '.spread', erase enough for given file size, otherwise,\n"
drivers/mtd/nand/nand_util.c
@@ -580,8 +580,23 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
if (actual)
*actual = 0;
-
+#ifdef CONFIG_CMD_NAND_YAFFS
+ if (flags & WITH_YAFFS_OOB) {
+ if (flags & ~WITH_YAFFS_OOB)
+ return -EINVAL;
+ int pages;
+ pages = nand->erasesize / nand->writesize;
+ blocksize = (pages * nand->oobsize) + nand->erasesize;
+ if (*length % (nand->writesize + nand->oobsize)){
+ printf ("Attempt to write incomplete page"
+ " in yaffs mode\n");
+ return -EINVAL;
+ }
+ }else
+#endif
+ {
blocksize = nand->erasesize;
+ }
/*
* nand_write() handles unaligned, partial page writes.
@@ -650,24 +665,55 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
else
write_size = blocksize - block_offset;
- truncated_write_size = write_size;
-#ifdef CONFIG_CMD_NAND_TRIMFFS
- if (flags & WITH_DROP_FFS)
- truncated_write_size = drop_ffs(nand, p_buffer,
- &write_size);
+#ifdef CONFIG_CMD_NAND_YAFFS
+ if (flags & WITH_YAFFS_OOB) {
+ int page, pages;
+ size_t pagesize = nand->writesize;
+ size_t pagesize_oob = pagesize + nand->oobsize;
+ struct mtd_oob_ops ops;
+
+ ops.len = pagesize;
+ ops.ooblen = nand->oobsize;
+ ops.mode = MTD_OPS_RAW; //這裡要改為RAW
+ ops.ooboffs = 0;
+
+ pages = write_size / pagesize_oob;
+ for (page = 0; page < pages; page++) {
+ WATCHDOG_RESET();
+
+ ops.datbuf = p_buffer;
+ ops.oobbuf = ops.datbuf + pagesize;
+
+ rval = nand->_write_oob(nand, offset, &ops);
+ if (rval != 0)
+ break;
+
+ offset += pagesize;
+ p_buffer += pagesize_oob;
+ }
+ }
+ else
#endif
+ {
- rval = nand_write(nand, offset, &truncated_write_size,
- p_buffer);
+ truncated_write_size = write_size;
+#ifdef CONFIG_CMD_NAND_TRIMFFS
+ if (flags & WITH_DROP_FFS)
+ truncated_write_size = drop_ffs(nand, p_buffer,
+ &write_size);
+#endif
- if ((flags & WITH_WR_VERIFY) && !rval)
- rval = nand_verify(nand, offset,
- truncated_write_size, p_buffer);
+ rval = nand_write(nand, offset, &truncated_write_size,
+ p_buffer);
- offset += write_size;
- p_buffer += write_size;
+ if ((flags & WITH_WR_VERIFY) && !rval)
+ rval = nand_verify(nand, offset,
+ truncated_write_size, p_buffer);
- if (rval != 0) {
+ offset += write_size;
+ p_buffer += write_size;
+ }
+ if (rval != 0) {
printf("NAND write to offset %llx failed %d\n",
offset, rval);
*length -= left_to_write;
include/configs/lip2440.h
@@ -85,6 +85,7 @@
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_USB
+#define CONFIG_CMD_NAND_YAFFS
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_CMDLINE_EDITING
include/nand.h
@@ -27,6 +27,9 @@
#endif
#endif
+#define WITH_YAFFS_OOB (1 << 0)
+#define WITH_DROP_FFS (1 << 0)
+
extern void nand_init(void);
#include <linux/compat.h>
重新編譯,即可
.size = SZ_4M, (0x40 0000) }, [3] = { .name = "root", // 根檔案系統所在分割槽,可用來存放 yaffs2 檔案系統,對應/dev/mtdblock3 /* *.offset = SZ_256K + SZ_128K + 0x00500000, *.size = MTDPART_SIZ_FULL, */ .offset = SZ_1M*5, (0x50 0000) .size = SZ_1M*100, (0x640 0000) }, };
nand erase 0x100000 0x400000 nand write 0x30008000 0x100000 0x400000 tftp 0x30008000 fs_mini.yaffs2 nand erase 0x500000 0x6400000 nand write.yaffs2 0x30008000 0x500000 [實際下載進去的大小,防止產生壞塊]
1. 首先下載 yaffs2 原始碼
git clone git://www.aleph1.co.uk/yaffs22. 將 yaffs2 選項放到linux 核心的配置選項中:
cd yaffs2 ./patch-ker.sh c m linux-tree 我的核心放在了 ~/wor_lip/linux-3.4.112 資料夾下,因此,命令為: ./patch-ker.sh c m ~/wor_lip/linux-3.4.1123. 檢視核心讓核心支援yaffs2:
進入linux核心原始碼目錄, make menuconfig File systems ---> [*] Miscellaneous filesystems --->4. uboot 中新增 支援 yaffs2 的燒寫:
支援 yaffs2 的燒寫,就是新增 nand write.yaffs2 命令 cmd/nand.c 檔案中: @@ -617,7 +617,17 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, - WITH_DROP_FFS | WITH_WR_VERIFY);4. 生成 yaffs2 型別的根檔案系統:
這裡用的製作 yaffs2 格式的工具是 韋東山 提供的工具,自己在yaffs2 原始碼的utils中make生成的是不能使用的,需要做一些相應的修改。 cp /mnt/hgfs/share/mkyaffs2image . ./mkyaffs2imagefs_mini fs_mini.yaffs2 (這裡有個坑,如果用 mkyaffs2image 則用的是系統中應用程式中資料夾中的 mkyaffs2image 程式,所以必須加上 ./ ) sudo chmod 777 fs_mini.yaffs2 cp fs_mini.yaffs2 /tftpboot/5. 將 yaffs2 型別的根檔案系統燒寫到nand的指定的如下中的 root 位置上。
對 linux 核心原始碼的 arch/arm/mach-s3c24xx/mach-mini2440.c 中的說明: static struct mtd_partition mini2440_default_nand_part[] __initdata = { [0] = { .name = "u-boot", // bootloader 所在分割槽,對應 /dev/mtdblock0 .size = SZ_512K, .offset = 0, }, [1] = { .name = "u-boot-env", // bootloader 的引數區,對應/dev/mtdblock1 .size = SZ_512K, .offset = SZ_512K, }, [2] = { .name = "kernel", // 核心所在分割槽,對應/dev/mtdblock2 /* 5 megabytes, for a kernel with no modules * or a uImage with a ramdisk attached */ /* *.size = 0x00500000, *.offset = SZ_256K + SZ_128K, */ .offset = SZ_1M, (0x10 0000).size = SZ_4M, (0x40 0000) }, [3] = { .name = "root", // 根檔案系統所在分割槽,可用來存放 yaffs2 檔案系統,對應/dev/mtdblock3 /* *.offset = SZ_256K + SZ_128K + 0x00500000, *.size = MTDPART_SIZ_FULL, */ .offset = SZ_1M*5, (0x50 0000) .size = SZ_1M*100, (0x640 0000) }, };
一個值得參考的設定:
6. 用tftp 命令,將 uImage和fs_mini.yaffs2分別下載到nand中去
首先檢視 uImage 和 fs_mini.yaffs2 的大小分別是 2.4M 和 6.1M tftp 0x30008000 uImagenand erase 0x100000 0x400000 nand write 0x30008000 0x100000 0x400000 tftp 0x30008000 fs_mini.yaffs2 nand erase 0x500000 0x6400000 nand write.yaffs2 0x30008000 0x500000 [實際下載進去的大小,防止產生壞塊]