系统介绍
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 函数就是整个文件系统的初始化了。