文件系统浅谈
本文章参考韦东山老师的《嵌入式杂谈之文件系统》,但同时将重心放在了内存文件系统之中。
嵌入式常用文件系统
这是整个文件系统的思维导图,下面将以这个图展开进行介绍:
查看本机所有文件系统
使用df -ahT命令查看当前系统的所有文件系统
- -h显示大小
- -T显示文件系统类型
- -a打印所有文件系统
文件系统总体介绍
一、内核生成的文件系统
sysfs与proc文件系统是内核自动生成的文件系统 。
分为两类:
一类文件系统有大小,称为基于存储设备的文件系统。
一类文件系统根本无法查看大小,称为基于逻辑的虚拟文件系统。
二、基于存储设备的文件系统
基于存储设备的文件系统可以分为内存文件系统和flash文件系统和扩展SD卡文件系统和网络文件系统。
三、内存文件系统
内存文件系统包括tmpfs和ramdisk。
tmpfs文件系统是一种临时的文件系统,由linux内核来支持,只需要在内存中指定一个区域,指定最大的大小,就可以直接使用,不需要对内存进行格式化。
ramdisk是将一部分固定大小的内存( RAM )空间模拟出硬盘分区,断电后会丢失。
四、flash文件系统
flash文件系统包括cramfs和squashfs和jffs/jffs2和yaffs/yaffs2和ubifs。
cramfs是只读压缩的文件系统,可以将文件系统进行压缩,提高存储效率。
squashfs是只读压缩的文件系统,相比于cramfs可以支持更大的单个文件大小。
jffs/jffs2是可以读写,压缩的日志闪存文件系统,主要是应用于nor flash。
yaffs/yaffs2是另一种日志闪存文件系统,主要是为nand型flash设计的文件系统,为了应对flash容量的快速增长。
ubifs是作为jffs2的后继文件系统,满足大容量的需求。
五、扩展SD卡文件系统
扩展SD卡文件系统包括FAT32和ext2/ext3。
FAT32是微软专为windows开发的文件系统,在windows上有很好的兼容性。
ext2/ext3是Linux上的日志文件系统,可靠性好,但在windows上支持不太好。
六、网络文件系统
网络文件系统包括NFS和Samba。
NFS是开发板与宿主机进行挂载的文件系统。
Samba是windows与Linux之间的共享机制。
七、虚拟文件系统
虚拟文件系统无法查看大小,称为基于逻辑的虚拟文件系统。
基于逻辑的虚拟文件系统包括进程文件系统和设备文件系统。
进程文件系统在Linux上常用的是procfs文件系统,Linux启动以后自动挂载在/proc目录下。
设备文件系统在Linux上常用的是sysfs文件系统与devfs文件系统,sysfs文件系统在Linux启动以后,自动挂载在sys目录下。
但devfs文件系统在Linux内核2.6以前使用,现在基本被废弃。
八、存储设备
存储设备可以分为内存和外存和网络,外存还可以分为内置和扩展。
内存对应三、内存文件系统。
外存对应四、flash文件系统。
网络对应六、网络文件系统。
内置包括四、flash文件系统与三、内存文件系统。
扩展对应五、扩展文件系统。
Linux内核虚拟文件系统
一、procfs文件系统
procfs是Linux内核信息的抽象文件接口,大量的内核中的信息以及可调参数都被作为常规文件映射到了一个目录树中/proc。
这样我们就可以简单直接的通过echo和cat这样的文件操作命令对系统信息进行查取和调整了。
大量的系统工具也通过procfs来获取内核参数,例如ps、lspci等。
首先对procfs进行挂载
# -t 是指定文件系统类型 ,第二个参数是挂载设备,因为是内核设备,所以写none,第三个参数是挂载目录
mount -t proc none /proc
# 或者在 /etc/fstab条目下添加
none /proc proc defaults 0 0
在fstab下添加会在开机以后自动挂载
一旦proc卸载掉,那么df命令就无法使用了。
因为df命令实际是去查看/proc/mounts文件来查看信息。
很多命令例如ps都是通过proc目录来查看系统信息。
再查看一下proc目录下的文件:带数字的表示是进程信息 :
其他的都是系统信息
- cmdline文件表示内核启动参数。
- cpuinfo文件表示cpu信息。
- meminfo文件表示内存信息。
sys目录表示系统运行相关的信息,包括内核等,但断电后重新上电会再次使用默认设置。
二、tmpfs文件系统
是一种虚拟内存文件系统,使用内存作为存储分区进行文件的临时性存取,掉电会丢失,创建时不需要使用mkfs进行格式化
使用如下命令进行挂载。
# 临时改变
# -o 指定大小
mount -t tmpfs none -o size=10M /tmp
# 永久改变
vim /etc/fstab
~
tmpfs /dev/shm tmpfs defaults,size=777M 0 0
~
所以一般tmp目录都是临时创建的虚拟文件系统。
在这个文件夹下创建的文件断电后会丢失。
所以通常使用这个目录保存应用程序运行时的信息,不用担心丢失。
作用是通过内存的读取速度提高程序效率,延长flash寿命。
/dev/shm
/dev/shm/是一个设备文件,它使用就是tmpfs文件系统
(注意:在CentOS和RedHat下,/dev/shm目录是一个链接,指向/run/shm目录,在Ubuntu系统下tmpfs文件系统对应的是/run/shm目录,可以使用df命令查看)
但后期的centos版本中 /dev/shm 就是一个被挂载的目录
介绍
tmpfs默认的大小是RM的一半,假如你的物理内存是1024M,那么tmpfs默认的大小就是512M。
tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的tmpfs文件系统会完全驻留在内存RAM中,读写几乎可以是瞬间的。同时它也有一个缺点tmpfs数据在重新启动之后不会保留,这点与内存的数据特性是一致的。
但是这个df查看到的挂载内存大小的数值,如果没有使用,是没有去真正占用的,只有真正在tmpfs存储数据了,才会去占用。比如,tmpfs大小是777M,如果用了10M大小,内存里就会使用真正使用10M,剩余的767M是可以继续被服务器其他程序来使用的。
适用场景:
天生就是为临时目录而生的
适合存储socket、session等,对于的临时数据也可以选择进行存储,
对于高I/O并且还需要持久化到磁盘的,需要通过其他手段,tmpfs可以提高linux系统的性能。
三、devfs文件系统
Linux2.6内核以前设备文件的抽象机制:提供了一种类似于文件的方法来管理位于/dev目录下的所有设备。
特殊设备文件/dev/console以及/dev/tty。
-
/dev目录下的zero以及null是黑洞文件,相当于输入给黑洞文件的信息全部都会消失。
-
devfs文件系统后来集成到了sysfs文件系统。
-
devfs缺点: 设备映射不同,没有主/次设备号,不能支持太多设备。
四、sysfs文件系统
Linux内核2.6以后引入sysfs文件系统:挂载于/sys目录下,把实际连接到系统上的设备和总线组织成一个分级的文件。
用户空间的程序也同样可以使用这些信息实现和内核的交互,该文件系统是当前系统上实际设备树的一个直观反映。
这些信息比/dev目录下的信息更为详细与丰富, 准确。
每个设备在sysfs中都有唯一对应的目录。
使用如下命令创建挂载点
## -t 是指定文件系统类型 ,第二个参数是挂载设备,因为是内核设备,所以写none,第三个参数是挂载目录
mount -t sysfs none /sys
# 或者在 /etc/fstab条目下添加
none /sys sysfs defaults 0 0
# 在fstab下添加会在开机以后自动挂载
udev工具是管理热插拔的工具,利用了sysfs提供的信息来实现所有devfs的功能,通过检测设备的插入与拔出,动态的在/dev目录下创建与删除设备文件。
总结:一切皆文件的抽象思想,使得Linux系统的管理变得简单统一。
initramfs文件系统
内核启动的时候需要挂载根文件系统,所以要在内核镜像中对存储设备进行初始化,但这样会导致内核镜像过大。所以可以使用ramfs文件系统。
一、rootfs、ramfs、ramdisk与tmpfs区别
· rootfs与根文件系统的英文rootfs不同,它是指内核启动的初始根文件系统,内核自身虚拟了一个文件系统,如果这个空间内没有文件系统,就回去查找其他文件系统。
· ramfs是基于内存的文件系统,没有内存大小的限制,会动态增加容量,直至耗尽系统内存,使用的是基于内存的缓存,所以io效率高。
· ramdisk是基于ram的块设备, 占据一块固定的内存,使用mke2fs格式化工具创建文件系统,还需要一个文件系统驱动来读写其中的文件。空间固定导致容量有限,想要写入更多内容需要重新格式化。由于Linux块设备缓冲的特点,所以ramdisk上的数据会被拷贝到内存上进行备份,造成内存浪费。
· ramfs的缺点会因为数据的写入自动增长空间,所以可能导致最后系统所有的内存耗完,所以只有root用户或者被授权的用户允许使用ramfs,但是tmpfs增加了容量的限制,允许用户把数据写入交换分区,允许普通用户使用。
二、initrd与initramfs
· initrd是intramfs之前的设计 。
· 作用都是为了在挂载真正的根文件系统之前将设备驱动,工具以及一些初始化流程先加载到内存中运行。
· initrd基于ramdisk技术,initrd的初始化程序是/linuxrc文件,负责 最终完成真正根文件系统的挂载。我们的Ubuntu上都会有一个boot目录,内核从boot分区找到initrd镜像,然后由initrd镜像完成真正跟文件系统的挂载。在PC上initrd用的比较少,initramfs在嵌入式用的多。
· initramfs的实现设计比initrd更简单,更灵活。是基于ramfs文件系统。不是在内核启动完成以后再从磁盘加载到内存进而挂载,而是构建到内核镜像中,所以内核启动完成以后,直接被拷贝到了rootfs空间,作为初始根文件系统,完成真正根文件系统的挂载。
三、initramfs使用
使用如下命令打包initramfs镜像
# 使用cpio命令进行打包
# -o指输出 -H newc 指定打包格式为newc,这是initramfs必须指定的打包格式
# gzip是将它进行压缩,此处可以压缩也可以不压缩
find .|cpio -o -H newc | gzip > ~/myinitramfs.cpio.gz
使用如下命令进行解压查看
# -i 表示指定文件输入进来 -d表示进行解压
# --no-absolute-filenames表示不解压到宿主机根目录下
zcat hello.cpio.gz | cpio -i -d -H newc --no-absolute-filenames
嵌入式flash上的文件系统cramfs与squashfs对比
嵌入式系统上面为了提高安全性与降低文件系统的空间占用。
文件系统一般设置具有如下两个特点:只读 + 压缩。
squashfs是cramfs的替代品。
cramfs全称compressed ROM filesyatem,主要用于嵌入式Linux系,简单与空间高效。
cramfs最大支持的256MB基本可以满足嵌入式Linux要求,允许的最大文件系统大小为256+16=272MB,必须设置内核的页大小也为4KB,才可以正确读取cramfs文件系统。
cramfs因为是对页进行压缩的,所以查看数据的时候先要知道数据在哪一页才能进行解压缩,这一点要求cramfs不能对元数据进行压缩,否则无法查看元数据,不能进行判断。
ACL是指访问控制列表,可以对文件进行权限管理,在嵌入式系统中基本不需要。
cramfs的超级块与目录结构不进行压缩,所谓布局与管理相对来说比较简单。
这里说的压缩是指数据一直处于被压缩状态,只有真正使用的时候才会对数据进行解压缩。
cramfs在2013年被linus标记为过时的文件系统,推荐使用aquashfs替代cramfs。
这两个文件系统都是只读文件系统。