掌握内核模块与 Caldera

作者:David B. Nelson

您本不应该需要阅读这篇文章。Linux 内核模块的概念相当简单。不幸的是,编译、安装和使用模块所需的信息分散在多个 HOWTO、README 和 man 页面中。此外,需要修改的文件位于几个晦涩的目录中。

我最终编写了这个食谱式的方法来帮助我自己,以及您,入门。一旦您开始运行模块,您可以稍后深入研究细节。我在运行 Caldera Open Linux 1.1 的 X86 处理器上测试了这些材料,它与 Red Hat 4.2 非常接近。您在其他处理器和发行版上的效果可能会有所不同。

为什么要使用模块?它们让您可以编译一个小型、快速的内核,然后在需要时安装和删除设备驱动程序。如果没有模块,Linux 内核可能会变得臃肿,并类似于某个商业操作系统。

首先,我建议您编译一个基本内核,其中包括您的系统所有必要的功能,但不使用模块。我知道这听起来像是我们在倒退,但您不希望因为您搞砸了您的模块而失去启动能力。/usr/src/linux 中的 README 是您的指南,但基本上您执行命令

make mrproper; make xconfig

(或 menuconfigconfig)以包含所有需要的功能,然后运行

make dep; make clean; make zImage
将您的内核配置保存到一个名为 kernelconf.base 的文件中,以防您需要重新编译。xconfig 菜单会提示您保存和加载配置文件。如果您使用 menuconfig 或 config,则当前配置位于文件 /usr/src/linux/.config 中;将该文件复制到 kernelconf.base。如果您配置的内核过大,最终编译将失败。如果发生这种情况,请执行 make bzImage 而不是 zImage。您编译的内核将位于目录 /usr/src/linux/arch/i386/boot 中。

您可能在编译基本内核时犯了错误,所以不要扔掉旧内核。如果您正在运行 LILO,请将您的新内核重命名为 zImage.base 并将其复制到当前内核的位置,通常是 / 或 /boot。在 /etc/lilo.conf 中添加一个部分,让您可以在启动时选择默认内核或基本内核。我的 lilo.conf 显示在列表 1中,减去了一些注释行。

lilo.conf 的重要添加是最后一部分(#base kernel),它告诉 LILO 关于您的新内核。此外,请确保 lilo.conf 具有 prompttimeout 行。现在执行 lilo 然后重新启动。LILO 将暂停,给出提示 boot:。如果您按 TAB 键,您将获得 linuxbase 选项。输入 base,您的新内核将启动。您可能会收到关于错误的模块依赖关系的消息,但如果您的基本内核是完整的,那应该不会困扰您。如果出现问题,重新启动并输入 linux(或只是等待超时时间),您的旧内核将启动。在继续之前,请确保您有一个可用的基本内核。使用这种方法,您永远不会自断后路(或内核)。

如果您不使用 LILO,请为您的基本内核制作一个启动软盘。为此,插入软盘并执行 make zdisk,而不是 zImage

您现在可以编译一个针对您的系统量身定制的模块化内核了。执行与上面相同的命令,但是当您执行 xconfig 或 menuconfig 时,选择一些要编译为模块的功能。我建议您首先尝试选择锦上添花但非必要的模块添加到 zImage.base 中。不错的选择可能是打印机支持或软盘支持(除非您是从软盘启动)。将您的配置另存为 kernelconf.mod,以防您需要返回。另外,写下您正在编译哪些模块。为了确切知道编译了哪些模块,我建议您移动或删除您的旧模块(如果有)。Caldera 发行版包含很多模块。它们位于 /lib/modules/2.0.29 中。我将我的旧模块移动到子目录中,而不是删除它们,以防我需要备份。如果您使用的是不同版本的内核,您将拥有一个与您的发行版号对应的子目录,而不是子目录 2.0.29。

在执行 make zImage 之后,运行

make modules; make modules_install

和以前一样,转到(使用 cd)包含 zImage 的目录,将其重命名为 zImage.mod 并将其移动到 LILO 将查找它的目录。在 lilo.conf 的底部添加一个新的部分,让您可以使用标签 modules 启动此内核。如果您不使用 LILO,请制作另一个 zDisk。

现在,执行 depmod -a。这将创建 /lib/modules/2.0.29/modules.dep,模块实用程序需要它。接下来,执行以下命令

modprobe -c | grep -v '^path' > /etc/conf.modules

此命令设置模块实用程序需要的另一个文件。

现在重新启动,在启动提示符下选择标签 modules。接下来,移动到 /etc/modules/2.0.29 目录。它应该包含一个文件名很长的文件,如下所示

#1 Tue Feb 11 20:36:48 MET 1997.default

此文件在启动时由 /etc/rc.d/rc.modules 读取。[Debian 和 Red Hat 使用 /etc/modules—编者注。]它包含内核启动时加载的默认模块列表。您需要更改名称和内容。修复名称是困难的部分。在目录 /etc/modules/2.0.29 中,执行命令

FILE=`uname -v`.default
cp "#1 Tue"* "$FILE"
这个魔法创建了一个文件,其名称是 rc.modules 在启动时会查找的名称。该名称基于内核编译的时间。如果您重新编译内核,则必须重复这个魔法。

编辑此文件,使其仅包含您希望在启动时加载的模块。例如,它可能包含以下行

floppy
lp

这将加载软盘和打印机模块,假设您将它们编译为模块。为了让您的编辑器接受此文件,您可能需要在名称周围加上引号。

要手动加载模块,请执行 insmod,并将您的模块名称作为参数。要删除它,请执行 rmmod,并将您的模块名称作为参数。要查看当前加载了哪些模块,请执行 lsmod

最好的玩具是 kerneld;它可以根据需要自动加载和卸载模块。假设您已将软盘驱动程序编译为模块。通过执行 lsmod 检查它是否已加载。如果是,请通过执行 rmmod floppy 删除它。然后执行 kerneld。现在执行 mount /mnt/floppy(或任何挂载您的软盘的命令)。神奇的是,kerneld 会在需要时安装软盘模块。它还会卸载一段时间未使用的模块,使您的内核保持精简和高效。

您现在已经了解了足够的知识来尝试模块,而不会在启动时使内核崩溃。阅读模块迷你 HOWTO、kerneld 迷你 HOWTO 以及实用程序的 man 页面,成为真正的专家。祝您模块化愉快!

资源

Mastering Kernel Modules with Caldera
David B. Nelson (nelson@er.doe.gov) 在美国能源部管理科学研究。在此之前,他以理论等离子体物理学家的身份谋生。他开始在 IBM 650 上使用绝对机器语言进行编程,后来为了他的研究而升级到 CDC、DEC 和 Cray 机器,但他认为 Linux 是最有趣的。他和他的妻子 Kathy 住在华盛顿特区附近;他们喜欢网球、滑雪、帆船、音乐、戏剧和美食。
加载 Disqus 评论