1{ buildPackages
2, ncurses
3, callPackage
4, perl
5, bison ? null
6, flex ? null
7, stdenv
8
9, # The kernel source tarball.
10 src
11
12, # The kernel version.
13 version
14
15, # Allows overriding the default defconfig
16 defconfig ? null
17
18, # Legacy overrides to the intermediate kernel config, as string
19 extraConfig ? ""
20
21, # kernel intermediate config overrides, as a set
22 structuredExtraConfig ? {}
23
24, # The version number used for the module directory
25 modDirVersion ? version
26
27, # An attribute set whose attributes express the availability of
28 # certain features in this kernel. E.g. `{iwlwifi = true;}'
29 # indicates a kernel that provides Intel wireless support. Used in
30 # NixOS to implement kernel-specific behaviour.
31 features ? {}
32
33, # A list of patches to apply to the kernel. Each element of this list
34 # should be an attribute set {name, patch} where `name' is a
35 # symbolic name and `patch' is the actual patch. The patch may
36 # optionally be compressed with gzip or bzip2.
37 kernelPatches ? []
38, ignoreConfigErrors ? stdenv.hostPlatform.platform.name != "pc" ||
39 stdenv.hostPlatform != stdenv.buildPlatform
40, extraMeta ? {}
41
42# easy overrides to stdenv.hostPlatform.platform members
43, autoModules ? stdenv.hostPlatform.platform.kernelAutoModules
44, preferBuiltin ? stdenv.hostPlatform.platform.kernelPreferBuiltin or false
45, kernelArch ? stdenv.hostPlatform.platform.kernelArch
46
47, mkValueOverride ? null
48, ...
49}:
50
51assert stdenv.isLinux;
52
53let
54
55 lib = stdenv.lib;
56
57 # Combine the `features' attribute sets of all the kernel patches.
58 kernelFeatures = lib.fold (x: y: (x.features or {}) // y) ({
59 iwlwifi = true;
60 efiBootStub = true;
61 needsCifsUtils = true;
62 netfilterRPFilter = true;
63 grsecurity = false;
64 xen_dom0 = false;
65 } // features) kernelPatches;
66
67 intermediateNixConfig = import ./common-config.nix {
68 inherit stdenv version structuredExtraConfig mkValueOverride;
69
70 # append extraConfig for backwards compatibility but also means the user can't override the kernelExtraConfig part
71 extraConfig = extraConfig + lib.optionalString (stdenv.hostPlatform.platform ? kernelExtraConfig) stdenv.hostPlatform.platform.kernelExtraConfig;
72
73 features = kernelFeatures; # Ensure we know of all extra patches, etc.
74 };
75
76 kernelConfigFun = baseConfig:
77 let
78 configFromPatches =
79 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
80 in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
81
82 configfile = stdenv.mkDerivation {
83 inherit ignoreConfigErrors autoModules preferBuiltin kernelArch;
84 name = "linux-config-${version}";
85
86 generateConfig = ./generate-config.pl;
87
88 kernelConfig = kernelConfigFun intermediateNixConfig;
89 passAsFile = [ "kernelConfig" ];
90
91 depsBuildBuild = [ buildPackages.stdenv.cc ];
92 nativeBuildInputs = [ perl ]
93 ++ lib.optionals (stdenv.lib.versionAtLeast version "4.16") [ bison flex ];
94
95 platformName = stdenv.hostPlatform.platform.name;
96 # e.g. "defconfig"
97 kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.platform.kernelBaseConfig;
98 # e.g. "bzImage"
99 kernelTarget = stdenv.hostPlatform.platform.kernelTarget;
100
101 prePatch = kernel.prePatch + ''
102 # Patch kconfig to print "###" after every question so that
103 # generate-config.pl from the generic builder can answer them.
104 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
105 '';
106
107 preUnpack = kernel.preUnpack or "";
108
109 inherit (kernel) src patches;
110
111 buildPhase = ''
112 export buildRoot="''${buildRoot:-build}"
113
114 # Get a basic config file for later refinement with $generateConfig.
115 make HOSTCC=${buildPackages.stdenv.cc.targetPrefix}gcc -C . O="$buildRoot" $kernelBaseConfig ARCH=$kernelArch
116
117 # Create the config file.
118 echo "generating kernel configuration..."
119 ln -s "$kernelConfigPath" "$buildRoot/kernel-config"
120 DEBUG=1 ARCH=$kernelArch KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \
121 PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. perl -w $generateConfig
122 '';
123
124 installPhase = "mv $buildRoot/.config $out";
125
126 enableParallelBuilding = true;
127 };
128
129 kernel = (callPackage ./manual-config.nix {}) {
130 inherit version modDirVersion src kernelPatches stdenv extraMeta configfile;
131
132 config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
133 };
134
135 passthru = {
136 features = kernelFeatures;
137 passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
138 };
139
140in lib.extendDerivation true passthru kernel