summary refs log tree commit diff
path: root/pkgs/os-specific/linux/kernel/generic.nix
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-01-01 09:21:25 -0500
committerShea Levy <shea@shealevy.com>2014-01-01 09:21:25 -0500
commitf95d214cfdf115b9444acc5ce8060a5b1b23ed77 (patch)
tree50c8abd98c10500e3c4729bb910154d067261b4b /pkgs/os-specific/linux/kernel/generic.nix
parenta87b1f36e0095956b9b170f2c7071263a36ae155 (diff)
downloadnixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar.gz
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar.bz2
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar.lz
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar.xz
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.tar.zst
nixpkgs-f95d214cfdf115b9444acc5ce8060a5b1b23ed77.zip
Implement generic kernel build via manual-config
This has three major benefits:

1. We no longer have two kernel build processes to maintain

2. The build process is (IMO) cleaner and cleaves more closely to
upstream. In partuclar, we use make install to install the kernel and
development source/build trees, eliminating the guesswork about which
files to copy.

3. The derivation has multiple outputs: the kernel and modules are in
the default `out' output, while the build and source trees are in a
`dev' output. This makes it possible for the full source and build tree
to be kept (which is expected by out-of-tree modules) without bloating
the closure of the system derivation.

In addition, if a solution for how to handle queries in the presence of
imports from derivations ever makes it into nix, a framework for
querying the full configuration of the kernel in nix expressions is
already in place.

Signed-off-by: Shea Levy <shea@shealevy.com>
Diffstat (limited to 'pkgs/os-specific/linux/kernel/generic.nix')
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix154
1 files changed, 62 insertions, 92 deletions
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index 3e1fc920a59..888dcf1e9a5 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl, perl, mktemp, kmod, bc
+{ stdenv, perl, linuxManualConfig
 
 , # The kernel source tarball.
   src
@@ -23,20 +23,7 @@
   # symbolic name and `patch' is the actual patch.  The patch may
   # optionally be compressed with gzip or bzip2.
   kernelPatches ? []
-
-, # Allows you to set your own kernel version suffix (e.g.,
-  # "-my-kernel").
-  localVersion ? ""
-
-, preConfigure ? ""
 , extraMeta ? {}
-, ubootChooser ? null
-, postInstall ? ""
-
-, # After the builder did a 'make all' (kernel + modules)
-  # we force building the target asked: bzImage/zImage/uImage/...
-  postBuild ? "make $makeFlags $kernelTarget; make $makeFlags -C scripts unifdef"
-
 , ...
 }:
 
@@ -52,93 +39,76 @@ let
         map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
     in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
 
+  configfile = stdenv.mkDerivation {
+    name = "linux-config-${version}";
+
+    generateConfig = ./generate-config.pl;
+
+    kernelConfig = kernelConfigFun config;
+
+    ignoreConfigErrors = stdenv.platform.name != "pc";
+
+    nativeBuildInputs = [ perl ];
+
+    platformName = stdenv.platform.name;
+    kernelBaseConfig = stdenv.platform.kernelBaseConfig;
+    kernelTarget = stdenv.platform.kernelTarget;
+    autoModules = stdenv.platform.kernelAutoModules;
+    arch = stdenv.platform.kernelArch;
+
+    crossAttrs = let
+        cp = stdenv.cross.platform;
+      in {
+        arch = cp.kernelArch;
+        platformName = cp.name;
+        kernelBaseConfig = cp.kernelBaseConfig;
+        kernelTarget = cp.kernelTarget;
+        autoModules = cp.kernelAutoModules;
+
+        # Just ignore all options that don't apply (We are lazy).
+        ignoreConfigErrors = true;
+
+        kernelConfig = kernelConfigFun configCross;
+      };
+    buildCommand = ''
+      # Get a basic config file for later refinement with $generateConfig.
+      make -C ${kernel.sourceRoot} O=$PWD $kernelBaseConfig ARCH=$arch
+
+      # Create the config file.
+      echo "generating kernel configuration..."
+      echo "$kernelConfig" > kernel-config
+      DEBUG=1 ARCH=$arch KERNEL_CONFIG=kernel-config AUTO_MODULES=$autoModules \
+           SRC=${kernel.sourceRoot} perl -w $generateConfig
+      mv .config $out
+    '';
+  };
+
+  kernel = linuxManualConfig {
+    inherit version modDirVersion src kernelPatches;
+
+    configfile = configfile.nativeDrv or configfile;
+
+    crossConfigfile = configfile.crossDrv or configfile;
+
+    config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
+
+    crossConfig = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
+  };
+
   configWithPlatform = kernelPlatform:
     import ./common-config.nix { inherit stdenv version kernelPlatform extraConfig; };
 
   config = configWithPlatform stdenv.platform;
   configCross = configWithPlatform stdenv.cross.platform;
 
-in
-
-stdenv.mkDerivation {
-  name = "linux-${version}";
-
-  enableParallelBuilding = true;
-
   passthru = {
-    inherit version modDirVersion kernelPatches;
     # Combine the `features' attribute sets of all the kernel patches.
     features = lib.fold (x: y: (x.features or {}) // y) features kernelPatches;
+
+    meta = kernel.meta // extraMeta;
   };
 
-  builder = ./builder.sh;
-
-  generateConfig = ./generate-config.pl;
-
-  inherit preConfigure src kmod localVersion postInstall postBuild;
-
-  patches = map (p: p.patch) kernelPatches;
-
-  kernelConfig = kernelConfigFun config;
-
-  # For UML and non-PC, just ignore all options that don't apply (We are lazy).
-  ignoreConfigErrors = stdenv.platform.name != "pc";
-
-  nativeBuildInputs = [ perl mktemp bc ];
-
-  buildInputs = lib.optional (stdenv.platform.uboot != null)
-    (ubootChooser stdenv.platform.uboot);
-
-  platformName = stdenv.platform.name;
-  kernelBaseConfig = stdenv.platform.kernelBaseConfig;
-  kernelTarget = stdenv.platform.kernelTarget;
-  autoModules = stdenv.platform.kernelAutoModules;
-
-  # Should we trust platform.kernelArch? We can only do
-  # that once we differentiate i686/x86_64 in platforms.
-  arch =
-    if stdenv.system == "i686-linux" then "i386" else
-    if stdenv.system == "x86_64-linux" then "x86_64" else
-    if stdenv.isArm then "arm" else
-    if stdenv.system == "mips64el-linux" then "mips" else
-    abort "Platform ${stdenv.system} is not supported.";
-
-  crossAttrs = let
-      cp = stdenv.cross.platform;
-    in
-      assert cp.name == "sheevaplug" -> cp.uboot != null;
-    {
-      arch = cp.kernelArch;
-      platformName = cp.name;
-      kernelBaseConfig = cp.kernelBaseConfig;
-      kernelTarget = cp.kernelTarget;
-      autoModules = cp.kernelAutoModules;
-
-      # Just ignore all options that don't apply (We are lazy).
-      ignoreConfigErrors = true;
-
-      kernelConfig = kernelConfigFun configCross;
-
-      # The substitution of crossAttrs happens *after* the stdenv cross adapter sets
-      # the parameters for the usual stdenv. Thus, we need to specify
-      # the ".crossDrv" in the buildInputs here.
-      buildInputs = lib.optional (cp.uboot != null) (ubootChooser cp.uboot).crossDrv;
-    };
-
-  meta = {
-    description =
-      "The Linux kernel" +
-      (if kernelPatches == [] then "" else
-        " (with patches: "
-        + lib.concatStrings (lib.intersperse ", " (map (x: x.name) kernelPatches))
-        + ")");
-    license = "GPLv2";
-    homepage = http://www.kernel.org/;
-    maintainers = [
-      lib.maintainers.eelco
-      lib.maintainers.chaoflow
-    ];
-    platforms = lib.platforms.linux;
-  } // extraMeta;
-}
+  nativeDrv = lib.addPassthru kernel.nativeDrv passthru;
 
+  crossDrv = lib.addPassthru kernel.crossDrv passthru;
+in if kernel ? crossDrv then nativeDrv // { inherit nativeDrv crossDrv; } else lib.addPassthru kernel passthru