Merge pull request #263056 from DanielSidhion/kernel-docs

doc: consolidate info on manual linux kernel configs

authored by Valentin Gagarin and committed by GitHub 57075782 359d5776

+140 -81
+104 -18
doc/packages/linux.section.md
··· 2 3 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). 4 5 - 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`). 6 7 - 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: 8 9 ```nix 10 modulesTree = [kernel] ··· 12 ++ ...; 13 ``` 14 15 - How to add a new (major) version of the Linux kernel to Nixpkgs: 16 17 - 1. Copy the old Nix expression (e.g., `linux-2.6.21.nix`) to the new one (e.g., `linux-2.6.22.nix`) and update it. 18 19 - 2. Add the new kernel to the `kernels` attribute set in `linux-kernels.nix` (e.g., create an attribute `kernel_2_6_22`). 20 21 - 3. Now we’re going to update the kernel configuration. First unpack the kernel. Then for each supported platform (`i686`, `x86_64`, `uml`) do the following: 22 23 - 1. Make a copy from the old config (e.g., `config-2.6.21-i686-smp`) to the new one (e.g., `config-2.6.22-i686-smp`). 24 25 - 2. Copy the config file for this platform (e.g., `config-2.6.22-i686-smp`) to `.config` in the kernel source tree. 26 27 - 3. Run `make oldconfig ARCH={i386,x86_64,um}` and answer all questions. (For the uml configuration, also add `SHELL=bash`.) Make sure to keep the configuration consistent between platforms (i.e., don’t enable some feature on `i686` and disable it on `x86_64`). 28 29 - 4. If needed, you can also run `make menuconfig`: 30 31 - ```ShellSession 32 - $ nix-env -f "<nixpkgs>" -iA ncurses 33 - $ export NIX_CFLAGS_LINK=-lncurses 34 - $ make menuconfig ARCH=arch 35 - ``` 36 37 - 5. Copy `.config` over the new config file (e.g., `config-2.6.22-i686-smp`). 38 39 - 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. 40 41 - 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.
··· 2 3 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). 4 5 + The function [`pkgs.buildLinux`](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/generic.nix) builds a kernel with [common configuration values](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/common-config.nix). 6 + This is the preferred option unless you have a very specific use case. 7 + Most kernels packaged in Nixpkgs are built that way, and it will also generate kernels suitable for NixOS. 8 + [`pkgs.linuxManualConfig`](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/manual-config.nix) requires a complete configuration to be passed. 9 + It has fewer additional features than `pkgs.buildLinux`, which provides common configuration values and exposes the `features` attribute, as explained below. 10 11 + 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`). 12 + 13 + 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. 14 + 15 + :::{.example #ex-skip-package-from-kernel-feature} 16 + 17 + # Skipping an external package because of a kernel feature 18 + 19 + 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: 20 21 ```nix 22 modulesTree = [kernel] ··· 24 ++ ...; 25 ``` 26 27 + ::: 28 29 + If you are using a kernel packaged in Nixpkgs, you can customize it by overriding its arguments. For details on how each argument affects the generated kernel, refer to [the `pkgs.buildLinux` source code](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/generic.nix). 30 31 + :::{.example #ex-overriding-kernel-derivation} 32 33 + # Overriding the kernel derivation 34 35 + Assuming you are using the kernel from `pkgs.linux_latest`: 36 37 + ```nix 38 + pkgs.linux_latest.override { 39 + ignoreConfigErrors = true; 40 + autoModules = false; 41 + kernelPreferBuiltin = true; 42 + extraStructuredConfig = with lib.kernel; { 43 + DEBUG_KERNEL = yes; 44 + FRAME_POINTER = yes; 45 + KGDB = yes; 46 + KGDB_SERIAL_CONSOLE = yes; 47 + DEBUG_INFO = yes; 48 + }; 49 + } 50 + ``` 51 52 + ::: 53 54 + ## Manual kernel configuration {#sec-manual-kernel-configuration} 55 56 + Sometimes it may not be desirable to use kernels built with `pkgs.buildLinux`, especially if most of the common configuration has to be altered or disabled to achieve a kernel as expected by the target use case. 57 + 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. 58 59 + :::{.example #ex-using-linux-manual-config} 60 61 + # Using `pkgs.linuxManualConfig` with a specific source, version, and config file 62 63 + ```nix 64 + { pkgs, ... }: { 65 + version = "6.1.55"; 66 + src = pkgs.fetchurl { 67 + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; 68 + hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8"; 69 + }; 70 + configfile = ./path_to_config_file; 71 + linux = pkgs.linuxManualConfig { 72 + inherit version src configfile; 73 + allowImportFromDerivation = true; 74 + }; 75 + } 76 + ``` 77 + 78 + If necessary, the version string can be slightly modified to explicitly mark it as a custom version. If you do so, ensure the `modDirVersion` attribute matches the source's version, otherwise the build will fail. 79 + 80 + ```nix 81 + { pkgs, ... }: { 82 + version = "6.1.55-custom"; 83 + modDirVersion = "6.1.55"; 84 + src = pkgs.fetchurl { 85 + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${modDirVersion}.tar.xz"; 86 + hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8"; 87 + }; 88 + configfile = ./path_to_config_file; 89 + linux = pkgs.linuxManualConfig { 90 + inherit version modDirVersion src configfile; 91 + allowImportFromDerivation = true; 92 + }; 93 + } 94 + ``` 95 + 96 + ::: 97 + 98 + Additional attributes can be used with `linuxManualConfig` for further customisation. You're encouraged to read [the `pkgs.linuxManualConfig` source code](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/manual-config.nix) to understand how to use them. 99 + 100 + To edit the `.config` file for Linux X.Y from within Nix, proceed as follows: 101 + 102 + ```ShellSession 103 + $ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv 104 + $ unpackPhase 105 + $ cd linux-* 106 + $ make nconfig 107 + ``` 108 + 109 + ## Developing kernel modules {#sec-linux-kernel-developing-modules} 110 + 111 + When developing kernel modules it's often convenient to run the edit-compile-run loop as quickly as possible. 112 + See the snippet below as an example. 113 + 114 + :::{.example #ex-edit-compile-run-kernel-modules} 115 + 116 + # Edit-compile-run loop when developing `mellanox` drivers 117 + 118 + ```ShellSession 119 + $ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev 120 + $ nix-shell '<nixpkgs>' -A linuxPackages.kernel 121 + $ unpackPhase 122 + $ cd linux-* 123 + $ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules 124 + # insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 125 + ``` 126 + 127 + :::
+3 -63
nixos/doc/manual/configuration/linux-kernel.chapter.md
··· 84 85 ## Building a custom kernel {#sec-linux-config-customizing} 86 87 - You can customize the default kernel configuration by overriding the arguments for your kernel package: 88 - 89 - ```nix 90 - pkgs.linux_latest.override { 91 - ignoreConfigErrors = true; 92 - autoModules = false; 93 - kernelPreferBuiltin = true; 94 - extraStructuredConfig = with lib.kernel; { 95 - DEBUG_KERNEL = yes; 96 - FRAME_POINTER = yes; 97 - KGDB = yes; 98 - KGDB_SERIAL_CONSOLE = yes; 99 - DEBUG_INFO = yes; 100 - }; 101 - } 102 - ``` 103 - 104 - See `pkgs/os-specific/linux/kernel/generic.nix` for details on how these arguments 105 - affect the generated configuration. You can also build a custom version of Linux by calling 106 - `pkgs.buildLinux` directly, which requires the `src` and `version` arguments to be specified. 107 108 To use your custom kernel package in your NixOS configuration, set 109 ··· 111 boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel; 112 ``` 113 114 - Note that this method will use the common configuration defined in `pkgs/os-specific/linux/kernel/common-config.nix`, 115 - which is suitable for a NixOS system. 116 - 117 - If you already have a generated configuration file, you can build a kernel that uses it with `pkgs.linuxManualConfig`: 118 - 119 - ```nix 120 - let 121 - baseKernel = pkgs.linux_latest; 122 - in pkgs.linuxManualConfig { 123 - inherit (baseKernel) src modDirVersion; 124 - version = "${baseKernel.version}-custom"; 125 - configfile = ./my_kernel_config; 126 - allowImportFromDerivation = true; 127 - } 128 - ``` 129 - 130 - ::: {.note} 131 - The build will fail if `modDirVersion` does not match the source's `kernel.release` file, 132 - so `modDirVersion` should remain tied to `src`. 133 - ::: 134 - 135 - To edit the `.config` file for Linux X.Y, proceed as follows: 136 - 137 - ```ShellSession 138 - $ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv 139 - $ unpackPhase 140 - $ cd linux-* 141 - $ make nconfig 142 - ``` 143 - 144 ## Developing kernel modules {#sec-linux-config-developing-modules} 145 146 - When developing kernel modules it's often convenient to run 147 - edit-compile-run loop as quickly as possible. See below snippet as an 148 - example of developing `mellanox` drivers. 149 - 150 - ```ShellSession 151 - $ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev 152 - $ nix-shell '<nixpkgs>' -A linuxPackages.kernel 153 - $ unpackPhase 154 - $ cd linux-* 155 - $ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules 156 - # insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 157 - ``` 158 159 ## ZFS {#sec-linux-zfs} 160 ··· 163 with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`). 164 165 Alternatively, it's possible to pin the system to the latest available kernel 166 - version *that is supported by ZFS* like this: 167 168 ```nix 169 {
··· 84 85 ## Building a custom kernel {#sec-linux-config-customizing} 86 87 + Please refer to the Nixpkgs manual for the various ways of [building a custom kernel](https://nixos.org/nixpkgs/manual#sec-linux-kernel). 88 89 To use your custom kernel package in your NixOS configuration, set 90 ··· 92 boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel; 93 ``` 94 95 ## Developing kernel modules {#sec-linux-config-developing-modules} 96 97 + This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#sec-linux-kernel-developing-modules). 98 99 ## ZFS {#sec-linux-zfs} 100 ··· 103 with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`). 104 105 Alternatively, it's possible to pin the system to the latest available kernel 106 + version _that is supported by ZFS_ like this: 107 108 ```nix 109 {
+33
pkgs/os-specific/linux/kernel/README.md
···
··· 1 + # How to add a new (major) version of the Linux kernel to Nixpkgs: 2 + 3 + 1. Copy the old Nix expression (e.g., `linux-2.6.21.nix`) to the new one (e.g., `linux-2.6.22.nix`) and update it. 4 + 5 + 2. Add the new kernel to the `kernels` attribute set in [`linux-kernels.nix`](./linux-kernels.nix) (e.g., create an attribute `kernel_2_6_22`). 6 + 7 + 3. Update the kernel configuration. First unpack the kernel. Then for each supported platform (`i686`, `x86_64`, `uml`) do the following: 8 + 9 + 1. Make a copy from the old config (e.g., `config-2.6.21-i686-smp`) to the new one (e.g., `config-2.6.22-i686-smp`). 10 + 11 + 2. Copy the config file for this platform (e.g., `config-2.6.22-i686-smp`) to `.config` in the kernel source tree. 12 + 13 + 3. Run `make oldconfig ARCH={i386,x86_64,um}` and answer all questions. (For the uml configuration, also add `SHELL=bash`.) Make sure to keep the configuration consistent between platforms (i.e., don’t enable some feature on `i686` and disable it on `x86_64`). 14 + 15 + 4. If needed, you can also run `make menuconfig`: 16 + 17 + ```ShellSession 18 + $ nix-env -f "<nixpkgs>" -iA ncurses 19 + $ export NIX_CFLAGS_LINK=-lncurses 20 + $ make menuconfig ARCH=arch 21 + ``` 22 + 23 + 5. Copy `.config` over the new config file (e.g., `config-2.6.22-i686-smp`). 24 + 25 + 4. Test building the kernel: 26 + 27 + ```ShellSession 28 + nix-build -A linuxKernel.kernels.kernel_2_6_22 29 + ``` 30 + 31 + If it compiles, ship it! For extra credit, try booting NixOS with it. 32 + 33 + 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.