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