#kernel #configuration #lua #kconfig #config-file #file-change

bin+lib autokernel

Autokernel is a tool for managing your kernel configuration that guarantees semantic correctness. It checks symbol assignments for validity by creating a native bridge to the kernel's Kconfig interface and ensures that your configuration does not silently break during kernel updates

2 stable releases

2.0.2 Mar 3, 2023
2.0.1 Nov 14, 2022

#2085 in Command line utilities

MIT license

125KB
3K SLoC

Rust 2.5K SLoC // 0.0% comments Lua 188 SLoC // 0.0% comments C 142 SLoC // 0.2% comments Shell 58 SLoC // 0.0% comments

Tutorial Crates.io MIT License

About autokernel

Autokernel is a tool for managing your kernel configuration that guarantees semantic correctness. It checks symbol assignments for validity by creating a native bridge to the kernel's Kconfig interface and ensures that your configuration does not silently break during kernel updates. The next time a config option is removed or renamed, similar to when CONFIG_THUNDERBOLT was merged with CONFIG_USB4, you will notice.

It provides a configuration framework which understands the semantics behind symbols, their dependencies and allowed values and enforces these rules when generating the final .config kernel configuration file. It is able to automatically resolve symbol dependencies and show useful diagnostics to help you solve configuration errors.

The configuration itself can be written using traditional kconfig files or by using the more flexible and powerful lua scripting api. This allows for more complex logic and compatibility with multiple kernel versions. All kernel versions back to v4.2.0 are supported.

Installation & Quickstart

Autokernel can be installed with cargo:

$ cargo install autokernel

Afterwards you will need to create a /etc/autokernel/config.toml (for a reference see examples/config.toml). Here you can configure which script is used to generate the kernel configuration and how the artifacts should be installed to your system when using autokernel build --install.

[config]
#script = "/etc/autokernel/legacy.config"
script = "/etc/autokernel/config.lua"

Now you can write your kernel configuration. You can either use a classic kconfig file here (just change the config above as the comment shows), or use the recommended lua interface. The provided lua API is a more powerful and versatile way to write your configuration. With it you will be able to create more structured, complex and reusable configurations. See tutorial.lua for an introduction to the api. Here's a very small example config.lua:

-- Begin with the defconfig for your architecture
load_kconfig_unchecked(kernel_dir .. "/arch/x86/configs/x86_64_defconfig")
-- Change some symbols
NET "y"
USB "y"

Finally run autokernel to generate a .config file. In case your configuration contains any errors, autokernel will abort and print the relevant diagnostics.

# Just generate the {kernel_dir}/.config file
$ autokernel generate-config
# Or directly build the whole kernel
$ autokernel build

If you want to maintain a package for your favourite distribution, feel free to do so and let us know!

Introduction

To set a symbol you can use the syntax below.

-- This will set `CONFIG_NET` to yes.
NET "y"

You can also try to assign a value that isn't allowed:

-- `CONFIG_NET` is a boolean symbol, so mod isn't allowed.
NET "m"

The kernel would usually ignore such statements entirely. Autokernel will instead abort with an error and display diagnostics telling you that only n or y are allowed:

Invalid assignment

Kernel options can also only be assigned if they are visible, meaning that their dependencies must be met. If you try to enable an option that has unmet dependencies, autokernel will detect that and automatically suggest a solution.

-- This requires WLAN=y and NETDEVICES=y
WLAN_VENDOR_REALTEK "y"

Automatic dependency resolution

Instead of blindly copying these assignments into your config, you can also invoke the solver directly from lua. This will only work when the solution is unambiguous, otherwise autokernel will raise an error and tell you what is missing.

-- Enable WLAN_VENDOR_REALTEK and any required dependencies
WLAN_VENDOR_REALTEK:satisfy { y, recursive = true }

You can also view what you would have to change without provoking an error in your config first by using autokernel satisfy --recursive WLAN_VENDOR_REALTEK as a one-shot command.

One-shot dependency resolution

There are also some symbols that cannot be set manually, like RTLWIFI_USB. Trying to assign them directly will cause an error:

RTLWIFI_USB "y"

Manual assignment error

Instead, these need to be enabled by setting another symbol that depends on RTLWIFI_USB. The automatic satisfier is able to solve these aswell, so you can use the same command as above to find the required assignments or just use satisfy directly from lua again:

RTLWIFI_USB:satisfy { y, recursive = true }

Finally you might want to build more complex scripts, which is were lua comes into play. It will allow you to do conditional assignments like this:

if kernel_version >= ver("5.6") then
	USB4 "y"
else
	THUNDERBOLT "y"
end

Refer to tutorial.lua for a thorough introduction to the api.

Hardening example

For an example configuration for kernel hardening, see hardening.lua.

Dependencies

~6–18MB
~254K SLoC