Skip to content

Latest commit

 

History

History
2307 lines (1618 loc) · 86.4 KB

userguide.rst

File metadata and controls

2307 lines (1618 loc) · 86.4 KB

Introduction

Generate Linux kernel configuration files from curated sources, detected hardware, installed packages and user input.

Installing kernelconfig

Dependencies

Required:

  • Python >= 3.4, or Python 3.3 with backports: enum
  • toposort
  • Python Lex-Yacc (PLY)
  • GNU make
  • git for various configuration sources
  • C compiler, ...
  • portage for package management integration

Optional, but recommended:

  • kmod with Python bindings for hardware detection based on module aliases
  • Python modules: lxml and beautifulsoup (>= 4), for the Ubuntu configuration source
  • perl, for the Fedora configuration source

Optional:

  • Linux kernel sources for copying certain files from scripts/kconfig, a bundled copy is used otherwise
  • docutils for generating manpages
  • docutils, rst2pdf for generating the documentation files

via emerge (Gentoo)

A live ebuild for sys-kernel/kernelconfig is available in the kernelconfig-portage overlay.

To add it with layman, run:

$ mkdir -p /etc/layman/overlays
$ wget -O /etc/layman/overlays/kernelconfig.xml "https://raw.githubusercontent.com/dywisor/kernelconfig-portage/master/layman.xml"
$ layman -a kernelconfig

or:

$ layman -o "https://raw.githubusercontent.com/dywisor/kernelconfig-portage/master/layman.xml" -f -a kernelconfig

The live ebuild needs to be KEYWORDS-unmasked:

$ mkdir -p /etc/portage/package.accept_keywords
$ echo "~sys-kernel/kernelconfig-9999 **" >> /etc/portage/package.accept_keywords/kernelconfig

It can then be installed with:

$ emerge -a sys-kernel/kernelconfig

Manual Installation

First, make sure to install the dependencies.

After that, clone the git repo and change to working directory to kernelconfig's sources:

git clone git://github.com/dywisor/kernelconfig.git

cd kernelconfig

Then, prepare the build by creating an installinfo file, which tells kernelconfig where to find its config and data files, once installed. This can be done with make prepare-installinfo, it should receive the same variables as setup.py install and make install later on (except for DESTDIR):

PREFIX=/usr/local   # default: /usr/local
SYSCONFDIR=/etc     # default: /usr/local/etc

make prepare-installinfo PREFIX="${PREFIX}" SYSCONFDIR="${SYSCONFDIR}"

Building requires a copy of some files from the Linux kernel sources. At this point, it is necessary to decide whether to use the bundled copy distributed with kernelconfig, which is recommended, or to import the files from a kernel source tree.

To use the bundled lkc files, export LKCONFIG_LKC:

export LKCONFIG_LKC="src/lkc-bundled"

Alternatively, to import the lkc files from a kernel source tree, run:

make import-lkc LK_SRC=/usr/src/linux
#export LKCONFIG_LKC="src/lkc"  # not necessary

After preparing installinfo and the lkc files, build kernelconfig with setup.py:

python ./setup.py build

This step can be repeated in case of multiple Python versions.

Finally, kernelconfig can be installed. The python files are installed with setup.py, and the data and config files with make:

# install
DESTDIR=/
python ./setup.py install --root "${DESTDIR}" --prefix "${PREFIX}"
make install-data install-config DESTDIR="${DESTDIR}" PREFIX="${PREFIX}" SYSCONFDIR="${SYSCONFDIR}"

The install-related make variables follow the GNU Coding Standards\: Directory Variables, except that the names are in uppercase. See mk/install.mk for a list of variables.

The man page(s) can be built with:

make man PREFIX="${PREFIX}" SYSCONFDIR="${SYSCONFDIR}"

The bash completion file, build/kernelconfig.bashcomp, can be created with make, but has to be installed manually:

make bashcomp PREFIX="${PREFIX}" SYSCONFDIR="${SYSCONFDIR}"

To generate the HTML documentation files in doc/html, run:

make htmldoc

Similarly, to create the PDF documentation files in doc/pdf, run:

make pdf

Warning

The generated PDF files may contain information about filesystem paths of the system that created the files, making them less ideal for sharing.

The HTML files do not have this issue.

Running kernelconfig without installing it

kernelconfig can be run in standalone mode from the project's sources. For this purpose, it offers a wrapper script named kernelconfig.py that takes care of running setup.py and invoking the main script.

First, get the sources by cloning the git repo:

$ mkdir -p ~/git
$ git clone git://github.com/dywisor/kernelconfig.git ~/git/kernelconfig

The wrapper can be run directly:

$ ~/git/kernelconfig/kernelconfig.py

or installed by creating a symlink in one of the PATH directories.

For example, if ~/bin is in your PATH:

$ ln -s ~/git/kernelconfig/kernelconfig.py ~/bin/kernelconfig
$ kernelconfig

Bash completion is also available, but has to be created first:

$ make -C ~/git/kernelconfig bashcomp-standalone

Then, add the following line to ~/.bash_completion:

source ~/git/kernelconfig/local/kernelconfig.bashcomp

Throughout the following sections, <prjroot> will be used to refer to the project's source directory.

The wrapper accepts all of the usual options, and additionally:

--wrapper-help

Prints a help message describing the wrapper's options.

--wrapper-prjroot <PRJROOT>

Path to the project's sources.

If not specified, defaults to the directory containing the wrapper script.

--wrapper-build-base <BUILD_BASE>

Root directory for build files, can also be specified via the PY_BUILDDIR environment variable.

Defaults to <PRJROOT>/build.

The wrapper creates per-Python version subdirectories in <BUILD_BASE>/kernelconfig-standalone.

--wrapper-lkc <LKC_SRC>

Alternate path to lkc files from the Linux kernel sources. Must point to <linux srctree>/scripts/kconfig and not just <linux srctree>. Can also be specified via the LKCONFIG_LKC environment variable.

Defaults to <PRJROOT>/src/lkc, which contains a bundled copy of the necessary files.

--wrapper-rebuild

Instructs the wrapper to rebuild Python modules by passing --force to setup.py build. The wrapper tries to reuse existing modules if this option is not given.

Running kernelconfig

In the simplest case, run kernelconfig without any arguments from within the kernel sources directory. It uses the default settings and creates a .config file.

It is not advised to run kernelconfig as root. Certain features involve execution of arbitrary code, namely configuration sources and package management integration. Write access to the kernel sources directory is not required, provided that --outconfig points to another location.

It is also possible to specify the kernel sources directory by hand, creating the .config file in this directory:

$ kernelconfig -k /usr/src/linux

Or write the configuration to a different output file:

$ kernelconfig -O ./my_config

Instead of using a configuration source, an input config file can be given on the command line:

$ kernelconfig --config ./my_config

The input and output config file can point to the same file. Prior to writing the output file, a backup of the old file is created (<output>.bak).

The target architecture is usually determined by uname -m. For cross-compilation scenarios, it is possible to specify it manually:

$ kernelconfig -a arm

To get an overview over which configuration sources are available, kernelconfig offers a few helper commands.

To get a list of all known configuration sources, run:

$ kernelconfig --list-source-names

or:

$ kernelconfig --list-sources

This list includes unvailable sources, e.g. sources that do not support the target architecture.

To print out help messages for all available sources, run:

$ kernelconfig --help-sources

To print out the help message for a particular source, and also report why the source is unavailable (if it is unavailable), e.g. for Fedora, run:

$ kernelconfig --help-source Fedora -a mips

Command Line Options

kernelconfig accepts a number of options:

-h, --help

Print the help message and exit.

--usage

Print the usage message and exit.

-V, --print-version

Print the version and exit.

-q, --quiet

Decrease the console log level.

This option can be given multiple times, each time it decreases the log verbosity by one level. By default, only warning messages are shown.

-v, --verbose

Increase the console log level.

Can be specified more than once, see --quiet for details.

-a <arch>, --arch <arch>

Target architecture, defaults to the system's architecture as returned by uname -m.

-k <srctree>, --kernel <srctree>

Path to the Linux kernel sources directory.

Defaults to the current working directory.

-s <settings>, --settings <settings>

Path to or name of the settings file.

Files can be specified with an absolute path or a relative path starting with ./.

Otherwise, <settings> refers to a settings file in one of the settings directories.

Defaults to "default".

--config <file>

An input configuration file that should be used instead of the source configured in the settings file.

The file can be gzip, bzip2 or xz-compressed, provided that its file suffix indicates the compression format (e.g. /proc/config.gz).

Not set by default.

--config <source>

Instead of a file, the name of a curated source prefixed with an at-sign @ may also be given, optionally followed by parameters separated with whitespace, that are passed as-is to the configuration source.

If parameters are specified, the <source> must be quoted.

Examples:

--config @ubuntu
--config "@fedora --pae --release f23"

See --list-sources for a complete list of available configuration sources, and --help-source <name> for parameters supported by a particular source.

--config-kver <kernelversion>

Force a specific kernel version for the input configuration.

Useful if the chosen configuration source does not offer a configuration for the version of the kernel sources being processed.

This is primarily meaningful for curated sources only. Some configuration sources ignore this option completely, for example --config /proc/config.gz, and others try to find a configuration whose version does not differ "too much".

-I <file>

File with additional kernel configuration modifications. The file format is identical to the that of the \[options\] section of the settings file, which also allows .config snippets.

Can be specified more than once. Not set by default.

-O <file>, --outconfig <file>

The output .config file.

Defaults to <srctree>/.config.

-H <file>, --hwdetect <file>

Enable hardware detection and read the information from a hwinfo file that has previously been created with the hwcollector script.

The <file> can also point to a remote file, e.g. http://192.168.1.1/hwdetect_info.txt.

Disables any other hardware detection, in particular hwdetect instructions in the \[options\] section of the settings file.

Not set by default.

-m <mod_dir>, --modules-dir <mod_dir>

The modalias information source which is used for modaliased-based hardware detection. It can be

  • a path to a directory, e.g. /lib/$(uname -r)/modules
  • a path to a tarball file
  • a http(s)/ftp uri to a tarball file
  • none, which disables modalias-based hardware detection completely
  • auto, which requires a cached modalias information source that has previously been created with --generate-modalias.
  • optional, which uses a cached modalias information source if there is one available, and otherwise disables modalias-based hardware detection

Defaults to optional.

--unsafe-modalias

Controls how strict cache searching is for --modules-dir auto and optional. If this option is given, less compatible modalias information sources are allowed if no better candidates exist.

The default behavior is --safe.

--safe-modalias

Forbid use of unsafe modalias information sources.

--generate-config

Generate a kernel configuration. This is the default mode.

--get-config

Retrieve the input configuration, but do not generate a configuration. Instead, write the input configuration to --outfile directly.

This mode is only meaningful for configuration sources that are not local files.

Together with --config @<name>, it can be used for testing out configuration sources.

--generate-modalias

Create a modalias information source and store it in the cache directory. It can then be used for modalias-based hardware detection in subsequent runs, or shared with others.

Warning

modalias information source involves building all kernel modules with an allmodconfig configuration, which takes a lot of time and about 2GiB of temporary disk space. kernelconfig will try to use /var/tmp if /tmp does not have enough free space, and --modalias-build-dir can be used to specify an alternate build root directory.

By default, up to number of CPU cores build jobs are used for compiling, this can be adjusted with --jobs.

-j <numjobs>, --jobs <numjobs>

Allow up to <numjobs> build jobs when building modules.

Defaults to the number of processor cores.

--modalias-build-dir <dir>

Alternative build root directory for modalias information source building. kernelconfig creates a temporary subdirectory within this directory, and cleans it up on exit.

By default, building takes place in /tmp or $TMPDIR, if set. /var/tmp is used as fallback if /tmp does not have enough free space.

--print-installinfo

List the directory paths where kernelconfig looks for settings, include files, configuration sources, cached and data files, alongside with their overall status (exists/missing).

The paths are grouped (settings:, include a.s.o.), and are printed in descending order of priority.

No configuration file is generated when this mode is requested.

--list-source-names

List the names of all known configuration sources. The information is based on file-exists checks and may be inaccurate.

No configuration file is generated when this mode is requested.

--list-sources

List the names of all known configuration sources alongside with their filesystem path. The information is based on file-exists checks and may be inaccurate.

No configuration file is generated when this mode is requested.

--help-sources

Print out help messages for all supported configuration sources that did successfully load. The information is accurate, but varies depending on which --arch has been specified.

No configuration file is generated when this mode is requested.

--help-source <name>

Print out the help message for a single configuration source if it is supported and did successfully load. Otherwise, print out why it is unavailable.

No configuration file is generated when this mode is requested.

--script-mode <mode>

As an alternative to the options above, the script mode can be given via this option.

<mode> must be either generate-config, get-config, generate-modalias, print-installinfo, list-source-names, list-sources, or help-sources.

help-source can not be specified with this option.

Settings File

The settings file is kernelconfig's main configuration file. It is an .ini-like file consisting of several sections.

Comment lines start with a # char, empty lines and most whitespace are ignored.

Sections are introduced with [<section name>], e.g. [source]. Unknown sections are ignored. The format inside each section varies, the following table gives a quick overview of all sections and their respective format:

settings file sections
section name section format short description
source command + text data input .config
options macros .config modifications

Settings Directories

Settings files are usually given by name and are searched for in some standard directories. The list of these directories varies depending on whether kernelconfig has been installed or is run in standalone mode.

If kernelconfig has been installed, the directories are as follows:

$HOME/.config/kernelconfig
/etc/kernelconfig

In standalone mode, the settings directories are:

$HOME/.config/kernelconfig
<prjroot>/local/config
<prjroot>/config

The directories are searched in the order as listed, and searching stops immediately if a file with the requested name is found.

Settings files should never be named include or data, these names are reserved for other purposes.

[source]

The [source] section is used to declare the input kernel configuration file. If a config file has been specified with the --config option, then the section is ignored.

kernelconfig needs a configuration basis to operate on. It is served by a configuration source and can be a single .config file or multiple files

The first non-comment, non-empty line specifies the configuration source. It starts with a keyword describing the source's type, which can be a local file, a remote file that can be downloaded via http(s) or ftp, a make defconfig target, a command or a script, and is followed by arguments such as the file path. The type keyword can be omitted if the specified configuration source is unambiguous.

It can also point to a curated source, which is a configuration source that exists separately from the settings file, in the sources subdirectory of the settings directories. Curated sources behave similar to commands in that they accept parameters, but their execution, especially argument parsing, is controlled by kernelconfig.

Except for curated sources, the configuration source line gets string-formatted, see the examples below, or Python String Formatting. While this allows for some variance in file paths and commands, it also requires to escape { and } characters, especially for shell scripts. ${var} needs to be written as ${{var}}, for instance.

Line continuation can be used to split long commands over multiple lines, with a backslash \\ at the end of each line except for the last one.

Subsequent non-comment lines form the source's data. Whether the data subsection is subject to string formatting or not depends on the configuration source type. Only script-type configuration sources accept non-empty data.

Using a curated source

Example:

[source]
ubuntu --lowlatency

Curated sources are referenced by their name, which is case-insensitive1. Their type keyword is source, it can be omitted unless the source's name itself is a keyword.

Curated sources usually accept a few parameters for selecting the configuration basis variant.

As outlined before, kernelconfig has more control over curated sources than over configuration sources specified in the settings file. For example, kernelconfig checks whether the target architecture is supported by the source, and refuses to continue if not.

Run kernelconfig --list-sources to get a list of potential curated source names. and kernelconfig --help-source <name> provides information about a particular source, including its parameters.

Currently, the following curated sources are available:

CentOS

Supported architectures: ppc64, ppc64le, s390x, x86, x86_64

Parameters:

--debug

Use the -debug config variant

--release

CentOS has per OS-release git branches that correspond to a specific kernel version. By default, the configuration source tries to identify the best-fitting branch, but this option can be used to override the auto detection.

Debian

Supported architectures: x86, x86_64

Parameters:

--flavour <flavour>

Debians kernel ecosystem distinguishes between specialized variants of architectures, so-called flavours, which can be specified with this option.

--featureset <featureset>

For some architectures, Debian has config variants that enable an additional feature. Supported feature sets depend on the target architecture and --flavour. Possible values are rt, none and the empty string.

Note

The supported architectures mapping for Debian is incomplete. The underlying script is able to handle other architectures (it has been tested with various mips arch flavours).

Fedora

Supported architectures: aarch64, arm, arm64, armv7hl, s390, s390x, x86, x86_64

Parameters:

--pae

Use the config variant with support for Physical Address Extensions (32-bit x86 only)

--lpae

Use config variant with support for Large Physical Address Extensions (arm only)

--debug

Use the -debug config variant

--release

Fedora has per OS-release git branches that correspond to a specific kernel version.

Liquorix

Supported architectures: x86, x86_64

Parameters:

--pae

Use the config variant with support for Physical Address Extensions (32-bit x86 only)

Ubuntu

Supported architectures: arm64, armhf, x86, x86_64

Parameters:

--lowlatency

Use the low-latency config variant (x86, x86_64 only)

--generic

Use the generic config variant (which is the default)

--lpae

Use config variant with support for Large Physical Address Extensions (arm only)

Using defconfig as configuration source

Run make defconfig with a temporary directory as output directory, and use the generated file as input config file:

[source]
defconfig

The type keyword is defconfig, and no parameters are accepted.

Using a file as configuration source

Use a local file named config_<arch> found in the sources/files subdirectory of the settings directories:

[source]
file config_{arch}

It is also possible to download a file via http/https/ftp, for example:

[source]
http://.../{kv}/config.{arch}

Absolute file paths and file uris starting with file:// are understood, too.

The type keyword is file and it can be omitted for absolute file paths and file uris, but not for relative file paths as that interferes with curated sources.

Besides the file path, no other parameters are accepted. The path is subject to basic string formatting.

Using a command as configuration source

Example:

[source]
command wget http://... -O {outconfig}

The type keyword is command or alternatively cmd, and it can not be omitted.

All arguments after the keyword are subject to string formatting, automatic format variables are supported. Additionally, commands have to access to the config source environment variables.

The initial working directory is a temporary directory which is cleaned up by kernelconfig. If no config file is referenced via the automatic {outconfig}, {out} format variables, kernelconfig expects that the command creates a config file in the temporary directory.

Using a script as configuration source

Download a tarball, extract it to a temporary directory, and pick some of its files as input config:

[source]
sh
wget http://.../file.tgz
tar xf file.tgz -C '{T0}'
cp '{T0}/config.common' '{out}'
for a in {arch} {karch} _; do
    if [ "$a" = "_" ]; then
        exit 1
    elif [ -e "{T0}/config.$a" ]; then
        cat "{T0}/config.$a" >> '{out}'
        break
    fi
done

The type keyword is sh for shell scripts, which are run in errexit mode (set -e).

The data subsection contains the script, and it must not be empty.

The script is subject to string formatting, automatic format variables are supported. Additionally, the script has access to the config source environment variables.

The initial working directory is a temporary directory which is cleaned up by kernelconfig. If no config file is referenced via the automatic {outconfig}, {out} format variables, kernelconfig expects that the script creates a config file in the temporary directory.

Configuration Source Environment Variables

Commands, including scripts, have access to the following environment variables:

Configuration Source Format Variables

All basic source types are subject to Python string formatting.

The available format variables are identical to the environment variables, except for TMPDIR (not set) and T (special, see below). Unlike the environment variables, the names of format variables are case-insensitive, e.g. both {kv} and {KV} are accepted.

Additionally, the script and command type config sources support automatic format variables, which can be used to request additional temporary directories and files and to tell kernelconfig where the .config file(s) can be found after processing the configuration source, without having to specify a filesystem path.

There is no guarantee that filesystem paths produced by automatic format variables do not require quoting in e.g. shell scripts, so make sure to quote the automatic variables where appropriate.

Automatic format variables start with a keyword and are optionally followed by an integer identifier, which can be used to request additional files of the same type.

The following variables exist:

outconfig or out

Request a temporary file and tell kernelconfig that it will be part of the configuration basis.

The identifier can be used to request additional files. Note that {out} and {outconfig} will point to distinct files, and so do {out}, {out0}, {out00}, ..., {out9}, ....

outfile

Request a temporary file that will not be part of the configuration basis.

Otherwise, identical to outconfig.

T

Request a temporary directory.

If used without an identifier, request the default private tmpdir. If used with an identifier, creates a new directory.

[options]

The [options] section should contain a list of config-modifying commands:

disable            A
builtin            B
module             C
builtin-or-module  D E F

set                G "value"
append             H "value"
add                I "value"

Config option names are case-insensitive and the CONFIG_ prefix can be omitted. The first group of commands accepts an arbitrary non-zero number of config options.

Config options can also be referenced by their module name, for example:

builtin-or-module module ddbridge   # enables DVB_DDBRIDGE

Hardware detection can be requested with hwdetect, however it has no effect if the --hwdetect option is passed to kernelconfig:

hwdetect

Config recommendations from installed packages can be requested with packages. The recommendations can be based on what was present at package build-time:

packages build-time

or re-evaluated against the kernel sources for which a configuration is being created:

packages
# packages re-eval  # alternatively

It also possible to load so-called feature set files:

include  feature
include  feature-dir/*
include  /path/to/feature/file

The format of feature set files is identical to that of the [options] section. Basically, settings files can be viewed as extended feature set files.

Relative file paths are looked up in the include subdirectories of the settings directories. Globbing is supported and expands to a combined list of glob matches from all directories, but with the usual order of preference.

See the next chapter, Configuration Language, for a more detailed explanation of the format.

Configuration Language

The kernel configuration itself is configured via kconfig instructions in the [options] section of the settings file, or in separate feature set files.

Instructions that operate on Kconfig symbols:

module             KCONFIG_OPTION [KCONFIG_OPTION...]
builtin            KCONFIG_OPTION [KCONFIG_OPTION...]
builtin-or-module  KCONFIG_OPTION [KCONFIG_OPTION...]
disable            KCONFIG_OPTION [KCONFIG_OPTION...]

m                  KCONFIG_OPTION [KCONFIG_OPTION...]
y                  KCONFIG_OPTION [KCONFIG_OPTION...]
ym                 KCONFIG_OPTION [KCONFIG_OPTION...]
n                  KCONFIG_OPTION [KCONFIG_OPTION...]

set                KCONFIG_OPTION  STR
append             KCONFIG_OPTION  STR
add                KCONFIG_OPTION  STR

hardware-detect
hwdetect

packages           [build-time|re-eval]
pkg                [build-time|re-eval]

The language is case-insensitive and ignores whitespace. String values should be quoted.

To refer to module names instead of config options, put the driver keyword after the command and before the module names:

module             driver  MODULE_NAME [MODULE_NAME...]
builtin            driver  MODULE_NAME [MODULE_NAME...]
builtin-or-module  driver  MODULE_NAME [MODULE_NAME...]
disable            driver  MODULE_NAME [MODULE_NAME...]

# likewise for m, y, ym, n

# not supported for set, append, add

# not supported for hardware-detect

# not supported for packages

The modalias allows to specify module aliases, its usage is identical to driver.

There is an alternative syntax that is more in line with the original format of .config files, which can be used interchangeably, but supports config option names only:

KCONFIG_OPTION=m            # module
KCONFIG_OPTION=y            # builtin
KCONFIG_OPTION=ym           # builtin-or-module
KCONFIG_OPTION=n            # disable

KCONFIG_OPTION="STR"        # set
KCONFIG_OPTION+="STR"       # append
KCONFIG_OPTION|="STR"       # add

Spaces around the assignment operators are ignored.

For compatibility with the original project, the following syntax is also accepted:

enable KCONFIG_OPTION [KCONFIG_OPTION...]   # builtin

set KCONFIG_OPTION=m                        # module
set KCONFIG_OPTION=y                        # builtin
set KCONFIG_OPTION=ym                       # builtin-or-module
set KCONFIG_OPTION=n                        # disable

set KCONFIG_OPTION="STR"                    # set

Additional instructions for loading other files:

include            FILE

Each statement may be followed by a if-condition, which disables the entire statement if the condition is not met, or a unless-condition with the opposite meaning.

Overall, the following conditions can be checked:

  • existence of config options or include files with the exists or exist keyword

    It accepts up to one arg. The meaning of this condition depends on whether the command it appears in is a kconfig instruction or a load-file instruction.

    If used with no arg or the placeholder arg _, it checks for existence of the config option or the file currently being processed.

    Otherwise, existence of the supplied arg is checked.

    A statement of the form

    builtin A B C if exists

    would enable any or all of the config options A, B and/or C if they exist, and is equivalent to the longer and overly explicit variant:

    builtin A if exists A
    builtin B if exists B
    builtin C if exists C
  • kernel version

    The kernelversion can be compared, either as a whole, or partially:

    builtin B if kver == 4.7.0            # full kernel version (a.b.c...)
    builtin A if kver >= 4.2              #  can also be given partially
    builtin C if kmaj < 5                 # the "version" of the kernel version
    builtin D if kmaj == 4 && kmin != 3   # the "sublevel" of the kernel version
    builtin E if kpatch == 0              # the "patchlevel" of the version
  • true/false
  • the truth value of the previous instruction's condition can be accessed with the placeholder expression _

    builtin A if false       # Disabled, sets _ to false
                             #
    builtin B unless _       # Enabled, because "unless false" is true.
                             # However, the value of the condition is false
                             # and thus _ is set to false.
                             #
    builtin D E if exists    # This sets _ twice,
                             # once to "exists D", and then to "exists E".

Conditions can be negated or combined with:

! COND
COND && COND
COND || COND

not COND
COND and COND
COND or  COND

Kconfig Instructions

hardware-detect

Scans /sys for kernel modules that are currently used by any device, and enables corresponding config options as builtin or module.

Modules for which no config options can be found are ignored, but get logged.

Alternative names: hwdetect.

packages [build-time|re-eval]

Query portage for a list of installed packages that use linux-info.eclass and get their build-time value of the CONFIG_CHECK variable or re-evaluate config recommendations against the kernel sources for which a configuration is being created.

Recommended config options are enabled as builtin or module (OPTION), or disabled (!OPTION), respectively.

If the modifier is omitted, re-eval is assumed.

Alternative names: pkg.

module KCONFIG_OPTION [KCONFIG_OPTION...]

Enable one or more kernel config options as module.

The modified options must be of tristate type.

builtin KCONFIG_OPTION [KCONFIG_OPTION...]

Enable one or more kernel config options as builtin.

The modified options must be of tristate or boolean type.

builtin-or-module KCONFIG_OPTION [KCONFIG_OPTION...]

Enable one or more kernel config options as builtin or module.

The modified options must be of tristate or boolean type. The effective value is y or m, out of which m gets preferred.

disable KCONFIG_OPTION [KCONFIG_OPTION...]

Disable one or more kernel config options.

set KCONFIG_OPTION VALUE

Set the value of a kernel config option to VALUE.

The modified option may be of any type, and the VALUE must match that type.

append KCONFIG_OPTION VALUE

Add a value to the end of a list-like, string-type option.

add KCONFIG_OPTION VALUE

Add a value to the end of a list-like, string-type option if it is not already part of that list.

Some of the instructions also accept kernel module names, which must be explicitly requested by putting the driver keyword in front of the module name list. The module names get expanded to a list of config options to which the instruction is then applied. Alternative names for the driver keyword are drv and module.

module driver MODULE_NAME [MODULE_NAME...]

Determine which config options correspond to the given modules and enable them as module.

The modified options must be of tristate type.

builtin driver MODULE_NAME [MODULE_NAME...]

Determine which config options correspond to the given modules and enable them as builtin.

The modified options must be of tristate or boolean type.

builtin-or-module driver MODULE_NAME [MODULE_NAME...]

Determine which config options correspond to the given modules and enable them as builtin or module.

The modified options must be of tristate or boolean type. The effective value is y or m, out of which m gets preferred.

disable driver MODULE_NAME [MODULE_NAME...]

Determine which config options correspond to the given modules and disable them.

Module aliases are also accepted by these commands by means of the modalias keyword. Module aliases are expanded to module names and then to config options.

module modalias MODULE_ALIAS [MODULE_ALIAS...]

Determine which config options correspond to the given module aliases and enable them as module.

Unmatched module aliases are ignored, but at least one alias must resolve to a config option.

The table below gives a quick overview of the instructions that modify the value of kernel config options:

kconfig instructions
keyword symbol type driver, modalias? description

builtin

tristate ---------------+ boolean ---------------+ string ---------------+ int ---------------+ hex

yes

set option to y ---------------------------------------------+ set option to y ---------------------------------------------+ illegal ---------------------------------------------+ illegal ---------------------------------------------+ illegal

module

tristate ---------------+ boolean ---------------+ string ---------------+ int ---------------+ hex

yes

set option to m or y ---------------------------------------------+ illegal ---------------------------------------------+ illegal ---------------------------------------------+ illegal ---------------------------------------------+ illegal

builtin-or-module +

tristate ---------------+ boolean ---------------+ string ---------------+ int ---------------+ hex

yes

set option to y or m ---------------------------------------------+ set option to y ---------------------------------------------+ illegal ---------------------------------------------+ illegal ---------------------------------------------+ illegal

disable

tristate ---------------+ boolean ---------------+ string ---------------+ int ---------------+ hex yes set option to n (# ... is not set)

set

---------------+

tristate

---------------+

boolean

---------------+

string

---------------+

int

---------------+

hex

no

set option to any value, provided that the symbol accepts this value

---------------------------------------------+

y, m or n

---------------------------------------------+

y or n

---------------------------------------------+

<str>

---------------------------------------------+

<int>

---------------------------------------------+

<hex>

append

tristate ---------------+ boolean ---------------+ string

---------------+

int

---------------+

hex

no

illegal ---------------------------------------------+ illegal ---------------------------------------------+ add <str> to the end of the existing value, preceeded by a separator (whitespace)

Same as set if no value defined.

---------------------------------------------+

illegal

---------------------------------------------+

illegal

add

tristate ---------------+ boolean ---------------+ string

---------------+

int

---------------+

hex

no

illegal ---------------------------------------------+ illegal ---------------------------------------------+ same as append, but set-like operation (membership test) ---------------------------------------------+ illegal ---------------------------------------------+ illegal
hardware-detect n/a n/a scan /sys for hardware identifiers and enable config options accordingly
packages n/a n/a scan portage's vdb for installed packages, get their CONFIG_CHECK value and enable config options accordingly

Load-File Instructions

include FILE

Load and process instructions from another file.

The FILE may be an absolute or relative filesystem path. Absolute paths are processed as-is, whereas relative paths are looked up in the include-file directories.

Relative paths can contain wildcard characters *, ?, and are subject to non-recursive glob expansion over all directories.

A statement of the form:

include pkg/*

would load all files that are in any pkg subdirectory of any include-file directory.

Assuming the default include-file directories and the following files structure, above command would load B and C from the home directory, and E from /etc:

/home/user/.config/kernelconfig/include/A
/home/user/.config/kernelconfig/include/pkg/B
/home/user/.config/kernelconfig/include/pkg/C
/etc/kernelconfig/include/D
/etc/kernelconfig/include/pkg/B
/etc/kernelconfig/include/pkg/E
/etc/kernelconfig/include/pkg/F/G
  • neither A nor D, because they are not matched by the pattern
  • not B from /etc, because it is overshadowed by the file in /home
  • not F, because it is a directory
  • not F/G, because the glob-expansion is non-recursive and therefore it is not matched by the pattern

If there are no files matching pkg/*, the command would fail. If that is not desired, an exists condition should be appended:

include pkg/* if exists

Files are not loaded directly when the include statement gets processed, but instead are accumulated and loaded after processing all other commands.

Note

Absolute filesystem paths do not get glob-expanded. This might change in future.

Hardware Detection

kernelconfig is able to determine which hardware is present on the system and enable config options accordingly.

This feature can be requested with hwdetect in the \[options\] section of the settings file, or with the --hwdetect <file> command line option. The latter is meant for collecting hardware information on a different machine.

In either case, it relies on at least one hardware information source and a mapping from hardware identifiers to config options, which is created at runtime from the kernel sources being processed.

Two different hardware information source are available:

  • driver - detect which kernel modules are currently used by any device
  • modalias - detect kernel modules for all device via module alias identifiers

kernelconfig uses whatever source is available and potentially both driver- and modalias-based detection. The hardware identifiers are translated into config options, which are enabled as builtin or module, and module is preferred.

If hardware detection has been requested and at least one hardware identifier has been found but no config options could be determined, then hardware detection is considered to have failed.

driver-based hardware detection has no special requirements except that modules for ideally all devices must be present and loaded (or builtin). This can work sufficiently well when a "big" kernel has been booted and a kernel configuration is being created for the same machine.

Otherwise, modalias-based hardware detection provides a more accurate selection of config options that also includes options for unknown devices, but requires a modalias information source.

Modalias Information Source

A modalias information source is, basically, a very reduced variant of a modules directory that would normally be installed to /lib/modules. The most important file provided by this source is modules.alias, a ideally complete mapping from module alias identifiers to modules.

modalias information sources as used by kernelconfig can be directories, but are usually xz-compressed tarballs that are kept in the modalias cache directory, $HOME/.cache/kernelconfig/modalias.

When kernelconfig is requested to locate a cached source, it will by default only look for sources that have been built for the same target architecture or at least for the same SUBARCH. Furthermore, the kernel version of the cached source must have the same major version and the version difference must not exceed 8 patchlevels. This is the so-called safe mode (--safe-modalias).

In unsafe mode, the kernel's major version must be equal but is otherwise unrestricted, and cached sources for different target architectures are considered, though not preferred. This mode has to be explicitly enabled with --unsafe-modalias.

A new modalias information source can be created with:

kernelconfig --generate-modalias -k /usr/src/linux

This will build all kernel modules using an allmodconfig configuration install them to a temporary directory, run depmod and create a tarball with the relevant files, which is stored in the cache directory as $HOME/.cache/kernelconfig/modalias/{kernelversion}__{arch}.txz, for example $HOME/.cache/kernelconfig/modalias/4.6.5__x86_64.txz.

The tarballs can be shared with others. Since there is no convenient way to import shared tarballs [yet], they have to specified with the --modules-dir option or copied to the cache directory manually.

Be aware of the time and disk space requirements, which are covered in --generate-modalias.

Collecting Hardware Information on a Different Machine

Hardware detection is not limited to the machine running kernelconfig, it is also possible to scan for hardware identifiers on another machine.

Note

modalias-based hardware detection is recommended for this use case.

Example scenarios include booting a live system on the target machine, for example SystemRescueCd, detecting its hardware and sending the information to the build machine, which then feeds kernelconfig with the data. Another example would be a minimal busybox-based initramfs booted via PXE that serves the hardware information via netcat.

For this purpose, kernelconfig offers a hwcollect shell script, which can be found under files/scripts/hwcollect.sh in the project's sources. It scans /sys and creates a JSON file containing the information, which is written to stdout, and can be fed to kernelconfig with the --hwdetect option.

Under normal circumstances, the script can be run by regular users. An exception to that is grsec /sys protections.

If the build machine is able to access the target machine via ssh as user hwcol and the script is installed on the target, the commands for generating a configuration for target with hardware detection would be:

[build] $ ssh -l hwcol target kernelconfig-hwcollect > ./hwinfo.json
[build] $ kernelconfig -H ./hwinfo.json ...

It is also possible to send the script to the target machine via ssh:

[build] $ cd <prjroot>
[build] $ < ./files/scripts/hwcollect.sh ssh -l hwcol target sh > ./hwinfo.json
[build] $ kernelconfig -H ./hwinfo.json ...

The script's dependencies are a few basic programs including a shell, /sys and /proc mounted, and a way to transfer files from the target machine to the build machine.

hwinfo file

The hardware information file is a JSON object with dummy null-terminates that lists which kernel modules and module alias identifiers have been detected on the target machine:

{
    "version": 1,
    "driver": [
        ...,
        ""
    ],
    "modalias": [
        ...,
        ""
    ],
    "__null__": null
}

The version tells kernelconfig the overall structure of the JSON object, it has to be 1.

driver is a list of kernel modules that kernelconfig should enable after translating them to config options, similar to driver-based hardware detection.

modalias is a list of module alias identifiers that kernelconfig should enable after translating them to config options.

__null__ is completely ignored, as are empty strings in lists. JSON list/object items need to be separated with a comma, but a comma after the last item is not allowed. By using dummy null values, this detail can be mostly ignored in the collector script, with a small file size overhead of one dummy item per list/object.

Package Management Integration

Installed packages can serve as source for config option recommendations. This feature relies on packages being managed by portage, and can be requested with packages in the \[options\] section of the settings file.

Two variants of pm-integration are available, static and dynamic, both query the value of the CONFIG_CHECK variable from installed packages, but to a different extent.

static pm-integration uses the package build-time value of CONFIG_CHECK, which can be retrieved quickly, but is not reliable, because CONFIG_CHECK could have been set conditionally, e.g. by comparing the kernel version against the kernel sources being present at package build time.

For that reason, a more reliable but also more (time-)complex solution exists, dynamic pm-integration, which re-evaluates CONFIG_CHECK by running the relevant ebuild phases again.

Either variant transforms CONFIG_CHECK into a sequence of enable option as builtin or module and disable option config modifications. Unknown config options listed in CONFIG_CHECK are ignored.

Warning

dynamic pm-integration runs the pkg_setup() ebuild phase for all installed packages that inherit linux-info.eclass, as regular user.

Since pkg_setup can do arbitrary things like creating users, this can fail for individual packages, in which case kernelconfig prints a warning message and tries to use the information gathered from running the ebuild so far.

  1. It is very unlikely that the failure is caused by kernelconfig, more likely the ebuild is doing things in pkg_setup() that should be handled during pkg_postinst() or pkg_preinst()
  2. Do not run kernelconfig as root, especially when using dynamic pm-integration!

For enewuser/enewgroup related failures, see Gentoo Bug \#217042.

Curated Sources

This section covers how to add new curated sources to kernelconfig.

As previously noted, the purpose of configuration sources is to provide a configuration basis, a non-empty list of files that is used as input .config.

Curated sources are configuration sources that exist separately from the settings file, in the sources subdirectory of the settings directories.

A curated source consists of

  • a script sources/<name> (script only)
  • a source definition file sources/<name>.def (sourcedef only)
  • a source definition file sources/<name>.def plus a script sources/<name> (sourcedef with script) or a Python module sources/<name> (sourcedef with pym)

Script-Only Curated Sources

The simplest case is script only, which is limited to single-file configuration bases. Just put a script in <settings>/source, e.g. $HOME/.config/kernelconfig/sources/my_source, and make it executable.

It can then be referenced in the settings file with:

[source]
my_source

When run, it receives a file path to which the configuration basis should be written to as first argument, the target architecture as second argument, and the short kernel version (kernel version and patchlevel, e.g. 4.1) as third argument. Parameters from the settings file are passed as-is to the script, starting at the fourth argument:

my_source {outconfig} {arch} {kmaj}.{kpatch} ...

The script has also access to the config source environment variables.

At some point, it might be useful to restrict the accepted architectures to what is actually supported and provide a more meaningful help message when kernelconfig --help-source my_source is run.

This can be done by creating a my_source.def source definition file in the same directory with the following content:

[source]
Architectures = x86_64

# use the script-only script calling convention,
#  which passes all unknown parameters as-is to the script
PassUnknownArgs = 1

Description = my source is ...

Source Definition File

Curated sources that are not script-type sources, or sources that want to benefit from argument parsing, need to be described in a source definition file.

Source definition files reside in the same directory as scripts, and their filename must end with .def.

Example: Liquorix (sources/liquorix.def):

[source]
Name = Liquorix

Architectures = x86_64 x86
Features = pae

Type = file
Path = http://liquorix.net/sources/{kmaj}.{kpatch}/config.{param_arch}{param_pae}

Description =
  Liquorix is a distro kernel replacement built using the best configuration
  and kernel sources for desktop, multimedia, and gaming workloads.

[Arch:x86_64]
Value = amd64

[Arch:x86]
Value = i386

[Feature:PAE]
Arch = x86
Value = -pae
Description = enable Physical Address Extensions ...

Liquorix supports 32-bit and 64-bit x86 architectures and has a -pae config variant for 32-bit x86. The config file can be downloaded via http, and the url can be constructed with the information from the source definition file.

The Description options are used for creating the help message that can be viewed with kernelconfig --help-source liquorix.

The source definition file is an ini file. Empty lines are ignored, comment lines start with #, sections are introduced with [<name>], and options are set with <option> = <value>. Option and section names are case-insensitive. Long values can span over multiple lines by indenting subsequent lines with whitespace.

The [source] section describes the source, how to run it, and states which architectures and features are supported.

The following options are recognized in the [source] section:

source definition [source] section options
field name value type required description
Name str default

Name of the curated source

Defaults to the name of the definition file (file suffix removed)

Description str no Description of the curated source, for informational purposes
Type str depends

The type of the source, which can be

  • file
  • script
  • pym
  • command
  • make

If not set, kernelconfig tries to autodetect the type:

  • script if Path= is set, or if a file with the source's name was found in the sources directory,
  • command if Command= is set and does not reference the {script_file} format variable
Path format str depends

For file-type sources, this is the path to the config file and required.

For script- and pym-type sources, this is the path to the script or Python module, and optional. It defaults to <settings dirs>/sources/<name>

Ignored for command and make.

Command

also: Cmd

format str depends

For command-type sources, this field specifies the command to be run and is mandatory.

For script-type sources, this field can be used to override the calling convention. It should include {script_file}, which gets replaced with the script specified in Path

For make-type sources, this field can be used to pass additional arguments to the make command.

Target str yes Target for make-type sources

Architectures

also: Arch

str-list no

List of supported architectures

Defaults to all.

Features

also: Feat

str-list no

List of source variants

Defaults to none (the empty string).

PassUnknownArgs bool no

Controls whether unknown parameters should be accepted. By default, kernelconfig refuses to operate when unknown parameters are encountered.

For script-type sources, the unknown parameters are passed as-is after Command.

|

If a list of supported architectures is specified, all other architectures are considered unsupported for a particular source, and kernelconfig refuses to operate.

Since naming of target architectures varies between sources, [Arch:<name>] sections can be used to provide a name mapping. They only have one option, Value, which sets the alternative name.

For example, x86_64 is often named amd64:

[Arch:x86_64]
Value = amd64

The architecture-rename sections are tried to match with the most specific arch first ($(uname -r), e.g. x86_64), and the most generic arch last (kernel arch, e.g. x86).

For renaming x86 to i386, it is necessary to provide an empty rename section for x86_64 since the kernel architecture is x86 in both cases:

[Arch:x86]
Value = i386

[Arch:x86_64]
#Value = x86_64

Supported architectures can also be listed with the Architectures option in the [source] section.

The renamed architecture is available via the {param_arch} format variable. If rename action has been taken, {param_arch} equals {arch}.

|

Each curated source has an argument parser that verifies and processes the parameters it receives from the settings file.

By default, no parameters are accepted, unless PassUnknownArgs is true.

Configuration sources usually offer several config variants, e.g. a debug variant or a PAE variant for x86. Such variants can be declared with [Feat:<name>] sections, which are converted to argparse arguments and can be specified in the settings file with --<name>.

In the source definition file, they are then available as param_{<name>} format variables for options with format str values Depending on the source type, they can also be accessed via PARAM_{<NAME>} environment variables.

For script-type sources, if no Command= has been specified in the [source] section, the parameters are put in the default command after the kernel version and before the unknown parameters:

{script_file} {outconfig} {arch} {kmaj}.{kpatch} [<param>...] [<unknown>...]

A [Feat:<name>] section can contain the following options:

source definition [Feature:<name>] section options
field name value type required description
Name str no

Name of the parameter, for informational purposes.

Defaults to <name>.

Description str no Description of the parameter, for informational purposes.
Dest str no

Parameter group name, parameters with the same Dest are mutually exclusive.

The group name is used as name for the format and environment variables.

Defaults to <name>.

Type str no

The argument type of the parameter, which can be

  • const

    parameter accepts no value and a constant value (Value) gets stored in Dest if the parameter is given, and the default value (Default) otherwise.

  • optin

    Similar to const, stores y and defaults to the empty string

  • optout

    Similar to const, stores the empty string and defaults to y.

  • arg

    parameter accepts one value and stores it in Dest,

Defaults to const.

Default str no

Default value if the parameter is not specified.

Only meaningful for const- and arg-type parameters.

Defaults to the empty string.

Value str no

Value gets set if the parameter is given

Only meaningful for const-type parameters, in which case it defaults to --<name>.

|

Another section exists that is only relevant to pym-type sources, [Config]. It can be accessed by the source via env.get_config(<option>), which options are recognized is therefore up to the source.

Python-Module Configuration Sources

Python-Module Configuration Sources gain access to kernelconfig's functionality such as error reporting and logging, and also temporary files/directories, file downloading and git repo handling.

A python module source must implement a run() function that takes exactly one argument, which is an object that acts as interface between the source and kernelconfig. It should be named env.

Additionally, a source definition file is required for this type, and its Type needs to be set to pym (in the [source] section).

Here is what a Python module looks like:

# Python Module for the <name> configuration source
# -*- coding: utf-8 -*-

def reset():
    """
    The reset() function is optional.

    It is called whenever the Python Module gets loaded.

    It takes no arguments and does not have access
    to kernelconfig's pymenv interface.

    Usage scenarios include initializing module-level global variables.
    """
    pass
# --- end of reset (...) ---


def run(env):
    """
    The run() function must be implemented
    and is responsible for setting up the configuration basis,
    e.g. by downloading files.

    To facilitate this, it has to access to kernelconfig's pymenv interface,
    which provides some useful helper methods
    as well as error reporting and logging.

    If this function returns False (or false value that is not None),
    kernelconfig prints an error message and exits.
    """

    # The parsed parameters can be accessed via the "parameters" attribute
    params = env.parameters

    # The kernel version for which a configuration basis should be provided
    # can be accessed via the "kernelversion" attribute
    kver = env.kernelversion
    #
    # The kernel version provides access to individual version components via
    # the version, patchlevel, sublevel, subsublevel and rclevel attributes.

    # As an example,
    # the Liquorix source presented before
    # could also be written as a Python-Module source.
    # It needs to
    # (1) construct the url by means of string formatting
    # (2) download the config file
    # (3) register the downloaded file as (part of the) configuration basis
    #
    # It can be done by chaining 3 function calls to pymenv,
    # which also takes care of error handling:
    env.add_config_file(
        env.download_file(
            env.str_format(
                'http://liquorix.net/sources/{kmaj}.{kpatch}/config.{param_arch}{param_pae}'
            )
        )
    )

    # the configuration basis can consist of multiple files,
    # just register them in the order as they should be read later on
    #
    # env.add_config_file(another_config_file)
# --- end of run (...) ---

Template files for pym-type configuration sources can be found in <settings>/sources/skel, named pymsource.def (source definition file) and pymsource (Python module).

The methods and attributes available via the pymenv interface are covered in detail as in-code documentation, which can be read with pydoc kernelconfig.sources.pymenv.

The class-level documentation gives a quick reference over what is offered:

class PymConfigurationSourceRunEnv(...):
    """
    This is the runtime environment that gets passed
    to configuration source python modules, version 1.

    The python module's run() function
    receives the environment as first arg,
    interfacing with kernelconfig should only occur via this environment.

    The following attributes can be referenced by the python module,
    they should all be treated as readonly except where noted otherwise,
    see the @property in-code doc for details:

    * logger:              logger, can also be accessed via log_*() methods

    * name:                conf source name
    * exc_types:           exception types (namespace object/module)
    * parameters:          arg parse result (namespace object)
    * environ:             extra-env vars dict
    * str_formatter:       string formatter
    * format_vars:         string formatter's vars dict
    * kernelversion:       fake kernel version (object)
    * real_kernelversion:  real kernel version (object)
    * tmpdir:              temporary dir object
    * tmpdir_path:         path to temporary dir

    The following methods can be used for communicating with kernelconfig:

    * log_debug(...)         --  log a debug-level message
    * log_info(...)          --  log an info-level message
    * log_warning(...)       --  log a warning-level message
    * log_error(...)         --  log an error-level message

    * error([msg])           --  signal a "config uncreatable" error
                                 (log an error-level message
                                  and raise an appropriate exception)

    * add_config_file(file)  --  add a .config file that will later be
                                 used as configuration basis
                                 (can be called multiple times
                                 in splitconfig scenarios)

    The pym-environment also offers some helper methods, including:

    * run_command(cmdv)      --  run a command
    * get_tmpfile()          --  create new temporary file

    * download(url)          --  download url, return bytes
    * download_file(url)     --  download url to temporary file


    * git_clone_configured_repo()
                             --  clone the repo configured in [config]
                                 and change the working dir to its path

    * git_clone(url)         --  clone a git repo and returns it path,
                                  using a per-confsource cache dir
    * git_checkout_branch(branch)
                             --   switch to git branch

    * run_git(argv)          --  run a git command in $PWD
    * run_git_in(dir, argv)  --  run a git command in <dir>
    """

  1. names are converted to lowercase before searching for the source