在新塘开发板NUC972上用华邦 的W25Q128flash 装载程序,rootfs以romfs方式在内核中时没有问题,然后换一种方式,给rootfs 创建独立分区时,加载rootfs失败,使得我要来好好整理一下这部分。
先恢复到rootfs在内核中的方式,然后单独创建一个usr分区来存放app,肯定是失败的,下面就是解决步骤。
/home/zjf/nuc970/nuc970bsp/applications/mtd-utils/mkfs.jffs2 -l -n -p -r app/ -o nuc972.img
制作好的app ,烧写到user 分区
zjf mount /dev/mtdblock2 /mnt/user
jffs2: Node at 0x000001c4 with length 0x00001020 would run over the end of the erase block
jffs2: Perhaps the file system was created with the wrong erase size?
为此,试过很多种方法,因为默认擦写大小为64K ,于是自己制定大小,-e 0x10000 以及-e 0x20000 还有-e 0x8000,都不行,纯粹摸索着来试验,后来想起来/proc/mtd有说擦写大小于是查看一下
~ # cat /proc/mtd
dev: size erasesize name
mtd0: 00200000 00001000 "u-boot"
mtd1: 00a00000 00001000 "kernel"
mtd2: 00200000 00001000 "user"
mtd3: 00100000 00001000 "app"
mtd4: 00100000 00001000 "rootfs"
这个竟然只有4K,怪不得一直不行,然后重新做镜像, -e 0x1000,失败,因为mkfs.jffs2不支持4K,然后网上查阅w25q128的资料,erasesize 支持32k/64k,于是需要修改驱动,后来通过网上查阅资料,找到spi flash 驱动在
/home/zjf/nuc970/nuc970bsp/linux-3.10.x/drivers/mtd/devices/m25p80.c里面有定义
{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K | M25P80_DUAL_READ | M25P80_QUAD_READ | M25P80_QUAD_WRITE) },
INFO的前两个参数跟厂商有关系,第三个是每个扇区大小,第四个是扇区个数,这样一算这个flash就是有16M大小,第五个参数就是flag,后续驱动probe的时候会使用。
然后找到m25p_probe
if (info->flags & SECT_4K) {
flash->erase_opcode = OPCODE_BE_4K;
flash->mtd.erasesize = 4096;
} else {
flash->erase_opcode = OPCODE_SE;
flash->mtd.erasesize = info->sector_size;
}
这里会走第一个分支,所以导致erasesize大小是4K
然后修改m25p80.c的w25q128 的info, 去掉SECT_4K ,这样就会走上面第二个分支,初始化时就erase size 就不会是4k,而是info 中的64k,启动后打印看出来erasesize已经变了
也可以将上面第二分支的OPCODE_SE 修改为OPCODE_BE_4K, 因为前者是以扇区(sector)擦写,后者是以块(block)擦写,当然还有全部擦除的OPCODE_CHIP_ERASE参数。
~ # cat /proc/mtd
dev: size erasesize name
mtd0: 00200000 00010000 "u-boot"
mtd1: 00a00000 00010000 "kernel"
mtd2: 00200000 00010000 "user"
mtd3: 00100000 00010000 "app"
mtd4: 00100000 00010000 "rootfs"
但是还是有error如下
jffs2: Empty flash at 0x00163fa0 ends at 0x00164000
jffs2: CLEANMARKER node found at 0x00164000, not first node in block (0x00160000)
jffs2: Empty flash at 0x0016400c ends at 0x00165000
jffs2: CLEANMARKER node found at 0x00165000, not first node in block (0x00160000)
jffs2: Empty flash at 0x0016500c ends at 0x00166000
jffs2: CLEANMARKER node found at 0x00166000, not first node in block (0x00160000)
jffs2: Empty flash at 0x0016600c ends at 0x00167000
jffs2: CLEANMARKER node found at 0x00167000, not first node in block (0x00160000)
jffs2: Empty flash at 0x0016700c ends at 0x00168000
jffs2: CLEANMARKER node found at 0x00168000, not first node in block (0x00160000)
jffs2: Empty flash at 0x0016800c ends at 0x00169000
jffs2: CLEANMARKER node found at 0x00169000, not first node in block (0x00160000)
看网上说出现这个空块因为是以扇区擦写导致,修改驱动以块擦写就可以了,但是我没改,只是擦了下分区重新烧写就好了,如下:
在uboot 下使用sf erase 0xc00000 0x200000,擦一遍user 分区,在烧写进去就OK了。
成功之后就可以单独创建rootfs分区了,首先取消内核的如下配置 ,(如果不单独分区还是放在内核,选中下面配置后,还要在该配置下面的选项添加rootfs目录,为../rootfs)
[ ] Initial RAM filesystem and RAM disk (initramfs/initrd) support
重新编译内核后,用mkfs.jffs2制作rootfs.img镜像
将uboot后面的flash在uboot下擦空一次,sf probe 0 18000000, sf erase 0x200000 0xe00000
通过烧写工具将kernel,和rootfs,分别烧写到对应分区,
修改启动参数
set bootargs "noinitrd root=/dev/mtdblock2 console=ttyS0,115200n8 rdinit=/sbin/init rootfstype=jffs2 mem=64M mtdparts=m25p80:2M(u-boot),3M@0x200000(kernel),-(rootfs)"
set bootcmd "sf probe 0 18000000; sf read 0x7fc0 0x200000 0x300000; bootm 0x7fc0"
重启,OK。
下面就可以随便分区,然后启动后mount 出来根据需要存放配置等文件
mount -t jffs2 /dev/mtdblock3 /mnt/user/