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