Skip to content

Commit

Permalink
doc: consolidate info on manual linux kernel configs
Browse files Browse the repository at this point in the history
The Nixpkgs documentation on the linux kernel builders focused on
using and extending kernels that were already packaged, but never
mentioned that it's possible to also build a kernel almost "from
scratch".
The NixOS documentation went a bit deeper on manual linux kernel
configs.

This commit consolidates the information related to building the
kernel on Nixpkgs's documentation, while keeping any additional
configuration-specific information on NixOS's documentation.
  • Loading branch information
DanielSidhion committed Oct 26, 2023
1 parent 200aa03 commit f2e42c3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 35 deletions.
37 changes: 35 additions & 2 deletions doc/builders/packages/linux.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

The Nix expressions to build the Linux kernel are in [`pkgs/os-specific/linux/kernel`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel).

The function that builds the kernel has an argument `kernelPatches` which should be a list of `{name, patch, extraConfig}` attribute sets, where `name` is the name of the patch (which is included in the kernel’s `meta.description` attribute), `patch` is the patch itself (possibly compressed), and `extraConfig` (optional) is a string specifying extra options to be concatenated to the kernel configuration file (`.config`).
[`pkgs/os-specific/linux/kernel/generic.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel/generic.nix) builds a kernel with common config values (defined in [`pkgs/os-specific/linux/kernel/common-config.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel/common-config.nix)), and is exposed in `pkgs.buildLinux`. This is the preferred option unless you have a very specific use case. Most kernels packaged in Nixpkgs are built through it, and it will also generate kernels suitable for NixOS.
[`pkgs/os-specific/linux/kernel/manual-config.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel/manual-config.nix) requires all configs to be passed and is much closer to a minimal build. It is exposed in `pkgs.linuxManualConfig`.

The kernel derivation exports an attribute `features` specifying whether optional functionality is or isn’t enabled. This is used in NixOS to implement kernel-specific behaviour. For instance, if the kernel has the `iwlwifi` feature (i.e., has built-in support for Intel wireless chipsets), then NixOS doesn’t have to build the external `iwlwifi` package:
Both functions have an argument `kernelPatches` which should be a list of `{name, patch, extraConfig}` attribute sets, where `name` is the name of the patch (which is included in the kernel’s `meta.description` attribute), `patch` is the patch itself (possibly compressed), and `extraConfig` (optional) is a string specifying extra options to be concatenated to the kernel configuration file (`.config`).

The kernel derivation created with `pkgs.buildLinux` exports an attribute `features` specifying whether optional functionality is or isn’t enabled. This is used in NixOS to implement kernel-specific behaviour. For instance, if the kernel has the `iwlwifi` feature (i.e., has built-in support for Intel wireless chipsets), then NixOS doesn’t have to build the external `iwlwifi` package:

```nix
modulesTree = [kernel]
Expand Down Expand Up @@ -39,3 +42,33 @@ How to add a new (major) version of the Linux kernel to Nixpkgs:
4. Test building the kernel: `nix-build -A linuxKernel.kernels.kernel_2_6_22`. If it compiles, ship it! For extra credit, try booting NixOS with it.

5. It may be that the new kernel requires updating the external kernel modules and kernel-dependent packages listed in the `linuxPackagesFor` function in `linux-kernels.nix` (such as the NVIDIA drivers, AUFS, etc.). If the updated packages aren’t backwards compatible with older kernels, you may need to keep the older versions around.

## Manual kernel configs {#sec-manual-kernel-configs}

Sometimes it may not be desirable to use kernels built with `pkgs.buildLinux`, especially if most of the default configuration has to be altered or disabled to achieve a kernel as expected by the target use case. An example of this is building a kernel for use in a VM or micro VM. You can use `pkgs.linuxManualConfig` in these cases. It requires the `src`, `version`, and `configfile` attributes to be specified. An example usage:

```nix
{ pkgs, ... }: {
version = "6.1.55";
src = pkgs.fetchurl {
url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz";
hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8";
};
configfile = ./path_to_config_file;
linux = pkgs.linuxManualConfig {
inherit version src configfile;
allowImportFromDerivation = true;
};
}
```

Additional attributes can be used with `linuxManualConfig` for further customisation. You're encouraged to read [`pkgs/os-specific/linux/kernel/manual-config.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel/manual-config.nix) to understand how to use them.

To edit the `.config` file for Linux X.Y, proceed as follows:

```ShellSession
$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
$ unpackPhase
$ cd linux-*
$ make nconfig
```
36 changes: 3 additions & 33 deletions nixos/doc/manual/configuration/linux-kernel.chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,45 +102,15 @@ pkgs.linux_latest.override {
```

See `pkgs/os-specific/linux/kernel/generic.nix` for details on how these arguments
affect the generated configuration. You can also build a custom version of Linux by calling
`pkgs.buildLinux` directly, which requires the `src` and `version` arguments to be specified.
affect the generated configuration.
You can also use any of the linux builders directly (see [this section](https://nixos.org/nixpkgs/manual#sec-linux-kernel) on the Nixpkgs manual), which will likely require the `src` and `version` arguments to be specified.

To use your custom kernel package in your NixOS configuration, set

```nix
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
```

Note that this method will use the common configuration defined in `pkgs/os-specific/linux/kernel/common-config.nix`,
which is suitable for a NixOS system.

If you already have a generated configuration file, you can build a kernel that uses it with `pkgs.linuxManualConfig`:

```nix
let
baseKernel = pkgs.linux_latest;
in pkgs.linuxManualConfig {
inherit (baseKernel) src modDirVersion;
version = "${baseKernel.version}-custom";
configfile = ./my_kernel_config;
allowImportFromDerivation = true;
}
```

::: {.note}
The build will fail if `modDirVersion` does not match the source's `kernel.release` file,
so `modDirVersion` should remain tied to `src`.
:::

To edit the `.config` file for Linux X.Y, proceed as follows:

```ShellSession
$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
$ unpackPhase
$ cd linux-*
$ make nconfig
```

## Developing kernel modules {#sec-linux-config-developing-modules}

When developing kernel modules it's often convenient to run
Expand All @@ -163,7 +133,7 @@ available Linux kernel. It is recommended to use the latest available LTS that's
with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`).

Alternatively, it's possible to pin the system to the latest available kernel
version *that is supported by ZFS* like this:
version _that is supported by ZFS_ like this:

```nix
{
Expand Down

0 comments on commit f2e42c3

Please sign in to comment.