···2233The 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).
4455-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`).
55+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).
66+This is the preferred option unless you have a very specific use case.
77+Most kernels packaged in Nixpkgs are built that way, and it will also generate kernels suitable for NixOS.
88+[`pkgs.linuxManualConfig`](https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/manual-config.nix) requires a complete configuration to be passed.
99+It has fewer additional features than `pkgs.buildLinux`, which provides common configuration values and exposes the `features` attribute, as explained below.
61077-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:
1111+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`).
1212+1313+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.
1414+1515+:::{.example #ex-skip-package-from-kernel-feature}
1616+1717+# Skipping an external package because of a kernel feature
1818+1919+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:
820921```nix
1022modulesTree = [kernel]
···1224 ++ ...;
1325```
14261515-How to add a new (major) version of the Linux kernel to Nixpkgs:
2727+:::
16281717-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.
2929+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).
18301919-2. Add the new kernel to the `kernels` attribute set in `linux-kernels.nix` (e.g., create an attribute `kernel_2_6_22`).
3131+:::{.example #ex-overriding-kernel-derivation}
20322121-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:
3333+# Overriding the kernel derivation
22342323- 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`).
3535+Assuming you are using the kernel from `pkgs.linux_latest`:
24362525- 2. Copy the config file for this platform (e.g., `config-2.6.22-i686-smp`) to `.config` in the kernel source tree.
3737+```nix
3838+pkgs.linux_latest.override {
3939+ ignoreConfigErrors = true;
4040+ autoModules = false;
4141+ kernelPreferBuiltin = true;
4242+ extraStructuredConfig = with lib.kernel; {
4343+ DEBUG_KERNEL = yes;
4444+ FRAME_POINTER = yes;
4545+ KGDB = yes;
4646+ KGDB_SERIAL_CONSOLE = yes;
4747+ DEBUG_INFO = yes;
4848+ };
4949+}
5050+```
26512727- 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`).
5252+:::
28532929- 4. If needed, you can also run `make menuconfig`:
5454+## Manual kernel configuration {#sec-manual-kernel-configuration}
30553131- ```ShellSession
3232- $ nix-env -f "<nixpkgs>" -iA ncurses
3333- $ export NIX_CFLAGS_LINK=-lncurses
3434- $ make menuconfig ARCH=arch
3535- ```
5656+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.
5757+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.
36583737- 5. Copy `.config` over the new config file (e.g., `config-2.6.22-i686-smp`).
5959+:::{.example #ex-using-linux-manual-config}
38603939-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.
6161+# Using `pkgs.linuxManualConfig` with a specific source, version, and config file
40624141-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.
6363+```nix
6464+{ pkgs, ... }: {
6565+ version = "6.1.55";
6666+ src = pkgs.fetchurl {
6767+ url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz";
6868+ hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8";
6969+ };
7070+ configfile = ./path_to_config_file;
7171+ linux = pkgs.linuxManualConfig {
7272+ inherit version src configfile;
7373+ allowImportFromDerivation = true;
7474+ };
7575+}
7676+```
7777+7878+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.
7979+8080+```nix
8181+{ pkgs, ... }: {
8282+ version = "6.1.55-custom";
8383+ modDirVersion = "6.1.55";
8484+ src = pkgs.fetchurl {
8585+ url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${modDirVersion}.tar.xz";
8686+ hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8";
8787+ };
8888+ configfile = ./path_to_config_file;
8989+ linux = pkgs.linuxManualConfig {
9090+ inherit version modDirVersion src configfile;
9191+ allowImportFromDerivation = true;
9292+ };
9393+}
9494+```
9595+9696+:::
9797+9898+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.
9999+100100+To edit the `.config` file for Linux X.Y from within Nix, proceed as follows:
101101+102102+```ShellSession
103103+$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
104104+$ unpackPhase
105105+$ cd linux-*
106106+$ make nconfig
107107+```
108108+109109+## Developing kernel modules {#sec-linux-kernel-developing-modules}
110110+111111+When developing kernel modules it's often convenient to run the edit-compile-run loop as quickly as possible.
112112+See the snippet below as an example.
113113+114114+:::{.example #ex-edit-compile-run-kernel-modules}
115115+116116+# Edit-compile-run loop when developing `mellanox` drivers
117117+118118+```ShellSession
119119+$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev
120120+$ nix-shell '<nixpkgs>' -A linuxPackages.kernel
121121+$ unpackPhase
122122+$ cd linux-*
123123+$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
124124+# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
125125+```
126126+127127+:::
···84848585## Building a custom kernel {#sec-linux-config-customizing}
86868787-You can customize the default kernel configuration by overriding the arguments for your kernel package:
8888-8989-```nix
9090-pkgs.linux_latest.override {
9191- ignoreConfigErrors = true;
9292- autoModules = false;
9393- kernelPreferBuiltin = true;
9494- extraStructuredConfig = with lib.kernel; {
9595- DEBUG_KERNEL = yes;
9696- FRAME_POINTER = yes;
9797- KGDB = yes;
9898- KGDB_SERIAL_CONSOLE = yes;
9999- DEBUG_INFO = yes;
100100- };
101101-}
102102-```
103103-104104-See `pkgs/os-specific/linux/kernel/generic.nix` for details on how these arguments
105105-affect the generated configuration. You can also build a custom version of Linux by calling
106106-`pkgs.buildLinux` directly, which requires the `src` and `version` arguments to be specified.
8787+Please refer to the Nixpkgs manual for the various ways of [building a custom kernel](https://nixos.org/nixpkgs/manual#sec-linux-kernel).
1078810889To use your custom kernel package in your NixOS configuration, set
10990···11192boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
11293```
11394114114-Note that this method will use the common configuration defined in `pkgs/os-specific/linux/kernel/common-config.nix`,
115115-which is suitable for a NixOS system.
116116-117117-If you already have a generated configuration file, you can build a kernel that uses it with `pkgs.linuxManualConfig`:
118118-119119-```nix
120120-let
121121- baseKernel = pkgs.linux_latest;
122122-in pkgs.linuxManualConfig {
123123- inherit (baseKernel) src modDirVersion;
124124- version = "${baseKernel.version}-custom";
125125- configfile = ./my_kernel_config;
126126- allowImportFromDerivation = true;
127127-}
128128-```
129129-130130-::: {.note}
131131-The build will fail if `modDirVersion` does not match the source's `kernel.release` file,
132132-so `modDirVersion` should remain tied to `src`.
133133-:::
134134-135135-To edit the `.config` file for Linux X.Y, proceed as follows:
136136-137137-```ShellSession
138138-$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
139139-$ unpackPhase
140140-$ cd linux-*
141141-$ make nconfig
142142-```
143143-14495## Developing kernel modules {#sec-linux-config-developing-modules}
14596146146-When developing kernel modules it's often convenient to run
147147-edit-compile-run loop as quickly as possible. See below snippet as an
148148-example of developing `mellanox` drivers.
149149-150150-```ShellSession
151151-$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev
152152-$ nix-shell '<nixpkgs>' -A linuxPackages.kernel
153153-$ unpackPhase
154154-$ cd linux-*
155155-$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
156156-# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
157157-```
9797+This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#sec-linux-kernel-developing-modules).
1589815999## ZFS {#sec-linux-zfs}
160100···163103with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`).
164104165105Alternatively, it's possible to pin the system to the latest available kernel
166166-version *that is supported by ZFS* like this:
106106+version _that is supported by ZFS_ like this:
167107168108```nix
169109{
+33
pkgs/os-specific/linux/kernel/README.md
···11+# How to add a new (major) version of the Linux kernel to Nixpkgs:
22+33+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.
44+55+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`).
66+77+3. Update the kernel configuration. First unpack the kernel. Then for each supported platform (`i686`, `x86_64`, `uml`) do the following:
88+99+ 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`).
1010+1111+ 2. Copy the config file for this platform (e.g., `config-2.6.22-i686-smp`) to `.config` in the kernel source tree.
1212+1313+ 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`).
1414+1515+ 4. If needed, you can also run `make menuconfig`:
1616+1717+ ```ShellSession
1818+ $ nix-env -f "<nixpkgs>" -iA ncurses
1919+ $ export NIX_CFLAGS_LINK=-lncurses
2020+ $ make menuconfig ARCH=arch
2121+ ```
2222+2323+ 5. Copy `.config` over the new config file (e.g., `config-2.6.22-i686-smp`).
2424+2525+4. Test building the kernel:
2626+2727+```ShellSession
2828+nix-build -A linuxKernel.kernels.kernel_2_6_22
2929+```
3030+3131+If it compiles, ship it! For extra credit, try booting NixOS with it.
3232+3333+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.