1{ buildPackages
2, callPackage
3, perl
4, bison ? null
5, flex ? null
6, gmp ? null
7, libmpc ? null
8, mpfr ? null
9, pahole
10, lib
11, stdenv
12
13, # The kernel source tarball.
14 src
15
16, # The kernel version.
17 version
18
19, # Allows overriding the default defconfig
20 defconfig ? null
21
22, # Legacy overrides to the intermediate kernel config, as string
23 extraConfig ? ""
24
25 # Additional make flags passed to kbuild
26, extraMakeFlags ? []
27
28, # enables the options in ./common-config.nix; if `false` then only
29 # `structuredExtraConfig` is used
30 enableCommonConfig ? true
31
32, # kernel intermediate config overrides, as a set
33 structuredExtraConfig ? {}
34
35, # The version number used for the module directory
36 # If unspecified, this is determined automatically from the version.
37 modDirVersion ? null
38
39, # An attribute set whose attributes express the availability of
40 # certain features in this kernel. E.g. `{iwlwifi = true;}'
41 # indicates a kernel that provides Intel wireless support. Used in
42 # NixOS to implement kernel-specific behaviour.
43 features ? {}
44
45, # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is
46 # automatically extended with extra per-version and per-config values.
47 randstructSeed ? ""
48
49, # A list of patches to apply to the kernel. Each element of this list
50 # should be an attribute set {name, patch} where `name' is a
51 # symbolic name and `patch' is the actual patch. The patch may
52 # optionally be compressed with gzip or bzip2.
53 kernelPatches ? []
54, ignoreConfigErrors ? stdenv.hostPlatform.linux-kernel.name != "pc"
55, extraMeta ? {}
56
57, isZen ? false
58, isLibre ? false
59, isHardened ? false
60
61# easy overrides to stdenv.hostPlatform.linux-kernel members
62, autoModules ? stdenv.hostPlatform.linux-kernel.autoModules
63, preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false
64, kernelArch ? stdenv.hostPlatform.linuxArch
65, kernelTests ? []
66, nixosTests
67, ...
68}@args:
69
70# Note: this package is used for bootstrapping fetchurl, and thus
71# cannot use fetchpatch! All mutable patches (generated by GitHub or
72# cgit) that are needed here should be included directly in Nixpkgs as
73# files.
74
75assert stdenv.isLinux;
76
77let
78 # Dirty hack to make sure that `version` & `src` have
79 # `<nixpkgs/pkgs/os-specific/linux/kernel/linux-x.y.nix>` as position
80 # when using `builtins.unsafeGetAttrPos`.
81 #
82 # This is to make sure that ofborg actually detects changes in the kernel derivation
83 # and pings all maintainers.
84 #
85 # For further context, see https://github.com/NixOS/nixpkgs/pull/143113#issuecomment-953319957
86 basicArgs = builtins.removeAttrs
87 args
88 (lib.filter (x: ! (builtins.elem x [ "version" "src" ])) (lib.attrNames args));
89
90 # Combine the `features' attribute sets of all the kernel patches.
91 kernelFeatures = lib.foldr (x: y: (x.features or {}) // y) ({
92 iwlwifi = true;
93 efiBootStub = true;
94 needsCifsUtils = true;
95 netfilterRPFilter = true;
96 ia32Emulation = true;
97 } // features) kernelPatches;
98
99 commonStructuredConfig = import ./common-config.nix {
100 inherit lib stdenv version;
101
102 features = kernelFeatures; # Ensure we know of all extra patches, etc.
103 };
104
105 intermediateNixConfig = configfile.moduleStructuredConfig.intermediateNixConfig
106 # extra config in legacy string format
107 + extraConfig
108 + stdenv.hostPlatform.linux-kernel.extraConfig or "";
109
110 structuredConfigFromPatches =
111 map ({extraStructuredConfig ? {}, ...}: {settings=extraStructuredConfig;}) kernelPatches;
112
113 # appends kernel patches extraConfig
114 kernelConfigFun = baseConfigStr:
115 let
116 configFromPatches =
117 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
118 in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
119
120 configfile = stdenv.mkDerivation {
121 inherit ignoreConfigErrors autoModules preferBuiltin kernelArch extraMakeFlags;
122 pname = "linux-config";
123 inherit version;
124
125 generateConfig = ./generate-config.pl;
126
127 kernelConfig = kernelConfigFun intermediateNixConfig;
128 passAsFile = [ "kernelConfig" ];
129
130 depsBuildBuild = [ buildPackages.stdenv.cc ];
131 nativeBuildInputs = [ perl gmp libmpc mpfr ]
132 ++ lib.optionals (lib.versionAtLeast version "4.16") [ bison flex ]
133 ++ lib.optional (lib.versionAtLeast version "5.2") pahole;
134
135 platformName = stdenv.hostPlatform.linux-kernel.name;
136 # e.g. "defconfig"
137 kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig;
138
139 makeFlags = lib.optionals (stdenv.hostPlatform.linux-kernel ? makeFlags) stdenv.hostPlatform.linux-kernel.makeFlags
140 ++ extraMakeFlags;
141
142 postPatch = kernel.postPatch + ''
143 # Patch kconfig to print "###" after every question so that
144 # generate-config.pl from the generic builder can answer them.
145 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
146 '';
147
148 preUnpack = kernel.preUnpack or "";
149
150 inherit (kernel) src patches;
151
152 buildPhase = ''
153 export buildRoot="''${buildRoot:-build}"
154 export HOSTCC=$CC_FOR_BUILD
155 export HOSTCXX=$CXX_FOR_BUILD
156 export HOSTAR=$AR_FOR_BUILD
157 export HOSTLD=$LD_FOR_BUILD
158
159 # Get a basic config file for later refinement with $generateConfig.
160 make $makeFlags \
161 -C . O="$buildRoot" $kernelBaseConfig \
162 ARCH=$kernelArch \
163 HOSTCC=$HOSTCC HOSTCXX=$HOSTCXX HOSTAR=$HOSTAR HOSTLD=$HOSTLD \
164 CC=$CC OBJCOPY=$OBJCOPY OBJDUMP=$OBJDUMP READELF=$READELF \
165 $makeFlags
166
167 # Create the config file.
168 echo "generating kernel configuration..."
169 ln -s "$kernelConfigPath" "$buildRoot/kernel-config"
170 DEBUG=1 ARCH=$kernelArch KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \
171 PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. MAKE_FLAGS="$makeFlags" \
172 perl -w $generateConfig
173 '';
174
175 installPhase = "mv $buildRoot/.config $out";
176
177 enableParallelBuilding = true;
178
179 passthru = rec {
180 module = import ../../../../nixos/modules/system/boot/kernel_config.nix;
181 # used also in apache
182 # { modules = [ { options = res.options; config = svc.config or svc; } ];
183 # check = false;
184 # The result is a set of two attributes
185 moduleStructuredConfig = (lib.evalModules {
186 modules = [
187 module
188 ] ++ lib.optionals enableCommonConfig [
189 { settings = commonStructuredConfig; _file = "pkgs/os-specific/linux/kernel/common-config.nix"; }
190 ] ++ [
191 { settings = structuredExtraConfig; _file = "structuredExtraConfig"; }
192 ]
193 ++ structuredConfigFromPatches
194 ;
195 }).config;
196
197 structuredConfig = moduleStructuredConfig.settings;
198 };
199 }; # end of configfile derivation
200
201 kernel = (callPackage ./manual-config.nix { inherit lib stdenv buildPackages; }) (basicArgs // {
202 inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile;
203 pos = builtins.unsafeGetAttrPos "version" args;
204
205 config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
206 } // lib.optionalAttrs (modDirVersion != null) { inherit modDirVersion; });
207
208 passthru = basicArgs // {
209 features = kernelFeatures;
210 inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre;
211 isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
212
213 # Adds dependencies needed to edit the config:
214 # nix-shell '<nixpkgs>' -A linux.configEnv --command 'make nconfig'
215 configEnv = kernel.overrideAttrs (old: {
216 nativeBuildInputs = old.nativeBuildInputs or [] ++ (with buildPackages; [
217 pkg-config ncurses
218 ]);
219 });
220
221 passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
222 tests = let
223 overridableKernel = finalKernel // {
224 override = args:
225 lib.warn (
226 "override is stubbed for NixOS kernel tests, not applying changes these arguments: "
227 + toString (lib.attrNames (if lib.isAttrs args then args else args {}))
228 ) overridableKernel;
229 };
230 in [ (nixosTests.kernel-generic.passthru.testsForKernel overridableKernel) ] ++ kernelTests;
231 };
232
233 finalKernel = lib.extendDerivation true passthru kernel;
234in finalKernel