Creating `kmod-` packages: How to set kernel options (bool, int) and check for kernel options in package `Makefile`?

Dear build system knowledgables,

To keep things clean, I am currently creating new kernel modules as separate packages in a separate feed.

I think I have already found out how to create kernel module packages, but one kernel module needs to set some other kernel features which are not available as modules but just as simple y/n and with an integer number in the kernel configuration.

That are:

  • CONFIG_CMA,
  • CONFIG_DMA_CMA,
  • CONFIG_CMA_SIZE_SEL_MBYTES,
  • CONFIG_CMA_SIZE_MBYTES=<number>,
  • CONFIG_CMA_ALIGNMENT=<number>.

CONFIG_CMA by itself depends on CONFIG_MMU, which seems to be automatically set or unset by the kernel config depending on the selected architecture or so.
CONFIG_DMA_CMA depends on CONFIG_HAVE_DMA_CONTIGUOUS, which also seems to be something automatically determined by the kernel config.

To make things clean, I want to add one OpenWrt configuration item for CONFIG_CMA and CONFIG_DMA_CMA and CONFIG_CMA_SIZE_SEL_MBYTES, and if selected two sub-configuration-items to specify CONFIG_CMA_SIZE_MBYTES and CONFIG_CMA_ALIGNMENT, with sensible defaults.

Also, I want to check for the needed options CONFIG_MMU=y and CONFIG_HAVE_DMA_CONTIGUOUS=y.

How do I do that in a package Makefile I create within a feed? Can anyone give an explanation + example, or one of them, how to

  • set kernel options which do not result in a module file,
  • check if some kernel configuration is present?

That would help me getting hardware functionality of my board more properly supported than hacking CONFIG_<something>=y into target/linux/*/config-5.10, and would allow to build loadable modules.

Moreover, one module is provided by external sources, and that module also has some in-kernel dependencies, so there I need to write a package and include dependencies for kernel options.

Regards!

So far, that was a misjudgement; it works by modifying the package/kernel/linux/modules/*.mk files or adding files there, but not so far by creating standalone new packages, see → "Making kernel module packages for in-tree-modules into a standalone feed?".

However, for

I have a working solution (although it is still quite hacky, maybe I can make it cleaner):

For example, I want to be able to set the kernel option ARM_MODULE_PLTS/ ARM64_MODULE_PLTS. I achieve this via a Config.in that gets pulled in via a Makefile (beside that, the Makefile does not do anything):

`arm-module-plts/Config.in` (*click* to see):
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# The Linux Kernel

#
# ARM Module PLTs
#

config KERNEL_ARM_MODULE_PLTS
        bool "Use PLTs to allow module memory to spill over into vmalloc area (ARM32)"
        depends on arm
        default y
        help
          Allocate PLTs when loading modules so that jumps and calls whose targets are too far away for their relative offsets to be encoded in the instructions themselves can be bounced via veneers in the module's PLT. This allows modules to be allocated in the generic vmalloc area after the dedicated module memory area has been exhausted. The modules will use slightly more memory, but after rounding up to page size, the actual memory footprint is usually the same.
          Disabling this is usually safe for small single-platform configurations.
          If unsure, say y, except you are memory constrained and use only a limited amount of kernel modules.
          This can be needed if you cannot load more modules because of some module memory has exhausted.

config KERNEL_ARM64_MODULE_PLTS
        bool "Use PLTs to allow module memory to spill over into vmalloc area (ARM64)"
        depends on aarch64
        default y
        help
          Allocate PLTs when loading modules so that jumps and calls whose targets are too far away for their relative offsets to be encoded in the instructions themselves can be bounced via veneers in the module's PLT. This allows modules to be allocated in the generic vmalloc area after the dedicated module memory area has been exhausted. The modules will use slightly more memory, but after rounding up to page size, the actual memory footprint is usually the same.
          When running with address space randomization (KASLR), the module region itself may be too far away for ordinary relative jumps and calls, and so in that case, module PLTs are required and cannot be disabled. Specific errata workaround(s) might also force module PLTs to be enabled (ARM64_ERRATUM_843419).
          Disabling this is usually safe for small single-platform configurations.
          If unsure, say y, except you are memory constrained and use only a limited amount of kernel modules.
          This can be needed if you cannot load more modules because of some module memory has exhausted.

`arm-module-plts/Makefile` (*click* to see):
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note

include $(TOPDIR)/rules.mk

PKG_NAME:=kernel-arm-module-plts
PKG_RELEASE:=$(AUTORELEASE)

PKG_MAINTAINER:=dreieck
PKG_LICENSE:=GPL-2.0

include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk

PKG_LICENSE_FILES:=$(LINUX_DIR)/COPYING
PKG_VERSION:=$(LINUX_VERSION)

_OUR_SECTION=kernel
_OUR_CATEGORY=Kernel
#_OUR_SUBMENU=Further general kernel settings

define Package/kernel-arm-module-plts
	HIDDEN:=1
	SECTION=$(_OUR_SECTION)
	CATEGORY=$(_OUR_CATEGORY)
	# SUBMENU:=$(_OUR_SUBMENU)
	TITLE:=Use PLTs to allow module memory to spill over into vmalloc area (ARM32/ ARM64)
	VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE)
	URL:=http://kernel.org/
	KCONFIG:= \
	  CONFIG_ARM_MODULE_PLTS=$(if $(CONFIG_KERNEL_ARM_MODULE_PLTS),y,n) \
	  CONFIG_ARM64_MODULE_PLTS=$(if $(CONFIG_KERNEL_ARM64_MODULE_PLTS),y,n)
endef

define Package/kernel-arm-module-plts/config
	source "$(SOURCE)/Config.in"
endef

define Package/kernel-arm-module-plts/description
	This option just toggles the kernel config `CONFIG_ARM_MODULE_PLTS` or `CONFIG_ARM64_MODULE_PLTS` to yes or no, if the architecture is arm or aarch64, respectively.
	
	Choosing "m" or "y" has no difference here.
endef

$(eval $(call BuildPackage,kernel-arm-module-plts))

(Note that all the informative texts in the Makefile are purely cosmetic, since the information to display is pulled in via the Config.in and the Makefile's menu item is hidden (HIDDEN:=1)


Putting this into a freshly created feed, installing that feed, this results in the option "Use PLTs to allow module memory to spill over into vmalloc area (ARM32)" (for my target, the ARM32 variant) to show up in make menuconfig under the category Kernel, and when I select it, the generated kernel's .config at build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-sunxi_cortexa7/linux-5.10.149/.config contains this setting set -- if I unset it it does not contain this setting.

I also made some more complex settings this way regarding CMA, DMA_CMA, and associated integer values.


This makes me question: Is there a way to directly define in the Makefile a bool option? Standard OpenWrt packages are always tristate -- which does not make sense here and is confusing.

Hi,

I am trying to so something similar with DVB modules.

How did you progress with this approach? Do you have a template you can share?

I did not continue but gave up on making my device, which already has some OpenWRT support and functions as a router, fully supported (or at least enabling what vanilla Linux would support but OpenWRT's Linux does not).
I would love to do this and give back to OpenWRT, but the learning courve to learn OpenWRT build system internals is too high in this regard and I miss(ed) good OpenWRT beginner-friendly documentation (aimed at people good with general GNU/Linux administration, who know how to compile Linux kernels, but who also do not know about kernel development and not know about OpenWRT build system and build systems in general).