···23The 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).
45-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`).
000067-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:
0000000089```nix
10modulesTree = [kernel]
···12 ++ ...;
13```
1415-How to add a new (major) version of the Linux kernel to Nixpkgs:
1617-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.
1819-2. Add the new kernel to the `kernels` attribute set in `linux-kernels.nix` (e.g., create an attribute `kernel_2_6_22`).
2021-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:
2223- 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`).
2425- 2. Copy the config file for this platform (e.g., `config-2.6.22-i686-smp`) to `.config` in the kernel source tree.
00000000000002627- 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`).
2829- 4. If needed, you can also run `make menuconfig`:
3031- ```ShellSession
32- $ nix-env -f "<nixpkgs>" -iA ncurses
33- $ export NIX_CFLAGS_LINK=-lncurses
34- $ make menuconfig ARCH=arch
35- ```
3637- 5. Copy `.config` over the new config file (e.g., `config-2.6.22-i686-smp`).
3839-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.
4041-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.
0000000000000000000000000000000000000000000000000000000000000000
···23The 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).
45+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.
1011+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:
2021```nix
22modulesTree = [kernel]
···24 ++ ...;
25```
2627+:::
2829+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).
3031+:::{.example #ex-overriding-kernel-derivation}
3233+# Overriding the kernel derivation
3435+Assuming you are using the kernel from `pkgs.linux_latest`:
3637+```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+```
5152+:::
5354+## Manual kernel configuration {#sec-manual-kernel-configuration}
5556+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.
0005859+:::{.example #ex-using-linux-manual-config}
6061+# Using `pkgs.linuxManualConfig` with a specific source, version, and config file
6263+```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+:::
···8485## Building a custom kernel {#sec-linux-config-customizing}
8687-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.
107108To use your custom kernel package in your NixOS configuration, set
109···111boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
112```
113114-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}
145146-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-```
158159## ZFS {#sec-linux-zfs}
160···163with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`).
164165Alternatively, it's possible to pin the system to the latest available kernel
166-version *that is supported by ZFS* like this:
167168```nix
169{
···8485## Building a custom kernel {#sec-linux-config-customizing}
8687+Please refer to the Nixpkgs manual for the various ways of [building a custom kernel](https://nixos.org/nixpkgs/manual#sec-linux-kernel).
00000000000000000008889To use your custom kernel package in your NixOS configuration, set
90···92boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
93```
9400000000000000000000000000000095## Developing kernel modules {#sec-linux-config-developing-modules}
9697+This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#sec-linux-kernel-developing-modules).
000000000009899## ZFS {#sec-linux-zfs}
100···103with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`).
104105Alternatively, it's possible to pin the system to the latest available kernel
106+version _that is supported by ZFS_ like this:
107108```nix
109{
+33
pkgs/os-specific/linux/kernel/README.md
···000000000000000000000000000000000
···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.