我使用特定品牌的电视调谐卡(TBS 技术),驱动程序不包含在内核中,因此每次更新内核后都必须重建。在安装昨天的内核更新到 4.4.0-143-generic 后,TBS 驱动程序无法构建,但如果我返回到 4.4.0-142-generic,它们就可以正常工作。运行 make 时会出现问题,特别是当它尝试构建名为 videobuf-dma-sg.o 的文件时,错误输出如下:
CC [M] /home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.o
/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c: In function 'videobuf_dma_init_user_locked':
/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:187:21: warning: passing argument 6 of 'get_user_pages' makes pointer from integer without a cast [-Wint-conversion]
rw == READ, 1, /* force */
^
In file included from include/linux/scatterlist.h:7:0,
from include/linux/dma-mapping.h:10,
from /home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:28:
include/linux/mm.h:1222:6: note: expected 'struct page **' but argument is of type 'int'
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
^
/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:188:9: warning: passing argument 7 of 'get_user_pages' from incompatible pointer type [-Wincompatible-pointer-types]
dma->pages, NULL);
^
In file included from include/linux/scatterlist.h:7:0,
from include/linux/dma-mapping.h:10,
from /home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:28:
include/linux/mm.h:1222:6: note: expected 'struct vm_area_struct **' but argument is of type 'struct page **'
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
^
/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:185:8: error: too many arguments to function 'get_user_pages'
err = get_user_pages(current, current->mm,
^
In file included from include/linux/scatterlist.h:7:0,
from include/linux/dma-mapping.h:10,
from /home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.c:28:
include/linux/mm.h:1222:6: note: declared here
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
^
scripts/Makefile.build:291: recipe for target '/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.o' failed
make[3]: *** [/home/backend/Drivers/linux-tbs-drivers/v4l/videobuf-dma-sg.o] Error 1
Makefile:1454: recipe for target '_module_/home/backend/Drivers/linux-tbs-drivers/v4l' failed
make[2]: *** [_module_/home/backend/Drivers/linux-tbs-drivers/v4l] Error 2
make[2]: Leaving directory '/usr/src/linux-headers-4.4.0-143-generic'
Makefile:51: recipe for target 'default' failed
make[1]: *** [default] Error 2
make[1]: Leaving directory '/home/backend/Drivers/linux-tbs-drivers/v4l'
Makefile:26: recipe for target 'all' failed
make: *** [all] Error 2
我基本上是按照“配方”来构建这些驱动程序的,所以我不知道实际的问题是什么,也不知道如何解决它。我不知道这是内核这个特定版本中的错误,还是发生了一些变化,导致驱动程序永远无法重建。我希望也许有比我更了解从源代码构建的好心人能给我一些线索,告诉我这里发生了什么,更重要的是,我可能需要做些什么来修复它。使用以前的 4.4.0-142-generic 内核时,Make 运行良好,并且没有错误地完成。那么我想知道是什么改变了?
答案1
改变的是 mm.h 文件的 get_user_pages() 接口。对基本内核代码的这一更改(1 月)最终影响到了 4.4.0-143 Ubuntu 内核版本。它给 Nvidia 驱动程序和一些 vm 驱动程序带来了各种麻烦,但它们已被重写。其他驱动程序,例如您的驱动程序或英特尔计算棒的 HDMI 音频驱动程序(位于 oem-hdmi-audio-dkms_0.1_all.deb 中),可能会或可能不会被重写。基本上您有三个选择:
- 继续使用 4.4.0-142 内核。放弃所有未来的内核补丁——除非您的驱动程序被重写,否则 4.4 系列对您来说已经过时了。请就此事联系卡供应商,他们可能有新的驱动程序。
- 自己重写驱动程序。这可能不是太糟糕,看起来这个接口在过去已经发生了变化,而当前的只是撤销了一些功能。除非您有一些内核代码经验,否则不要尝试。如果安全性和使用该卡对您来说很重要,也许可以聘请第三方开发人员来修复驱动程序。
- 花时间寻找具有驱动程序支持的更高内核。HDMI 音频已在更高版本的内核(如 4.18)中得到修复,因此也许您可以升级操作系统/内核。再次与卡的供应商核实,他们可能知道哪些更高版本的内核包含可用的驱动程序(如果有)。
有些机器在某个地方崩溃了,所以有人认为更改 LTS 内核接口是可以接受的。我个人认为他们错了,但我又有什么资格说呢。这种改变是 Canonical 的上游,所以它被认为是一个功能,而不是一个错误,而且不太可能被改变,因为一些旧的驱动程序不再起作用了。
答案2
对于其他试图解决此特定问题的人,可以使用 CrazyCat 提供的用户名修复此问题的 TBS 驱动程序补丁/更新。还有一个TBS 驱动程序和软件更新论坛中对此问题的讨论。