lib/systems: move kernel configuration out of the platform structure

Currently, you need to override `stdenv.hostPlatform` to request a
compressed kernel on AArch64, and the kernel configuration is split
between the central structured configuration and string snippets in
platform definitions. This has consequently made the latter bitrot
terribly. Since the platform‐specific logic is now very limited after
cleaning up the detritus, we can move it into the kernel derivation
and expose the relevant configuration there for anyone who wants to
customize it further or needs to read it out.

Co-authored-by: zowoq <59103226+zowoq@users.noreply.github.com>
This commit is contained in:
Emily
2026-06-10 11:17:38 +10:00
committed by zowoq
co-authored by zowoq
parent a6d914805c
commit 31d1d80b3f
14 changed files with 60 additions and 150 deletions
+7
View File
@@ -19,6 +19,13 @@
- `uhttpmock` providing 0.0 ABI was removed. `uhttpmock_1_0` providing 1.0 ABI was renamed to `uhttpmock` and `uhttpmock_1_0` was kept as an alias. - `uhttpmock` providing 0.0 ABI was removed. `uhttpmock_1_0` providing 1.0 ABI was renamed to `uhttpmock` and `uhttpmock_1_0` was kept as an alias.
- Linux kernel configuration has been moved out of the `linux-kernel` field of the platform structure into the kernel builders:
- `linux-kernel.name` has been removed.
- `linux-kernel.target` is available as the `target` parameter and passthru attribute on the kernel builders.
- `linux-kernel.installTarget` has been removed, as it should not be necessary to customize.
- `linux-kernel.DTB` is available as the `buildDTBs` parameter and passthru attribute on the kernel builders.
- `linux-kernel.{autoModules,preferBuiltin,extraConfig}` were already available as kernel builder parameters.
- The ARMv5 Linux kernel build now uses a standard configuration and generates a standard compressed image instead of the deprecated legacy UBoot image format. - The ARMv5 Linux kernel build now uses a standard configuration and generates a standard compressed image instead of the deprecated legacy UBoot image format.
`lib.systems.{examples,platforms}.{sheevaplug,pogoplug4}` have been unified into `lib.systems.examples.armv5tel-multiplatform`. `lib.systems.{examples,platforms}.{sheevaplug,pogoplug4}` have been unified into `lib.systems.examples.armv5tel-multiplatform`.
Note that there is no official support for ARMv5 and it is not possible to build even a simple NixOS configuration out of the box. Note that there is no official support for ARMv5 and it is not possible to build even a simple NixOS configuration out of the box.
+5 -2
View File
@@ -299,12 +299,10 @@ let
inherit inherit
( (
{ {
linux-kernel = args.linux-kernel or { };
gcc = args.gcc or { }; gcc = args.gcc or { };
} }
// platforms.select final // platforms.select final
) )
linux-kernel
gcc gcc
; ;
@@ -692,6 +690,11 @@ let
}; };
}; };
in in
# TODO: Remove in 27.05.
assert
args ? linux-kernel
-> throw "lib.systems.elaborate: linux-kernel has been removed; see the 26.11 release notes";
assert final.useAndroidPrebuilt -> final.isAndroid; assert final.useAndroidPrebuilt -> final.isAndroid;
assert foldl' (pass: { assertion, message }: if assertion final then pass else throw message) true ( assert foldl' (pass: { assertion, message }: if assertion final then pass else throw message) true (
final.parsed.abi.assertions or [ ] final.parsed.abi.assertions or [ ]
+3 -114
View File
@@ -3,74 +3,21 @@
# targetPlatform, etc) containing at least the minimal set of attrs # targetPlatform, etc) containing at least the minimal set of attrs
# required (see types.parsedPlatform in lib/systems/parse.nix). This # required (see types.parsedPlatform in lib/systems/parse.nix). This
# file takes an already-valid platform and further elaborates it with # file takes an already-valid platform and further elaborates it with
# optional fields; currently these are: linux-kernel, gcc, and rustc. # optional fields; currently these are: gcc, and rustc.
{ lib }: { lib }:
rec { rec {
pc = {
linux-kernel = {
name = "pc";
baseConfig = "defconfig";
# Build whatever possible as a module, if not stated in the extra config.
autoModules = true;
target = "bzImage";
};
};
##
## POWER
##
powernv = {
linux-kernel = {
name = "PowerNV";
baseConfig = "powernv_defconfig";
target = "vmlinux";
autoModules = true;
};
};
ppc64 = {
linux-kernel = {
name = "powerpc64";
baseConfig = "ppc64_defconfig";
target = "vmlinux";
autoModules = true;
};
};
## ##
## ARM ## ARM
## ##
armv5tel-multiplatform = { armv5tel-multiplatform = {
linux-kernel = {
name = "armv5tel-multiplatform";
baseConfig = "multi_v5_defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = { gcc = {
arch = "armv5te"; arch = "armv5te";
}; };
}; };
raspberrypi = { raspberrypi = {
linux-kernel = {
name = "raspberrypi";
baseConfig = "bcm2835_defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = { gcc = {
# https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications # https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications
arch = "armv6kz"; arch = "armv6kz";
@@ -105,7 +52,6 @@ rec {
# https://developer.android.com/ndk/guides/abis#v7a # https://developer.android.com/ndk/guides/abis#v7a
armv7a-android = { armv7a-android = {
linux-kernel.name = "armeabi-v7a";
gcc = { gcc = {
arch = "armv7-a"; arch = "armv7-a";
float-abi = "softfp"; float-abi = "softfp";
@@ -114,14 +60,6 @@ rec {
}; };
armv7l-hf-multiplatform = { armv7l-hf-multiplatform = {
linux-kernel = {
name = "armv7l-hf-multiplatform";
baseConfig = "defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = { gcc = {
# Some table about fpu flags: # Some table about fpu flags:
# http://community.arm.com/servlet/JiveServlet/showImage/38-1981-3827/blogentry-103749-004812900+1365712953_thumb.png # http://community.arm.com/servlet/JiveServlet/showImage/38-1981-3827/blogentry-103749-004812900+1365712953_thumb.png
@@ -146,14 +84,6 @@ rec {
}; };
aarch64-multiplatform = { aarch64-multiplatform = {
linux-kernel = {
name = "aarch64-multiplatform";
baseConfig = "defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "Image";
};
gcc = { gcc = {
arch = "armv8-a"; arch = "armv8-a";
}; };
@@ -171,9 +101,6 @@ rec {
## ##
ben_nanonote = { ben_nanonote = {
linux-kernel = {
name = "ben_nanonote";
};
gcc = { gcc = {
arch = "mips32"; arch = "mips32";
float = "soft"; float = "soft";
@@ -230,17 +157,6 @@ rec {
## Other ## Other
## ##
riscv-multiplatform = {
linux-kernel = {
name = "riscv-multiplatform";
target = "Image";
autoModules = true;
preferBuiltin = true;
baseConfig = "defconfig";
DTB = true;
};
};
loongarch64-multiplatform = { loongarch64-multiplatform = {
gcc = { gcc = {
# https://github.com/loongson/la-softdev-convention/blob/master/la-softdev-convention.adoc#10-operating-system-package-build-requirements # https://github.com/loongson/la-softdev-convention/blob/master/la-softdev-convention.adoc#10-operating-system-package-build-requirements
@@ -252,14 +168,6 @@ rec {
# https://github.com/llvm/llvm-project/pull/132173 # https://github.com/llvm/llvm-project/pull/132173
cmodel = "medium"; cmodel = "medium";
}; };
linux-kernel = {
name = "loongarch-multiplatform";
target = "vmlinuz.efi";
autoModules = true;
preferBuiltin = true;
baseConfig = "defconfig";
DTB = true;
};
}; };
# This function takes a minimally-valid "platform" and returns an # This function takes a minimally-valid "platform" and returns an
@@ -267,17 +175,13 @@ rec {
# included in the platform in order to further elaborate it. # included in the platform in order to further elaborate it.
select = select =
platform: platform:
# x86
if platform.isx86 then
pc
# ARM # ARM
else if platform.isAarch32 then if platform.isAarch32 then
let let
version = platform.parsed.cpu.version or null; version = platform.parsed.cpu.version or null;
in in
if version == null then if version == null then
pc { }
else if lib.versionOlder version "6" then else if lib.versionOlder version "6" then
armv5tel-multiplatform armv5tel-multiplatform
else if lib.versionOlder version "7" then else if lib.versionOlder version "7" then
@@ -291,24 +195,9 @@ rec {
else if platform.isLoongArch64 then else if platform.isLoongArch64 then
loongarch64-multiplatform loongarch64-multiplatform
else if platform.isRiscV then
riscv-multiplatform
else if platform.parsed.cpu == lib.systems.parse.cpuTypes.mipsel then else if platform.parsed.cpu == lib.systems.parse.cpuTypes.mipsel then
(import ./examples.nix { inherit lib; }).mipsel-linux-gnu (import ./examples.nix { inherit lib; }).mipsel-linux-gnu
else if platform.isPower64 then
if platform.isLittleEndian then powernv else ppc64
else if platform.isSh4 then
{
linux-kernel = {
target = "vmlinux";
# SH arch doesn't have a 'make install' target.
installTarget = "vmlinux";
};
}
else else
{ }; { };
} }
+2 -1
View File
@@ -123,7 +123,8 @@ in
options = { options = {
hardware.deviceTree = { hardware.deviceTree = {
enable = lib.mkOption { enable = lib.mkOption {
default = pkgs.stdenv.hostPlatform.linux-kernel.DTB or false; default = config.boot.kernelPackages.kernel.buildDTBs;
defaultText = lib.literalExpression "config.boot.kernelPackages.kernel.buildDTBs";
type = lib.types.bool; type = lib.types.bool;
description = '' description = ''
Build device tree files. These are used to describe the Build device tree files. These are used to describe the
+1 -1
View File
@@ -111,7 +111,7 @@ with lib;
#!ipxe #!ipxe
# Use the cmdline variable to allow the user to specify custom kernel params # Use the cmdline variable to allow the user to specify custom kernel params
# when chainloading this script from other iPXE scripts like netboot.xyz # when chainloading this script from other iPXE scripts like netboot.xyz
kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline} kernel ${config.boot.kernelPackages.kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline}
initrd initrd initrd initrd
boot boot
''; '';
@@ -139,8 +139,8 @@ in
system.boot.loader.kernelFile = mkOption { system.boot.loader.kernelFile = mkOption {
internal = true; internal = true;
default = pkgs.stdenv.hostPlatform.linux-kernel.target; default = config.boot.kernelPackages.kernel.target;
defaultText = literalExpression "pkgs.stdenv.hostPlatform.linux-kernel.target"; defaultText = literalExpression "config.boot.kernelPackages.kernel.target";
type = types.str; type = types.str;
description = '' description = ''
Name of the kernel file to be passed to the bootloader. Name of the kernel file to be passed to the bootloader.
@@ -66,7 +66,6 @@ in
system.build.installBootLoader = generationsDirBuilder; system.build.installBootLoader = generationsDirBuilder;
system.boot.loader.id = "generationsDir"; system.boot.loader.id = "generationsDir";
system.boot.loader.kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
}; };
} }
+2 -2
View File
@@ -152,7 +152,7 @@ let
tarball tarball
// { // {
meta = { meta = {
description = "NixOS system tarball for ${system} - ${stdenv.hostPlatform.linux-kernel.name}"; description = "NixOS system tarball for ${system}";
maintainers = map (x: lib.maintainers.${x}) maintainers; maintainers = map (x: lib.maintainers.${x}) maintainers;
}; };
inherit config; inherit config;
@@ -188,7 +188,7 @@ let
modules = makeModules module { }; modules = makeModules module { };
}; };
build = configEvaled.config.system.build; build = configEvaled.config.system.build;
kernelTarget = configEvaled.pkgs.stdenv.hostPlatform.linux-kernel.target; kernelTarget = build.kernel.target;
in in
configEvaled.pkgs.symlinkJoin { configEvaled.pkgs.symlinkJoin {
name = "netboot"; name = "netboot";
+1 -2
View File
@@ -27,11 +27,10 @@
# ---------------------------- # ----------------------------
# The following arguments form the "interface" of `pkgs.vmTools`. # The following arguments form the "interface" of `pkgs.vmTools`.
# Note that `img` is a real package, but is set to this default in `all-packages.nix`.
# ---------------------------- # ----------------------------
customQemu ? null, customQemu ? null,
kernel ? linux, kernel ? linux,
img ? stdenv.hostPlatform.linux-kernel.target, img ? kernel.target,
storeDir ? builtins.storeDir, storeDir ? builtins.storeDir,
rootModules ? [ rootModules ? [
"virtio_pci" "virtio_pci"
+18 -6
View File
@@ -63,6 +63,19 @@ lib.makeOverridable (
kernelPatches ? [ ], kernelPatches ? [ ],
# The kernel .config file # The kernel .config file
configfile, configfile,
target ?
if stdenv.hostPlatform.isx86 then
"bzImage"
else if stdenv.hostPlatform.isAarch32 then
"zImage"
else if stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isRiscV then
"Image"
else if stdenv.hostPlatform.isLoongArch64 then
"vmlinuz.efi"
else
"vmlinux",
buildDTBs ?
stdenv.hostPlatform.isAarch || stdenv.hostPlatform.isRiscV || stdenv.hostPlatform.isLoongArch64,
# Manually specified nixexpr representing the config # Manually specified nixexpr representing the config
# If unspecified, this will be autodetected from the .config # If unspecified, this will be autodetected from the .config
config ? lib.optionalAttrs (builtins.isPath configfile || allowImportFromDerivation) ( config ? lib.optionalAttrs (builtins.isPath configfile || allowImportFromDerivation) (
@@ -139,9 +152,7 @@ lib.makeOverridable (
isModular = config.isYes "MODULES"; isModular = config.isYes "MODULES";
withRust = config.isYes "RUST"; withRust = config.isYes "RUST";
target = stdenv.hostPlatform.linux-kernel.target or "vmlinux"; inherit buildDTBs target;
buildDTBs = stdenv.hostPlatform.linux-kernel.DTB or false;
# Dependencies that are required to build kernel modules # Dependencies that are required to build kernel modules
moduleBuildDependencies = [ moduleBuildDependencies = [
@@ -204,7 +215,7 @@ lib.makeOverridable (
buildFlags = [ buildFlags = [
"KBUILD_BUILD_VERSION=1-NixOS" "KBUILD_BUILD_VERSION=1-NixOS"
stdenv.hostPlatform.linux-kernel.target target
"vmlinux" # for "perf" and things like that "vmlinux" # for "perf" and things like that
"scripts_gdb" "scripts_gdb"
] ]
@@ -496,6 +507,8 @@ lib.makeOverridable (
config config
kernelPatches kernelPatches
configfile configfile
target
buildDTBs
moduleBuildDependencies moduleBuildDependencies
stdenv stdenv
commonMakeFlags commonMakeFlags
@@ -511,7 +524,7 @@ lib.makeOverridable (
# Some image types need special install targets # Some image types need special install targets
installTargets = [ installTargets = [
(stdenv.hostPlatform.linux-kernel.installTarget or ( (
if if
(target == "zImage" || target == "Image.gz" || target == "vmlinuz.efi") (target == "zImage" || target == "Image.gz" || target == "vmlinuz.efi")
&& builtins.elem stdenv.hostPlatform.linuxArch [ && builtins.elem stdenv.hostPlatform.linuxArch [
@@ -525,7 +538,6 @@ lib.makeOverridable (
else else
"install" "install"
) )
)
]; ];
karch = stdenv.hostPlatform.linuxArch; karch = stdenv.hostPlatform.linuxArch;
@@ -1130,7 +1130,7 @@ let
useZstd = stdenv.buildPlatform.is64bit; useZstd = stdenv.buildPlatform.is64bit;
in in
{ {
# stdenv.hostPlatform.linux-kernel.target assumes uncompressed on RISC-V. # The default target assumes uncompressed on RISC-V.
KERNEL_UNCOMPRESSED = lib.mkIf stdenv.hostPlatform.isRiscV yes; KERNEL_UNCOMPRESSED = lib.mkIf stdenv.hostPlatform.isRiscV yes;
KERNEL_XZ = lib.mkIf ( KERNEL_XZ = lib.mkIf (
@@ -36,5 +36,4 @@
"CFLAGS_KERNEL=-I${clangLib}/lib/clang/${majorVer}/include" "CFLAGS_KERNEL=-I${clangLib}/lib/clang/${majorVer}/include"
] ]
) )
++ (stdenv.hostPlatform.linux-kernel.makeFlags or [ ])
++ extraMakeFlags ++ extraMakeFlags
+17 -14
View File
@@ -32,7 +32,16 @@ lib.makeOverridable (
version, version,
# Allows overriding the default defconfig # Allows overriding the default defconfig
defconfig ? null, # TODO: Reconsider some of these defaults?
defconfig ?
if stdenv.hostPlatform.isAarch32 && stdenv.hostPlatform.parsed.cpu.version or null == "5" then
"multi_v5_defconfig"
else if stdenv.hostPlatform.isAarch32 && stdenv.hostPlatform.parsed.cpu.version or null == "6" then
"bcm2835_defconfig"
else if stdenv.hostPlatform.isPower64 then
if stdenv.hostPlatform.isLittleEndian then "powernv_defconfig" else "ppc64_defconfig"
else
"defconfig",
# Legacy overrides to the intermediate kernel config, as string # Legacy overrides to the intermediate kernel config, as string
extraConfig ? "", extraConfig ? "",
@@ -66,20 +75,17 @@ lib.makeOverridable (
# symbolic name and `patch' is the actual patch. The patch may # symbolic name and `patch' is the actual patch. The patch may
# optionally be compressed with gzip or bzip2. # optionally be compressed with gzip or bzip2.
kernelPatches ? [ ], kernelPatches ? [ ],
ignoreConfigErrors ? ignoreConfigErrors ? !(stdenv.hostPlatform.isx86 || stdenv.hostPlatform.isAarch64),
!lib.elem stdenv.hostPlatform.linux-kernel.name or "" [
"aarch64-multiplatform"
"pc"
],
extraMeta ? { }, extraMeta ? { },
extraPassthru ? { }, extraPassthru ? { },
isLTS ? false, isLTS ? false,
isZen ? false, isZen ? false,
# easy overrides to stdenv.hostPlatform.linux-kernel members autoModules ? true,
autoModules ? stdenv.hostPlatform.linux-kernel.autoModules or true, # TODO: Remove this default?
preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false, preferBuiltin ?
stdenv.hostPlatform.isAarch || stdenv.hostPlatform.isRiscV || stdenv.hostPlatform.isLoongArch64,
kernelArch ? stdenv.hostPlatform.linuxArch, kernelArch ? stdenv.hostPlatform.linuxArch,
kernelTests ? { }, kernelTests ? { },
@@ -116,9 +122,7 @@ lib.makeOverridable (
intermediateNixConfig = intermediateNixConfig =
configfile.moduleStructuredConfig.intermediateNixConfig configfile.moduleStructuredConfig.intermediateNixConfig
# extra config in legacy string format # extra config in legacy string format
+ extraConfig + extraConfig;
# need the 'or ""' at the end in case enableCommonConfig = true and extraConfig is not present
+ lib.optionalString enableCommonConfig stdenv.hostPlatform.linux-kernel.extraConfig or "";
structuredConfigFromPatches = map ( structuredConfigFromPatches = map (
{ {
@@ -205,8 +209,7 @@ lib.makeOverridable (
buildPhase = buildPhase =
let let
# e.g. "defconfig" # e.g. "defconfig"
kernelBaseConfig = kernelBaseConfig = defconfig;
if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig or "defconfig";
kernelIntermediateConfig = writeText "kernel-intermediate-config" ( kernelIntermediateConfig = writeText "kernel-intermediate-config" (
kernelConfigFun intermediateNixConfig kernelConfigFun intermediateNixConfig
); );
+1 -3
View File
@@ -909,9 +909,7 @@ with pkgs;
inherit (darwin) signingUtils; inherit (darwin) signingUtils;
}; };
vmTools = callPackage ../build-support/vm { vmTools = callPackage ../build-support/vm { };
img = stdenv.hostPlatform.linux-kernel.target;
};
releaseTools = callPackage ../build-support/release { }; releaseTools = callPackage ../build-support/release { };