无法将简单的内核模块添加到Yocto镜像中

5

目标

我想将Linux内核源代码中的触摸屏驱动程序添加到我的Yocto镜像中(此链接将带您到goodix.c)。基本上我需要将其添加为内核模块。

解决方案

我按照Yocto Mega手册中的合并树外模块部分进行操作。其中,我以他们的示例内核模块配方为基础,称之为hello-mod

  1. 在配方文件goodix-9271_0.1.bb中:RPROVIDES_${PN} = "kernel-module-goodix"
  2. layer.conf中:MACHINE_EXTRA_RDEPENDS += "kernel-module-goodix"

问题

我的构建过程在do_rootfs中一直失败,并显示以下错误:

Error: 
 Problem: package packagegroup-base-1.0-r83.imx6ul_var_dart requires packagegroup-machine-base, but none of the providers can be installed
  - package packagegroup-base-extended-1.0-r83.imx6ul_var_dart requires packagegroup-base, but none of the providers can be installed
  - package packagegroup-machine-base-1.0-r83.imx6ul_var_dart requires kernel-module-goodix, but none of the providers can be installed
  - conflicting requests
  - nothing provides kernel-module-goodix-5.4.3-imx6ul+gb40ccfdb73ea needed by goodix-9271-0.1-r0.imx6ul_var_dart
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

在阅读了这一部分的文档后,我无法理解的是为什么会出现这个错误。我尝试调整配方名称(删除内核模块前缀等),但似乎没有任何作用。到底是哪里出了问题呢?


来源

inherit module logging

# Driver for Goodix touchscreens
SUMMARY = "Generic driver for Goodix touchscreens"
DESCRIPTION = "Support for Goodix 1151, 5663, 5688, 917S, 9286, 911, 9271, 9110, 927, 928, 912, 9147, and 967 touchscreens"

# License
LICENSE = "GPL-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"

# Compatibility
COMPATIBLE_MACHINE = "(imx)"

# Package name 
RPROVIDES_${PN} = "kernel-module-goodix"

# Source
S = "${WORKDIR}"
SRC_URI = "file://Makefile \
           file://goodix.c"

# Functions

do_install() {
    bbwarn "Installing Goodix kernel module ..."
    bbwarn "KERNEL_SRC = ${KERNEL_SRC}"
    bbwarn "KERNEL_VERSION = ${KERNEL_VERSION}"
    bbwarn "WORKDIR = ${WORKDIR}"
    cd ${S}
    xz goodix.ko
    install --verbose -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/input/touchscreen
    install --verbose -m 0644 goodix.ko.xz ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/input/touchscreen
}

# Reference included files
FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/input/touchscreen/*"

编辑

  1. 这个错误基本上是说没有提供kernel-module-goodix-5.3.4-imx6ul+gb40ccfdb73ea。然而我并没有用那种方式命名我的包。所以为什么它要在那里寻找具有后缀5.3.4-imx6ul+gb40ccfdb73ea的东西呢?

编辑(解决方案)

对于任何不满意已接受答案的读者,请注意,我的原始配方出了问题,因为我没有将我的实际配方命名为"kernel-module-<name>.bb"。这实际上是所需的。


你尝试过使用 RPROVIDES_${PN} += 而不是 = 吗? - Barnabas Busa
1
很遗憾,它并没有帮助。 - Micrified
1
把内核打补丁并在内核配置中启用它不是更容易吗? - Oleksandr Kravchuk
@OleksandrKravchuk 或许是这样。但我真的想知道为什么它不能正常工作。值得一提的是,如果我采用类似修改我的编辑中显示后缀并将其添加到“RPROVIDES”的方法,我就可以构建它。但这似乎只是绕过其他地方的错误,而我想知道原因是什么。 - Micrified
@OleksandrKravchuk,此外,内核配置中没有这个驱动程序(至少在我的配置中不可用)。 - Micrified
2个回答

2

之前我创建了一个UART蓝牙驱动程序的配方,对我来说效果很不错,以下是这个配方:

#
# FNLINK BLUETOOTH 8822 KERNEL DRIVER
#

LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

SRC_URI = "file://uart_bt.zip"

S = "${WORKDIR}/bluetooth_uart_driver"

inherit module

EXTRA_OEMAKE_append_task-install = " -C ${STAGING_KERNEL_DIR} M=${S}"
EXTRA_OEMAKE += "KDIR=${STAGING_KERNEL_DIR}"

将S更改为“bluetooth_uart_driver”,因为zip文件包含该目录及其内容:

ifneq ($(KERNELRELEASE),)
    obj-m       := hci_uart.o
    hci_uart-y  := hci_ldisc.o hci_h4.o hci_rtk_h5.o rtk_coex.o
    #EXTRA_CFLAGS += -DDEBUG

else
    PWD := $(shell pwd)
    KVER := $(shell uname -r)
    KDIR := /lib/modules/$(KVER)/build

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    rm -rf *.o *.mod.c *.mod.o *.ko *.symvers *.order *.a

endif

这对我来说很有效,.ko文件会生成并放置在/lib/modules/${KVER}/extra中,所以您可以覆盖do_install函数并将其安装到您想要的位置。

简单测试:

我下载了goodix.c驱动程序,并创建了一个自定义配方,其中包含此Makefile(我修改了旧的BT Makefile):

ifneq ($(KERNELRELEASE),)
    obj-m       := goodix.o

else
    PWD := $(shell pwd)
    KVER := $(shell uname -r)
    KDIR := /lib/modules/$(KVER)/build

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    rm -rf *.o *.mod.c *.mod.o *.ko *.symvers *.order *.a

endif

我的配方:

|meta-test/
    |--> recipes-driver/
         |--> files/
              |--> goodix.c
              |--> Makefile
         |--> goodix-driver_0.1.bb

goodix-driver_0.1.bb:

LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
SRC_URI = "file://goodix.c file://Makefile"
S = "${WORKDIR}"
inherit module
EXTRA_OEMAKE_append_task-install = " -C ${STAGING_KERNEL_DIR} M=${S}"
EXTRA_OEMAKE += "KDIR=${STAGING_KERNEL_DIR}"

通过这个简单的构建,我能够生成.ko文件。

注意:

如果goodix.c已经包含在您的上游Linux内核中,也就是说您可以在以下位置找到它:

tmp/work/.../linux-../../git/drivers/input/touchscreen/goodix.c

这意味着你可以直接打补丁而不必为此创建整个配方,你只需直接编辑它,然后返回到git文件夹并执行以下操作:
git add drivers/input/touchscreen/goodix.c
git commit -m "My-updates"
git format-patch -1 -o /path/to/meta-custom/recipes-kernel/linux/files

现在,在 /path/to/meta-custom/recipes-kernel/linux/linux-xx_%.bbappend 中添加以下内容:
SRC_URI_append = " file://My-updates.patch"

现在,不要忘记通过menuconfig激活它,并将其标志添加到内核defconfig文件中,以便它被编译并随rootfs一起发布。

所以你没有声明你的配方提供任何软件包?你只是在层配置中包含了镜像? - Micrified
食谱名称为fnlink-uart_0.1.bb,当您在食谱中提供某些内容时,意味着该食谱将具有额外的名称,可以由许多食谱提供,就像virtual/kernel由linux-imx、linux-yocto等提供一样。您可以将食谱放置在任何层中,最佳实践是创建一个自定义层来保存新驱动程序的食谱,然后将该食谱添加到IMAGE_INSTALL变量中。 - Talel BELHADJSALEM
好的,这就是我预料到的。我将选择您的答案进行批准。我更希望有人能够解释如何正确处理RPROVIDES错误,因为它在文档中有提到,但是您已经付出了努力并给出了一个解决方法。 - Micrified
好的,我自己无法使用你的配方模板。我从我的模板中删除了RDEPENDS内容,并将其纯粹作为一个带有“IMAGE_INSTALL_append”的图像添加。它仍然出现了一些错误(我认为与模块类相关)。一旦我找到让你的配方工作的方法,我会标记它为已解决。在那之前,我会点赞它作为一个好答案,并尝试在没有丑陋的hack的情况下解决我的问题。 - Micrified
我会尝试为你的 Goodix 驱动程序创建一个配方。但是我的问题是,为什么要创建一个配方,而不是在内核配置中自动选择它呢? - Talel BELHADJSALEM
显示剩余3条评论

1
我正在更新我的问题,并提供一个答案,其中还描述了如何创建一个简单的内核模块 bitbake 文件。

文件名和位置

  • 我的内核模块名称: foo
  • 我的 bitbake 文件名称: kernel-module-foo (需要前缀 kernel-module-)
  • 拓扑结构(见下文):
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
├── recipes-kernel
│   └── linux
│       ├── kernel-module-foo.bb

Bitbake文件
# Bitbake class(es)
inherit module 

# Dependencies
DEPENDS = "virtual/kernel"

# Metadata
SUMMARY = "Sample kernel module"

# Licensing
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5= 0835ade698e0bcf8506ecda2f7b4f302"

# Source
GIT_BRANCH = "my-branch"
SRC_URI = "git://<path-to-git-repo>;branch=${GIT_BRANCH}"
SRCREV = "<my-git-branch-src-revision>"

# OE build directives
EXTRA_OEMAKE_append_task-install = "-C ${STAGING_KERNEL_DIR} M=${S}"
EXTRA_OEMAKE += "KDIR=${STAGING_KERNEL_DIR}"

# Autoinstall (optionally disable)
KERNEL_MODULE_AUTOLOAD += "pwr_ctl_onoff"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接