1# Linux kernel {#sec-linux-kernel} 2 3The 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 5The 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). 6This is the preferred option unless you have a very specific use case. 7Most 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. 9It has fewer additional features than `pkgs.buildLinux`, which provides common configuration values and exposes the `features` attribute, as explained below. 10 11Both 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 13The 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 15If 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). 16 17:::{.example #ex-overriding-kernel-derivation} 18 19# Overriding the kernel derivation 20 21Assuming you are using the kernel from `pkgs.linux_latest`: 22 23```nix 24pkgs.linux_latest.override { 25 ignoreConfigErrors = true; 26 autoModules = false; 27 kernelPreferBuiltin = true; 28 extraStructuredConfig = with lib.kernel; { 29 DEBUG_KERNEL = yes; 30 FRAME_POINTER = yes; 31 KGDB = yes; 32 KGDB_SERIAL_CONSOLE = yes; 33 DEBUG_INFO = yes; 34 }; 35} 36``` 37 38::: 39 40## Manual kernel configuration {#sec-manual-kernel-configuration} 41 42Sometimes 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. 43An 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. 44 45:::{.example #ex-using-linux-manual-config} 46 47# Using `pkgs.linuxManualConfig` with a specific source, version, and config file 48 49```nix 50{ pkgs, ... }: { 51 version = "6.1.55"; 52 src = pkgs.fetchurl { 53 url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; 54 hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8"; 55 }; 56 configfile = ./path_to_config_file; 57 linux = pkgs.linuxManualConfig { 58 inherit version src configfile; 59 allowImportFromDerivation = true; 60 }; 61} 62``` 63 64If 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. 65 66```nix 67{ pkgs, ... }: { 68 version = "6.1.55-custom"; 69 modDirVersion = "6.1.55"; 70 src = pkgs.fetchurl { 71 url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${modDirVersion}.tar.xz"; 72 hash = "sha256:1h0mzx52q9pvdv7rhnvb8g68i7bnlc9rf8gy9qn4alsxq4g28zm8"; 73 }; 74 configfile = ./path_to_config_file; 75 linux = pkgs.linuxManualConfig { 76 inherit version modDirVersion src configfile; 77 allowImportFromDerivation = true; 78 }; 79} 80``` 81 82::: 83 84Additional 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. 85 86To edit the `.config` file for Linux X.Y from within Nix, proceed as follows: 87 88```ShellSession 89$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv 90$ unpackPhase 91$ cd linux-* 92$ make nconfig 93``` 94 95## Developing kernel modules {#sec-linux-kernel-developing-modules} 96 97When developing kernel modules it's often convenient to run the edit-compile-run loop as quickly as possible. 98See the snippet below as an example. 99 100:::{.example #ex-edit-compile-run-kernel-modules} 101 102# Edit-compile-run loop when developing `mellanox` drivers 103 104```ShellSession 105$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev 106$ nix-shell '<nixpkgs>' -A linuxPackages.kernel 107$ unpackPhase 108$ cd linux-* 109$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules 110# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 111``` 112 113:::