如何构建一个单独的内核模块?

linux-source-...在配置文件/boot/config-3.4-trunk-686-pae中禁用了一个模块,因此它不是linux-image-...的一部分(这是在Debian上,但解决方案应该对于Ubuntu也是相同的,对吗?),例如。
# CONFIG_CAN_PEAK_USB is not set

如何编译只有内核模块,以便与分发的内核一起使用?
相应的linux-source-...软件包已经安装、解压缩并链接到/usr/src/linux。/boot/config-3.4-trunk-686-pae被复制到/usr/src/linux/.config,并进行了修改。
CONFIG_CAN_PEAK_USB=m

使用

make
make modules

可以编译内核和所有模块。但是如何只编译特定的单个模块呢?
(注意:在此之前还需要编译内核,否则会出现以下错误:no symbol version for module_layout

请将此问题关闭为14627的重复问题。用户'Radu C'的回答解决了这个问题。 - mab
你在执行modprobe之前尝试过depmod -a吗? - Nadia
1请考虑阅读以下文章:https://stackoverflow.com/questions/8744087/how-to-recompile-just-a-single-kernel-module/44204152#44204152 - Oleg Kokorin
4个回答

我遇到了同样的问题。我猜你不仅需要复制.config文件,还需要复制Module.symvers文件。
我编译ft1000模块的步骤(在Debian Wheeze 7.1.0上运行,内核版本为3.2.0-4-686-pae):
aptitude install linux-headers-3.2.0-4-686-pae
aptitude install linux-source-3.2
cd /usr/src/
tar xjf linux-source-3.2.tar.bz2
cd /usr/src/linux-source-3.2
cp ../linux-headers-3.2.0-4-686-pae/Module.symvers .
make oldconfig # it copies .config to ./
vi .config # enable ft1000 module: CONFIG_FT1000=m
make prepare # setup FT1000 as module
make modules_prepare
make SUBDIRS=scripts/mod
make SUBDIRS=drivers/staging/ft1000/ft1000-usb modules
cp drivers/staging/ft1000/ft1000-usb/ft1000.ko /lib/modules/3.2.0-4-686-pae/kernel
/drivers/staging/
depmod
modprobe ft1000

9我不确定SUBDIRS仍然正确。对我来说它被忽略了。在阅读https://www.kernel.org/doc/Documentation/kbuild/modules.txt后,我尝试使用`make M=/path/to/module`,似乎起作用了。 - harmic
我正在尝试修改一个不同的模块(只是向现有模块添加USB ID),当我编译它时,没有出现错误,但是当我插入它时,却出现了无效的模块格式,为什么?! - Zibri

从顶级源目录中,只需将路径指定为模块名称或模块目录,例如:
make drivers/net/can/usb/peak_usb/

或者以一个更简单的例子来说明(Intel e1000 以太网驱动程序):
make drivers/net/ethernet/intel/e1000/e1000.ko

只是执行: make drivers/net/can/usb/peak_usb/pcan_usb.ko 只编译了 pcan_usb.o。执行 make drivers/net/can/usb/peak_usb/ && make drivers/net/can/usb/peak_usb/pcan_usb.ko 进行编译,但 insmod 报错 错误:无法插入模块 drivers/net/can/usb/peak_usb/peak_usb.ko:无效的模块格式。dmesg: peak_usb: no symbol version for module_layout - mab
你正在运行那个特定的内核吗?你已经编译过内核了吗?请尝试使用modprobe命令。 - ish
我正在运行打包的内核。编译完整的内核是可以的,但我想尝试不编译完整的内核,只编译特定的内核模块。是否有一个make目标可以“准备”单个模块的编译?modprobe显示相同的错误。 - mab
6根据stackoverflow的说法,你只需要使用make modules SUBDIRS=drivers/net/can/usb/peak_usb或者其他子目录即可。 这在这里运行得很好。 - Treviño
如果你发现新驱动程序仍在使用旧版本,有时在构建之前需要运行 make clean && make mrproper - fkpwolf

就像这样简单:(这个例子说明了ft1000驱动程序,如果不是瞬间完成,也只需要几分钟)
cd /usr/src/kernel-sources
make SUBDIRS=drivers/staging/ft1000/ft1000-usb modules
# Enable the ft1000 module: CONFIG_FT1000=m  on the config with 
make xconfig # or "make menuconfig" then save
make prepare
make modules_prepare
make SUBDIRS=scripts/mod
make SUBDIRS=drivers/staging/ft1000/ft1000-usb modules
make SUBDIRS=drivers/staging/ft1000/ft1000-usb modules_install

你可以在depmod之后使用modprobe加载模块。
注意:根据模块的依赖关系,您可能需要重新构建整个内核。

因为这种方法可以用于任何make项目,而不仅限于Linux内核。 - Alireza Mohamadi

要在目录中构建最终的模块映像,您可以在make命令中使用M=参数: make M=drivers/usb/serial
这将在该目录中构建所有所需的文件,并链接最终的模块映像。
要在内核树中仅构建特定的文件,请将其作为参数传递给make命令: make drivers/usb/serial/visor.ko
构建系统将为visor.ko内核模块构建所有所需的文件,并进行最终的链接以创建模块。