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.
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!
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:
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"
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.
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"
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.
For an example configuration for kernel hardening, see hardening.lua.