Linux kernel: Difference between revisions

From NixOS Wiki
imported>Zimbatm
m ws
imported>SteveeJ
Add custom kernel sources example
Line 135: Line 135:
- arch: https://git.archlinux.org/svntogit/packages.git/tree/trunk/config?h=packages/linux
- arch: https://git.archlinux.org/svntogit/packages.git/tree/trunk/config?h=packages/linux
- debian: https://salsa.debian.org/kernel-team/linux/blob/master/debian/config/config and the ARCH specific ones
- debian: https://salsa.debian.org/kernel-team/linux/blob/master/debian/config/config and the ARCH specific ones
== Booting a kernel from a custom source ==
The following example shows how to configure NixOS to compile and boot a kernel from a custom source, and with custom configuration options.
<syntaxHighlight lang=nix>
{ pkgs, ... }:
{
  boot.kernelPackages = let
      linux_sgx_pkg = { stdenv, fetchurl, buildLinux, ... } @ args:
        with stdenv.lib;
        buildLinux (args // rec {
          version = "5.4.0-rc3";
          modDirVersion = "5.4.0-rc3";
          src = fetchurl {
            url = "https://github.com/jsakkine-intel/linux-sgx/archive/v23.tar.gz";
            sha256 = "11rwlwv7s071ia889dk1dgrxprxiwgi7djhg47vi56dj81jgib20";
          };
          kernelPatches = [];
          extraConfig = ''
            INTEL_SGX y
          '';
          extraMeta.branch = "5.4";
        } // (args.argsOverride or {}));
      linux_sgx = pkgs.callPackage linux_sgx_pkg{};
    in
      pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor linux_sgx);
}
</syntaxHighlight>





Revision as of 16:34, 28 November 2019

Configuration

You can choose your kernel simply by setting the boot.kernelPackages option

For example by adding this to /etc/nixos/configuration.nix:

boot.kernelPackages = pkgs.linuxPackages_latest;

And rebuild your system and reboot to use your new kernel:

$ sudo nixos-rebuild boot
$ sudo reboot

List available kernels

You can list available kernels using nix repl (previously nix-repl) :

$ nix repl
nix-repl> :l <nixpkgs>
Added 8557 variables.
 
nix-repl> pkgs.linuxPackages
pkgs.linuxPackages                           pkgs.linuxPackages_latest_hardened
pkgs.linuxPackagesFor                        pkgs.linuxPackages_latest_xen_dom0
pkgs.linuxPackages_4_14                      pkgs.linuxPackages_latest_xen_dom0_hardened
pkgs.linuxPackages_4_15                      pkgs.linuxPackages_mptcp
pkgs.linuxPackages_4_4                       pkgs.linuxPackages_rpi
pkgs.linuxPackages_4_9                       pkgs.linuxPackages_samus_4_12
pkgs.linuxPackages_beagleboard               pkgs.linuxPackages_samus_latest
pkgs.linuxPackages_copperhead_hardened       pkgs.linuxPackages_testing
pkgs.linuxPackages_custom                    pkgs.linuxPackages_testing_bcachefs
pkgs.linuxPackages_hardened                  pkgs.linuxPackages_xen_dom0

Custom kernel modules

Note that if you deviate from the default kernel version, you should also take extra care that extra kernel modules must match the same version. The safest way to do this is to use config.boot.kernelPackages to select the correct module set:

{ config, ... }:
{
  boot.extraModulePackages = with config.boot.kernelPackages; [ wireguard ];
}

Custom kernel commandline

The config attribute boot.kernelParams can be set to supply the Linux kernel with additional command line arguments at boot time.

{ pkgs, config, ... }:

{
  boot.kernelParams = [ /* list of command line arguments */ ];
}

Custom configuration

It is sometimes desirable to change the configuration of your kernel, while keeping the kernel version itself managed through Nixpkgs. To do so, you can add the configuration to a dummy boot.kernelPatches,[1][2] which will then be merged and applied to the current kernel. As with kernel configuration with NixOS, drop the CONFIG_ prefix from the kernel configuration names.

This example is from the boot.crashDump.enable option:

{
      boot.kernelPatches = [ {
        name = "crashdump-config";
        patch = null;
        extraConfig = ''
                CRASH_DUMP y
                DEBUG_INFO y
                PROC_VMCORE y
                LOCKUP_DETECTOR y
                HARDLOCKUP_DETECTOR y
              '';
        } ];
}

Debugging a failed configuration

As dependencies between kernel configurations items need to be addressed manually, you can inspect the intermediate nix config file after for instance the error

note: keeping build directory '/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0'

by opening /tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0/.attr-0.

Developing kernel modules

See also: NixOS Manual, 12.2. Developing kernel modules

If you work on an out-of-tree kernel module the workflow could look as follow:

#include <linux/module.h>
#define MODULE_NAME "hello"
static int __init hello_init(void)
{
    printk(KERN_INFO "hello world!");
    return 0;
}
static void __exit hello_cleanup(void) {}
module_init(hello_init);
module_exit(hello_cleanup);
$ nix-shell '<nixpkgs>' -A linux.dev
$ make -C $(nix-build -E '(import <nixpkgs> {}).linux.dev' --no-out-link)/lib/modules/*/build M=$(pwd) modules
$ insmod ./hello.ko
$ dmesg | grep hello
[   82.027229] hello world!

make menuconfig

It is (currently) not possible to run make menuconfig in the checked out linux kernel sources. This is because ncurses is not part of your working environment when you start it with nix-shell '<nixpkgs>' -A linuxPackages.kernel.

This nix-shell hack adds ncurses as a build dependency to the kernel:

$ nix-shell -E 'with import <nixpkgs> {}; linux.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkgconfig ncurses ];})'
[nix-shell] $ unpackPhase && cd linux-*
[nix-shell] $ make menuconfig

(thanks to sphalerite)

make xconfig

Similarly to make menuconfig, you need to import qt in the environment:

$ nix-shell -E 'with import <nixpkgs> {}; linux.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkgconfig qt5.qtbase ];})'

If the source was unpacked and an initial config exists, you can run make xconfig KCONFIG_CONFIG=build/.config


Requesting a change in the default nixos kernel configuration

Please provide a comparison with other distributions' kernel: - arch: https://git.archlinux.org/svntogit/packages.git/tree/trunk/config?h=packages/linux - debian: https://salsa.debian.org/kernel-team/linux/blob/master/debian/config/config and the ARCH specific ones

Booting a kernel from a custom source

The following example shows how to configure NixOS to compile and boot a kernel from a custom source, and with custom configuration options.

{ pkgs, ... }:

{
  boot.kernelPackages = let
      linux_sgx_pkg = { stdenv, fetchurl, buildLinux, ... } @ args:

        with stdenv.lib;

        buildLinux (args // rec {
          version = "5.4.0-rc3";
          modDirVersion = "5.4.0-rc3";

          src = fetchurl {
            url = "https://github.com/jsakkine-intel/linux-sgx/archive/v23.tar.gz";
            sha256 = "11rwlwv7s071ia889dk1dgrxprxiwgi7djhg47vi56dj81jgib20";
          };
          kernelPatches = [];

          extraConfig = ''
            INTEL_SGX y
          '';

          extraMeta.branch = "5.4";
        } // (args.argsOverride or {}));
      linux_sgx = pkgs.callPackage linux_sgx_pkg{};
    in 
      pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor linux_sgx);
}


References