请教如何删除jffs2分区

如题所述

第1个回答  2017-03-28
一、系统介绍
1. 采用加补丁方式的uClinux内核,不是uClinux-dist结构的。原始linux 2.4.22
2. Flash 地址0x46000000 ---- (0x46800000-0x1)
3. 192K 存放loader所以映像烧写起始 0x46030000
4. 832K 存放内核 0x46030000----(0x46100000-0x1)
5.
二、打开jffs2支持
File systems --->
<*> Journalling Flash File System (JFFS) support
(0) JFFS debugging verbosity (0 = quiet, 3 = noisy)
<*> JFFS stats available in /proc filesystem
<*> Journalling Flash File System v2 (JFFS2) support
(0) JFFS2 debugging verbosity (0 = quiet, 2 = noisy)

Memory Technology Devices (MTD) --->
<*> Memory Technology Device (MTD) support
<*> MTD partitioning support
<*> Direct char device access to MTD devices
<*> Caching block device access to MTD devices

RAM/ROM/Flash chip drivers --->
<*> Detect flash chips by Common Flash Interface (CFI) probe
<*> Support for AMD/Fujitsu flash chips
三、分区说明
文件:driver/mtd/maps/xxxxx_map.c 有(不同的厂商或flash会有不同的map文件)
static struct mtd_partition xxxxmap_partitions[] = {
XXXXX_MTD_PARTITIONS
} 结构对应分区
宏XXXXX_MTD_PARTITIONS对应在 (有一些是不用宏直接写在结构里也一样)
include/asm-arm/arch-xxxxx/board-xxxxx/mtdpartitions.h 文件中
测试时分了一个区8M的最后2M。分区如下
{ /* 2MB:test */ /
name: "test jffs2", / /*分区名称,启动时候会显示*/
size: 0x200000, / /*分区大小两兆*/
offset: 0x600000, / /*6M处开始*/
mask_flags: 0, / /*0表示读写*/
}
编译后在系统中会产生/dev/mtdblock/0 和 /dev/mtdblock/1;/dev/mtdblock/1就是对应该分区。
注:我用的版本会自动产生设备文件,它使用一个所谓的devfs,比我以前用过要在Makefile中添加设备节点的方便多了。
四、用最简单的方法进行测试
1. 格式化
在开发系统中新建jffs2目录随便放个文件
mkfs.jffs2 -d ./jffs2 -o jffs2.img –l –U (mkfs.jffs2 可在mtd包的util目录中编译生成)
编译好带网络的映像,写入,启动,映射好nfs。在uClinux中运行
cat ./jffs2.img > /dev/mtdblock/2 (格式化前一定要使用bootloader erase该分区)
2. 使用
mount -t jffs2 /dev/mtdblock/1 /mnt
进入/mnt 目录测试一下
五、根目录使用jffs2分区
1. 方案说明
内核映像还是放在romfs文件系统中,一般bootloader仅仅支持romfs的启动。Root文件系统制作成jffs2的映像。连接到romfs下面。最后进行整体烧入。
2. 8Mflash具体分区
{ /* 7104KB read/write */ / /*root 文件系统*/
name: "Root fs", /
size: 0x6f0000, /
offset:0x100000, /
mask_flags: 0, /
}, /
{ /* 64KB read/write */ / /*分1块其他用途*/
name: "User", /
size: 0x10000, /
offset: 0x7f0000, /
mask_flags: 0, /
}, /
#if 0 //可以分出来,但最好不要,没有用处,里面的内容也不是jffs2结构
//前面1M是laoder和内核
{ /* 192KB readonly: bootloader */ /
name: "BootROM", /
size: 0x20000, /
offset: 0x0, /
mask_flags: 0, /* Not writable */ /
}, /
{ /* 832KB: kernel*/ /
name: "Kernel", /
size: 0xe0000, /
offset: 0x20000, /
mask_flags: 0, /
}
#endif
这样/dev/mtdblock/1就是root分区了
3. 关于启动命令行do_mounts.c::__setup
General Setup --- >
[*] Compiled – in Kernel Boot Parameter
Default kernel command string : “root=/dev/mtdblock1 rw”

该配置产生的结果保存在include/linux/autoconf.h 中
注意 root=/dev/mtdblock1 rw,1的前面的 / 是没有的。在程序中do_mounts.c
static int __init root_dev_setup(char *line) 中把/dev/mtdblock1转化成 kdev_t ROOT_DEV; 来保存rootfs设备主从设备号。加了/后解析从设备号就出错,默认为 0 了,导致mount错误。
加了 rw ,__setup("rw", readwrite) 语句会调用static int __init readwrite(char *str) 函数,把root_mountflags 设置成可写。相关函数mount_block_root("/dev/root", root_mountflags) (在调用之前 "/dev/root" 被映射到mtd设备了)
4. 关于blkmem
Block devices --- >

< > Rom dis memory block device (blkmem)
[ ] Per partition statistics in /proc/partitions
blkmem去掉,否则在blkmem模块加载的时候会修改全局变量ROOT_DEV,到运行mount_block_root 使已经不是对应的mtd设备了。具体见blkmem.c : int __init blkmem_init( void ) 函数的最后几行。
5. 关于jffs
File systems--- >

< > Journalling Flash File System (JFFS) support

去掉 jffs的支持,我使用的时候不知道为什么 jffs 会mount jffs2格式成功,但最后肯定是不能用的。mount_block_root 函数中会循环系统中所有支持的文件系统去 mount root分区。找到mount成功就停止循环。去掉后就不会循环到 jffs系统了,先用ext2试了一下失败,就是用jffs2加载了。
6. 映像文件的制作
下面列举我的制作脚本(在 make romfs 后运行)
#制作一个romfs目录仅仅存放一个linux.bin.gz文件的内核文件系统
cd /home/hge/armutils_xxxxx
rm -rf ./build_arm/romfs
mkdir -p ./build_arm/romfs
cp “内核根目录下的linux.bin” ./build_arm/romfs/linux.bin
gzip -f ./build_arm/romfs/linux.bin

#romfs 制作内核文件系统映像并使文件固定为823K即flash存放内核的大小
genromfs -f ./bin/hge-romfs-linux.bin -V mambo -d ./build_arm/romfs
cat ./bin/hge-romfs-linux.bin /dev/zero | dd of=./bin/hge-romfs-fixsize.bin bs=1024 count=64 bs=1024 count=832

#在内核文件系统映像的前后各加上64K空白
#所以romfs其实是从第二个64K块开始,而jffs2则从对应分区的第三个块开始
#内核实际数据是不能大于823 – 64 = 768K,root分区很大少128K影响不大
#例子是这样,否则可能出现很多错误信息,但好像还是可以使用
dd if=/dev/zero of=./bin/64KB_blank bs=1024 count=64
cat ./bin/64KB_blank ./bin/hge-romfs-fixsize.bin ./bin/64KB_blank > ./bin/hge-romfs-rootfs.bin

#rootfs 制作jffs2 格式的root 文件系统
rm -rf ./build_arm/romfs
mkdir -p ./build_arm/romfs
cp -Rdf ./build_arm/root/* ./build_arm/romfs
/home/hge/mkfs.jffs2 -d ./build_arm/romfs/ -o ./bin/hge-rootfs-jffs.img -l -U

#romfs+rootfs 两个文件连接起来
cat ./bin/hge-rootfs-jffs.img >> ./bin/hge-romfs-rootfs.bin

#gzip
gzip -fc ./bin/hge-romfs-rootfs.bin > ./bin/hge-romfs-rootfs.bin.gz

#uuencode
uuencode ./bin/hge-romfs-rootfs.bin.gz x.gz > ./bin/hge-romfs-rootfs.bin.gz.uue

最后 hge-romfs-rootfs.bin.gz.uue 用来烧写
7. 烧写注意
必须把jffs2 文件系统对应的flash 全部擦除后再进行烧写,否则那些多余的数据也会被当作文件系统的数据导致CRC错误。
boot> flash erase 0x46030000 0x467d0000
8.
六、其他
在内核启动mount文件系统前会运行一个 linux-2.4.22-XX/init/main.c : init 函数,在函数中有prepare_namespace 函数就是整个文件系统的初始化了。本回答被网友采纳
相似回答