当前位置:网站首页>initramfs详解----设备文件系统
initramfs详解----设备文件系统
2022-08-03 01:02:00 【巭犇】
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目录下
[[email protected]_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文件:
[[email protected]_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
边栏推荐
- 做快乐的事情
- 暴力递归到动态规划 08(小马走象棋)
- Auto.js special positioning control method cannot perform blocking operations on the ui thread, please use setTimeout instead
- async-await
- “蔚来杯“2022牛客暑期多校训练营4 补题题解(N)
- 如何备考PMP才能一次通过?
- 增删改查这么多年,最后栽在MySQL的架构设计上!
- HCIP第十二天_二层MPLS实验
- VS Code 这么牛,再次印证了一句名言
- The Sandbox 市场平台将上线 Isla Obscura 第五期 NFT 作品集
猜你喜欢

Violence recursion to dynamic programming 08 (pony go chess)

接口流量突增,如何做好性能优化?

Violent recursion to dynamic programming 06 (the sword refers to Offer II 095. Longest common subsequence)

麒麟信安邀您抢先看 | openEuler 志高远,开源汇智创未来-开放原子全球开源峰会欧拉分论坛最详细议程出炉

XSS攻击

新库上线 | CnOpenDataA股上市公司董监高信息数据

torchvision.datasets.ImageFolder使用详解

中科磁业IPO过会:年营收5.5亿 吴中平家族持股85%

Greenplum数据库故障分析——can not listen port

暴力递归到动态规划 06 (剑指 Offer II 095. 最长公共子序列)
随机推荐
SAP ABAP Gateway Client 里 OData 测试的 PUT, PATCH, MERGE 请求有什么区别
apache-activemq-5.14.1
电信业务分类
科捷智能冲刺科创板:年营收12.8亿 顺丰与日日顺是股东
EasyGBS播放器优化:设备通道视频播放出现跳屏问题的修复
2149. 按符号重排数组
Wireshark data capture and analysis of the transport layer protocol (TCP protocol)
为什么要使用 playwright 做浏览器自动化测试?
如何让优炫数据库开机自启
聊聊 Nacos
个人开发者必备,免费 API 网关工具推荐
中科磁业IPO过会:年营收5.5亿 吴中平家族持股85%
在表格数据上,为什么基于树的模型仍然优于深度学习?
德邦科技通过注册:年营收5.8亿 国家集成电路基金为大股东
PAT甲级 1051 Pop Sequence
“蔚来杯“2022牛客暑期多校训练营4 补题题解(N)
MATLAB绘制填充图(X轴上下两种颜色)
一个人的精力
通力传动递交注册:年营收4.7亿 实控人项献忠家族色彩浓厚
OpenWRT setup ipv6 network