当前位置: 首页 > 科技观察

如何加载-卸载Linux内核模块

时间:2023-03-16 23:54:26 科技观察

查找并加载内核模块以修复外围问题。本文来自LinuxinAction的第15章,由Manning出版。Linux使用内核模块来管理硬件外围设备。让我们看看它是如何工作的。正在运行的Linux内核是您不想破坏的东西之一。毕竟,内核是驱动计算机所做的一切的软件。考虑到必须在运行的系统上同时管理许多细节,最好让内核以尽可能少的干扰来完成它的工作。但是,如果对您的计算环境进行任何微小的更改都需要重新启动整个系统,那么插入新的网络摄像头或打印机可能会严重扰乱您的工作流程。每次添加设备时都必须重新启动系统才能识别它,效率低下。为了在稳定性和可用性之间取得有效平衡,Linux隔离了内核,但允许您通过可加载内核模块(LKM)动态添加特定功能。如下图所示,您可以将模块视为软件的一部分,它告诉内核在哪里可以找到设备以及如何使用它。反过来,内核使设备对用户和进程可用并监视它们的操作。内核模块充当设备和Linux内核之间的翻译器。虽然您可以编写自己的模块来完全按照您喜欢的方式支持设备,但为什么要这样做呢?Linux模块库已经很强大了,通常不需要自己实现一个模块。大多数时候,Linux会在您不知情的情况下自动为新设备加载模块。但有时,出于某种原因,它不会自动发生。(你当然不希望那个招聘经理不耐烦地等着你的笑脸加入视频面试。)为了帮助你,你需要了解更多关于内核模块的知识,特别是如何找到真正需要的模块。运行你的外围设备,然后如何手动激活它。查找内核模块按照公认的惯例,内核模块是位于/lib/modules/目录中的具有.ko(内核对象)扩展名的文件。但是,在找到这些文件之前,您仍然需要进行选择。由于您需要从一个版本列表中选择要在启动时加载的版本,因此支持您选择的特定软件(包括内核模块)必须存在于某个地方。那么,/lib/modules/就是其中之一。您会发现包含每个可用Linux内核版本的模块的目录;例如:$ls/lib/modules4.4.0-101-generic4.4.0-103-generic4.4.0-104-generic在我的电脑上,运行内核是版本号最高的版本(4.4.0-104-generic),但不能保证这对您来说是一样的(内核经常更新)。如果您要在实时系统上使用模块进行一些工作,则需要确保找到正确的目录树。好消息:有一个万无一失的把戏。您可以使用始终指向所用内核名称的系统变量,而不是通过名称识别目录并希望找到正确的目录。您可以使用uname-r调用此变量(-r指定来自系统信息的正常显示的内核版本号):合并到您的文件系统参考中。例如,要导航到正确的目录,您需要将其添加到/lib/modules。要告诉Linux“uname”不是文件系统中的位置,请将uname部分括在反引号中,如下所示:$ls/lib/modules/`uname-r`buildmodules.aliasmodules.depmodules.softdepinitrdmodules。alias.binmodules.dep.binmodules.symbolskernelmodules.builtinmodules.devnamemodules.symbols.binmiscmodules.builtin.binmodules.ordervdso您可以在kernel/目录的子目录中找到大多数模块。花几分钟时间浏览这些目录,看看它们是如何排列的以及有哪些可用的。这些文件名通常可以让您了解它们是什么。$ls/lib/modules/`uname-r`/kernelarchcryptodriversfskernellibmmnetsoundubuntuvirtzfs这是查找内核模块的一种方法;实际上,这是一种快速的方法。但这不是唯一的方法。如果你想获得完整的集合,你可以使用lsmod列出所有当前加载的模块以及一些基本信息。此截断输出的第一列(太多而无法在此处列出)是模块名称,然后是文件大小和计数,然后是每个模块的名称:$lsmod[...]vboxdrv4546563vboxnetadp,vboxnetflt,vboxpcirt2x00usb245761rt2800usbrt2800lib942081rt2800usb[…]有多少个?好吧,让我们再次运行lsmod,但这次将输出通过管道传输到wc-l以查看有多少行:$lsmod|wc-l113这是加载的模块。总共有多少个?运行modprobe-c并计算行数将为我们提供以下数字:$modprobe-c|wc-l33350有33,350个可用模块!?看起来有人多年来一直致力于为我们提供软件来驱动我们的物理设备。注意:在某些系统上,您可能会遇到自定义模块,这些模块要么在/etc/modules文件中使用唯一条目引用,要么在/etc/modules-load.d/中间的配置文件中引用。这些模块很可能是本地开发项目的产物,可能涉及尖端实验。无论如何,了解您所看到的总是好的。这就是查找模块的方法。如果出于某种原因,它不会自行加载,您的下一个工作就是弄清楚如何手动加载非活动模块。手动加载内核模块在加载内核模块之前,逻辑上您必须确认它存在。在这样做之前,您需要知道它叫什么。要做到这一点有时需要魔法和运气的结合以及在线文档作者的辛勤工作。我将通过描述我前段时间遇到的一个问题来说明这个过程。一个晴朗的日子,出于某种原因,我笔记本电脑上的WiFi接口停止工作了。就这样。也许软件升级搞砸了。谁知道?我运行lshw-cnetwork并收到一条非常奇怪的消息:networkUNCLAIMEDAR9485WirelessNetworkAdapterLinux识别接口(AtherosAR9485)但将其列为无人认领。好吧,正如他们所说,“当事情变得艰难时,请在互联网上进行艰苦的搜索。”我用谷歌搜索了atherosar9linux模块,在五年前浏览一页又一页之前,甚至在十年的页面建议我自己编写一个模块或放弃之后,我终于发现(至少对于Ubuntu16.04)有一个工作模块。它的名字是ath9k。是的!战斗一触即发!向内核添加模块比听起来容易得多。要仔细检查它是否可用,请针对模块的目录树运行find,指定-typef以告诉Linux您正在寻找文件,然后附加字符串ath9k和一个星号以包括以您的字符串开头的所有文件:$find/lib/modules/$(uname-r)-typef-nameath9k*/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_common.ko/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k.ko/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_htc.ko/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_hw.ko再一步,加载模块:#modprobeath9k就这样。没有引导,没有大惊小怪。这是另一个示例,向您展示如何使用已经崩溃的运行模块。曾经有一段时间我使用罗技网络摄像头,在下一次系统启动之前,一个特定的软件使任何其他程序都无法访问摄像头。有时我需要在不同的应用程序中打开相机,但没有时间关闭并重新启动。(我运行了很多应用程序,启动后需要一些时间才能将它们全部准备好。)由于这个模块可能正在运行,所以使用lsmod搜索单词video应该会给我有关相关模块名称的提示。上,它比提示更好:用video这个词描述的唯一一个模块是uvcvideo(如下所示):$lsmod|grepvideouvcvideo901120videobuf2_vmalloc163841uvcvideovideobuf2_v4l2286721uvcvideovideobuf2_core368642uvcvideo,videobuf2_v4l2videodev1761284uvcvideo,v4l2_common,videobuf2_core,videobuf2_v4l2media245762uvcvideo,videodevIt'spossiblemyownactionsarecausingthecrash,IfiguredIcoulddigalittledeeperandseeif我可以以正确的方式解决问题。但事实证明你知道;有时您不关心理论,您只希望设备正常工作。所以我用rmmod杀死了uvcvideo模块并用modprobe重新启动它,一切都很好:#rmmoduvcvideo#modprobeuvcvideo再次:没有重新启动。没有其他后续影响。