1{ stdenv, perl, buildLinux
2
3, # The kernel source tarball.
4 src
5
6, # The kernel version.
7 version
8
9, # Overrides to the kernel config.
10 extraConfig ? ""
11
12, # The version number used for the module directory
13 modDirVersion ? version
14
15, # An attribute set whose attributes express the availability of
16 # certain features in this kernel. E.g. `{iwlwifi = true;}'
17 # indicates a kernel that provides Intel wireless support. Used in
18 # NixOS to implement kernel-specific behaviour.
19 features ? {}
20
21, # A list of patches to apply to the kernel. Each element of this list
22 # should be an attribute set {name, patch} where `name' is a
23 # symbolic name and `patch' is the actual patch. The patch may
24 # optionally be compressed with gzip or bzip2.
25 kernelPatches ? []
26, ignoreConfigErrors ? stdenv.platform.name != "pc"
27, extraMeta ? {}
28, ...
29}:
30
31assert stdenv.platform.name == "sheevaplug" -> stdenv.platform.uboot != null;
32assert stdenv.isLinux;
33
34let
35
36 lib = stdenv.lib;
37
38 kernelConfigFun = baseConfig:
39 let
40 configFromPatches =
41 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
42 in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
43
44 configfile = stdenv.mkDerivation {
45 inherit ignoreConfigErrors;
46 name = "linux-config-${version}";
47
48 generateConfig = ./generate-config.pl;
49
50 kernelConfig = kernelConfigFun config;
51
52 nativeBuildInputs = [ perl ];
53
54 platformName = stdenv.platform.name;
55 kernelBaseConfig = stdenv.platform.kernelBaseConfig;
56 kernelTarget = stdenv.platform.kernelTarget;
57 autoModules = stdenv.platform.kernelAutoModules;
58 arch = stdenv.platform.kernelArch;
59
60 crossAttrs = let
61 cp = stdenv.cross.platform;
62 in {
63 arch = cp.kernelArch;
64 platformName = cp.name;
65 kernelBaseConfig = cp.kernelBaseConfig;
66 kernelTarget = cp.kernelTarget;
67 autoModules = cp.kernelAutoModules;
68
69 # Just ignore all options that don't apply (We are lazy).
70 ignoreConfigErrors = true;
71
72 kernelConfig = kernelConfigFun configCross;
73
74 inherit (kernel.crossDrv) src patches preUnpack;
75 };
76
77 prePatch = kernel.prePatch + ''
78 # Patch kconfig to print "###" after every question so that
79 # generate-config.pl from the generic builder can answer them.
80 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
81 '';
82
83 inherit (kernel) src patches preUnpack;
84
85 buildPhase = ''
86 cd $buildRoot
87
88 # Get a basic config file for later refinement with $generateConfig.
89 make -C ../$sourceRoot O=$PWD $kernelBaseConfig ARCH=$arch
90
91 # Create the config file.
92 echo "generating kernel configuration..."
93 echo "$kernelConfig" > kernel-config
94 DEBUG=1 ARCH=$arch KERNEL_CONFIG=kernel-config AUTO_MODULES=$autoModules \
95 SRC=../$sourceRoot perl -w $generateConfig
96 '';
97
98 installPhase = "mv .config $out";
99
100 enableParallelBuilding = true;
101 };
102
103 kernel = buildLinux {
104 inherit version modDirVersion src kernelPatches;
105
106 configfile = configfile.nativeDrv or configfile;
107
108 crossConfigfile = configfile.crossDrv or configfile;
109
110 config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
111
112 crossConfig = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
113 };
114
115 passthru = {
116 # Combine the `features' attribute sets of all the kernel patches.
117 features = lib.fold (x: y: (x.features or {}) // y) features kernelPatches;
118
119 meta = kernel.meta // extraMeta;
120
121 passthru = kernel.passthru // (removeAttrs passthru [ "passthru" "meta" ]);
122 };
123
124 configWithPlatform = kernelPlatform: import ./common-config.nix
125 { inherit stdenv version kernelPlatform extraConfig;
126 features = passthru.features; # Ensure we know of all extra patches, etc.
127 };
128
129 config = configWithPlatform stdenv.platform;
130 configCross = configWithPlatform stdenv.cross.platform;
131
132 nativeDrv = lib.addPassthru kernel.nativeDrv passthru;
133
134 crossDrv = lib.addPassthru kernel.crossDrv passthru;
135in if kernel ? crossDrv then nativeDrv // { inherit nativeDrv crossDrv; } else lib.addPassthru kernel passthru