Merge branch 'manual-kernel-config'

This adds a function to build a kernel from a .config generated via the kernel's configuration system.

The function takes a version, a modDirVersion, the src, and the config.
Additionally, patches can be specified.

The kernel's features can be autodetected from the config, or manually specified.

Known future work includes:
* Testing to determine minimal features required for NixOS booting
  * Updating NixOS modules to explicitly require the features they require
* Cross-compilation support
This commit is contained in:
Shea Levy 2012-07-29 05:03:05 -04:00
commit 2a12fe8f8b
3 changed files with 142 additions and 2 deletions

View file

@ -0,0 +1,135 @@
{ stdenv, runCommand, nettools, perl, kmod, writeTextFile }:
with stdenv.lib;
let
# Function to parse the config file to get the features supported
readFeatures = config:
let
# !!! Original causes recursion too deep, need to import from derivation
# linesWithComments = splitString "\n" (builtins.readFile config);
lines = import "${runCommand "lines.nix" {} ''
echo "[" >> $out
while read line; do
if [ -n "$line" ] && [ "#" != ''${line:0:1} ]; then
echo "'''" >> $out
echo $(echo $line | sed "s/'''/''''/g")"'''" >> $out
fi
done < ${config}
echo "]" >> $out
''}";
nvpairs = map (s: let split = splitString "=" s; fst = head split; in {
name = substring (stringLength "CONFIG_") (stringLength fst) fst;
value = head (tail split);
}) lines;
configAttrs = listToAttrs nvpairs;
getValue = option:
if hasAttr option configAttrs then getAttr option configAttrs else null;
isYes = option: (getValue option) == "y";
in
{
modular = isYes "MODULES";
};
in
{
# The kernel version
version,
# The version of the kernel module directory
modDirVersion ? version,
# The kernel source (tarball, git checkout, etc.)
src,
# Any patches
patches ? [],
# The kernel .config file
config,
# Manually specified features the kernel supports
# If unspecified, this will be autodetected from the .config
features ? readFeatures config
}:
let
commonMakeFlags = [
"O=../build"
"INSTALL_PATH=$(out)"
"INSTALLKERNEL=${installkernel}"
];
installkernel = writeTextFile { name = "installkernel"; executable=true; text = ''
#!/bin/sh
mkdir $4
mv -v $2 $4
mv -v $3 $4
'';};
in
stdenv.mkDerivation ({
name = "linux-${version}";
enableParallelBuilding = true;
passthru = {
inherit version modDirVersion features;
};
inherit patches src;
prePatch = ''
for mf in $(find -name Makefile -o -name Makefile.include); do
echo "stripping FHS paths in \`$mf'..."
sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g ; s|/sbin/||g'
done
'';
configurePhase = ''
runHook preConfigure
mkdir ../build
make $makeFlags "''${makeFlagsArray[@]}" mrproper
ln -sv ${config} ../build/.config
make $makeFlags "''${makeFlagsArray[@]}" oldconfig
rm ../build/.config.old
runHook postConfigure
'';
buildNativeInputs = [ perl nettools kmod ];
makeFlags = commonMakeFlags;
meta = {
description = "The Linux kernel";
license = "GPLv2";
homepage = http://www.kernel.org/;
maintainers = [
maintainers.shlevy
];
platforms = lib.platforms.linux;
};
} // optionalAttrs (features ? modular && features.modular) {
makeFlags = commonMakeFlags ++ [
"MODLIB=\"$(out)/lib/modules/${modDirVersion}\""
];
postInstall = ''
make modules_install $makeFlags "''${makeFlagsArray[@]}" \
$installFlags "''${installFlagsArray[@]}"
rm -f $out/lib/modules/${modDirVersion}/{build,source}
cd ..
mv $sourceRoot $out/lib/modules/${modDirVersion}/source
mv build $out/lib/modules/${modDirVersion}/build
unlink $out/lib/modules/${modDirVersion}/build/source
ln -sv $out/lib/modules/${modDirVersion}/{,build/}source
'';
postFixup = ''
if [ -z "$dontStrip" ]; then
find $out -name "*.ko" -print0 | xargs -0 strip -S
fi
'';
})

View file

@ -1,11 +1,11 @@
{ stdenv, fetchurl, xz, zlib, pkgconfig }:
stdenv.mkDerivation rec {
name = "kmod-8";
name = "kmod-9";
src = fetchurl {
url = "mirror://kernel/linux/utils/kernel/kmod/${name}.tar.xz";
sha256 = "0kbkjzcyhkwgcplwa29n0f03ccwpg4df83pdl5nkvsk2rzgx3xrm";
sha256 = "1kyfplx0gygzxp5dn81yk3cn8zzraqm497vis04r1g1dnry2c1q6";
};
# Disable xz/zlib support to prevent needing them in the initrd.

View file

@ -5856,6 +5856,11 @@ let
linux = linuxPackages.kernel;
linuxPackages = linuxPackages_3_2;
# A function to build a manually-configured kernel
linuxManualConfig = import ../os-specific/linux/kernel/manual-config.nix {
inherit stdenv runCommand nettools perl kmod writeTextFile;
};
keyutils = callPackage ../os-specific/linux/keyutils { };
libselinux = callPackage ../os-specific/linux/libselinux { };