如何使uClinux根目录使用jffs2分区(转)

一、系统介绍

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: 0x 6f 0000, /

        offset:0x100000, /

        mask_flags: 0, /

    }, /

    { /* 64KB read/write */ / /*1块其他用途*/

        name: "User", /

        size: 0x10000, /

        offset: 0x 7f 0000, /

        mask_flags: 0, /

    }, /

#if 0 //可以分出来,但最好不要,没有用处,里面的内容也不是jffs2结构

        //前面 1Mlaoder和内核

    { /* 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 Pa ra meter

               Default kernel command string : “root=/dev/mtdblock 1 rw”

 

该配置产生的结果保存在include/linux/autoconf.h

注意 root=/dev/mtdblock1 rw1的前面的 / 是没有的。在程序中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 Fla sh 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 = 768Kroot分区很大少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 函数就是整个文件系统的初始化了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值