romfs详解

更新时间:2023-07-27 08:53:36 阅读: 评论:0

linuxromfs的详解

Romfs是一种相对简单、占用空间较少的文件系统。
空间的节约来自于两个方面:首先内核支持Romfs文件系统比支持 ext2文件系统需要更少的代码;其次romfs文件系
统相对简单,在建立文件系统超级块(Superblock)需要更少的存储空间。
Romfs是只读的文件系统,禁止写操作,因此系统同时需要虚拟盘(RAMDISK)支持临时文件和数据文件的存储。

ROMFS文件系统的分析
引言:ROMFS是在嵌入式设备上常用的一种文件系统,具备体积小,可靠性好,读取速度快等优点。同时支持目录,
符号链接,硬链接,设备文件。但也有其局限性。ROMFS是一种只读文件系统,同时由于ROMFS本身设计上的原因,使
ROMFS支持的最大文件不超过256M。本文讨论了ROMFS的原理,并针对其代码做了详细的分析,指出了ROMFS的优缺点并做了相应的改进。Linux, uclinux都支持ROMFS文件系统。除ROMFS外,其它常用的嵌入式设备的文件系统还有
CRAMFSJFFS2等,它们各有特色。
1ROMFS文件系统的特点
ROMFS是一种只读的文件系统,它使用顺序存储方式,所有数据,包括目录,链接等都按目录树的顺序存放。相对于EXT2等较大型的文件系统而言,ROMFS非常节省空间。通常ROMFS用在嵌入式设备中作为根文件系统,或者用于保存boot loader以便引导系统启动。

2ROMFS文件系统的数据存储方式
设计一个文件系统首先要确定它的数据存储方式。不同的数据存储方式对文件系统占用空间,读写效率,查找速度等主要性能有极大影响。ROMFS是一种只读的文件系统,它使用顺序存储方式,所有数据都是顺序存放的。因此ROMFS中的数据一旦确定就无法修改,这是ROMFS只能是一种只读文件系统的原因,它的数据存储方式决定了无法对ROMFS进行写操作。由于采用了顺序存放策略,ROMFS中每个文件的数据都能连续存放,读取过程中只需要一次寻址操作,进而就可以读入整块数据,因此ROMFS中读取数据效率很高。
整个ROMFS文件系统的布局如下:
ROMFS的首部

前八个字节是文件系统的名字,在这里是-rom1fs-, 8-11字节存放该文件系统大小,12-15字节为前512字节的校验和,从16字节开始是文件系统的卷名,卷名的长度必须的16字节的整数倍,不足的部分可以用‘0’填充。
ROMFS的首部是ROMFS的超级块信息,操作系统通过超级块来识别文件系统的类型。首部之后就是实际的数据,包括目录,普通文件,设备文件,硬链接等。ROMFS支持所有这些类型的文件。
3.ROMFS的主要数据结构
ROMFS的数据结构比较简单,主要有文件系统结构和文件结构两种数据结构。

ROMFS的文件系统结构如下:

struct romfs_super_block
{
     
__u32 word0;
     
__u32 word1;
     
__u32 size;
     
__u32 checksum;
私车公用协议
     
char name[0];        /* volume name */

};

该结构用于识别整个ROMFS文件系统,大小为512字节,word0初始值为'-','r','o','m'word1初始值为 '-','1','f','s',通过这两个字操作系统确定这是一个ROMFS文件系统。size字段用于记录整个文件系统的大小,理论上ROMFS大小最多可以达到4Gchecksum是前512字节的校验和,用于确认整个文件系统结构数据的正确性。前面4个字段占用了16字节,剩下的都可以用作文件系统的卷名,如果整个首部不足512怎么算圆的周长字节便用0填充,以保证首部符合16字节对齐的规则。
ROMFS的文件结构如下:
struct romfs_inode
{
     
__u32 next;          /* low 4 bits e ROMFH_ */
      __
u32 spec;
     
__u32 size;
     
__u32 checksum;
     
char name[0];
};

少代会next 字段是下一个文件的偏移地址,该地址的后4位是保留的,用于记录文件模式信息,其中前两位为文件类型,后两位则标识该文件是否为可执行文件。因此ROMFS用于文件寻址的字段实际上只有28bit,所以ROMFS中文件大小不能超过256Mspec字段用于标识该文件类型。目前ROMFS支持的文件类型包括普通文件,目录文件,符号链接,块设备和字符设备文件。size是文件大小,checksum是校验和,校验内容包括文件名,填充字段。name是文件名首地址,文件名长度必须保证16字节对齐,不足的部分用可以0填充。
4.ROMFS的实现
Linux系统中定义一个文件系统首先要定义相应的file_system_type以及读取超级块的函数。
static DECLARE_FSTYPE_DEV(romfs_fs_type,"romfs",romfs_read_super);
具体到ROMFS本身,这两个对象分别
romfs_fs_typeromfs_read_super,文件系统名为"romfs",通过宏DECLARE_FSTYPE_DEV来实现对
romfs_fs_type的定义以及初始化工作。此外还需要实现对目录,文件的读写操作。
LinuxROMFS的实现中,比较重要的数据结构如下:

超级块操作表

static struct super_operations romfs_ops =
{
     
read_inode:    romfs_read_inode,
     
statfs:            romfs_statfs,};

页操作表

static struct address_space_operations romfs_aops =
{
      readpage: romfs_readpage};

常规文件操作表

static struct file_operations romfs_dir_operations =
{
     
read:      generic_read_dir,
     
readdir:    romfs_readdir,};

索引节点操作表

static struct inode_operations romfs_dir_inode_operations = 怎样长高男生
{
     
lookup:    romfs_lookup,};

romfs_read_super()用来读取ROMFS文件系统的首部,并利用该首部初始化一个超级块对象作为相应ROMFS的超级块,具体流程如下
1 初始化超级块。

A 设置一次读取的块大小并初始化超级块对象某些域。

B 从指定ROMFS中读取第0块到一个缓冲区。bh=sb_bread(s, 0),其中s是文件系统的超级块对象。ROMFS的文件系统结构被保存到缓冲区bh中。

C 取出ROMFS的文件系统结构,rsb = (struct romfs_super_block *)bh->b_datarsb是一个
romfs_super_block结构,用以保存该ROMFS的文件系统结构的数据。然后对该数据进行检验,确定其文件系统类型,检验和,文件系统大小。

D 继续初始化超级块对象某些域,比较重要的是s_magic = ROMFS_MAGICs_flags |= MS_RDONLY,分别表明了该超级块的magic签名和s_flags参数,此处它们分别表示该文件系统类型为romfs,并且是只读文件系统。

2 给超级块对象的操作表赋值(s->s_op = &romfs_ops

3 为根目录分配目录项 s->s_root = d_alloc_root(iget(s,sz), sz成事不足为文件系统开始偏移。
京东自营是什么意思    超级块操作表中romfs文件系统实现了两个函数
static struct super_operations romfs_ops =
{
     
read_inode:    romfs_read_inode,
     
statfs:          romfs_statfs,
};

圆脸适合的发型图片函数romfs_read_inode是从ROMFS中读取一个inode索引节点对象并进行一些初始化工作,具体流程如下:

1 根据inode参数寻找对应的索引节点。

2 初始化索引节点某些域
3 根据该inode对应的文件的访问权限和类别来设置索引节点的相应操作表

A 如果是目录文件则将索引节点操作表设为i_>i_op=&romfs_dir_inode_operations;文件操作表设置为i->i_fop=&romfs_dir_operations

B 如果是常规文件,则将文件操作表设置为i->i_fop=&generic_ro_fops;将页高诉缓存表设置为
i->i_data.a_ops=&romfs_aops;由于romfs是只读文件系统,它在对常规文件操作时不需要索引节点操作,如mknodlink等,因此不用设置索引节点操作表。
对常规文件的操作也只需要使用内核提供的通用函数表
generic_ro_fops ,它包含基本的三种常规文件操作:
             
llek:  generic_file_llek,
             
read:  generic_file_read,
             
mmap:  generic_file_mmap,

这几种函数是块设备读取的通用函数,它们可以实现对ROMFS中常规文件的读取,寻址等操作。
C 如果是符号链接文件,则将索引节点操作表设置为
       
i->i_op = &page_symlink_inode_operation; page_symlink_inode_operations是通用的符号链接操作表。同时还需要实现页高速缓存操作,
因此将页高速缓存表设置为i->i_data.a_ops=&romfs_aops

D 如果是套接字或管道则进行特殊文件初始化操作init_special_inode(I,ino,nextfh);
函数romfs_statfs用于提取一些ROMFS的基本信息,包括文件系统大小,卷名等。相对而言非常简单。
齐人有好猎者
1.1 什么是romfs
    romfs是一个只读文件系统,主要用在 mainly for initial RAM disks of installation disks.使用romfs文件系统可以构造出一个最小的内核,并且很节省内存。相比而言,早期的minixxiafs(现在已经过时)文件系统如果编译为模块的形式则大小超过20000字节(在x86机器上大小为38502字节),而romfs却小于一页(在linux系统中,一页大小为PAGE_OFFSET,一般为4K),大约4000字节(在x86机器上大小为10479字节)。在相同的条件下,msdos文件系统模块大约30K(并且不支持设备节点和符号链接,在x86机器上大小为12K)。ntfsnfsroot文件系统模块大约57K(在x86机器上大小为102K)。
注:上面叙述中的数值都是针对i586机器,括号中叙述的数值是在现在的x86机器上的大小,针对2.6.28内核。
1.2 romfs的用途
    romfs本设计的主要目标是构造一个最小内核,在内核中只链接romfs文件系统,这样就可以使用romfs在稍后加载其他模块。romfs也可以用来运行一些程序,从而决定你是否需要SCSI设备,或者IDE设备,或者如果你使用的是"initrd"结构的内核,romfs也可以用来在之后加载软驱驱动。romfs的另一个用途是在你使用romfs文件系统的时候,你可以关闭ext
2或者minix甚至affs文件系统直到你确信需要的时候再开启。
1.3 romfs的性能
    romfs的操作是基于块设备的,它的底层结构非常简单。为了快速访问,每个单元被设计为起始于16字节边界。一个最小的文件为32字节(文件内容为空,并且文件名长度小于16字节)。对于一个非空文件的最大的开销是位于文件内容前面的文件头和其后的16字节的文件名(因为大多数的文件名长度大于3字节并且小于15字节,所以预置文件名长度为16字节)。
1.4 如何使用romfs映像
    要使用一个制作好的romfs格式的映像,是将其挂载在其他文件系统的某个节点上。并且还有一个很重要的前提,就是内核要支持romfs文件系统。这一点可以通过配置内核实现,有两个方法:
1.romfs配置成直接编译进内核,方法为使用make menuconfig命令进入内核配置界面,选择"File systems"并进入,选择“Miscellaneous filesystems”并进入,选择“ROM file system support(ROMFS)”,将其配置成"*"(直接编译进内核)。这样生成的内核就直接包含对romfs文件系统的支持。
2.romfs配置成模块的形式,步骤和前面一样,只是在最后选择"ROM file system support(ROMFS)"的时候将其配置成"M"(编译为内核模块)。这样编译好的内核并不包含对romfs文件系统的支持,只是生成了romfs.ko模块(fs/romfs/romfs.ko),需要在启动系统后将其加载进内核才能使内核支持romfs文件系统。
有了内核对romfs文件系统的支持,就可以直接挂载romfs格式的映像了,挂载方法为:
niutao@niutao:~/kernel/romfs$ ls
hello.img
niutao@niutao:~/kernel/romfs$ file hello.img
hello.img: romfs filesystem, version 1 208 bytes, named rom 49e05ac0.
niutao@niutao:~/kernel/romfs$ sudo mount -o loop hello.img /mnt
niutao@niutao:~/kernel/romfs$ cd /mnt/
niutao@niutao:/mnt$ ls
hello.c
niutao@niutao:/mnt$
可以看到使用mount命令将hello.img挂载到了/mnt目录下,其内只有一个文件。
  卸载一个已经被挂载的romfs格式映像使用umount命令。
1.5如何制作romfs映像
如果要创建一个romfs文件系统,需要使用genromfs工具。具体用法为:
-f IMAGE    指定输出romfs映像的名字
-d DIRECTORY 指定源目录(将该目录制作成romfs文件系统)
-v          显示详细的创建过程
-V VOLUME    指定卷标
-a ALIGN    指定普通文件的对齐边界(默认为16字节)
-A ALIGN,PATTERN 匹配参数PATTERN的对象对齐在ALIGN边界上
-x PATTERN 不包括匹配PATTERN的对象。
-h 显示帮助文档。
上节我们说到使用genromfs工具生成romfs映像,现在我们一一详细讲述genromfs的各个参数的含义及用法。
1. -f参数
  该参数指定要生成的romfs映像的名字,是一个必须参数,如果缺少,则无法生成映像。例如:
niutao@niutao:~/kernel/romfs$ ls
hello.c
niutao@niutao:~/kernel/romfs$ genromfs -f hello.img
niutao@niutao:~/kernel/romfs$ ls
hello.c hello.img
  可以看到生成了名为hello.imgromfs格式的映像。那么genromfs是将那个目录制作成了hello.img?将hello.img挂载之后,可以看到其内的文件为当前路径下的文件(hello.chello.img)。所以在没有指定源目录(要将那个目录制作成romfs映像)的时候,默认为当前目录。这一点也可以从genromfs的源代码中看到:

本文发布于:2023-07-27 08:53:36,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1119737.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:文件   操作   内核
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图