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, extraMeta ? {}
27, ...
28}:
29
30assert stdenv.platform.name == "sheevaplug" -> stdenv.platform.uboot != null;
31assert stdenv.isLinux;
32
33let
34
35 lib = stdenv.lib;
36
37 kernelConfigFun = baseConfig:
38 let
39 configFromPatches =
40 map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
41 in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
42
43 configfile = stdenv.mkDerivation {
44 name = "linux-config-${version}";
45
46 generateConfig = ./generate-config.pl;
47
48 kernelConfig = kernelConfigFun config;
49
50 ignoreConfigErrors = stdenv.platform.name != "pc";
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 preConfigure = ''
61 buildFlagsArray+=("KBUILD_BUILD_TIMESTAMP=Thu Jan 1 00:00:01 UTC 1970")
62 '';
63
64 crossAttrs = let
65 cp = stdenv.cross.platform;
66 in {
67 arch = cp.kernelArch;
68 platformName = cp.name;
69 kernelBaseConfig = cp.kernelBaseConfig;
70 kernelTarget = cp.kernelTarget;
71 autoModules = cp.kernelAutoModules;
72
73 # Just ignore all options that don't apply (We are lazy).
74 ignoreConfigErrors = true;
75
76 kernelConfig = kernelConfigFun configCross;
77
78 inherit (kernel.crossDrv) src patches preUnpack;
79 };
80
81 prePatch = kernel.prePatch + ''
82 # Patch kconfig to print "###" after every question so that
83 # generate-config.pl from the generic builder can answer them.
84 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
85 '';
86
87 inherit (kernel) src patches preUnpack;
88
89 buildPhase = ''
90 cd $buildRoot
91
92 # Get a basic config file for later refinement with $generateConfig.
93 make -C ../$sourceRoot O=$PWD $kernelBaseConfig ARCH=$arch
94
95 # Create the config file.
96 echo "generating kernel configuration..."
97 echo "$kernelConfig" > kernel-config
98 DEBUG=1 ARCH=$arch KERNEL_CONFIG=kernel-config AUTO_MODULES=$autoModules \
99 SRC=../$sourceRoot perl -w $generateConfig
100 '';
101
102 installPhase = "mv .config $out";
103
104 enableParallelBuilding = true;
105 };
106
107 kernel = buildLinux {
108 inherit version modDirVersion src kernelPatches;
109
110 configfile = configfile.nativeDrv or configfile;
111
112 crossConfigfile = configfile.crossDrv or configfile;
113
114 config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
115
116 crossConfig = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
117 };
118
119 passthru = {
120 # Combine the `features' attribute sets of all the kernel patches.
121 features = lib.fold (x: y: (x.features or {}) // y) features kernelPatches;
122
123 meta = kernel.meta // extraMeta;
124
125 passthru = kernel.passthru // (removeAttrs passthru [ "passthru" "meta" ]);
126 };
127
128 configWithPlatform = kernelPlatform: import ./common-config.nix
129 { inherit stdenv version kernelPlatform extraConfig;
130 features = passthru.features; # Ensure we know of all extra patches, etc.
131 };
132
133 config = configWithPlatform stdenv.platform;
134 configCross = configWithPlatform stdenv.cross.platform;
135
136 nativeDrv = lib.addPassthru kernel.nativeDrv passthru;
137
138 crossDrv = lib.addPassthru kernel.crossDrv passthru;
139in if kernel ? crossDrv then nativeDrv // { inherit nativeDrv crossDrv; } else lib.addPassthru kernel passthru