21 let overridableKernel =
22 lib.makeOverridable ({ # The kernel source tarball.
25 , # The kernel version.
28 , # Allows overriding the default defconfig
31 , # Legacy overrides to the intermediate kernel config, as string
34 # Additional make flags passed to kbuild
37 , # enables the options in ./common-config.nix; if `false` then only
38 # `structuredExtraConfig` is used
39 enableCommonConfig ? true
41 , # kernel intermediate config overrides, as a set
42 structuredExtraConfig ? {}
44 , # The version number used for the module directory
45 # If unspecified, this is determined automatically from the version.
48 , # An attribute set whose attributes express the availability of
49 # certain features in this kernel. E.g. `{ia32Emulation = true;}'
50 # indicates a kernel that provides Intel wireless support. Used in
51 # NixOS to implement kernel-specific behaviour.
54 , # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is
55 # automatically extended with extra per-version and per-config values.
58 , # A list of patches to apply to the kernel. Each element of this list
59 # should be an attribute set {name, patch} where `name' is a
60 # symbolic name and `patch' is the actual patch. The patch may
61 # optionally be compressed with gzip or bzip2.
63 , ignoreConfigErrors ? stdenv.hostPlatform.linux-kernel.name != "pc"
70 # easy overrides to stdenv.hostPlatform.linux-kernel members
71 , autoModules ? stdenv.hostPlatform.linux-kernel.autoModules
72 , preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false
73 , kernelArch ? stdenv.hostPlatform.linuxArch
76 , stdenv ? args'.stdenv
77 , buildPackages ? args'.buildPackages
82 # Note: this package is used for bootstrapping fetchurl, and thus
83 # cannot use fetchpatch! All mutable patches (generated by GitHub or
84 # cgit) that are needed here should be included directly in Nixpkgs as
87 assert stdenv.hostPlatform.isLinux;
90 # Dirty hack to make sure that `version` & `src` have
91 # `<nixpkgs/pkgs/os-specific/linux/kernel/linux-x.y.nix>` as position
92 # when using `builtins.unsafeGetAttrPos`.
94 # This is to make sure that ofborg actually detects changes in the kernel derivation
95 # and pings all maintainers.
97 # For further context, see https://github.com/NixOS/nixpkgs/pull/143113#issuecomment-953319957
98 basicArgs = builtins.removeAttrs
100 (lib.filter (x: ! (builtins.elem x [ "version" "pname" "src" ])) (lib.attrNames args));
102 # Combine the `features' attribute sets of all the kernel patches.
103 kernelFeatures = lib.foldr (x: y: (x.features or {}) // y) ({
105 netfilterRPFilter = true;
106 ia32Emulation = true;
107 } // features) kernelPatches;
109 commonStructuredConfig = import ./common-config.nix {
110 inherit lib stdenv version;
112 lib.any (lib.meta.platformMatch stdenv.hostPlatform) rustc.targetPlatforms
113 && lib.all (p: !lib.meta.platformMatch stdenv.hostPlatform p) rustc.badTargetPlatforms
114 # Known to be broken: https://lore.kernel.org/lkml/31885EDD-EF6D-4EF1-94CA-276BA7A340B7@kernel.org/T/
115 && !(stdenv.hostPlatform.isRiscV && stdenv.cc.isGNU);
117 features = kernelFeatures; # Ensure we know of all extra patches, etc.
120 intermediateNixConfig = configfile.moduleStructuredConfig.intermediateNixConfig
121 # extra config in legacy string format
123 + stdenv.hostPlatform.linux-kernel.extraConfig or "";
125 structuredConfigFromPatches =
126 map ({extraStructuredConfig ? {}, ...}: {settings=extraStructuredConfig;}) kernelPatches;
128 # appends kernel patches extraConfig
129 kernelConfigFun = baseConfigStr:
132 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
133 in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
135 withRust = ((configfile.moduleStructuredConfig.settings.RUST or {}).tristate or null) == "y";
137 configfile = stdenv.mkDerivation {
138 inherit ignoreConfigErrors autoModules preferBuiltin kernelArch extraMakeFlags;
139 pname = "linux-config";
142 generateConfig = ./generate-config.pl;
144 kernelConfig = kernelConfigFun intermediateNixConfig;
145 passAsFile = [ "kernelConfig" ];
147 depsBuildBuild = [ buildPackages.stdenv.cc ];
148 nativeBuildInputs = [ perl gmp libmpc mpfr bison flex ]
149 ++ lib.optional (lib.versionAtLeast version "5.2") pahole
150 ++ lib.optionals withRust [ rust-bindgen rustc ]
153 RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc;
155 platformName = stdenv.hostPlatform.linux-kernel.name;
157 kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig;
159 makeFlags = lib.optionals (stdenv.hostPlatform.linux-kernel ? makeFlags) stdenv.hostPlatform.linux-kernel.makeFlags
162 postPatch = kernel.postPatch + ''
163 # Patch kconfig to print "###" after every question so that
164 # generate-config.pl from the generic builder can answer them.
165 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
168 preUnpack = kernel.preUnpack or "";
170 inherit (kernel) src patches;
173 export buildRoot="''${buildRoot:-build}"
174 export HOSTCC=$CC_FOR_BUILD
175 export HOSTCXX=$CXX_FOR_BUILD
176 export HOSTAR=$AR_FOR_BUILD
177 export HOSTLD=$LD_FOR_BUILD
179 # Get a basic config file for later refinement with $generateConfig.
181 -C . O="$buildRoot" $kernelBaseConfig \
183 HOSTCC=$HOSTCC HOSTCXX=$HOSTCXX HOSTAR=$HOSTAR HOSTLD=$HOSTLD \
184 CC=$CC OBJCOPY=$OBJCOPY OBJDUMP=$OBJDUMP READELF=$READELF \
187 # Create the config file.
188 echo "generating kernel configuration..."
189 ln -s "$kernelConfigPath" "$buildRoot/kernel-config"
190 DEBUG=1 ARCH=$kernelArch KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \
191 PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. MAKE_FLAGS="$makeFlags" \
192 perl -w $generateConfig
195 installPhase = "mv $buildRoot/.config $out";
197 enableParallelBuilding = true;
200 module = import ../../../../nixos/modules/system/boot/kernel_config.nix;
201 # used also in apache
202 # { modules = [ { options = res.options; config = svc.config or svc; } ];
204 # The result is a set of two attributes
205 moduleStructuredConfig = (lib.evalModules {
208 ] ++ lib.optionals enableCommonConfig [
209 { settings = commonStructuredConfig; _file = "pkgs/os-specific/linux/kernel/common-config.nix"; }
211 { settings = structuredExtraConfig; _file = "structuredExtraConfig"; }
213 ++ structuredConfigFromPatches
217 structuredConfig = moduleStructuredConfig.settings;
219 }; # end of configfile derivation
221 kernel = (callPackage ./manual-config.nix { inherit lib stdenv buildPackages; }) (basicArgs // {
222 inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile modDirVersion;
223 pos = builtins.unsafeGetAttrPos "version" args;
226 CONFIG_MODULES = "y";
227 CONFIG_FW_LOADER = "y";
228 CONFIG_RUST = if withRust then "y" else "n";
233 kernel.overrideAttrs (finalAttrs: previousAttrs: {
235 passthru = previousAttrs.passthru or { } // basicArgs // {
236 features = kernelFeatures;
237 inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre;
238 isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
240 # Adds dependencies needed to edit the config:
241 # nix-shell '<nixpkgs>' -A linux.configEnv --command 'make nconfig'
242 configEnv = kernel.overrideAttrs (old: {
243 nativeBuildInputs = old.nativeBuildInputs or [] ++ (with buildPackages; [
249 overridableKernel = finalAttrs.finalPackage // {
252 "override is stubbed for NixOS kernel tests, not applying changes these arguments: "
253 + toString (lib.attrNames (lib.toFunction args { }))
256 /* Certain arguments must be evaluated lazily; so that only the output(s) depend on them.
257 Original reproducer / simplified use case:
259 versionDoesNotDependOnPatchesEtcNixOS =
261 (nixos ({ config, pkgs, ... }: {
262 boot.kernelPatches = [
263 (builtins.seq config.boot.kernelPackages.kernel.version { patch = pkgs.emptyFile; })
265 })).config.boot.kernelPackages.kernel.outPath
267 versionDoesNotDependOnPatchesEtc =
269 (import ./generic.nix args' (args // (
270 let explain = attrName:
272 The ${attrName} attribute must be able to access the kernel.version attribute without an infinite recursion.
273 That means that the kernel attrset (attrNames) and the kernel.version attribute must not depend on the ${attrName} argument.
274 The fact that this exception is raised shows that such a dependency does exist.
275 This is a problem for the configurability of ${attrName} in version-aware logic such as that in NixOS.
276 Strictness can creep in through optional attributes, or assertions and warnings that run as part of code that shouldn't access what is checked.
279 kernelPatches = throw (explain "kernelPatches");
280 structuredExtraConfig = throw (explain "structuredExtraConfig");
281 modDirVersion = throw (explain "modDirVersion");
285 inherit versionDoesNotDependOnPatchesEtc;
286 testsForKernel = nixosTests.kernel-generic.passthru.testsForKernel overridableKernel;
287 # Disabled by default, because the infinite recursion is hard to understand. The other test's error is better and produces a shorter trace.
288 # inherit versionDoesNotDependOnPatchesEtcNixOS;