Configuration is now held by the `.org` files. All `.nix` files are tangled from the org-mode files.
3.6 KiB
Kernel Configuration
Kernel Configuration
This module centralises everything related to the kernel: which
package to boot, which extra modules to load, which KVM module the
CPU needs, and a couple of modprobe quirks for specific devices.
Here’s the skeleton of the nixos.kernel module.
{
flake.modules.nixos.kernel = {
pkgs,
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.boot.kernel;
in {
<<options>>
<<config>>
};
}
Declaring the Options
options.mySystem.boot.kernel = {
<<opt-package>>
<<opt-modules>>
<<opt-cpu-vendor>>
<<opt-v4l2loopback>>
<<opt-extra-modprobe>>
};
Kernel Package
package picks which kernel to boot. I default to the Zen kernel for
its desktop-tuned scheduler, but a host can override it with a
hardened or hardware-specific kernel instead.
package = mkOption {
type = types.raw;
default = pkgs.linuxPackages_zen;
};
Extra Kernel Modules
modules lists any extra kernel modules a host needs beyond the ones
this module already adds on its own.
modules = mkOption {
type = types.listOf types.str;
default = [];
};
CPU Vendor
cpuVendor tells the module which KVM module to load, since Intel and
AMD CPUs each need their own.
cpuVendor = mkOption {
description = "Intel or AMD?";
type = types.enum ["intel" "amd"];
default = "amd";
};
Virtual Webcam
v4l2loopback.enable turns on a virtual video device. I feed it a
video source, and OBS Studio picks it up as if it were a webcam.
v4l2loopback.enable = mkEnableOption "Enables v4l2loopback kernel module";
Extra Modprobe Configuration
extraModprobeConfig lets a host inject raw modprobe.d lines. The
example below fixes a USB sound card that otherwise misconfigures
itself on boot.
extraModprobeConfig = mkOption {
type = types.lines;
default = "";
example = ''
options snd_usb_audio vid=0x1235 pid=0x8212 device_setup=1
'';
};
Wiring It All Up
config.boot = {
<<initrd-driver>>
<<extra-modprobe-lines>>
<<kernel-packages-and-modules>>
};
Choosing the Initrd Driver
Most of my machines have Intel graphics, so this module loads i915
early, in the initrd, to keep the Plymouth splash screen from flashing
or glitching before the proper driver takes over. Machines with an AMD
GPU instead load amdgpu early; the AMD GPU module handles that
itself, so this module doesn’t need to know or care which GPU a host
actually has.
initrd.kernelModules = ["i915"];
Assembling Modprobe Configuration
This concatenates whatever a host set through cfg.extraModprobeConfig
with the v4l2loopback quirk line whenever v4l2loopback.enable is on.
extraModprobeConfig =
strings.concatLines
([cfg.extraModprobeConfig]
++ lists.optional cfg.v4l2loopback.enable ''options v4l2loopback exclusive_caps=1 devices=1 video_nr=0 card_label="OBS Studio"'');
Kernel Package and Extra Modules
Finally, kernelPackages and kernelModules wire the chosen package
and modules through, appending the vendor-specific KVM module.
kernelPackages = cfg.package;
kernelModules = cfg.modules ++ ["kvm-${cfg.cpuVendor}"];