initramfs详解----设备文件系统

        initramfs的重要作用之一就是允许内核将保存根文件系统的存储设备的驱动不再编译进内核。本文我们就将硬盘驱动编译为模块,然后去识别硬盘设备。说道驱动,那么驱动一定是外部硬件设备的驱动,所以在介绍驱动之前,先介绍一下Linux对设备的管理,以及随之而产生的设备文件系统。

什么是devtmpfs

        既然提到设备,而且Linux将设备也抽象为文件,这里就不得不讨论一下设备文件或者说设备节点。通常情况下,某些需要从用户空间访问的设备都会在文件系统中建立一个设备文件,作为用户空间访问设备的接口。得益于Linux中虚拟文件系统的设计,用户空间的程序可以像访问普通文件一样,使用标准的文件访问接口实现与设备的交互。

        根据FHS的规定,设备文件存放在/dev目录下。在Linux系统的早期,设备文件是静态创建的,所有的设备节点是手动、事先创建的。笔者还记得在早期制作Linux发行版时,安装系统时,需要静态安装大量的设备文件,把所有可能的设备节点一并创建出来。但是,这样带来的一个问题就是,随着设备的种类越来越多,这个目录会越来越大,对于某一台具体的机器来说,dev目录下充斥着大量无用的设备文件,因为某些设备在某些机器上根本就不存在。而且,这种方法会逐渐耗尽设备号,虽然可以通过扩展设备号的位数来增加设备号,但终究不是长久之计。

        鉴于静态创建设备文件的种种问题,开发人员开发了devfs。devfs虽然解决了按需创建设备节点的机制,但是还是有很多问题,比如设备文件的名称依然由驱动开发人员在代码中指定,而不能由系统管理员指定。因此,后来又出现了udev,使得设备命名策略、权限控制等都在用户空间完成。如此,设备文件不再是静态创建,而是由udev根据内核检测到的实际连接的设备,创建相应的设备文件。

        对于动态创建设备文件,推荐在/dev目录下挂载一个基于内存的文件系统。基于内存的文件系统会完全驻留在RAM中,读写可以瞬间完成。除了性能优势之外,基于内存的文件系统的另外一个特点就是没有持久性,基于内存的文件系统中的数据在系统重新启动之后不会保留。这看起来可能不像是个积极因素,然而,对于动态创建设备节点这种情况来说,这实际上是一个优势。在系统关闭后,所有的设备节点无须保留,系统重启后,udev将根据内核检测到的实际设备创建设备文件。

        Linux从2.6.18开始采用udev,/dev目录使用了基于内存的文件系统tmpfs管理设备文件。

        2009年初,开发人员又提出了devtmpfs,并在同年年底被Linux2.6.32正式收录。内核引导时,devtmpfs将所有注册的设备在devtmpfs中建立相应的设备文件,一旦进入用户空间,在启动udev前,就可以将devtmpfs挂载到/dev目录下。也就是说,在启动udev前,devtmpfs中已经建立了初步的设备文件,一般启动程序不必再等待udev建立设备节点,甚至在某些嵌入式系统上,不再需要udev创建设备节点,因为这个基本的/dev已经足够,从而缩短了系统的启动时间。同rootfs类似,devtmpfs也不是新设计的文件系统,如果内核配置支持tmpfs,那么其就是tmpfs;否则,devtmpfs就是ramfs,只不过换了一个名字而已。

/dev目录下保存了设备文件的名称

devfs解决/dev目录下设备文件号耗尽问题,但是设备文件的名称由驱动开发人员设置

udev实现了由内核自动检测到实际到设备,自动创建设备文件

devtmpfs内核引导时,devtmpfs将所有注册的设备在devtmpfs中建立相应的设备文件,一旦进入用户空间,在启动udev前,就可以将devtmpfs挂载到/dev目录下

[root@ct7_node02 ~]# cat /etc/mtab 
...
devtmpfs /dev devtmpfs rw,nosuid,size=483816k,nr_inodes=120954,mode=755 0 0
...

测试devtmpfs     

        编译内核支持devtmpfs,并将内核与前面准备好的initramfs复制到虚拟机的目标系统上,然后重启进入操作系统。使用ls列出操作系统/dev下的设备文件

        根据图可见,/dev目录下包含一个设备节点console。但是我们的initramfs中并没有包含这个设备节点,那么这个设备节点是谁创建的呢?大家一定还记得我们前面讨论过的内置的initramfs吧?没错,这个console就是由内置的initramfs创建的。

        接下来我们使用下面的命令将ramfs挂载到/dev目录下。

mount -n -t ramfs none /dev

        因为ramfs只是一个基于内存的文件系统,与设备无关,所以mount命令中的“device”参数可以使用任意字串描述。习惯上,对于这类没有具体设备的,一般使用字串“none”表示。但是mount命令不推荐这样使用,因为在某些情况下,某些提示很容易让用户费解,比如“mount:none already mounted”。这里我们暂时使用“none”,在最终系统中我们使用“udev”,表示该目录下的节点是由udev创建的。默认情况下,mount命令会在文件/etc/mtab中维护一份当前已挂载的文件系统列表,因为我们的initramfs中没有创建/etc/mtab文件,initramfs中也不需要,因此使用参数“-n”告诉mount不需维护这份列表。

         挂载完成后,我们查看/dev下的设备文件。情况非常糟糕,/dev下挂载了一个空的ramfs文件系统,原有的console设备节点也被覆盖了,如上图所示。

        接下来我们使用下面的命令将devtmpfs挂载到/dev目录下:

mount -n -t devtmpfs none /dev

        挂载完成后,我们再次查看/dev下的设备文件。可以看到,devtmpfs下面已经建立了若干设备节点,如上图所示。

        既然devtmpfs有这么多的好处,/dev目录当然要使用devtmpfs文件系统了。因此,按照下面的脚本修改initramfs中的init文件:

[root@ct7_node02 initramfs]# cat init 
#!/bin/bash

echo "Hello Michael"
export PATH=/bin:/usr/bin:/usr/sbin
mount -n -t devtmpfs udev /dev
exec /bin/bash

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值