Linux 如何仅重新编译单个内核模块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8744087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to recompile just a single kernel module?
提问by user1056635
Usually kernel source are stored in /usr/src/linux-2.6.x/
.
To avoid to recompile the entire kernel if I modify a module's source, how can I recompile just that module?
通常内核源代码存储在/usr/src/linux-2.6.x/
. 为了避免在修改模块的源代码时重新编译整个内核,我该如何只重新编译该模块?
回答by Niklas B.
Switch to the root directory of your source tree and run the following command:
切换到源代码树的根目录并运行以下命令:
$ make modules SUBDIRS=drivers/the_module_directory
And to install the compiled module:
并安装编译模块:
$ make modules_install SUBDIRS=drivers/the_module_directory
Note:As lunakid mentions, the latter command might notbuild the module first, so be careful.
注意:正如 lunakid 提到的,后一个命令可能不会先构建模块,所以要小心。
回答by Szilárd Pfeiffer
You can pass the path to the module name or module directory to make as parameter.
您可以将路径传递到模块名称或模块目录以作为参数。
make path/to/the/module/itself.ko
make path/to/the/module/directory/
回答by Oleg Kokorin
since kernel versions 3.x.xand 4.x.xthe procedure gets more complicated (but there is a hope, so keep reading):
由于内核版本3.xx和4.xx,过程变得更加复杂(但有希望,所以请继续阅读):
make distclean
if you haven't just cloned a new source but used to build other modules before- create new folder somewhere for the module source (example: extra) and copy only source files (from the kernel source or somewhere else) related to the module needed to be build into this new folder
- copy
/boot/config-`uname -r`
file (example: /boot/config-4.8.0-46-generic) into kernel source folder file .configand runmake oldconfig
. if the module belongs to the kernel source, verify if it has been enabled by callingmake menuconfig
, by searching for the module and applying letter 'M' if necessary - kernel source root Makefilehas to be altered with exact version components matching the current running one (you may verify with
make kernelversion
if it matches exactly theuname -r
one) - there is been a strong suggestion to build scripts also before with
make scripts
make prepare
andmake modules_prepare
has to be executed prior to the actual module build- Module.symvershas to be copied from the target system headers folder corresponding running kernel version
/usr/src/linux-headers-`uname -r`/Module.symvers
(example: /usr/src/linux-headers-3.13.0-117-generic/Module.symvers) into the newly created module source files folder prepared for the module compilation (the one extrain example). - create new Makefileinside module source compilation folder having following line:
obj-y += <module_source_file_name>.o
or if the source code is complicated, use the guidance from here - only then it's the right time to build module with
make -C <kernel source path> M=the_module_directory
(example:make -C . M=extra/
) - Use command
modprobe --dump-modversion <module_name>.ko
to verify CRC match between module exporting API and corresponding values in Module.symvers. in case of failure use commandmodinfo <module_name>.ko
instead - verify if kernel.releasefile content match exactly the one from headers of the current running version. if you'll discover +appended at the end, it means you've been compiling git clonned source and your experimental modifications caused build system to compromise the localversion string by adding +at the end.
- if only +has been discovered at the tail of kernel.releasestored value and it's a mismatch with the exact name of the target running kernel,
make distclean
如果你之前不只是克隆了一个新的源,而是用来构建其他模块- 在某处为模块源(例如:extra)创建新文件夹,并仅将与需要构建的模块相关的源文件(来自内核源或其他地方)复制到此新文件夹中
- 将
/boot/config-`uname -r`
文件(例如:/boot/config-4.8.0-46-generic)复制到内核源文件夹文件.config并运行make oldconfig
. 如果模块属于内核源代码,请通过调用make menuconfig
、搜索模块并在必要时应用字母“M”来验证它是否已启用 - 内核源根Makefile必须使用与当前正在运行的组件匹配的确切版本组件进行更改(您可以验证它
make kernelversion
是否完全匹配uname -r
) - 之前也有强烈建议使用以下命令构建脚本
make scripts
make prepare
并且make modules_prepare
必须在实际模块构建之前执行- Module.symvers必须从目标系统 headers 文件夹中对应运行的内核版本
/usr/src/linux-headers-`uname -r`/Module.symvers
(例如:/usr/src/linux-headers-3.13.0-117-generic/Module.symvers)复制到新创建的准备好的模块源文件文件夹中用于模块编译(示例中额外的一个)。 - 在具有以下行的模块源编译文件夹中创建新的Makefile:
obj-y += <module_source_file_name>.o
或者如果源代码很复杂,请使用此处的指导 - 只有它的合适的时间来构建模块
make -C <kernel source path> M=the_module_directory
(例如:make -C . M=extra/
) - 使用命令
modprobe --dump-modversion <module_name>.ko
来验证模块导出 API 和Module.symvers 中相应值之间的 CRC 匹配。在失败的情况下使用命令modinfo <module_name>.ko
代替 - 验证kernel.release文件内容是否与当前运行版本的头文件内容完全匹配。如果您发现在末尾附加了+,则表示您一直在编译 git 克隆源,并且您的实验性修改导致构建系统通过在末尾添加+来破坏 localversion 字符串。
- 如果在kernel.release存储值的尾部只发现+并且它与目标运行内核的确切名称不匹配,
the solution would be following:
解决方案如下:
commit all your changes, force release tag to shift above your modifications with the git tag -a <tag version> -f
command. then rebuild your modules from step 8
提交所有更改,使用git tag -a <tag version> -f
命令强制释放标签移动到您的修改之上。然后从步骤 8 重建模块
回答by rocky
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module
https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module
回答by siz
In case you have edited just code in drivers/net/ethernet/intel/e1000/e1000_main.c file
如果您只编辑了drivers/net/ethernet/intel/e1000/e1000_main.c 文件中的代码
Build the module.
构建模块。
make scripts prepare modules_prepare
make -C . M=drivers/net/ethernet/intel/e1000
Install the module.
安装模块。
cp drivers/net/ethernet/intel/e1000/e1000.ko /lib/modules/5.1.15/kernel/drivers/net/ethernet/intel/e1000/e1000.ko