Linux kernel: Difference between revisions
m →Embedded Linux Cross-compile: Remove <nowiki>, as it breaks '<' and '>' characters |
→Custom configuration: emphasise structuredExtraConfig and note what actually causes the "unused option" errors |
||
(25 intermediate revisions by 18 users not shown) | |||
Line 115: | Line 115: | ||
* {{ic|b}}: Reboot the system. | * {{ic|b}}: Reboot the system. | ||
Check | 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: | Also see {{nixos:option|services.earlyoom.enable}} and {{nixos:option|systemd.oomd.enable}}. | ||
=== Custom configuration === | === Custom configuration === | ||
Line 127: | Line 127: | ||
<syntaxhighlight lang=nix> | <syntaxhighlight lang=nix> | ||
{ | { | ||
boot.kernelPatches = [ { | |||
name = "crashdump-config"; | |||
patch = null; | |||
structuredExtraConfig = { | |||
CRASH_DUMP = lib.kernel.yes; | |||
DEBUG_INFO = lib.kernel.yes; | |||
PROC_VMCORE = lib.kernel.yes; | |||
LOCKUP_DETECTOR = lib.kernel.yes; | |||
HARDLOCKUP_DETECTOR = lib.kernel.yes; | |||
}; | |||
} ]; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Another way is to create | Alternatively, you can pass a string as <code>extraConfig</code>, with option names and answers formatted like so: | ||
<pre> | |||
CRASH_DUMP y | |||
DEBUG_INFO y | |||
PROC_VMCORE y | |||
LOCKUP_DETECTOR y | |||
HARDLOCKUP_DETECTOR y | |||
</pre> | |||
Another way is to create an 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. | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | {{file|/etc/nixos/configuration.nix|nix|<nowiki> | ||
Line 148: | Line 159: | ||
overlays = [ | overlays = [ | ||
(self: super: { | (self: super: { | ||
linuxZenWMuQSS = pkgs.linuxPackagesFor (pkgs.linux_zen | linuxZenWMuQSS = pkgs.linuxPackagesFor (pkgs.linuxKernel.kernels.linux_zen.override { | ||
structuredExtraConfig = with lib.kernel; { | structuredExtraConfig = with lib.kernel; { | ||
SCHED_MUQSS = yes; | SCHED_MUQSS = yes; | ||
}; | }; | ||
ignoreConfigErrors = true; | ignoreConfigErrors = true; # not necessarily a good idea | ||
}); | }); | ||
}) | }) | ||
Line 159: | Line 170: | ||
} | } | ||
</nowiki>}} | </nowiki>}} | ||
If the kernel config fails to build with messages like <code>error: unused option: DRM_I915_GVT</code>, try setting e.g. <code>DRM_I915_GVT = lib.kernel.unset</code>. Setting {{ic|ignoreConfigErrors}} will also silence these errors, at the cost of ignoring potential problems. ([https://github.com/NixOS/nixpkgs/blob/3ab9a9d12ba76f6a544c207e1364da5b3087b77c/pkgs/os-specific/linux/kernel/generate-config.pl generate-config.pl] is responsible for these; they are often produced when [https://github.com/NixOS/nixpkgs/blob/3ab9a9d12ba76f6a544c207e1364da5b3087b77c/pkgs/os-specific/linux/kernel/common-config.nix the default config] doesn't use <code>lib.kernel.option</code> for an option that is implicitly disabled by whatever change you made.) | |||
=== Pinning a kernel version === | === Pinning a kernel version === | ||
Line 164: | Line 177: | ||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | {{file|/etc/nixos/configuration.nix|nix|<nowiki> | ||
{ | { | ||
boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_4_19.override { | boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linuxKernel.kernels.linux_4_19.override { | ||
argsOverride = rec { | argsOverride = rec { | ||
src = pkgs.fetchurl { | src = pkgs.fetchurl { | ||
url = "mirror://kernel/linux/kernel/ | url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz"; | ||
sha256 = "0ibayrvrnw2lw7si78vdqnr20mm1d3z0g6a0ykndvgn5vdax5x9a"; | sha256 = "0ibayrvrnw2lw7si78vdqnr20mm1d3z0g6a0ykndvgn5vdax5x9a"; | ||
}; | }; | ||
version = "4.19.60"; | version = "4.19.60"; | ||
modDirVersion = "4.19.60"; | modDirVersion = "4.19.60"; | ||
}; | |||
}); | }); | ||
} | } | ||
Line 193: | Line 206: | ||
targetPkgs = pkgs: (with pkgs; | targetPkgs = pkgs: (with pkgs; | ||
[ | [ | ||
pkg-config | |||
ncurses | ncurses | ||
qt5.qtbase | qt5.qtbase | ||
Line 215: | Line 228: | ||
== make menuconfig == | == make menuconfig == | ||
It is | It is not possible to run <code>make menuconfig</code> in the standard kernel shell. This is because <code>ncurses</code> is not part of your working environment when you start it with <code>nix-shell '<nixpkgs>' -A linuxPackages.kernel</code>. | ||
Use <code>linuxPackages.kernel.configEnv</code> instead, which adds ncurses as a build dependency to the kernel: | |||
<syntaxHighlight lang=console> | <syntaxHighlight lang=console> | ||
$ nix-shell | $ nix-shell '<nixpkgs>' -A linuxPackages.kernel.configEnv | ||
[nix-shell] $ unpackPhase && cd linux-* | [nix-shell] $ unpackPhase && cd linux-* | ||
[nix-shell] $ patchPhase | [nix-shell] $ patchPhase | ||
Line 276: | Line 289: | ||
=== Packaging out-of-tree kernel modules === | === Packaging out-of-tree kernel modules === | ||
There are a couple of steps that you will most likely need to do a couple of things. Here is an annotated example: | There are a couple of steps that you will most likely need to do a couple of things. Here is an annotated example: | ||
< | <syntaxhighlight lang="nix"> | ||
{ stdenv, lib, fetchFromGitHub, kernel, kmod }: | { stdenv, lib, fetchFromGitHub, kernel, kernelModuleMakeFlags, kmod }: | ||
stdenv.mkDerivation rec { | stdenv.mkDerivation rec { | ||
pname = "v4l2loopback-dc"; | |||
version = "1.6"; | version = "1.6"; | ||
Line 287: | Line 300: | ||
repo = "droidcam"; | repo = "droidcam"; | ||
rev = "v${version}"; | rev = "v${version}"; | ||
hash = "1d9qpnmqa3pfwsrpjnxdz76ipk4w37bbxyrazchh4vslnfc886fx"; | |||
}; | }; | ||
Line 294: | Line 307: | ||
nativeBuildInputs = kernel.moduleBuildDependencies; # 2 | nativeBuildInputs = kernel.moduleBuildDependencies; # 2 | ||
makeFlags = [ | makeFlags = kernelModuleMakeFlags ++ [ | ||
"KERNELRELEASE=${kernel.modDirVersion}" # 3 | "KERNELRELEASE=${kernel.modDirVersion}" # 3 | ||
"KERNEL_DIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" # 4 | "KERNEL_DIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" # 4 | ||
Line 300: | Line 313: | ||
]; | ]; | ||
meta = | meta = { | ||
description = "A kernel module to create V4L2 loopback devices"; | description = "A kernel module to create V4L2 loopback devices"; | ||
homepage = "https://github.com/aramg/droidcam"; | homepage = "https://github.com/aramg/droidcam"; | ||
license = licenses.gpl2; | license = lib.licenses.gpl2; | ||
maintainers = [ maintainers.makefu ]; | maintainers = [ lib.maintainers.makefu ]; | ||
platforms = platforms.linux; | platforms = lib.platforms.linux; | ||
}; | }; | ||
} | } | ||
</ | </syntaxhighlight> | ||
1. For kernel modules it is necessary to disable <code>pic</code> in compiler hardenings as the kernel need different compiler flags. | 1. For kernel modules it is necessary to disable <code>pic</code> in compiler hardenings as the kernel need different compiler flags. | ||
Line 323: | Line 336: | ||
=== Developing out-of-tree kernel modules === | === Developing out-of-tree kernel modules === | ||
See also: {{ | See also: {{Nixpkgs Manual|name=Nixpkgs Manual, Developing kernel modules|anchor=#sec-linux-kernel-developing-modules}} | ||
If you work on an out-of-tree kernel module the workflow could look as follow: | If you work on an out-of-tree kernel module the workflow could look as follow: | ||
Line 389: | Line 402: | ||
and the module will be automatically loaded after a reboot. If you want instead to load it at stage 1 (before the root is even mounted), you need to add it to <code>boot.initrd.availableKernelModules</code> and <code>boot.initrd.kernelModules</code>. | and the module will be automatically loaded after a reboot. If you want instead to load it at stage 1 (before the root is even mounted), you need to add it to <code>boot.initrd.availableKernelModules</code> and <code>boot.initrd.kernelModules</code>. | ||
Note that if you don't reboot, you can still load manually the module using <code>modprobe yourmodulename></code>, and to automatically enable a module during configuration switch/reboot, you can put <code>modprobe yourmodulename || true</code> inside the script of a systemctl service (it is for example what does wireguard). | Note that if you don't reboot, you can still load manually the module using <code>modprobe <yourmodulename></code>, and to automatically enable a module during configuration switch/reboot, you can put <code>modprobe yourmodulename || true</code> inside the script of a systemctl service (it is for example what does wireguard). | ||
Finally, if you want to define some options by default (used when you load manually a module using <code>modprobe</code>, or when the system boots), you can specify them in: | Finally, if you want to define some options by default (used when you load manually a module using <code>modprobe</code>, or when the system boots), you can specify them in: | ||
Line 423: | Line 436: | ||
Save the following as <code>shell.nix</code> for your nix-shell: | Save the following as <code>shell.nix</code> for your nix-shell: | ||
< | <syntaxhighlight lang="nix"> | ||
{ pkgs ? import <nixpkgs> {} }: | { pkgs ? import <nixpkgs> {} }: | ||
let | let | ||
Line 432: | Line 445: | ||
# the override is optional if you need for example more build dependencies | # the override is optional if you need for example more build dependencies | ||
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.gllvm ]; | nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.gllvm ]; | ||
} | }) | ||
</ | </syntaxhighlight> | ||
Then you can run the following commands (in the nix-shell <code>$makeFlags</code> will contain | Then you can run the following commands (in the nix-shell <code>$makeFlags</code> will contain | ||
Line 549: | Line 562: | ||
After packaging the kernel module you can add it to your system just like an out-of-tree kernel module, it will replace the default module provided by the linux package because it has the same name: | After packaging the kernel module you can add it to your system just like an out-of-tree kernel module, it will replace the default module provided by the linux package because it has the same name: | ||
< | <syntaxhighlight lang="nix"> | ||
{pkgs, config, ...}: | {pkgs, config, ...}: | ||
let | let | ||
Line 561: | Line 574: | ||
(amdgpu-kernel-module.overrideAttrs (_: { | (amdgpu-kernel-module.overrideAttrs (_: { | ||
patches = [ ./patches/amdgpu-foo-bar.patch ]; | patches = [ ./patches/amdgpu-foo-bar.patch ]; | ||
}) | })) | ||
]; | ]; | ||
} | } | ||
</ | </syntaxhighlight> | ||
== Sysctls == | |||
Example of configuring kernel sysctls: | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
boot.kernel.sysctl."net.ipv4.tcp_ecn" = 1; | |||
} | |||
</syntaxhighlight> | |||
== Sysfs == | |||
Example of configuring kernel sysfs: | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
boot.kernel.sysfs = { | |||
kernel.mm.transparent_hugepage = { | |||
enabled = "always"; | |||
defrag = "defer"; | |||
shmem_enabled = "within_size"; | |||
}; | |||
}; | |||
} | |||
</syntaxhighlight> | |||
== Troubleshooting == | == Troubleshooting == | ||
=== Build fails === | === Build fails === | ||
==== Too high ram usage ==== | ==== Too high ram usage ==== | ||
turn off | turn off <code>DEBUG_INFO_BTF</code> | ||
== See also == | == See also == |