《Linux From Scratch》第三部分:构建LFS系统 第七章:基本系统配置- 7.3. LFS 系统中的设备和模块管理

本文涉及的产品
对象存储 OSS,标准 - 本地冗余存储 20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000 次 1年
简介:

 在 第六章, 我们通过 systemd 的源码包安装好了 udev。在开始了解它是如何工作之前,我们先来简要的回顾下以前处理设备的方法。

传统的 Linux 不管硬件是否真实存在,都以创建静态设备的方法来处理硬件,因此需要在 /dev 目录下创建大量的设备节点文件(有时会有上千个)。这通常由 MAKEDEV 脚本完成,它通过大量调用 mknod 程序为这个世界上可能存在的每一个设备建立对应的主设备号和次设备号。

而使用 udev 方法,只有当内核检测到硬件接入,才会建立对应的节点文件。因为需要在系统启动的时候重新建立设备节点文件,所以将它存储在 devtmpfs 文件系统中(完全存在于内存中的虚拟文件系统)。设备节点文件无需太多的空间,所以占用的内存也很小。

7.3.1. 历史

2000 年 2 月,一种名叫 devfs 的文件系统被合并到 2.3.46 内核版本,2.4 系列的稳定内核中基本可用。尽管它存在于内核的源代码中,但是这种动态创建设备的方法却从来都得不到核心内核开发者的大力支持。

问题存在于它处理设备的检测、创建和命令的方式,其中最大的问题莫过于它对设备节点的命名方式。大部分开发者的观点是,设备的命名应该由系统的所有者决定,而不是开发者。 devfs 存在一个严重的设计缺陷:它存在严重的 race conditions 问题,如不对内核做大量的修改就无法修正这一问题。最终,因为缺乏有效的维护,在 2006 年 6 月终被移出内核源代码。

再后来,随着非稳定的 2.5 版本的内核开发,到稳定的 2.6 内核,又出现了一种全新的虚拟文件系统 sysfssysfs 的工作是将系统的硬件配置导入到用户空间进程。通过对用户空间可视化的改善,代替devfs 变得更加现实。

7.3.2. Udev 实现

7.3.2.1. Sysfs

上文简单的提及了 sysfs 文件系统。有些人可能会问,sysfs 到底是如何知道当前系统有哪些设备,这些设备又该使用什么设备号呢。对于那些已经编译进内核的设备,会在内核检测到时直接注册为 sysfs 对象(devtmpfs 内建)。对于编译为内核模块的设备,将会在模块载入的时候注册。一旦 sysfs 文件系统挂载到 /sys,已经在 sysfs 注册的硬件数据就可以被用户空间的进程使用, udevd 也就能够处理了(包括对设备节点进行修改)。

7.3.2.2. 设备节点的创建

设备文件是通过内核中的 devtmpfs 文件系统创建的。任何想要注册的设备都需要通过 devtmpfs (通过驱动程序核心)实现。每当一个 devtmpfs 实例挂载到 /dev,就会建立一个设备节点文件,它拥有固定 的名称、权限、所有者。

很短的时间之后,内核将给 udevd 一个 uevent。基于 /etc/udev/rules.d/lib/udev/rules.d/run/udev/rules.d 目录内文件指定的规则,udevd 将会建立到设备节点文件的额外符号链接,这有可能更改其权限,所有者,所在组,或者是更改 udevd 内建接口(名称)。

这三个目录下的规则都像 LFS-Bootscripts 包那样标有数字,所有三个目录都会统一到一起。如果 udevd 找不到和所创建设备相应的规则,它会保留 devtmpfs 里初始化时使用过的权限和属主。

7.3.2.3. 加载模块

编译成模块的设备驱动可能会包含别名。别名可以通过 modinfo 打印出来查看,一般是模块支持的特定总线的设备描述符。举个例子,驱动 snd-fm801 支持厂商 ID 为 0x1319 以及设备 ID 为 0x0801 的设备,它包含一个 “pci:v00001319d00000801sv*sd*bc04sc01i*” 的别名,总线驱动导出该驱动别名并通过 sysfs 处理相关设备。例如,文件 /sys/bus/pci/devices/0000:00:0d.0/modalias 应该会包含字符串 “pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”。Udev 采用的默认规则会让 udevd 根据 uevent 环境变量 MODALIAS 的内容(它应该和 sysfs 里的 modalias 文件内容一样)调用 /sbin/modprobe,这样就可以加载在通配符扩展后能和这个字符串一致的所有模块。

在这个例子里,意味着,除了 snd-fm801 之外,一个已经废弃的(不是我们所希望的)驱动 forte 如果存在的话也会被加载。下面有几种可以避免加载多余驱动的方式。

内核本身也能够根据需要加载网络协议,文件系统以及 NLS 支持模块。

7.3.2.4. 处理热插拔/动态设备

在你插入一个设备时,例如一个通用串行总线(USB)MP3 播放器,内核检测到设备已连接就会生成一个 uevent。这个 uevent 随后会被上面所说的 udevd 处理。

7.3.3. 加载模块和创建设备时可能碰到的问题

在自动创建设备节点时可能会碰到一些问题。

7.3.3.1. 内核模块没有自动加载

Udev 只会加载包含有特定总线别名而且已经被总线驱动导出到 sysfs 下的模块。在其它情况下,你应该考虑用其它方式加载模块。采用 Linux-3.19,Udev 可以加载编写合适的 INPUT、IDE、PCI、USB、SCSI、SERIO 和 FireWire 设备驱动。

要确定你希望加载的驱动是否支持 Udev,可以用模块名字作为参数运行 modinfo。然后查看 /sys/bus 下的设备目录里是否有个 modalias 文件。

如果在 sysfs 下能找到 modalias 文件,那么就能驱动这个设备并可以直接操作它,但是如果该文件里没有包含设备别名,那意味着这个驱动有问题。我们可以先尝试不依靠 Udev 直接加载驱动,等这个问题以后解决。

如果在 /sys/bus 下的相应目录里没有 modalias 的话,意味着内核开发人员还没有为这个总线类型增加 modalias 支持。使用 Linux-3.19 内核,应该是 ISA 总线的问题。希望这个可以在后面的内核版本里得到解决。

Udev 不会尝试加载类似 snd-pcm-oss 这样的“封装”驱动,也不会加载类似 loop 这样的非硬件驱动。

7.3.3.2. 内核驱动没有自动加载,Udev 也没有尝试加载

如果是 “封装” 模块只是强化其它模块的功能(比如,snd-pcm-oss 模块通过允许 OSS 应用直接访问声卡的方式加强了 snd-pcm 模块的功能),需要配置 modprobe 在 Udev 加载硬件驱动模块后再加载相应的封装模块。可以在任意 /etc/modprobe.d/<filename>.conf文件里增加一行 “softdep”,例如:

softdep snd-pcm post: snd-pcm-oss

请注意 “softdep” 也支持 pre: 的依赖方式,或者混合 pre:post:。查看 modprobe.d(5) 手册了解更多关于 “softdep” 语法和功能的信息。

如果问题模块不是一个封装而且也是有用的,配置 modules 开机脚本在引导系统的时候加载模块。这样需要把模块名字添加到 /etc/sysconfig/modules 文件里的单独一行。这个也可以用于封装模块,但是只是备用方式。

7.3.3.3. Udev 加载了一些无用模块

要么不要编译该模块,或者把它加入到模块黑名单 /etc/modprobe.d/blacklist.conf 里,像下面的例子里屏蔽了 forte 模块:

blacklist forte

被屏蔽的模块仍然可以用 modprobe 强行加载。

7.3.3.4. Udev 创建了错误的设备节点,或错误的软链接

这个情况通常是因为设备匹配错误。例如,一条写的不好的规则可能同时匹配到 SCSI 磁盘(希望加载的)和对应厂商的 SCSI 通用设备(错误的)。找出这条问题规则,并通过 udevadm info 命令的帮助改得更具体一些。

7.3.3.5. Udev 规则工作不可靠

这可能是上个问题的另一种表现形式。如果不是,而且你的规则使用了 sysfs 特性,那可能是内核时序问题,希望在后面版本内核里能解决。目前的话,你可以暂时建立一条规则等待使用的 sysfs 特性,并附加到 /etc/udev/rules.d/10-wait_for_sysfs.rules 文件里(如果没有这个文件就创建一个)。如果你碰到这种情形请通知 LFS 开发邮件列表,这个对我们有帮助。

7.3.3.6. Udev 没有创建设备

后面的内容会假设驱动已经静态编译进内核或已经作为模块加载,而且你也已经确认 Udev 没有创建相应的设备节点。

如果内核驱动没有将自己的数据导出到 sysfs 里,Udev 就没有相关信息来创建设备节点。这通常发生在内核树之外的第三方驱动里。我们可以使用合适的主/副设备数字 ID(查看内核文档里或第三方驱动厂商提供的文档里的 devices.txt 文件) 在 /lib/udev/devices 目录里创建一个静态设备节点。这个静态设备节点随后会被 udev 引导脚本复制到 /dev 里。

7.3.3.7. 设备名称顺序在重启后随机改变

这是因为 Udev 被设计成并行处理 uevents 并加载模块,所以是不可预期的顺序。这个不会“修复”。你不应该依赖稳定的内核模块名称。而是,在检测到设备的稳定特征,比如序列号或 Udev 安装的一些 *_id 应用的输出,来判断设备的稳定名称,之后创建自己的规则生成相应的软链接。可以参考 7.4, “创建自定义符号链接到设备”7.2, “通用网络设置”

7.3.4. 有用的读物

点击以下链接可以获得一些额外的帮助文档:

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
相关文章
|
3月前
|
Ubuntu Linux Anolis
Linux系统禁用swap
本文介绍了在新版本Linux系统(如Ubuntu 20.04+、CentOS Stream、openEuler等)中禁用swap的两种方法。传统通过注释/etc/fstab中swap行的方式已失效,现需使用systemd管理swap.target服务或在/etc/fstab中添加noauto参数实现禁用。方法1通过屏蔽swap.target适用于新版系统,方法2通过修改fstab挂载选项更通用,兼容所有系统。
230 3
Linux系统禁用swap
|
3月前
|
Linux
Linux系统修改网卡名为eth0、eth1
在Linux系统中,可通过修改GRUB配置和创建Udev规则或使用systemd链接文件,将网卡名改为`eth0`、`eth1`等传统命名方式,适用于多种发行版并支持多网卡配置。
344 3
|
4月前
|
Ubuntu Linux
计算机基础知识:linux系统怎么安装?
在虚拟机软件中创建一个新的虚拟机,并选择相应操作系统类型和硬盘空间大小等参数。将下载的 ISO 镜像文件加载到虚拟机中。启动虚拟机,进入安装界面,并按照步骤进行安装。安装完成后,可以在虚拟机中使用 Linux 系统。
|
4月前
|
存储 Ubuntu Linux
「正点原子Linux连载」第二章Ubuntu系统入门
在图2.8.2.4中,我们使用命令umount卸载了U盘,卸载以后当我们再去访问文件夹/mnt/tmp的时候发现里面没有任何文件了,说明我们卸载成功了。
|
4月前
|
Ubuntu Linux 网络安全
Linux服务器之Ubuntu的安装与配置
Ubuntu Desktop是目前最成功、最流行的图形界面的Linux发行版;而Ubuntu Server也在服务器端市场占据了较大的份额。今天为大家详细介绍了Ubuntu Server的安装与配置,希望对你能有所帮助。关于VMware、VirtualBox等虚拟化软件的使用,朱哥还会在后续的文章中为大家详细介绍,敬请关注!
|
2月前
|
存储 Linux 开发工具
Linux环境下使用Buildroot配置软件包
使用Buildroot可以大大简化嵌入式Linux系统的开发和维护工作,但它需要对Linux系统和交叉编译有深入的理解。通过上述步骤,可以有效地配置和定制软件包,为特定的嵌入式应用构建高效、稳定的系统。
216 11
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
305 0
Linux系统初始化脚本
|
4月前
|
运维 Linux 开发者
Linux系统中使用Python的ping3库进行网络连通性测试
以上步骤展示了如何利用 Python 的 `ping3` 库来检测网络连通性,并且提供了基本错误处理方法以确保程序能够优雅地处理各种意外情形。通过简洁明快、易读易懂、实操性强等特点使得该方法非常适合开发者或系统管理员快速集成至自动化工具链之内进行日常运维任务之需求满足。
240 18
|
3月前
|
安全 Linux Shell
Linux系统提权方式全面总结:从基础到高级攻防技术
本文全面总结Linux系统提权技术,涵盖权限体系、配置错误、漏洞利用、密码攻击等方法,帮助安全研究人员掌握攻防技术,提升系统防护能力。
286 1
|
3月前
|
监控 安全 Linux
Linux系统提权之计划任务(Cron Jobs)提权
在Linux系统中,计划任务(Cron Jobs)常用于定时执行脚本或命令。若配置不当,攻击者可利用其提权至root权限。常见漏洞包括可写的Cron脚本、目录、通配符注入及PATH变量劫持。攻击者通过修改脚本、创建恶意任务或注入命令实现提权。系统管理员应遵循最小权限原则、使用绝对路径、避免通配符、设置安全PATH并定期审计,以防范此类攻击。
1014 1