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
2025-06-25 13:52:43 +01:00
committed by zowoq
parent a6d914805c
commit 31d1d80b3f
14 changed files with 60 additions and 150 deletions

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.
- 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.
`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.

View File

@@ -299,12 +299,10 @@ let
inherit
(
{
linux-kernel = args.linux-kernel or { };
gcc = args.gcc or { };
}
// platforms.select final
)
linux-kernel
gcc
;
@@ -692,6 +690,11 @@ let
};
};
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 foldl' (pass: { assertion, message }: if assertion final then pass else throw message) true (
final.parsed.abi.assertions or [ ]

View File

@@ -3,74 +3,21 @@
# targetPlatform, etc) containing at least the minimal set of attrs
# required (see types.parsedPlatform in lib/systems/parse.nix). This
# 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 }:
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
##
armv5tel-multiplatform = {
linux-kernel = {
name = "armv5tel-multiplatform";
baseConfig = "multi_v5_defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = {
arch = "armv5te";
};
};
raspberrypi = {
linux-kernel = {
name = "raspberrypi";
baseConfig = "bcm2835_defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = {
# https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications
arch = "armv6kz";
@@ -105,7 +52,6 @@ rec {
# https://developer.android.com/ndk/guides/abis#v7a
armv7a-android = {
linux-kernel.name = "armeabi-v7a";
gcc = {
arch = "armv7-a";
float-abi = "softfp";
@@ -114,14 +60,6 @@ rec {
};
armv7l-hf-multiplatform = {
linux-kernel = {
name = "armv7l-hf-multiplatform";
baseConfig = "defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "zImage";
};
gcc = {
# Some table about fpu flags:
# http://community.arm.com/servlet/JiveServlet/showImage/38-1981-3827/blogentry-103749-004812900+1365712953_thumb.png
@@ -146,14 +84,6 @@ rec {
};
aarch64-multiplatform = {
linux-kernel = {
name = "aarch64-multiplatform";
baseConfig = "defconfig";
DTB = true;
autoModules = true;
preferBuiltin = true;
target = "Image";
};
gcc = {
arch = "armv8-a";
};
@@ -171,9 +101,6 @@ rec {
##
ben_nanonote = {
linux-kernel = {
name = "ben_nanonote";
};
gcc = {
arch = "mips32";
float = "soft";
@@ -230,17 +157,6 @@ rec {
## Other
##
riscv-multiplatform = {
linux-kernel = {
name = "riscv-multiplatform";
target = "Image";
autoModules = true;
preferBuiltin = true;
baseConfig = "defconfig";
DTB = true;
};
};
loongarch64-multiplatform = {
gcc = {
# 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
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
@@ -267,17 +175,13 @@ rec {
# included in the platform in order to further elaborate it.
select =
platform:
# x86
if platform.isx86 then
pc
# ARM
else if platform.isAarch32 then
if platform.isAarch32 then
let
version = platform.parsed.cpu.version or null;
in
if version == null then
pc
{ }
else if lib.versionOlder version "6" then
armv5tel-multiplatform
else if lib.versionOlder version "7" then
@@ -291,24 +195,9 @@ rec {
else if platform.isLoongArch64 then
loongarch64-multiplatform
else if platform.isRiscV then
riscv-multiplatform
else if platform.parsed.cpu == lib.systems.parse.cpuTypes.mipsel then
(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
{ };
}

View File

@@ -123,7 +123,8 @@ in
options = {
hardware.deviceTree = {
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;
description = ''
Build device tree files. These are used to describe the

View File

@@ -111,7 +111,7 @@ with lib;
#!ipxe
# Use the cmdline variable to allow the user to specify custom kernel params
# 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
boot
'';

View File

@@ -139,8 +139,8 @@ in
system.boot.loader.kernelFile = mkOption {
internal = true;
default = pkgs.stdenv.hostPlatform.linux-kernel.target;
defaultText = literalExpression "pkgs.stdenv.hostPlatform.linux-kernel.target";
default = config.boot.kernelPackages.kernel.target;
defaultText = literalExpression "config.boot.kernelPackages.kernel.target";
type = types.str;
description = ''
Name of the kernel file to be passed to the bootloader.

View File

@@ -66,7 +66,6 @@ in
system.build.installBootLoader = generationsDirBuilder;
system.boot.loader.id = "generationsDir";
system.boot.loader.kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
};
}

View File

@@ -152,7 +152,7 @@ let
tarball
// {
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;
};
inherit config;
@@ -188,7 +188,7 @@ let
modules = makeModules module { };
};
build = configEvaled.config.system.build;
kernelTarget = configEvaled.pkgs.stdenv.hostPlatform.linux-kernel.target;
kernelTarget = build.kernel.target;
in
configEvaled.pkgs.symlinkJoin {
name = "netboot";

View File

@@ -27,11 +27,10 @@
# ----------------------------
# 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,
kernel ? linux,
img ? stdenv.hostPlatform.linux-kernel.target,
img ? kernel.target,
storeDir ? builtins.storeDir,
rootModules ? [
"virtio_pci"

View File

@@ -63,6 +63,19 @@ lib.makeOverridable (
kernelPatches ? [ ],
# The kernel .config file
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
# If unspecified, this will be autodetected from the .config
config ? lib.optionalAttrs (builtins.isPath configfile || allowImportFromDerivation) (
@@ -139,9 +152,7 @@ lib.makeOverridable (
isModular = config.isYes "MODULES";
withRust = config.isYes "RUST";
target = stdenv.hostPlatform.linux-kernel.target or "vmlinux";
buildDTBs = stdenv.hostPlatform.linux-kernel.DTB or false;
inherit buildDTBs target;
# Dependencies that are required to build kernel modules
moduleBuildDependencies = [
@@ -204,7 +215,7 @@ lib.makeOverridable (
buildFlags = [
"KBUILD_BUILD_VERSION=1-NixOS"
stdenv.hostPlatform.linux-kernel.target
target
"vmlinux" # for "perf" and things like that
"scripts_gdb"
]
@@ -496,6 +507,8 @@ lib.makeOverridable (
config
kernelPatches
configfile
target
buildDTBs
moduleBuildDependencies
stdenv
commonMakeFlags
@@ -511,7 +524,7 @@ lib.makeOverridable (
# Some image types need special install targets
installTargets = [
(stdenv.hostPlatform.linux-kernel.installTarget or (
(
if
(target == "zImage" || target == "Image.gz" || target == "vmlinuz.efi")
&& builtins.elem stdenv.hostPlatform.linuxArch [
@@ -525,7 +538,6 @@ lib.makeOverridable (
else
"install"
)
)
];
karch = stdenv.hostPlatform.linuxArch;

View File

@@ -1130,7 +1130,7 @@ let
useZstd = stdenv.buildPlatform.is64bit;
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_XZ = lib.mkIf (

View File

@@ -36,5 +36,4 @@
"CFLAGS_KERNEL=-I${clangLib}/lib/clang/${majorVer}/include"
]
)
++ (stdenv.hostPlatform.linux-kernel.makeFlags or [ ])
++ extraMakeFlags

View File

@@ -32,7 +32,16 @@ lib.makeOverridable (
version,
# 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
extraConfig ? "",
@@ -66,20 +75,17 @@ lib.makeOverridable (
# symbolic name and `patch' is the actual patch. The patch may
# optionally be compressed with gzip or bzip2.
kernelPatches ? [ ],
ignoreConfigErrors ?
!lib.elem stdenv.hostPlatform.linux-kernel.name or "" [
"aarch64-multiplatform"
"pc"
],
ignoreConfigErrors ? !(stdenv.hostPlatform.isx86 || stdenv.hostPlatform.isAarch64),
extraMeta ? { },
extraPassthru ? { },
isLTS ? false,
isZen ? false,
# easy overrides to stdenv.hostPlatform.linux-kernel members
autoModules ? stdenv.hostPlatform.linux-kernel.autoModules or true,
preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false,
autoModules ? true,
# TODO: Remove this default?
preferBuiltin ?
stdenv.hostPlatform.isAarch || stdenv.hostPlatform.isRiscV || stdenv.hostPlatform.isLoongArch64,
kernelArch ? stdenv.hostPlatform.linuxArch,
kernelTests ? { },
@@ -116,9 +122,7 @@ lib.makeOverridable (
intermediateNixConfig =
configfile.moduleStructuredConfig.intermediateNixConfig
# extra config in legacy string format
+ 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 "";
+ extraConfig;
structuredConfigFromPatches = map (
{
@@ -205,8 +209,7 @@ lib.makeOverridable (
buildPhase =
let
# e.g. "defconfig"
kernelBaseConfig =
if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig or "defconfig";
kernelBaseConfig = defconfig;
kernelIntermediateConfig = writeText "kernel-intermediate-config" (
kernelConfigFun intermediateNixConfig
);

View File

@@ -909,9 +909,7 @@ with pkgs;
inherit (darwin) signingUtils;
};
vmTools = callPackage ../build-support/vm {
img = stdenv.hostPlatform.linux-kernel.target;
};
vmTools = callPackage ../build-support/vm { };
releaseTools = callPackage ../build-support/release { };