Jump to content

Linux kernel: Difference between revisions

m
Fix usage of template
m (Fix typos in example code)
m (Fix usage of template)
 
(10 intermediate revisions by 6 users not shown)
Line 3: Line 3:
== Configuration ==
== Configuration ==


You can choose your kernel simply by setting the <code>boot.kernelPackages</code> option
You can change the installed kernel using {{nixos:option|boot.kernelPackages}}. To use the latest release:


For example by adding this to  <code>/etc/nixos/configuration.nix</code>:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
<syntaxhighlight lang="nix">
{
boot.kernelPackages = pkgs.linuxKernel.packages.linuxPackages_latest;
  boot.kernelPackages = pkgs.linuxPackages_latest;
</syntaxhighlight>
}
And rebuild your system and reboot to use your new kernel:
</nowiki>}}
 
Then rebuild your system and reboot to use your new kernel:
<syntaxHighlight lang="console">
<syntaxHighlight lang="console">
$ sudo nixos-rebuild boot
$ sudo nixos-rebuild boot
Line 17: Line 19:
=== List available kernels ===
=== List available kernels ===
You can list available kernels using  <code>nix repl</code> (previously <code>nix-repl</code>) by typing the package name and using the tab completion:
You can list available kernels using  <code>nix repl</code> (previously <code>nix-repl</code>) by typing the package name and using the tab completion:
 
 
<syntaxHighlight lang="console">
<syntaxHighlight lang="console">
$ nix repl
$ nix repl
Line 26: Line 28:


nix-repl> pkgs.linuxPackages
nix-repl> pkgs.linuxPackages
pkgs.linuxPackages                          pkgs.linuxPackages_latest
pkgs.linuxPackages                          pkgs.linuxPackages_custom
pkgs.linuxPackages-libre                    pkgs.linuxPackages_latest-libre
pkgs.linuxPackages-libre                    pkgs.linuxPackages_custom_tinyconfig_kernel
pkgs.linuxPackages-rt                        pkgs.linuxPackages_latest_hardened
pkgs.linuxPackages-rt                        pkgs.linuxPackages_hardened
pkgs.linuxPackages-rt_5_4                    pkgs.linuxPackages_latest_xen_dom0
pkgs.linuxPackages-rt_latest                pkgs.linuxPackages_latest
pkgs.linuxPackages-rt_5_6                    pkgs.linuxPackages_latest_xen_dom0_hardened
pkgs.linuxPackagesFor                        pkgs.linuxPackages_latest-libre
pkgs.linuxPackages-rt_latest                pkgs.linuxPackages_mptcp
pkgs.linuxPackages_4_14                      pkgs.linuxPackages_latest_hardened
pkgs.linuxPackagesFor                        pkgs.linuxPackages_rpi0
pkgs.linuxPackages_4_19                      pkgs.linuxPackages_latest_xen_dom0
pkgs.linuxPackages_4_14                     pkgs.linuxPackages_rpi1
pkgs.linuxPackages_4_19_hardened            pkgs.linuxPackages_latest_xen_dom0_hardened
pkgs.linuxPackages_4_19                      pkgs.linuxPackages_rpi2
pkgs.linuxPackages_4_9                      pkgs.linuxPackages_lqx
pkgs.linuxPackages_4_4                      pkgs.linuxPackages_rpi3
pkgs.linuxPackages_5_10                      pkgs.linuxPackages_rpi0
pkgs.linuxPackages_4_9                      pkgs.linuxPackages_rpi4
pkgs.linuxPackages_5_10_hardened            pkgs.linuxPackages_rpi02w
pkgs.linuxPackages_5_4                      pkgs.linuxPackages_testing
pkgs.linuxPackages_5_15                     pkgs.linuxPackages_rpi1
pkgs.linuxPackages_5_8                       pkgs.linuxPackages_testing_bcachefs
pkgs.linuxPackages_5_15_hardened            pkgs.linuxPackages_rpi2
pkgs.linuxPackages_5_9                       pkgs.linuxPackages_testing_hardened
pkgs.linuxPackages_5_18                      pkgs.linuxPackages_rpi3
pkgs.linuxPackages_custom                    pkgs.linuxPackages_xen_dom0
pkgs.linuxPackages_5_19                      pkgs.linuxPackages_rpi4
pkgs.linuxPackages_custom_tinyconfig_kernel  pkgs.linuxPackages_xen_dom0_hardened
pkgs.linuxPackages_5_4                      pkgs.linuxPackages_rt_5_10
pkgs.linuxPackages_hardened                  pkgs.linuxPackages_zen
pkgs.linuxPackages_5_4_hardened              pkgs.linuxPackages_rt_5_15
pkgs.linuxPackages_hardkernel_4_14
pkgs.linuxPackages_6_0                      pkgs.linuxPackages_rt_5_4
pkgs.linuxPackages_hardkernel_latest
pkgs.linuxPackages_6_1                      pkgs.linuxPackages_rt_6_1
pkgs.linuxPackages_6_1_hardened              pkgs.linuxPackages_testing
pkgs.linuxPackages_6_2                       pkgs.linuxPackages_testing_bcachefs
pkgs.linuxPackages_6_3                       pkgs.linuxPackages_xanmod
pkgs.linuxPackages_6_4                      pkgs.linuxPackages_xanmod_latest
pkgs.linuxPackages_6_5                      pkgs.linuxPackages_xanmod_stable
pkgs.linuxPackages_6_6                      pkgs.linuxPackages_xen_dom0
pkgs.linuxPackages_6_6_hardened              pkgs.linuxPackages_xen_dom0_hardened
pkgs.linuxPackages_6_7                      pkgs.linuxPackages_zen
pkgs.linuxPackages_6_8
</syntaxhighlight>
</syntaxhighlight>


Line 51: Line 62:
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 <code>config.boot.kernelPackages</code> to select the correct module set:
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 <code>config.boot.kernelPackages</code> to select the correct module set:


<syntaxHighlight lang="nix">
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ config, ... }:
{ config, ... }:
{
{
   boot.extraModulePackages = with config.boot.kernelPackages; [ bbswitch ];
   boot.extraModulePackages = with config.boot.kernelPackages; [ bbswitch ];
}
}
</syntaxHighlight>
</nowiki>}}


=== Customizing kernel module parameters ===
=== Customizing kernel module parameters ===


You can use <code>boot.extraModprobeConfig</code>, which is analogous to creating modprobe.conf files in /etc/modprobe.d/ in regular Linux distributions. This can be used for both built-in and loadable kernel modules.  
You can use {{nixos:option|boot.extraModprobeConfig}}, which is analogous to creating modprobe.conf files in /etc/modprobe.d/ in regular Linux distributions. This can be used for both built-in and loadable kernel modules.
</syntaxHighlight>
 
<syntaxHighlight lang=nix>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
boot.extraModprobeConfig = ''
{
  # example settings
  boot.extraModprobeConfig = ''
  options yourmodulename optionA=valueA optionB=valueB # syntax
    # example settings
  options thinkpad_acpi  fan_control=1                # example #1 kernel module parameter
    options yourmodulename optionA=valueA optionB=valueB # syntax
  options usbcore        blinkenlights=1              # example #2 kernel module parameter
    options thinkpad_acpi  fan_control=1                # example #1 kernel module parameter
'';
    options usbcore        blinkenlights=1              # example #2 kernel module parameter
</syntaxHighlight>
  '';
}
</nowiki>}}


The config attribute <code>boot.kernelParams</code> can be set to supply the Linux kernel with additional command line arguments at boot time. It can only be used for built-in modules.
{{nixos:option|boot.kernelParams}} can be used to set additional kernel command line arguments at boot time. It can only be used for built-in modules. For example:


<syntaxhighlight lang="nix">
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ ... }:
{
{
   boot.kernelParams = [  
   boot.kernelParams = [
    # example settings
     "quiet"
     "quiet"
     "splash"
     "splash"
     "usbcore.blinkenlights=1" # example kernel module parameter
     "usbcore.blinkenlights=1"
   ];
   ];
}
}
</syntaxhighlight>
</nowiki>}}
 
=== Enable SysRq ===
 
The Linux kernel is known<ref>https://github.com/hakavlad/nohang?tab=readme-ov-file#what-is-the-problem</ref> to not handle out-of-memory situation properly and can freeze for a long time, often leaving no option but doing a hard reboot. The [https://en.wikipedia.org/wiki/Magic_SysRq_key SysRq shortcuts] can be used to trigger a more graceful reboot. However, most keys are disabled by default on NixOS. To enable:
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
  boot.kernel.sysctl."kernel.sysrq" = 1;
}
</nowiki>}}
 
Useful shortcuts, triggered using {{ic|Alt+SysRq+<key>}}:
 
* {{ic|h}}: Print help to the system log.
* {{ic|f}}: Trigger the kernel oom killer.
* {{ic|s}}: Sync data to disk before triggering the reset options below.
* {{ic|e}}: SIGTERM all processes except PID 0.
* {{ic|i}}: SIGKILL all processes except PID 0.
* {{ic|b}}: Reboot the system.
 
Check <code>journalctl</code> to see if you are triggering the shortcuts correctly, which might be different for your keyboard, as noted in the Wikipedia page.
 
Also see {{nixos:option|services.earlyoom.enable}} and {{nixos:option|systemd.oomd.enable}}.


=== Custom configuration ===
=== 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 {{nixos:option|boot.kernelPatches}},<ref>[https://logs.nix.samueldr.com/nixos/2018-05-09#1525898458-1525898534; #nixos 2018-05-09]</ref><ref>[https://github.com/NixOS/nixpkgs/blob/03d4694e6110fa9c16e88ee74085ea2068c27494/nixos/modules/misc/crashdump.nix#L63-L73 <tt>nixos/modules/misc/crashdump.nix#L63-L73</tt>]</ref> which will then be merged and applied to the current kernel. As with kernel configuration with NixOS, drop the <tt>CONFIG_</tt> prefix from the kernel configuration names.
It is sometimes desirable to change the configuration of your kernel, while keeping the kernel version itself managed through Nixpkgs.


This example is from the {{nixos:option|boot.crashDump.enable}} option:
One way is to use {{nixos:option|boot.kernelPatches}}<ref>[https://logs.nix.samueldr.com/nixos/2018-05-09#1525898458-1525898534; #nixos 2018-05-09]</ref><ref>[https://github.com/NixOS/nixpkgs/blob/03d4694e6110fa9c16e88ee74085ea2068c27494/nixos/modules/misc/crashdump.nix#L63-L73 <tt>nixos/modules/misc/crashdump.nix#L63-L73</tt>]</ref>. For example, {{nixos:option|boot.crashDump.enable}} is configured as shown below. Note that the {{ic|CONFIG_}} prefix is not used in the configuration names.


<syntaxhighlight lang=nix>
<syntaxhighlight lang=nix>
Line 107: Line 141:
</syntaxhighlight>
</syntaxhighlight>


Another way to build a kernel with custom configuration is to create a overlay and use either <tt>extraConfig</tt> or <tt>structuredExtraConfig</tt>. This allows for more flexibility, since you can basically override any kernel option available here <ref>[https://github.com/NixOS/nixpkgs/blob/e6db435973160591fe7348876a5567c729495175/pkgs/os-specific/linux/kernel/generic.nix#L11-L56<tt>pkgs/os-specific/linux/kernel/generic.nix#L11-L56</tt>]</ref>. Using <tt>structuredExtraConfig</tt> is recommended since there is some sanity check if the options you're passing to your kernel is correct. Also, setting <tt>ignoreConfigErrors</tt> is useful to avoid <tt>error: unused option</tt> during build.
Another way is to create a overlay to configure either {{ic|extraConfig}} or {{ic|structuredExtraConfig}}. This allows for more flexibility, since you can basically override any available kernel option<ref>[https://github.com/NixOS/nixpkgs/blob/e6db435973160591fe7348876a5567c729495175/pkgs/os-specific/linux/kernel/generic.nix#L11-L56<tt>pkgs/os-specific/linux/kernel/generic.nix#L11-L56</tt>]</ref>. Using {{ic|structuredExtraConfig}} is recommended as it checks if the configured option are correct. You may also want to set {{ic|ignoreConfigErrors}} to avoid {{ic|error: unused option}} during builds.


<syntaxhighlight lang=nix>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
{
   nixpkgs = {
   nixpkgs = {
Line 124: Line 158:
   };
   };
}
}
</syntaxhighlight>
</nowiki>}}


=== Pinning a kernel version ===
=== Pinning a kernel version ===


<syntaxhighlight lang=nix>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_4_19.override {
{
  boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_4_19.override {
     argsOverride = rec {
     argsOverride = rec {
       src = pkgs.fetchurl {
       src = pkgs.fetchurl {
Line 139: Line 174:
       };
       };
   });
   });
</syntaxhighlight>
}
 
</nowiki>}}


=== Debugging a failed configuration  ===
=== Debugging a failed configuration  ===


As dependencies between kernel configurations items need to be addressed manually, use <code>--keep-failed</code> to inspect the intermediate nix config file after for instance the error
As dependencies between kernel configurations need to be addressed manually, use [https://nixos.org/manual/nix/stable/command-ref/nix-build#opt-keep-failed --keep-failed] to inspect the intermediate nix config file after any build failures:
{{bc|note: keeping build directory '/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0'}}
{{bc|note: keeping build directory '/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0'}}
by opening {{ic|/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0/.attr-0}}.


== Embedded Linux Cross-compile xconfig and menuconfig ==
== Embedded Linux Cross-compile ==
This section details the on how to get an environment that can be used to configure and cross-compile the kernel for embedded Linux development. The kernel source won't come from nix unpack phase but rather gotten externally(such as from the chip vendor github). So first clone the kernel source, then use the shell.nix below to set up the dev environment(example below is for aarch64):
 
To configure and cross-compile Linux kernels for embedded development, often distributed separately instead of using the stock kernel, you can setup a development environment as shown below:  


<syntaxHighlight lang=nix>
{{file|shell.nix|nix|3=let
let
   pkgs = import <nixpkgs> { };
   pkgs = import <nixpkgs> { };
in
in
Line 176: Line 210:
     exec bash
     exec bash
   '';
   '';
}).env
}).env}}
</syntaxHighlight>


Finally, cd to the kernel source dir and do development normally.
Clone the kernel sources, enter the environment using {{ic|nix-shell}}, and then do development normally.


== make menuconfig ==
== make menuconfig ==