1<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-kernel-config">
2 <title>Linux Kernel</title>
3 <para>
4 You can override the Linux kernel and associated packages using the
5 option <literal>boot.kernelPackages</literal>. For instance, this
6 selects the Linux 3.10 kernel:
7 </para>
8 <programlisting language="bash">
9boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10;
10</programlisting>
11 <para>
12 Note that this not only replaces the kernel, but also packages that
13 are specific to the kernel version, such as the NVIDIA video
14 drivers. This ensures that driver packages are consistent with the
15 kernel.
16 </para>
17 <para>
18 While <literal>pkgs.linuxKernel.packages</literal> contains all
19 available kernel packages, you may want to use one of the
20 unversioned <literal>pkgs.linuxPackages_*</literal> aliases such as
21 <literal>pkgs.linuxPackages_latest</literal>, that are kept up to
22 date with new versions.
23 </para>
24 <para>
25 The default Linux kernel configuration should be fine for most
26 users. You can see the configuration of your current kernel with the
27 following command:
28 </para>
29 <programlisting>
30zcat /proc/config.gz
31</programlisting>
32 <para>
33 If you want to change the kernel configuration, you can use the
34 <literal>packageOverrides</literal> feature (see
35 <xref linkend="sec-customising-packages" />). For instance, to
36 enable support for the kernel debugger KGDB:
37 </para>
38 <programlisting language="bash">
39nixpkgs.config.packageOverrides = pkgs: pkgs.lib.recursiveUpdate pkgs {
40 linuxKernel.kernels.linux_5_10 = pkgs.linuxKernel.kernels.linux_5_10.override {
41 extraConfig = ''
42 KGDB y
43 '';
44 };
45};
46</programlisting>
47 <para>
48 <literal>extraConfig</literal> takes a list of Linux kernel
49 configuration options, one per line. The name of the option should
50 not include the prefix <literal>CONFIG_</literal>. The option value
51 is typically <literal>y</literal>, <literal>n</literal> or
52 <literal>m</literal> (to build something as a kernel module).
53 </para>
54 <para>
55 Kernel modules for hardware devices are generally loaded
56 automatically by <literal>udev</literal>. You can force a module to
57 be loaded via <xref linkend="opt-boot.kernelModules" />, e.g.
58 </para>
59 <programlisting language="bash">
60boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
61</programlisting>
62 <para>
63 If the module is required early during the boot (e.g. to mount the
64 root file system), you can use
65 <xref linkend="opt-boot.initrd.kernelModules" />:
66 </para>
67 <programlisting language="bash">
68boot.initrd.kernelModules = [ "cifs" ];
69</programlisting>
70 <para>
71 This causes the specified modules and their dependencies to be added
72 to the initial ramdisk.
73 </para>
74 <para>
75 Kernel runtime parameters can be set through
76 <xref linkend="opt-boot.kernel.sysctl" />, e.g.
77 </para>
78 <programlisting language="bash">
79boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
80</programlisting>
81 <para>
82 sets the kernel’s TCP keepalive time to 120 seconds. To see the
83 available parameters, run <literal>sysctl -a</literal>.
84 </para>
85 <section xml:id="sec-linux-config-customizing">
86 <title>Customize your kernel</title>
87 <para>
88 The first step before compiling the kernel is to generate an
89 appropriate <literal>.config</literal> configuration. Either you
90 pass your own config via the <literal>configfile</literal> setting
91 of <literal>linuxKernel.manualConfig</literal>:
92 </para>
93 <programlisting language="bash">
94custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
95 in super.linuxKernel.manualConfig {
96 inherit (super) stdenv hostPlatform;
97 inherit (base_kernel) src;
98 version = "${base_kernel.version}-custom";
99
100 configfile = /home/me/my_kernel_config;
101 allowImportFromDerivation = true;
102};
103</programlisting>
104 <para>
105 You can edit the config with this snippet (by default
106 <literal>make menuconfig</literal> won't work out of the box on
107 nixos):
108 </para>
109 <programlisting>
110nix-shell -E 'with import <nixpkgs> {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
111</programlisting>
112 <para>
113 or you can let nixpkgs generate the configuration. Nixpkgs
114 generates it via answering the interactive kernel utility
115 <literal>make config</literal>. The answers depend on parameters
116 passed to
117 <literal>pkgs/os-specific/linux/kernel/generic.nix</literal>
118 (which you can influence by overriding
119 <literal>extraConfig, autoModules, modDirVersion, preferBuiltin, extraConfig</literal>).
120 </para>
121 <programlisting language="bash">
122mptcp93.override ({
123 name="mptcp-local";
124
125 ignoreConfigErrors = true;
126 autoModules = false;
127 kernelPreferBuiltin = true;
128
129 enableParallelBuilding = true;
130
131 extraConfig = ''
132 DEBUG_KERNEL y
133 FRAME_POINTER y
134 KGDB y
135 KGDB_SERIAL_CONSOLE y
136 DEBUG_INFO y
137 '';
138});
139</programlisting>
140 </section>
141 <section xml:id="sec-linux-config-developing-modules">
142 <title>Developing kernel modules</title>
143 <para>
144 When developing kernel modules it's often convenient to run
145 edit-compile-run loop as quickly as possible. See below snippet as
146 an example of developing <literal>mellanox</literal> drivers.
147 </para>
148 <programlisting>
149$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev
150$ nix-shell '<nixpkgs>' -A linuxPackages.kernel
151$ unpackPhase
152$ cd linux-*
153$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
154# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
155</programlisting>
156 </section>
157</chapter>