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