5

Goal

I want to add a touchscreen driver available in the linux kernel source tree to my Yocto image (The link takes you to goodix.c). I basically need to add it as a kernel module.

Solution

I follow the Incorporating Out-of-Tree Modules section of the Yocto Mega Manual. I base mine off their example kernel-module recipe, called hello-mod.

  1. In recipe goodix-9271_0.1.bb: RPROVIDES_${PN} = "kernel-module-goodix"
  2. In layer.conf: MACHINE_EXTRA_RDEPENDS += "kernel-module-goodix"

Problem

My build simply consistently fails in do_rootfs with:

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)

What I cannot understand after reading the documentation on this section is why this error is happening. I tried adjusting the recipe names (removing the kernel-module prefix, etc) but nothing seems to work. What is going wrong?


Source

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/*"

Edits

  1. The error basically says that kernel-module-goodix-5.3.4-imx6ul+gb40ccfdb73ea isn't provided. I didn't name my package that way though. So why is it looking for something with the suffix 5.3.4-imx6ul+gb40ccfdb73ea there?

Edit (Solution)

For anyone reading this who isn't satisfied by the accepted answer. Just know that what was wrong with my original recipe was that I wasn't naming my actual recipe "kernel-module-<name>.bb". That was actually what was required.

Micrified
  • 3,338
  • 4
  • 33
  • 59
  • Have you tried using `RPROVIDES_${PN} +=`  and not `=`? – Barnabas Busa Jun 22 '21 at 13:50
  • 1
    Yes, it does not help unfortunately. – Micrified Jun 22 '21 at 13:53
  • 1
    Wouldn't it be easier to patch the kernel and enable it in kernel config? – Oleksandr Kravchuk Jun 22 '21 at 14:14
  • @OleksandrKravchuk Perhaps so. I really wanted to understand why this was not working though. For what it's worth, I can get it to build if I hackily just copy the suffix shown in my edit and add it to the `RPROVIDES`. But that seems like I'm just sidestepping a mistake someplace else, and I'd like to know what the cause is. – Micrified Jun 22 '21 at 14:26
  • @OleksandrKravchuk Also, kernel config does not have this driver (at least it wasn't available in mine). – Micrified Jun 23 '21 at 07:18

2 Answers2

2

I have created a recipe for an UART Bluetooth driver before and it works fine for me, here is the recipe:

#
# 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}"

Change S to "bluetooth_uart_driver" because the zip file contains that directory with the content:

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

This works well for me, and the .ko file is generated and shipped into /lib/modules/${KVER}/extra , so you can override the do_install function and install it where you want.

Simple Test:

I downloaded the goodix.c driver and created a custom recipe for it with this Makefile (I modified my old 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

My recipe:

|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}"

With this in a simple poky build I was able to generate the .ko file.

Note:

If goodix.c is present in your upstream Linux kernel, which means you can find it in:

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

which means you can just patch it without creating a whole recipe for it, you just edit it directly and then go back to git folder and :

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

Now, in /path/to/meta-custom/recipes-kernel/linux/linux-xx_%.bbappend add:

SRC_URI_append = " file://My-updates.patch"

Now, do not forget to activate it via menuconfig and add its flag to the kernel defconfig file so it gets compiled and shipped within the rootfs.

Talel BELHADJSALEM
  • 3,199
  • 1
  • 10
  • 30
  • So you did not declare your recipe to be providing any packages? Did you simply include the image in the layer conf? – Micrified Jun 22 '21 at 15:22
  • The recipe name is fnlink-uart_0.1.bb , when you provide something in the recipe means that the recipe will have an extra name that can be provided by many recipes just like virtual/kernel is provided by linux-imx, linux-yocto, ...etc, you can put the recipe in any layer, best practice is to create a custom layer holding the new recipe for the driver, and then add the recipe to IMAGE_INSTALL variable. – Talel BELHADJSALEM Jun 22 '21 at 15:29
  • Alright, that's what I figured. I'm going to select your answer for approval. I would have rather someone explained how to properly address the `RPROVIDES` error since it's in the documentation, but you put effort and gave a workaround. – Micrified Jun 23 '21 at 07:13
  • Okay I was unable to use your recipe template myself. I removed the RDEPENDS stuff from mine and purely added it as a image with `IMAGE_INSTALL_append`. It still gave some error (related to the module class I think). I will mark it resolved once I find a way to make your recipe work. Until then, I will upvote it for being a good answer and try to resolve my problem without my ugly hack around. – Micrified Jun 23 '21 at 14:09
  • I will try to create a recipe for your goodix driver. But my question is why creating a recipe while you can automatically select it in your kernel config ? – Talel BELHADJSALEM Jun 23 '21 at 15:24
  • Because the driver has a problem I'm trying to circumvent. I'm going to patch the driver. I need to (1) disable the default one included via the Kernel config (2) supply my own modified one as a module. – Micrified Jun 23 '21 at 15:25
  • You can use the default driver and apply a simple patch on it and let it be build via the kernel Kbuild system. Just make your modifs and create the patch and add it to your custom linux bbappend recipe. – Talel BELHADJSALEM Jun 23 '21 at 15:50
  • Yes thank you. I have chosen to simply go the patch route. – Micrified Jun 24 '21 at 12:47
1

I am updating my question with an answer which also describes how to create a simple kernel module bitbake file.


File name and placement

  • Name of my kernel module: foo
  • Name of my bitbake file: kernel-module-foo (kernel-module- prefix required)
  • Topology (see below):
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
├── recipes-kernel
│   └── linux
│       ├── kernel-module-foo.bb

Bitbake file

# 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"
Micrified
  • 3,338
  • 4
  • 33
  • 59