// -*- mode:doc; -*- // vim: set syntax=asciidoc: === Infrastructure for packages building kernel modules Buildroot offers a helper infrastructure to make it easy to write packages that build and install Linux kernel modules. Some packages only contain a kernel module, other packages contain programs and libraries in addition to kernel modules. Buildroot's helper infrastructure supports either case. [[kernel-module-tutorial]] ==== +kernel-module+ tutorial Let's start with an example on how to prepare a simple package that only builds a kernel module, and no other component: ---- 01: ################################################################################ 02: # 03: # foo 04: # 05: ################################################################################ 06: 07: FOO_VERSION = 1.2.3 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPLv2 11: FOO_LICENSE_FILES = COPYING 12: 13: $(eval $(kernel-module)) 14: $(eval $(generic-package)) ---- Lines 7-11 define the usual meta-data to specify the version, archive name, remote URI where to find the package source, licensing information. On line 13, we invoke the +kernel-module+ helper infrastructure, that generates all the appropriate Makefile rules and variables to build that kernel module. Finally, on line 14, we invoke the xref:generic-package-tutorial[+generic-package+ infrastructure]. The dependency on +linux+ is automatically added, so it is not needed to specify it in +FOO_DEPENDENCIES+. What you may have noticed is that, unlike other package infrastructures, we explicitly invoke a second infrastructure. This allows a package to build a kernel module, but also, if needed, use any one of other package infrastructures to build normal userland components (libraries, executables...). Using the +kernel-module+ infrastructure on its own is not sufficient; another package infrastructure *must* be used. Let's look at a more complex example: ---- 01: ################################################################################ 02: # 03: # foo 04: # 05: ################################################################################ 06: 07: FOO_VERSION = 1.2.3 08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz 09: FOO_SITE = http://www.foosoftware.org/download 10: FOO_LICENSE = GPLv2 11: FOO_LICENSE_FILES = COPYING 12: 13: FOO_MODULE_SUBDIRS = driver/base 14: FOO_MODULE_MAKE_OPTS = KVERSION=$(LINUX_VERSION_PROBED) 15: 16: ifeq ($(BR2_PACKAGE_LIBBAR),y) 17: FOO_DEPENDENCIES = libbar 18: FOO_CONF_OPTS = --enable-bar 19: FOO_MODULE_SUBDIRS += driver/bar 20: else 21: FOO_CONF_OPTS = --disable-bar 22: endif 23: 24: $(eval $(kernel-module)) 26: $(eval $(autotools-package)) ---- Here, we see that we have an autotools-based package, that also builds the kernel module located in sub-directory +driver/base+ and, if libbar is enabled, the kernel module located in sub-directory +driver/bar+, and defines the variable +KVERSION+ to be passed to the Linux buildsystem when building the module(s). [[kernel-module-reference]] ==== +kernel-module+ reference The main macro for the kernel module infrastructure is +kernel-module+. Unlike other package infrastructures, it is not stand-alone, and requires any of the other +*-package+ macros be called after it. The +kernel-module+ macro defines post-build and post-target-install hooks to build the kernel modules. If the package's +.mk+ needs access to the built kernel modules, it should do so in a post-build hook, *registered after* the call to +kernel-module+. Similarly, if the package's +.mk+ needs access to the kernel module after it has been installed, it should do so in a post-install hook, *registered after* the call to +kernel-module+. Here's an example: ---- $(eval $(kernel-module)) define FOO_DO_STUFF_WITH_KERNEL_MODULE # Do something with it... endef FOO_POST_BUILD_HOOKS += FOO_DO_STUFF_WITH_KERNEL_MODULE $(eval $(generic-package)) ---- Finally, unlike the other package infrastructures, there is no +host-kernel-module+ variant to build a host kernel module. The following additional variables can optionally be defined to further configure the build of the kernel module: * +FOO_MODULE_SUBDIRS+ may be set to one or more sub-directories (relative to the package source top-directory) where the kernel module sources are. If empty or not set, the sources for the kernel module(s) are considered to be located at the top of the package source tree. * +FOO_MODULE_MAKE_OPTS+ may be set to contain extra variable definitions to pass to the Linux buildsystem. Yo may also reference (but you may *not* set!) those variables: * +LINUX_DIR+ contains the path to where the Linux kernel has been extracted and built. * +LINUX_VERSION+ contains the version string as configured by the user. * +LINUX_VERSION_PROBED+ contains the real version string of the kernel, retrieved with running `make -C $(LINUX_DIR) kernelrelease` * +KERNEL_ARCH+ contains the name of the current architecture, like `arm`, `mips`...