如何单独编译Linux源代码中的驱动模块,比如NVMe驱动?

的确,在下载了Linux的源代码之后,Linux的Makefile提供个很完善灵活的编译方法,比如:make menuconfig 可以让我们非常方便的编译一个完整的内核。
但是,对于模块开发来说我们不需要编译一个完整的内核,而只更改对应模块中的部分代码。那么本文就一步一步的告诉你该怎么编译一个驱动模块,比如NVMe驱动(默认你已经下载了完整的Linux源代码)。

  1. 确定将要运行你新编译的模块的平台的Linux版本信息
uname -r

笔者的平台信息是:5.13.0-41-generic
如果你不确认主机平台的信息,而随意使用其它版本的Linux源码编译的话,那你在插入模块的时候会遇到以下错误:

insmod: ERROR: could not insert module nvme.ko: Invalid module format
  1. 根据运行平台的版本信息,将Linux源代码的版本切换到相应的版本
git reset --hard v5.13-rc7
  1. 进入到目标模块目录中,更改Makefile
cd drivers/nvme
# 在Makefile的最后添加以下命令
# 如果你是在运行平台上编译的,你可以直接用下面这一行,来动态的找到平台的Linux版本编译模块所需的目录
# KERNEL_DIR = /lib/modules/`uname -r`/build
KERNEL_DIR = /lib/modules/5.13.0-40-generic/build
MODULEDIR := $(shell pwd)

modules:
        make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
  1. 更改驱动模块源代码
# 在模块进入函数:nvme_init 中随便加入一句打印
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index a29b170701fc..a09ea1e5aa7e 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3317,6 +3317,7 @@ static int __init nvme_init(void)
        BUILD_BUG_ON(sizeof(struct nvme_create_sq) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64);
        BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2);
+       printk("This is new test driver");

        return pci_register_driver(&nvme_driver);
 }
  1. 编译,等待完成
make
  1. 安装
insmod host/nvme-core.ko
insmod host/nvme.ko

如果你在插入模块的时候遇到了这个问题:

ERROR: could not insert module host/nvme.ko: Unknown symbol in module

说明是依赖模块没有插入,你可以使用以下命令来获取依赖模块的名称,然后先把对应模块插入。

modinfo xxx.ko | grep depends
  1. 查看
dmesg

在这里插入图片描述

你可能感兴趣的:(Linux学习,linux,bash)