【问题标题】:How to recompile just a single kernel module?如何只重新编译单个内核模块?
【发布时间】:2012-02-03 08:54:12
【问题描述】:

通常内核源代码存储在/usr/src/linux-2.6.x/。 为避免在修改模块源代码时重新编译整个内核,如何仅重新编译该模块?

【问题讨论】:

    标签: linux makefile linux-kernel gnu-make kernel-module


    【解决方案1】:

    切换到源代码树的根目录并运行以下命令:

    $ make modules SUBDIRS=drivers/the_module_directory
    

    并安装编译后的模块:

    $ make modules_install SUBDIRS=drivers/the_module_directory
    

    注意:正如 lunakid 所提到的,后一个命令可能不会先构建模块,所以要小心。

    【讨论】:

    • (只要确保你在树根中运行它,不像我。;))
    • @lunakid 好点 ;) 虽然应该很清楚 SUBDIRS 与 CWD 相关:P
    • 这绝对清楚,但后来我发现自己最终还是坐在了 wacom 驱动程序目录中。 :) 只是没有看我的脚步。另外,您能否在答案中添加它也可以安装相同的方式,只需输入make modules_install SUBDIRS=...。这几乎可以肯定是下一步,并且可能不会立即变得微不足道(即使看起来如此,例如,在我花了几分钟谷歌搜索它是徒劳的...... :) )。谢谢,干杯!
    • @lunakid 完成。我假设 modules_install 也会构建,所以它实际上是一个一步过程
    • +1,谢谢。至于构建+安装:似乎不是:不幸的是,如果这确实是它的感觉的话,它只是自欺欺人:安装驱动程序/输入/触摸屏/wacom_w8001.ko cp:无法统计“驱动程序/输入/触摸屏/wacom_w8001.ko”:没有这样的文件或目录 DEPMOD 3.4.34-x61t`(仍然运行 DEPMOD,这就是我不确定的原因。)
    【解决方案2】:

    由于内核版本 3.x.x4.x.x 程序变得更加复杂(但有希望,所以请继续阅读):

    1. make distclean 如果您之前没有克隆过新的源代码,而是用于构建其他模块
    2. 在某处为模块源创建新文件夹(例如:extra) 并仅将与需要构建的模块相关的源文件(来自内核源代码或其他地方)复制到这个新文件夹中
    3. /boot/config-`uname -r`文件(例如:/boot/config-4.8.0-46-generic)复制到内核源文件夹文件.config并运行make oldconfig .如果模块属于内核源,请通过调用make menuconfig 验证它是否已启用,通过搜索模块并在必要时应用字母“M”
    4. 内核源根目录 Makefile 必须使用与当前运行的组件匹配的确切版本组件进行更改(如果它与 uname -rone 完全匹配,您可以使用 make kernelversion 进行验证)
    5. 之前也强烈建议使用 make scripts
    6. make preparemake modules_prepare 必须在实际模块构建之前执行
    7. Module.symvers 必须从对应运行内核版本/usr/src/linux-headers-`uname -r`/Module.symvers 的目标系统头文件文件夹中复制(例如:/usr/src/linux-headers-3.13.0-117-generic/ Module.symvers)放入新创建的为模块编译准备的模块源文件文件夹(例如extra)。
    8. 在模块源代码编译文件夹中创建新的Makefile,包含以下行:obj-y += <module_source_file_name>.o 或者如果源代码复杂,请使用here 的指导
    9. 只有这样才是使用make -C <kernel source path> M=the_module_directory 构建模块的正确时机(例如:make -C . M=extra/
    10. 使用命令modprobe --dump-modversion <module_name>.ko 验证模块导出API 与Module.symvers 中对应值之间的CRC 匹配。如果失败,请改用命令modinfo <module_name>.ko
    11. 验证 kernel.release 文件内容是否与当前运行版本的标头中的内容完全匹配。如果您发现末尾附加了 +,则表示您一直在编译 git 克隆源,并且您的实验性修改导致构建系统通过添加 + 来破坏本地​​版本字符串最后。
    12. 如果在 kernel.release 存储值的尾部仅发现 + 并且它与目标运行内核的确切名称不匹配,

    解决方案如下:

    提交您的所有更改,使用git tag -a <tag version> -f 命令强制发布标签转移到您的修改之上。然后从第 8 步重建你的模块

    【讨论】:

    • 如果驱动程序有自己的子目录(例如linux/drivers/net/ethernet/natsemi),是否还需要将驱动程序代码复制到自己的“额外”文件夹中?
    【解决方案3】:

    您可以将要制作的模块名称或模块目录的路径作为参数传递。

    make path/to/the/module/itself.ko
    make path/to/the/module/directory/
    

    【讨论】:

    • make path/to/the/module/itself.ko 与 make 模块 SUBDIRS=directory/path 相比需要更多时间(3 分钟 vs 5 秒)。实际上,只是make path/to/directory似乎不起作用,它总是说“Nothing to be done”,但我确实修改了代码
    【解决方案4】:

    如果您只编辑了 drivers/net/ethernet/intel/e1000/e1000_main.c 文件中的代码

    构建模块。

    make scripts prepare modules_prepare
    make -C . M=drivers/net/ethernet/intel/e1000
    

    安装模块。

    cp drivers/net/ethernet/intel/e1000/e1000.ko /lib/modules/5.1.15/kernel/drivers/net/ethernet/intel/e1000/e1000.ko
    

    【讨论】:

      【解决方案5】:
      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-22
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        相关资源
        最近更新 更多