// -*- mode:doc; -*-
// vim: set syntax=asciidoc:

[[linux-kernel-specific-infra]]
=== Infrastructure specific to the Linux kernel package

The Linux kernel package can use some specific infrastructures based on package
hooks for building Linux kernel tools or/and building Linux kernel extensions.

[[linux-kernel-tools]]
==== linux-kernel-tools

Buildroot offers a helper infrastructure to build some userspace tools
for the target available within the Linux kernel sources. Since their
source code is part of the kernel source code, a special package,
+linux-tools+, exists and re-uses the sources of the Linux kernel that
runs on the target.

Let's look at an example of a Linux tool. For a new Linux tool named
+foo+, create a new menu entry in the existing
+package/linux-tools/Config.in+.  This file will contain the option
descriptions related to each kernel tool that will be used and
displayed in the configuration tool. It would basically look like:

----
01: config BR2_PACKAGE_LINUX_TOOLS_FOO
02: 	bool "foo"
03: 	select BR2_PACKAGE_LINUX_TOOLS
04: 	help
05: 	  This is a comment that explains what foo kernel tool is.
06:
07: 	  http://foosoftware.org/foo/
----

The name of the option starts with the prefix +BR2_PACKAGE_LINUX_TOOLS_+,
followed by the uppercase name of the tool (like is done for packages).

.Note
Unlike other packages, the +linux-tools+ package options appear in the
+linux+ kernel menu, under the `Linux Kernel Tools` sub-menu, not under
the `Target packages` main menu.

Then for each linux tool, add a new +.mk.in+ file named
+package/linux-tools/linux-tool-foo.mk.in+. It would basically look like:

----
01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: LINUX_TOOLS += foo
08:
09: FOO_DEPENDENCIES = libbbb
10:
11: define FOO_BUILD_CMDS
12: 	$(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools foo
13: endef
14:
15: define FOO_INSTALL_STAGING_CMDS
16: 	$(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \
17: 		DESTDIR=$(STAGING_DIR) \
18: 		foo_install
19: endef
20:
21: define FOO_INSTALL_TARGET_CMDS
22: 	$(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \
23: 		DESTDIR=$(TARGET_DIR) \
24: 		foo_install
25: endef
----

On line 7, we register the Linux tool +foo+ to the list of available
Linux tools.

On line 9, we specify the list of dependencies this tool relies on. These
dependencies are added to the Linux package dependencies list only when the
+foo+ tool is selected.

The rest of the Makefile, lines 11-25 defines what should be done at the
different steps of the Linux tool build process like for a
xref:generic-package-tutorial[+generic package+]. They will actually be
used only when the +foo+ tool is selected. The only supported commands are
+_BUILD_CMDS+, +_INSTALL_STAGING_CMDS+ and +_INSTALL_TARGET_CMDS+.

.Note
One *must not* call +$(eval $(generic-package))+ or any other
package infrastructure! Linux tools are not packages by themselves,
they are part of the +linux-tools+ package.

[[linux-kernel-ext]]
==== linux-kernel-extensions

Some packages provide new features that require the Linux kernel tree
to be modified. This can be in the form of patches to be applied on
the kernel tree, or in the form of new files to be added to the
tree. The Buildroot's Linux kernel extensions infrastructure provides
a simple solution to automatically do this, just after the kernel
sources are extracted and before the kernel patches are
applied. Examples of extensions packaged using this mechanism are the
real-time extensions Xenomai and RTAI, as well as the set of
out-of-tree LCD screens drivers +fbtft+.

Let's look at an example on how to add a new Linux extension +foo+.

First, create the package +foo+ that provides the extension: this
package is a standard package; see the previous chapters on how to
create such a package. This package is in charge of downloading the
sources archive, checking the hash, defining the licence information
and building user space tools if any.

Then create the 'Linux extension' proper: create a new menu entry in
the existing +linux/Config.ext.in+. This file contains the option
descriptions related to each kernel extension that will be used and
displayed in the configuration tool. It would basically look like:

----
01: config BR2_LINUX_KERNEL_EXT_FOO
02: 	bool "foo"
03: 	help
04: 	  This is a comment that explains what foo kernel extension is.
05:
06: 	  http://foosoftware.org/foo/
----

Then for each linux extension, add a new +.mk+ file named
+linux/linux-ext-foo.mk+. It should basically contain:

----
01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: LINUX_EXTENSIONS += foo
08:
09: define FOO_PREPARE_KERNEL
10:	$(FOO_DIR)/prepare-kernel-tree.sh --linux-dir=$(@D)
11: endef
----

On line 7, we add the Linux extension +foo+ to the list of available
Linux extensions.

On line 9-11, we define what should be done by the extension to modify
the Linux kernel tree; this is specific to the linux extension and can
use the variables defined by the +foo+ package, like: +$(FOO_DIR)+ or
+$(FOO_VERSION)+... as well as all the Linux variables, like:
+$(LINUX_VERSION)+ or +$(LINUX_VERSION_PROBED)+, +$(KERNEL_ARCH)+...
See the xref:kernel-variables[definition of those kernel variables].
