如何(配方)只构建一个内核模块?

我在Linux内核模块中有一个错误导致Ubuntu 14.04内核的存储过程(崩溃)。

这就是为什么我想编辑 / 修补只有那个单个内核模块的源来添加一些额外的调试输出。 有问题的内核模块是mvsas ,不需要启动。 出于这个原因,我认为没有必要更新任何initrd图像。

我已经阅读了很多信息(如下所示),并发现设置和构建过程混乱。 我需要两个食谱:

  1. 一次设置/配置构建环境
  2. 编辑此内核模块( .c.h )的任何源文件并将该编辑转换为新的内核模块( .ko )后要执行的步骤

使用的来源是:

  • 构建一个内核模块 – 谷歌搜索
  • 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
  • http://www.pixelbeat.org/docs/rebuild_kernel_module.html
  • 如何构建单个树内核模块?
  • http://ubuntuforums.org/showthread.php?t=1153067
  • http://ubuntuforums.org/showthread.php?t=2112166
  • http://ubuntuforums.org/showthread.php?t=1115593
  • 构建一个内核模块ubuntu – 谷歌搜索
  • ‘make + single + kernel + module’ – 问问Ubuntu
  • ‘make + kernel + module’ – 问问Ubuntu
  • 我的makefile导致:没有规则来制作目标`arch / x86 / tools / relocs.c’,这是必需的
  • ‘“无效的模块格式”’ – 询问Ubuntu
  • 驱动程序安装:编译较新内核的源代码
  • Modprobe:’无效的结节格式’,但在insmod之后仍然有效
  • “符号版本转储”“缺失” – Google搜索
  • https://stackoverflow.com/questions/9425523/should-i-care-that-the-symbol-version-dump-is-missing-how-do-i-get-one
  • https://askubuntu.com/questions/369051/where-can-i-find-the-corresponding-module-symvers-and-config-files-for-ubutunu
  • 尝试加载usbhid.ko时“没有module_layout的符号版本”
  • Linux头文件夹中的链接断开
  • ‘make modules_install’ – 问问Ubuntu
  • ‘modules_install’ – 问问Ubuntu
  • 自定义编译内核中的空构建目录
  • https://askubuntu.com/questions/444345/not-able-to-see-pr-info-output
  • https://askubuntu.com/questions/472496/in-which-directory-are-the-kernel-source-files-and-how-can-i-recompile-it
  • 如何编译和安装修补后的libata-eh.c文件?
  • ‘modules_install + depmod’ – 问问Ubuntu
  • modules_install depmod – 谷歌搜索
  • “make modules_install” – Google搜索
  • http://www.csee.umbc.edu/courses/undergraduate/CMSC421/fall02/burt/projects/howto_build_kernel.html
  • https://unix.stackexchange.com/questions/20864/what-happens-in-each-step-of-the-linux-kernel-building-process
  • https://wiki.ubuntu.com/KernelCustomBuild
  • 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搜索
  • http://ubuntuforums.org/showthread.php?t=1963515
  • ubuntu“make prepare”版本 – 谷歌搜索
  • https://stackoverflow.com/questions/8276245/how-to-compile-a-kernel-module-against-a-new-source
  • https://help.ubuntu.com/community/Kernel/Compile
  • 如何编译内核模块?
  • 如何将自定义驱动程序添加到我的内核?
  • https://askubuntu.com/questions/426549/compile-and-loading-kernel-module-without-compiling-the-kernel

构建自定义模块的方法可能需要分为三个部分。

安装一次

 $ 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/安装内核模块,如果您没有重命名分发内核模块文件,则不会覆盖分发模块。 在这个mvsas案例中,它也将运行depmod 。

 $ lsmod | grep mvsas 

如果这导致任何输出,则mvsas模块首先需要使用( modprobe -r mvsas )卸载。

 $ sudo modprobe -v mvsas 

这应该加载新的内核模块。

检查输出以validation是否正在加载/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 

笔记

  1. 可能的情况是,生成的.ko模块文件的大小(例如20倍)比Ubuntu分发的原始模块文件大; 在这种情况下, make prepare步骤可能已经创建了一个Linux开发人员调试内核配置文件,并且您正在从源目录构建。 您的-C参数可能无法按预期运行。
  2. 我已经看过其他命令的指南,比如make modules_preparemake M=scripts/mod但我不认为这些是必要的。
  3. 您可以使用Linux开发人员调试配置,将-C /lib/modules/$(uname -r)/build替换为-C /usr/src/linux-headers-$(uname -r)
  4. 在默认设置中, 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 ,然后该命令将为您提供源代码。 另请参阅此问题 ,其中还描述了执行此操作的GUI方法。