Linux kernel 将内核内置模块替换为可加载模块

Linux kernel 将内核内置模块替换为可加载模块,linux-kernel,linux-device-driver,kernel-module,device-tree,Linux Kernel,Linux Device Driver,Kernel Module,Device Tree,我开发了一个内核模块,将nf4标记作为字符设备进行管理 我在内核之外开发了这个模块,并在开发阶段将其编译为可加载内核模块(即ko)进行了测试 一旦驱动程序运行正常且足够稳定,我就使用补丁将其插入到linux内核源代码(v4.9.30)中,因此它是作为内核的一部分构建的 在这里,我所处的情况是,内核在引导时对模块进行加载探测,因为它是内置的,并且出现在设备树中 现在,我想尝试对驱动程序进行一些改进,我不想直接在内核中实现这些更改 因此,我希望将驱动程序代码集成到linux内核中,但不要在引导时插入

我开发了一个内核模块,将nf4标记作为字符设备进行管理

我在内核之外开发了这个模块,并在开发阶段将其编译为可加载内核模块(即ko)进行了测试

一旦驱动程序运行正常且足够稳定,我就使用补丁将其插入到linux内核源代码(v4.9.30)中,因此它是作为内核的一部分构建的

在这里,我所处的情况是,内核在引导时对模块进行加载探测,因为它是内置的,并且出现在设备树中

现在,我想尝试对驱动程序进行一些改进,我不想直接在内核中实现这些更改

因此,我希望将驱动程序代码集成到linux内核中,但不要在引导时插入。 为此,我刚刚用
status=“disable”更改了驾驶员的状态字段
进入设备树,实际上在引导时不再插入模块

但是,我无法插入已修改的可加载模块。我在插入时出现了一个
ENODEV
,这是由于探测函数中没有找到平台设备

我不明白的是,除了状态字段值之外,设备树没有被更改,为什么平台设备没有被找到


编辑:添加有关情况的精确性

在进一步探索之后,我必须确定,我甚至没有进入回调
nf4\u探测

在检查了v4.9.30内核源代码中的
平台\u驱动程序\u probe
实现(请参阅)之后,错误似乎来自这里:

if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
    retval = -ENODEV;
通过从命令行检查设备树,我可以看到设备被定义为目录
/proc/device tree/nf4tag
存在,并且填充了与设备树对应的值


编辑:在@sawdust的答案后添加问题目的的精确性

我显然误解了
status=disable
意味着设备在硬件配置上根本不存在。虽然只是描述了weither,但司机是否应该被调查

为了使我的目标更明确,我确实将驱动程序编码为适当的模块,并将其编译为我正在使用的内核的可加载模块

然而,我不想重新编译内核来测试我所做的每一个更改。因此,我的目标是只重新编译.ko,直到我的修改完成,然后,一旦一切都完成了,使用补丁将这些修改添加到内置模块中

通过这种工作方式,我可以重建.ko并将其插入目标平台,而不是为每次修改重新编译内核

因此,我的问题应该是:

如何用可加载模块替换内置模块,而无需重新编译内核以禁用内置模块?

除了禁用编译到内核上的内置模块外,可能没有其他解决方案

我不明白的是,除了状态字段值之外,设备树没有被更改,为什么平台设备没有被找到

您似乎误解了
status=“disable”
属性的实际含义。
除了意味着内核应该“在引导时不插入”外,禁用的节点意味着设备根本不是当前硬件配置的一部分。
驱动程序,无论是内置的还是可加载的模块,都不需要探测,因为它已被当前配置禁用

如果希望驱动程序(无论是内置的还是可加载的模块)处于当前配置中,则在其设备树节点中具有
status=“ok”
属性

设备树用于描述内核的当前硬件配置。
不要尝试使用设备树来控制可加载模块(因为它不能)

在这里,我所处的情况是,模块在内核引导时被加载,因为它是内置的,并且出现在设备树中

这种说法毫无意义,因为您似乎同时将驱动程序描述为内置模块和可加载模块。
无需“加载”内置驱动程序即可调用其探测例程。
因为驱动程序既可以是内置的,也可以是可加载的,“加载”和“探测”是两个不同的阶段,不应该混为一谈

因此,我希望将驱动程序代码集成到linux内核中,但不要在引导时插入

您似乎将Linux内核的概念与源代码树混为一谈。
“集成到linux内核中的驱动程序代码”通常被解释为一个内置驱动程序,即驱动程序链接到启动时加载的内核映像中并作为内核映像的一部分。
而存储在内核源代码树中的驱动程序代码不必指定它是内置模块还是可加载模块。许多驱动程序(和其他类型的模块)都可以构建为其中之一,而构建配置指定了哪个驱动程序

如果希望驱动程序是可加载模块,则(而不是更改设备树):

a。您需要将驱动程序编码为适当的模块
B您需要修改Kconfig文件,以便在内置或可加载模块(即
tristate
bool
选择规范)之间进行选择。
C配置内核以将驱动程序构建为可加载模块


作为可加载模块并在设备树中定义的设备驱动程序仍然可以在引导期间自动加载和探测。 您可能必须使用模块黑名单来防止这种情况


**增编**

如何用可加载的模块替换内置模块,而无需重新编译内核以禁用内置模块

你不能。这就是为什么Kconfig强迫你