问题描述
我在Linux内核模块中有一个错误,该错误会导致普通的Ubuntu 14.04内核崩溃(崩溃)。
这就是为什么我只想编辑/修补单个内核模块的源代码以添加一些额外的调试输出的原因。有问题的内核模块是mvsas
,不需要引导。因此,我看不到需要更新任何initrd映像。
我已经阅读了很多信息(如下所示),并发现设置和构建过程令人困惑。我需要两个食谱:
-
一次设置/配置构建环境
-
编辑此内核模块的任何源文件(
.c
和.h
)并将该编辑转换为新的内核模块(.ko
)后要做的步骤
已使用的来源是:
-
建立一个内核模块-Google搜索
-
http://www.linuxquestions.org/questions/linux-kernel-70/rebuilding-a-single-kernel-module-595116/
-
https://stackoverflow.com/questions/8744087/how-to-recompile-just-a-single-kernel-module
-
建立一个内核模块ubuntu-Google搜索
-
‘make +单+内核+模块’-询问Ubuntu
-
‘make + kernel + module’-问Ubuntu
-
My makefile results in: No rule to make target `arch/x86/tools/relocs.c’, needed
-
““无效的模块格式””-询问Ubuntu
-
“缺少符号版本dump” “is”-Google搜索
-
“no symbol version for module_layout” when trying to load usbhid.ko
-
‘make modules_install’-询问Ubuntu
-
‘modules_install’-询问Ubuntu
-
https://askubuntu.com/questions/444345/not-able-to-see-pr-info-output
-
How can I compile and install that patched libata-eh.c file?
-
‘modules_install +depmod’-询问Ubuntu
-
modules_install depmod-Google搜索
-
“ make modules_install”-Google搜索
-
http://www.csee.umbc.edu/courses/undergraduate/CMSC421/fall02/burt/projects/howto_build_kernel.html
-
http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html
-
http://www.linuxforums.org/forum/kernel/170617-solved-make-modules_install-different-path.html
-
“make prepare”-Google搜索
-
“make prepare”“ scripts /kconfig /conf –silentoldconfig Kconfig”-Google搜索
-
ubuntu “make prepare”版本-Google搜索
-
https://stackoverflow.com/questions/8276245/how-to-compile-a-kernel-module-against-a-new-source
最佳方案
构建自定义模块的方法可能需要分为三个部分。
设置一次
$ cd ~
$ apt-get source linux-source-3.13.0
我懒得复制mvsas特定的驱动程序源文件。只需将它们全部复制到当前工作目录即可。如果apt-get
导致出现有关缺少源URI的错误消息,请参阅底部的注释4。
$ cd linux-3.13.0
$ make oldconfig
$ make prepare
$ make scripts
这将准备一些构建内核模块所需的文件。
每个内核版本
$ apt-get install linux-headers-$(uname -r)
这将在/lib /modules中安装该内核版本的标头和Ubuntu内核配置文件。
$ cd ~/linux-3.13.0
$ cp -v /usr/src/linux-headers-$(uname -r)/Module.symvers .
这是为了防止在使用insmod或modprobe加载模块时出现消息“ module_layout没有符号版本”。
$ mv -v /lib/modules/$(uname -r)/kernel/drivers/scsi/mvsas/mvsas.ko /lib/modules/$(uname -r)/kernel/drivers/scsi/mvsas/mvsas.ko.backup
这将重命名原始(Ubuntu构建)内核模块,以确保将加载自定义的修补程序。
每次编辑
$ cd ~/linux-3.13.0/drivers/scsi/mvsas
$ nano mv_sas.h
$ nano mv_sas.c
这些是用于编辑的。
$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
这将使用存储在/lib/modules/$(uname -r)/
中的现有Ubuntu发行版中的内核配置来编译和构建内核模块.ko
文件。
$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
这将把内核模块安装在/lib/modules/$(uname -r)/extra/
中,以防万一您没有重命名分发内核模块文件,也不会覆盖分发模块。在这种情况下,它还将运行depmod。
$ lsmod | grep mvsas
如果这导致任何输出,则mvsas模块首先需要使用(modprobe -r mvsas
)进行卸载。
$ sudo modprobe -v mvsas
这应该加载新的内核模块。
检查输出以验证是否正在加载/lib/modules/.../extra/mvsas.ko
。
Modprobe错误:无法插入
在某些情况下,您可能会遇到modprobe: ERROR: could not insert 'xyz': Unknown symbol in module, or unknown parameter (see dmesg)
,而在详细的modprobe输出中,您会看到insmod
正在尝试从内核默认位置加载模块。例如:
# insmod /lib/modules/3.17.0-031700rc7-generic/kernel/drivers/scsi/pm8001/pm80xx.ko
modprobe: ERROR: could not insert 'pm80xx': Unknown symbol in module, or unknown parameter (see dmesg)
在这种情况下,您需要手动运行depmod并尝试再次加载该模块:
# depmod
# sudo modprobe -v mvsas
说明
-
可能的情况是,生成的
.ko
模块文件的大小要比Ubuntu分发的原始模块文件大很多(例如20倍)。在这种情况下,make prepare
步骤可能已经创建了Linux开发人员来调试内核配置文件,而您是从源目录进行构建的。您的-C
参数可能无法按预期运行。 -
我已经看到了其他命令的指南,例如
make modules_prepare
和make M=scripts/mod
,但是我认为这些对于这种情况不是必需的。 -
您可以通过将
-C /lib/modules/$(uname -r)/build
替换为-C /usr/src/linux-headers-$(uname -r)
来使用Linux开发人员调试配置 -
在默认设置中,
apt-get source linux-sources
将返回错误E: You must put some 'source' URIs in your sources.list
。要解决此问题,您可以通过取消注释第一行deb-src
(从中删除开头的#
)来修改文件/etc/apt/sources.list
。 Ubuntu 17.10的示例:deb-src http://ie.archive.ubuntu.com/ubuntu/ artful main restricted
。运行sudo apt-get update
,然后该命令将为您提供源。另请参见this question,其中也描述了用于执行此操作的GUI方法。