1{ buildPackages
2, callPackage
3, perl
4, bison ? null
5, flex ? null
6, gmp ? null
7, libmpc ? null
8, mpfr ? null
9, stdenv
10
11, # The kernel source tarball.
12 src
13
14, # The kernel version.
15 version
16
17, # Allows overriding the default defconfig
18 defconfig ? null
19
20, # Legacy overrides to the intermediate kernel config, as string
21 extraConfig ? ""
22
23, # kernel intermediate config overrides, as a set
24 structuredExtraConfig ? {}
25
26, # The version number used for the module directory
27 modDirVersion ? version
28
29, # An attribute set whose attributes express the availability of
30 # certain features in this kernel. E.g. `{iwlwifi = true;}'
31 # indicates a kernel that provides Intel wireless support. Used in
32 # NixOS to implement kernel-specific behaviour.
33 features ? {}
34
35, # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is
36 # automatically extended with extra per-version and per-config values.
37 randstructSeed ? ""
38
39, # A list of patches to apply to the kernel. Each element of this list
40 # should be an attribute set {name, patch} where `name' is a
41 # symbolic name and `patch' is the actual patch. The patch may
42 # optionally be compressed with gzip or bzip2.
43 kernelPatches ? []
44, ignoreConfigErrors ? stdenv.hostPlatform.platform.name != "pc" ||
45 stdenv.hostPlatform != stdenv.buildPlatform
46, extraMeta ? {}
47
48# easy overrides to stdenv.hostPlatform.platform members
49, autoModules ? stdenv.hostPlatform.platform.kernelAutoModules
50, preferBuiltin ? stdenv.hostPlatform.platform.kernelPreferBuiltin or false
51, kernelArch ? stdenv.hostPlatform.platform.kernelArch
52
53, ...
54}:
55
56assert stdenv.isLinux;
57
58let
59
60 lib = stdenv.lib;
61
62 # Combine the `features' attribute sets of all the kernel patches.
63 kernelFeatures = lib.fold (x: y: (x.features or {}) // y) ({
64 iwlwifi = true;
65 efiBootStub = true;
66 needsCifsUtils = true;
67 netfilterRPFilter = true;
68 grsecurity = false;
69 xen_dom0 = false;
70 ia32Emulation = true;
71 } // features) kernelPatches;
72
73 commonStructuredConfig = import ./common-config.nix {
74 inherit stdenv version ;
75
76 features = kernelFeatures; # Ensure we know of all extra patches, etc.
77 };
78
79 intermediateNixConfig = configfile.moduleStructuredConfig.intermediateNixConfig
80 # extra config in legacy string format
81 + extraConfig
82 + lib.optionalString (stdenv.hostPlatform.platform ? kernelExtraConfig) stdenv.hostPlatform.platform.kernelExtraConfig;
83
84 structuredConfigFromPatches =
85 map ({extraStructuredConfig ? {}, ...}: {settings=extraStructuredConfig;}) kernelPatches;
86
87 # appends kernel patches extraConfig
88 kernelConfigFun = baseConfigStr:
89 let
90 configFromPatches =
91 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
92 in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
93
94 configfile = stdenv.mkDerivation {
95 inherit ignoreConfigErrors autoModules preferBuiltin kernelArch;
96 pname = "linux-config";
97 inherit version;
98
99 generateConfig = ./generate-config.pl;
100
101 kernelConfig = kernelConfigFun intermediateNixConfig;
102 passAsFile = [ "kernelConfig" ];
103
104 depsBuildBuild = [ buildPackages.stdenv.cc ];
105 nativeBuildInputs = [ perl gmp libmpc mpfr ]
106 ++ lib.optionals (stdenv.lib.versionAtLeast version "4.16") [ bison flex ];
107
108 platformName = stdenv.hostPlatform.platform.name;
109 # e.g. "defconfig"
110 kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.platform.kernelBaseConfig;
111 # e.g. "bzImage"
112 kernelTarget = stdenv.hostPlatform.platform.kernelTarget;
113
114 prePatch = kernel.prePatch + ''
115 # Patch kconfig to print "###" after every question so that
116 # generate-config.pl from the generic builder can answer them.
117 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
118 '';
119
120 preUnpack = kernel.preUnpack or "";
121
122 inherit (kernel) src patches;
123
124 buildPhase = ''
125 export buildRoot="''${buildRoot:-build}"
126
127 # Get a basic config file for later refinement with $generateConfig.
128 make -C . O="$buildRoot" $kernelBaseConfig \
129 ARCH=$kernelArch \
130 HOSTCC=${buildPackages.stdenv.cc.targetPrefix}gcc \
131 HOSTCXX=${buildPackages.stdenv.cc.targetPrefix}g++
132
133 # Create the config file.
134 echo "generating kernel configuration..."
135 ln -s "$kernelConfigPath" "$buildRoot/kernel-config"
136 DEBUG=1 ARCH=$kernelArch KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \
137 PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. perl -w $generateConfig
138 '';
139
140 installPhase = "mv $buildRoot/.config $out";
141
142 enableParallelBuilding = true;
143
144 passthru = rec {
145
146 module = import ../../../../nixos/modules/system/boot/kernel_config.nix;
147 # used also in apache
148 # { modules = [ { options = res.options; config = svc.config or svc; } ];
149 # check = false;
150 # The result is a set of two attributes
151 moduleStructuredConfig = (lib.evalModules {
152 modules = [
153 module
154 { settings = commonStructuredConfig; _file = "pkgs/os-specific/linux/kernel/common-config.nix"; }
155 { settings = structuredExtraConfig; _file = "structuredExtraConfig"; }
156 ]
157 ++ structuredConfigFromPatches
158 ;
159 }).config;
160
161 #
162 structuredConfig = moduleStructuredConfig.settings;
163 };
164
165
166 }; # end of configfile derivation
167
168 kernel = (callPackage ./manual-config.nix {}) {
169 inherit version modDirVersion src kernelPatches randstructSeed stdenv extraMeta configfile;
170
171 config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
172 };
173
174 passthru = {
175 features = kernelFeatures;
176 inherit commonStructuredConfig;
177 passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
178 };
179
180in lib.extendDerivation true passthru kernel