驱动程序模块是否自动加载和卸载?


15

在Ubuntu 14.04上,我发现当不插入外部无线适配器时,其模块rt2800usb仍显示在中lsmod

  1. 什么时候会自动加载驱动程序模块?是设备连接到计算机时还是操作系统启动时?

  2. 什么时候会自动卸载驱动程序模块?是设备断开与计算机的连接还是操作系统关闭时?

Answers:


13

当内核检测到新设备时,它将运行该程序modprobe并向其传递一个标识该设备的名称。大多数设备通过供应商和型号的注册号进行标识,例如PCIUSB标识符。该modprobe程序查询模块别名表以查找包含该特定设备的驱动程序的文件的名称。类似的原理适用于非硬件设备的驱动程序,例如文件系统和密码算法。有关更多详细信息,请参阅重启后Debian无法检测到串行PCI卡。/lib/modules/VERSION/modules.alias

一旦modprobe确定了哪个模块文件(.ko)包含请求的驱动程序,它将模块文件加载到内核中:模块代码被动态加载到内核​​中。如果模块加载成功,它将出现在列表中lsmod

当内核检测到新的可热插拔硬件时,例如当您连接USB外设时,模块会自动加载。操作系统还对枚举在启动过程中早期在系统上存在的所有硬件进行了检查,以便为启动时存在的外围设备加载驱动程序。

也可以使用modprobeor insmod命令手动请求加载模块。大多数发行版都包含一个启动脚本,用于加载中列出的模块/etc/modules。加载模块的另一种方式是,如果它们是模块的依赖项:如果模块A依赖于模块B,则modprobe A在加载A之前先加载B。

加载模块后,即使使用该驱动程序的所有设备都已断开连接,模块也将保持加载状态,直到明确卸载为止。很久以前,有一种机制可以自动卸载未使用的模块,但是,如果我没记错的话,udev出现在现场时,它已被删除。我怀疑自动模块卸载不是一个常见功能,因为可能需要自动卸载的系统大多数是台式计算机,它们无论如何都具有大量内存(按驱动程序代码的大小)。


谢谢。我还没有修改/etc/modulesrt2800usb在的输出中lsmod,这是否意味着自启动以来我已将其设备连接至计算机?
2015年

1
@Tim如果模块已加载,而您没有显式加载它,并且未在中列出/etc/modules,则可以,可能是模块加载的原因是某个时候存在该设备。
吉尔斯(Gilles)'所以

5

当系统通过初始RAM磁盘(即initrd)引导时,将加载模块。基本原理部分指出:

许多Linux发行版附带一个通用的Linux内核映像–发行版的开发人员专门创建该映像以在多种硬件上启动。此通用内核映像的设备驱动程序包含在可加载内核模块中,因为将许多驱动程序静态编译到一个内核中会导致内核映像更大,甚至太大而无法在内存有限的计算机上启动。这就提出了一个问题,即在引导时检测并加载安装根文件系统所需的模块,或者为此推断出根文件系统在哪里或什么。

与许多其他发行版一样,Ubuntu选择将每个设备驱动程序加载到此initrd中,而不管是否需要该驱动程序,也不管系统上是否存在该设备。正如Giles指出的那样,整个东西都被加载到RAM中,然后在启动时检测到已使用的模块,然后将未使用的模块从RAM中删除。使用此方法可确保Ubuntu始终在任何系统上启动,无论设置如何。Ubuntu正在使用微内核构造模仿单片内核。看到这个工作的原因


  1. 该模块rt2800usb将始终在启动时加载,因为该模块已包含在Gilles提到的initramfs中。initramfs是initrd的后继,因此始终以表示lsmod。请注意,您可以通过使用modprobe后跟模块名称的方式将新编译的模块插入内核。

作为测试,请在拔下无线适配器的情况下重新引导系统。如果一切顺利,该模块将不会在lsmod输出中列出,因为在启动过程中,由initramfs启动的检测过程和init系统在探测期间未找到该设备,并且已从RAM中删除了该模块。

  1. 要在系统运行时卸下模块,可以使用命令,例如rmmod或,modprobe -r后跟模块名称。在下次启动时,将重新加载该模块。往上看。在大多数情况下,模块不会动态移除,因为这将禁用热插拔,即,一旦模块被移除,使用该模块的设备在重新插入时将无法再次检测到。

为了从中删除模块lsmod,必须从通过不选择所选模块的情况下重新编译内核然后重建映像而创建的initramfs映像中将其删除。这样做会禁用所有对该模块的检测。


3
您将文件作为RAM磁盘的一部分加载到RAM中以及将模块加载(即动态链接)到正在运行的内核中感到困惑。模块是从initrd(现今从技术上说是initramfs)暂时加载到内存中而不是内核中的,但是在安装了真正的根目录之后,它们会从内存中删除。仅在检测到使用模块的设备时(少数例外),模块才会加载到内核中。
吉尔斯(Gilles)'所以

虽然我在这里表示同意,但是他所谈论的是卸载和加载一个模块,除非他选择重新配置Ubuntu RAM磁盘,否则这是无法完成的,不建议这样做,因为Ubuntu会在每次内核更新时选择将所有模块加载到RAM。每次都加载所有模块,但并非全部使用。
eyoung100

2
不,问题是关于将模块加载和卸载到内核中。您的原始答案或修订后的答案均未解决该问题。initramfs与该问题无关(或至多与外围无关)。
吉尔斯(Gilles)'“ SO-别再作恶了”

@Gilles这样好吗?
eyoung100'2015-4-21

1
@ eyoung100,我同意吉尔斯的观点。有关initramfs的讨论与该问题无关。通常,通过/sys在系统中实际找到的设备中枚举设备并加载驱动程序来加载模块。无论设备是在启动时存在还是在以后热插拔,都会发生这种情况。udev与initramfs / initrd相比,它有更多的作用,并且是否将全部,大多数或仅某些模块复制到initramfs中(与中的配置选项/etc/initramfs-tools/initramfs.conf无关)。
Celada's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.