您的位置:首页 > 其它

Jffs2文件系统的制作及使用

2017-08-22 13:50 639 查看

为什么使用Jffs2?

在嵌入式系统中,为加速启动,核心的根文件系统会使用RamFs,一般会放到RAM中,但是这种文件系统一般是掉电丢失的,因为存储在Ram中。但实际应用中有一些配置文件是需要非易失特性的,主要用于配置应用程序。因此,一般的嵌入式产品的文件系统是多种格式共存的,核心的Rootfs使用ramfs,可以加速系统运行速度,一些需要非易失性的配置文件一般使用Jffs2(norflash做为存储介质时)或者yffs2(nandflash做为存储介质时)文件系统。

Jffs2(Journalling Flash FileSystem Version2)文件系统专为嵌入式系统设计,存储介质主要是NorFlash或者NandFlash,是一种简单非易失性的文件系统。

分区是啥?

我们习惯将大的复杂的东西划分为小的简单的东西,就像你买个衣橱,会把衣橱按照功能划分成几个区域(有放上衣的、有放裤子的)。利用信息存储空间也一样,当你拿到一个256G硬盘的时候,你很自然地会按照功能分出几个空间来—–分区。一般会有安装OS的盘、软件的盘、资料盘、游戏盘。这样会有几个好处—易查找、故障隔离,好了,通俗地讲:好找资料、一个分区如果出了问题,一般不会影响到别的分区。硬盘的分区信息是被存储到硬盘的0磁道0柱面1扇区的DPT(Disk Partition Table硬盘分区表)。说的直白点就是画出几个范围,大家互相不干扰,这些分区作为OS格式化文件系统的最小单位。

Jffs2文件系统的存储介质一般是norflash,也可以划分分区,但这些分区并不保存到norflash上。只是BootLoader和kernel的之间的一种约定。嵌入式系统中的分区一般分为:u-boot、u-boot环境变量、kernel、dtb、rootfs、其他一些设计需要的分区。

说了这么多,来点实际的:

我的板子上有个128M的norflash,然后分了6个分区。

fe8000000.flash: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x000001 Chip ID 0x002801

Amd/Fujitsu Extended Query Table at 0x0040

Amd/Fujitsu Extended Query version 1.5.

number of CFI chips: 1

6 cmdlinepart partitions found on MTD device fe8000000.flash

Creating 6 MTD partitions on "fe8000000.flash":

0x000000000000-0x000006e00000 : "uboot"

0x000006e00000-0x000006e20000 : "kernel"

0x000006e20000-0x000006e40000 : "dtb"

0x000006e40000-0x000006e60000 : "jffs2"

0x000005000000-0x000005300000 : "test"

0x000005300000-0x000008000000 : "fs"


嵌入式系统下所有的norflash、nandflash等存储设备都被抽象成mtd存储设备。上面分区的u-boot对应系统下的dev/mtdblock0,test分区代表dev/mtdblock4。

fdisk -l |grep mtd


Disk /dev/mtdblock0: 110 MiB, 115343360 bytes, 225280 sectors

Disk /dev/mtdblock1: 128 KiB, 131072 bytes, 256 sectors

Disk /dev/mtdblock2: 128 KiB, 131072 bytes, 256 sectors

Disk /dev/mtdblock3: 128 KiB, 131072 bytes, 256 sectors

Disk /dev/mtdblock4: 3 MiB, 3145728 bytes, 6144 sectors

Disk /dev/mtdblock5: 45 MiB, 47185920 bytes, 92160 sector


分区有了,我们就可以制作文件系统了。

mkfs.mkfs.jffs2 /dev/mtdblock4


好像很明朗了,分区是制作文件系统的最小单位。就是说你可以把/dev/mtdblock3格式化成ext2格式的文件系统,同时把/dev/mtdblock4格式化成jffs2格式的文件系统。

下面的章节会详细说明制作jffs2文件系统并尽量说明白u-boot、kernel和文件系统的关系以及使用方法。

u-boot下的分区和Linux下的分区的联系和区别

从上面的描述看到,分区就说约定了怎么划分存储空间的一种说法而已。那就顺便带出了几个问题,u-boot下怎么划分分区?需要将分区信息存储吗?kernel怎么分区?u-boot下分区和kernel下分区有什么区别和联系呐?

u-boot下有时候也有分区的概念,但u-boot下的分区的概念和linux下不太一样,linux下主要是用于将一个block设备从物理这个层面上划分为几个分区,是系统格式化成不同文件系统的最小单元。

但在u-boot下只是一个地址范围,仅仅表示起始、结束地址而已。其实也差不多了,一样的目的只是表示的方法不一样罢了。

在代码里写死(此方法已经不使用,dts替代)。

使用dts文件创建分区。

在u-boot下使用cmdline传参(bootargs->mtdparts),且cmdline的优先级较高,即如果dtb设置了mtd 分区,但同时cmdline也设置了分区则,cmdline设置的分区会覆盖掉kernel设置的分区。以mtdparts设置的为最后的设置内容。

我们使用cmdline传参数的方法来做说明。

setenv bootargs "root=/dev/ram rw console=ttyS0,115200 ramdisk_size=70000000 mtdparts=fe8000000.flash:110m(uboot),128k(kernel),128k(dtb),128k(jffs2),3m@0x5000000(test),-(fs)"


使用环境变量mtdparts,具体说明见u-boot官网。

总之,u-boot里划分的存储设备分区和kernel需一致,这样在u-boot里升级固件会方便一些。因为我们在开发阶段,会使用HOST开发主机制作文件系统,然后烧录到指定的分区,kernel启动后可以mount该分区,从而读写文件。

怎么制作Jffs2文件系统?

制作jffs2文件系统很简单。

mkfs.jffs2 -r ./jaffs2_rootfs  -o rootfs.jaffs2   -pad 0x300000 -b -n


具体参数
mkfs.jffs2 --help


使用Jffs2

我们得将制作好的jffs2格式的文件系统烧写到norflash上,烧录到那个分区?那个位置?客官别着急,我们看下我们的分区咋划分的,上面的mtdparts=tdparts=fe8000000.flash:110m(uboot),128k(kernel),128k(dtb),128k(jffs2),3m@0x5000000(test),-(fs)

我们计划使用test这个分区来做测试。可以看到test分区大小是3M,且起始地址在norflash的0x5000000的offset处。而且我们的flash存储映射到CPU线性地址0xfe8000000开始的地方,从CPU侧来看的线性地址为:0xfe8000000+0x5000000=0xfed000000。test这个分区的基地址=fe8000000,加上offset=0x5000000 因此地址=0xfed000000,其中在CPU侧来操作nor flash 时,操作的地址为0xed000000,0xfed000000为内部addr bus地址,该CPU是一个32bit指令集,32bit data bus,64bit address bus的IC,在指令集这一层面来看,操作的存储器地址32bit,CPU内部做移位。

启动系统后,可以查看test分区对应的/dev/mtdblock4。

fdisk -l /dev/mtdblock4


Disk /dev/mtdblock4: 3 MiB, 3145728 bytes, 6144 sectors

Units: sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes


系统启动log里面test分区的range:

0x000005000000-0x000005300000 : "test"


对应到CPU那一侧的操作地址range:

0x0000ed000000-0x0000ed300000


好,烧录到那个位置知道了,下面开始烧录。

usb start;fatload usb 0 1000000 jaffs2_rootfs
·

protect off 0xed000000  +$filesize;erase  0xed000000  +$filesize;cp.b 1000000 0xed000000  $filesize;protect on 0xed000000  +$filesize


不同开发环境的烧录方法可能不一样,但是大致思路是将生成的jffs2文件系统的image烧录到指定的offset上。

然后启动kernel,启动后:

mkdir test


mount -t jffs2 /dev/mtdblock4 test/


mount |grep jffs2


/dev/mtdblock4 on /home/root/test type jffs2 (rw,relatime)


df -h


Filesystem      Size  Used Avail Use% Mounted on

/dev/root       202M   83M  109M  44% /

devtmpfs        2.0G  4.0K  2.0G   1% /dev

tmpfs           2.0G  168K  2.0G   1% /run

tmpfs           2.0G  156K  2.0G   1% /var/volatile

/dev/sda1       3.5G  859M  2.6G  25% /run/media/sda1

/dev/mtdblock4  3.0M  388K  2.7M  13% /home/root/test


附录

dts 中的norflash分区

nor@0,0 {

#address-cells = <0x1>;

#size-cells = <0x1>;

compatible = "cfi-flash";

reg = <0x0 0x0 0x8000000>;

bank-width = <0x2>;

device-width = <0x2>;


`   partition@0 {
reg = <0x0 0x20000>;
label = "RCW";
read-only;
};

partition@20000 {
reg = <0x20000 0x6e0000>;
label = "kernel";
};

partition@800000 {
reg = <0x800000 0x100000>;
label = "DTB";
};

partition@a00000 {
reg = <0xa00000 0x3540000>;
label = "File system";
};
};`


mtdpart 设置

setenv bootargs "root=/dev/ram rw console=ttyS0,115200 ramdisk_size=70000000 mtdparts=fe8000000.flash:110m(uboot),128k(kernel),128k(dtb),128k(jffs2),3m@0x5000000(test),-(fs)"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jffs2 u-boot 分区 kernel