为什么 dkms 在 Debian 上安装失败并出现“不兼容的指针类型”,而在 Ubuntu 上却不然?

为什么 dkms 在 Debian 上安装失败并出现“不兼容的指针类型”,而在 Ubuntu 上却不然?

我的系统是 Intel nuc (NUC6CAYH),运行 Debian 11。我正在尝试安装内核模块以通过 acpi 与可编程 LED 交互。我已在 Ubuntu 20.04 LTS 下的相同系统上成功安装此模块,但在 Debian 11 上安装失败。

司机在这里:https://github.com/milesp20/intel_nuc_led

我的安装过程:

git clone https://github.com/milesp20/intel_nuc_led.git
cd intel_nuc_led
sudo make dkms-deb
sudo dpkg -i /var/lib/dkms/intel-nuc-led/1.0/deb/intel-nuc-led-dkms_1.0_all.deb

最后一个命令的输出:

Selecting previously unselected package intel-nuc-led-dkms.
(Reading database ... 89355 files and directories currently installed.)
Preparing to unpack .../intel-nuc-led-dkms_1.0_all.deb ...
Unpacking intel-nuc-led-dkms (1.0) ...
Setting up intel-nuc-led-dkms (1.0) ...
Removing old intel-nuc-led-1.0 DKMS files...

------------------------------
Deleting module version: 1.0
completely from the DKMS tree.
------------------------------
Done.
Loading new intel-nuc-led-1.0 DKMS files...
Building for 5.10.0-10-amd64
Building for architecture x86_64
Building initial module for 5.10.0-10-amd64
Error! Bad return status for module build on kernel: 5.10.0-10-amd64 (x86_64)
Consult /var/lib/dkms/intel-nuc-led/1.0/build/make.log for more information.
dpkg: error processing package intel-nuc-led-dkms (--install):
 installed intel-nuc-led-dkms package post-installation script subprocess returned error exit status 10
Errors were encountered while processing:
 intel-nuc-led-dkms

并且,查看该日志文件:

DKMS make.log for intel-nuc-led-1.0 for kernel 5.10.0-10-amd64 (x86_64)
Tue 21 Dec 2021 02:26:47 PM EST
make: Entering directory '/usr/src/linux-headers-5.10.0-10-amd64'
  CC [M]  /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.o
/var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c: In function ‘init_nuc_led’:
/var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c:475:75: error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
  475 |         acpi_entry = proc_create("nuc_led", nuc_led_perms, acpi_root_dir, &proc_acpi_operations);
      |                                                                           ^~~~~~~~~~~~~~~~~~~~~
      |                                                                           |
      |                                                                           struct file_operations *
In file included from /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c:36:
/usr/src/linux-headers-5.10.0-10-common/include/linux/proc_fs.h:109:122: note: expected ‘const struct proc_ops *’ but argument is of type ‘struct file_operations *’
  109 | struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct proc_ops *proc_ops);
      |                                                                                                   ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [/usr/src/linux-headers-5.10.0-10-common/scripts/Makefile.build:285: /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.o] Error 1
make[1]: *** [/usr/src/linux-headers-5.10.0-10-common/Makefile:1846: /var/lib/dkms/intel-nuc-led/1.0/build] Error 2
make: *** [/usr/src/linux-headers-5.10.0-10-common/Makefile:185: __sub-make] Error 2
make: Leaving directory '/usr/src/linux-headers-5.10.0-10-amd64'

因此,回顾一下,它在使用 kernel 的 Ubuntu 20.04 LTS 上可以正常构建和安装5.4.0-91,但在使用 kernel 的 Debian 11 上失败5.10.0-10

谢谢。

答案1

Linux 内核 v5.6 的重大变化

这涉及到Linux 内核的变化至于 5.6 版本中引入的 proc_create API,但庆幸的是,使用此后发布的版本构建它所需的代码更改非常少。

简而言之,proc_create 的第四个参数从 更改struct file_operations *proc_fopsstruct proc_ops *proc_ops。更深入地观察,我们可以看到它owner完全删除了结构体的成员,并将readandwrite成员重命名为proc_readand proc_write

要在您的内核上进行此构建,请打开 nuc_led.c 文件并替换第 446-450 行使用以下代码片段(或继续阅读此响应的下一部分,获取补丁文件的链接,其中包含这些更改以及模块的构建系统和 DKMS 配置的其他更改):

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
static struct proc_ops proc_acpi_operations = {
    .proc_read     = acpi_proc_read,
    .proc_write    = acpi_proc_write,
};
#else
static struct file_operations proc_acpi_operations = {
    .owner    = THIS_MODULE,
    .read     = acpi_proc_read,
    .write    = acpi_proc_write,
};
#endif

进一步观察

具体而言,关于这个引用的用例,而不是内核版本 5.6 中的重大更改的更广泛问题,这个答案也可能有助于提供解决方案,我对问题中的链接存储库有一些额外的观察,即:

  1. 它有打开拉取请求它以与我自己的解决方案类似的方式解决这个问题,多年来甚至没有存储库所有者的评论,这让我得出结论:
  2. 该模块实际上是废弃软件,并且(最关键的是),
  3. 它涉及到有关 DKMS 系统及其配置的几种已知的不良做法。

审查生成文件以及相应的dkms.conf存储库中的文件让我得出了一个初步结论,即除了用于启动正在运行的系统的内核版本之外,它无法正确构建多个内核版本(尽管我很懒,在继续进行下面提供的编辑之前未能测试我的假设) 。它们已在 Kubuntu 21.10“Impish Indri”上进行了测试,并在 v5.15 和 v5.16 内核上成功构建。我已将它们合并为通过 GitHub Gist 共享的补丁文件因此可以使用以下命令轻松地将它们应用到存储库的本地克隆中curl https://gist.githubusercontent.com/RogueScholar/02624d2e8a6d9e286dbece73f48106db/raw/f6c0b1e82f970f2c3c74c5f91ec42059ba1e8f13/Add-conditional-for-proc_create-API-changes-in-kernel-5.6+.patch | git apply -v --index

相关内容