From f1b77805373c31c2db5a4faa1052136a5e3de94a Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Wed, 19 Oct 2022 17:34:22 +0100 Subject: [PATCH] speed up kernel build by having two separate derivations for patching the kernel source tree and building it, we have to copy said source trees from one store location to another which takes non-neglible time on spinning rust (literally minutes on my machine). Replace with a single derivation that can do more things on one tree in-place --- default.nix | 31 +++++--- devices/gl-ar750/default.nix | 70 +++++++------------ devices/qemu/default.nix | 34 +++------ kernel/dtb.nix | 9 +-- kernel/uimage.nix | 4 +- overlay.nix | 1 + kernel/vmlinux.nix => pkgs/kernel/default.nix | 29 +++++--- 7 files changed, 77 insertions(+), 101 deletions(-) rename kernel/vmlinux.nix => pkgs/kernel/default.nix (89%) diff --git a/default.nix b/default.nix index 6a8c1ac..2e5a7fb 100644 --- a/default.nix +++ b/default.nix @@ -17,20 +17,31 @@ let (if phram then ./modules/phram.nix else (args: {})) ] nixpkgs; squashfs = liminix.builders.squashfs config.filesystem.contents; - kernel = callPackage ./kernel { - inherit (config.kernel) config checkedConfig; + + openwrt = fetchFromGitHub { + name = "openwrt-source"; + repo = "openwrt"; + owner = "openwrt"; + rev = "a5265497a4f6da158e95d6a450cb2cb6dc085cab"; + hash = "sha256-YYi4gkpLjbOK7bM2MGQjAyEBuXJ9JNXoz/JEmYf8xE8="; }; outputs = rec { - inherit squashfs kernel; - dtb = kernel.dtb { - dts = "qca9531_glinet_gl-ar750.dts"; - + inherit squashfs; + kernel = nixpkgs.kernel.override { + inherit (config.kernel) config checkedConfig; }; - uimage = kernel.uimage { + dtb = (callPackage ./kernel/dtb.nix {}) { + dts = "${openwrt}/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts"; + includes = [ + "${openwrt}/target/linux/ath79/dts" + "${kernel.headers}/include" + ]; + }; + uimage = (callPackage ./kernel/uimage.nix {}) { commandLine = concatStringsSep " " config.boot.commandLine; inherit (device.boot) loadAddress entryPoint; - inherit (kernel) vmlinux; + inherit kernel; inherit dtb; }; combined-image = nixpkgs.runCommand "firmware.bin" { @@ -60,9 +71,9 @@ let mkdir $out cd $out ln -s ${squashfs} squashfs - ln -s ${kernel.vmlinux} vmlinux + ln -s ${kernel} vmlinux ln -s ${manifest} manifest - ln -s ${kernel.vmlinux.modulesupport} build + ln -s ${kernel.headers} build '' + (if device ? boot then '' ln -s ${uimage} uimage diff --git a/devices/gl-ar750/default.nix b/devices/gl-ar750/default.nix index bbca070..6a96451 100644 --- a/devices/gl-ar750/default.nix +++ b/devices/gl-ar750/default.nix @@ -32,53 +32,33 @@ overlay = final: prev: let - inherit (final) fetchFromGitHub fetchgit stdenvNoCC; - openwrt = fetchFromGitHub { + openwrt = final.fetchFromGitHub { name = "openwrt-source"; repo = "openwrt"; owner = "openwrt"; rev = "a5265497a4f6da158e95d6a450cb2cb6dc085cab"; hash = "sha256-YYi4gkpLjbOK7bM2MGQjAyEBuXJ9JNXoz/JEmYf8xE8="; }; - mainline = fetchFromGitHub { - name = "kernel-source"; - owner = "torvalds"; - repo = "linux"; - rev = "90c7e9b400c751dbd73885f494f421f90ca69721"; - hash = "sha256-pq6QNa0PJVeheaZkuvAPD0rLuEeKrViKk65dz+y4kqo="; - }; in { - sources = { - inherit openwrt; - kernel = stdenvNoCC.mkDerivation { - name = "spindled-kernel-tree"; - src = mainline; - phases = [ - "unpackPhase" "patchPhase" "openWrtPatchPhase" - "patchScripts" "installPhase" - ]; - patches = [ ../../kernel/random.patch ]; - patchScripts = '' - patchShebangs scripts/ - ''; - openWrtPatchPhase = '' - cp -av ${openwrt}/target/linux/generic/files/* . - chmod -R u+w . - cp -av ${openwrt}/target/linux/ath79/files/* . - chmod -R u+w . - patches() { - for i in $* ; do patch --batch --forward -p1 < $i ;done - } - patches ${openwrt}/target/linux/generic/backport-5.15/*.patch - patches ${openwrt}/target/linux/generic/pending-5.15/*.patch - patches ${openwrt}/target/linux/generic/hack-5.15/*.patch - patches ${openwrt}/target/linux/ath79/patches-5.15/*.patch - ''; - installPhase = '' - mkdir -p $out - cp -a . $out - ''; + kernel = prev.kernel.override { + src = final.fetchurl { + name = "linux.tar.gz"; + url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz"; + hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8="; }; + extraPatchPhase = '' + cp -av ${openwrt}/target/linux/generic/files/* . + chmod -R u+w . + cp -av ${openwrt}/target/linux/ath79/files/* . + chmod -R u+w . + patches() { + for i in $* ; do patch --batch --forward -p1 < $i ;done + } + patches ${openwrt}/target/linux/generic/backport-5.15/*.patch + patches ${openwrt}/target/linux/generic/pending-5.15/*.patch + patches ${openwrt}/target/linux/generic/hack-5.15/*.patch + patches ${openwrt}/target/linux/ath79/patches-5.15/*.patch + ''; }; }; kernel = rec { @@ -88,8 +68,6 @@ USE_OF = "y"; ATH79 = "y"; - LIMINIX = "y"; - SERIAL_8250_CONSOLE = "y"; SERIAL_8250 = "y"; SERIAL_CORE_CONSOLE = "y"; @@ -118,9 +96,10 @@ AG71XX = "y"; # ethernet (qca,qca9530-eth) MFD_SYSCON = "y"; # ethernet (compatible "syscon") AR8216_PHY = "y"; # eth1 is behind a switch - }; - config = { - CPU_LITTLE_ENDIAN= "n"; + + MTD = "y"; + MTD_CMDLINE_PARTS = "y"; + MTD_BLOCK = "y"; # fix undefined ref to register_mtd_blktrans_devs CPU_BIG_ENDIAN= "y"; # this is all copied from nixwrt ath79 config. Clearly not all @@ -128,7 +107,6 @@ # installation method config or ... "CMDLINE_PARTITION" = "y"; - "DEBUG_INFO" = "y"; "EARLY_PRINTK" = "y"; "FW_LOADER" = "y"; # we don't have a user helper, so we get multiple 60s pauses @@ -136,7 +114,7 @@ "FW_LOADER_USER_HELPER" = "n"; "MODULE_SIG" = "y"; - "MTD_CMDLINE_PARTS" = "y"; + "PARTITION_ADVANCED" = "y"; "PRINTK_TIME" = "y"; "SQUASHFS" = "y"; diff --git a/devices/qemu/default.nix b/devices/qemu/default.nix index ba67427..30394be 100644 --- a/devices/qemu/default.nix +++ b/devices/qemu/default.nix @@ -16,31 +16,15 @@ overlay = final: prev: let inherit (final) stdenvNoCC fetchFromGitHub; in { - sources = { - kernel = - let src = fetchFromGitHub { - name = "kernel-source"; - owner = "torvalds"; - repo = "linux"; - rev = "3d7cb6b04c3f3115719235cc6866b10326de34cd"; # v5.19 - hash = "sha256-OVsIRScAnrPleW1vbczRAj5L/SGGht2+GnvZJClMUu4="; - }; - in stdenvNoCC.mkDerivation { - name = "spindled-kernel-tree"; - inherit src; - phases = [ - "unpackPhase" - "patchScripts" "installPhase" - ]; - - patchScripts = '' - patchShebangs scripts/ - ''; - installPhase = '' - mkdir -p $out - cp -a . $out - ''; - }; + kernel = prev.kernel.override { + # using fetchurl not fetchzip because it doesn't unpack, and + # copying 6GB of data from one store location to another + # takes an absolute bloody age + src = final.fetchurl { + name = "linux.tar.gz"; + url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.19.16.tar.gz"; + hash = "sha256-m4NeoEsCEK0HSIKTZ6zYTgk1fD3W0PSOMXN6fyHpkP8="; + }; }; }; diff --git a/kernel/dtb.nix b/kernel/dtb.nix index 4c28ee7..b53d525 100644 --- a/kernel/dtb.nix +++ b/kernel/dtb.nix @@ -1,15 +1,10 @@ { stdenv -, openwrt , dtc -, kernel }: { dts +, includes }:let - includes = [ - "${openwrt}/target/linux/ath79/dts" - "${kernel}/include" - ]; cppDtSearchFlags = builtins.concatStringsSep " " (map (f: "-I${f}") includes); dtcSearchFlags = builtins.concatStringsSep " " (map (f: "-i${f}") includes); in stdenv.mkDerivation { @@ -17,7 +12,7 @@ in stdenv.mkDerivation { phases = [ "buildPhase" ]; nativeBuildInputs = [ dtc ]; buildPhase = '' - ${stdenv.cc.targetPrefix}cpp -nostdinc -x assembler-with-cpp ${cppDtSearchFlags} -undef -D__DTS__ -o dtb.tmp ${openwrt}/target/linux/ath79/dts/${dts} + ${stdenv.cc.targetPrefix}cpp -nostdinc -x assembler-with-cpp ${cppDtSearchFlags} -undef -D__DTS__ -o dtb.tmp ${dts} dtc ${dtcSearchFlags} -I dts -O dtb -o $out dtb.tmp test -e $out ''; diff --git a/kernel/uimage.nix b/kernel/uimage.nix index c09b50b..c92faa8 100644 --- a/kernel/uimage.nix +++ b/kernel/uimage.nix @@ -7,7 +7,7 @@ let objcopy = "${stdenv.cc.bintools.targetPrefix}objcopy"; in { - vmlinux + kernel , commandLine , entryPoint , extraName ? "" # e.g. socFamily @@ -28,7 +28,7 @@ stdenv.mkDerivation { ubootTools ]; preparePhase = '' - cp ${vmlinux} vmlinux.elf; chmod +w vmlinux.elf + cp ${kernel} vmlinux.elf; chmod +w vmlinux.elf ''; dtbPhase = '' dtc -I dtb -O dts -o tmp.dts ${dtb} diff --git a/overlay.nix b/overlay.nix index ce3f747..d7bf8a0 100644 --- a/overlay.nix +++ b/overlay.nix @@ -12,6 +12,7 @@ final: prev: { s6-init-bin = final.callPackage ./pkgs/s6-init-bin {}; s6-rc-database = final.callPackage ./pkgs/s6-rc-database {}; + kernel = final.callPackage ./pkgs/kernel {}; dnsmasq = let d = prev.dnsmasq.overrideAttrs(o: { diff --git a/kernel/vmlinux.nix b/pkgs/kernel/default.nix similarity index 89% rename from kernel/vmlinux.nix rename to pkgs/kernel/default.nix index 72d9998..ec3354b 100644 --- a/kernel/vmlinux.nix +++ b/pkgs/kernel/default.nix @@ -6,7 +6,8 @@ , config , checkedConfig ? {} - , tree + , src + , extraPatchPhase ? "true" } : let writeConfig = name : config: writeText name (builtins.concatStringsSep @@ -30,8 +31,8 @@ let writeConfig = name : config: writeText name checkedConfigFile = writeConfig "checked_kconfig" checkedConfig ; inherit lib; in stdenv.mkDerivation rec { - name = "vmlinux"; - + name = "kernel"; + inherit src extraPatchPhase; hardeningDisable = ["all"]; nativeBuildInputs = [buildPackages.stdenv.cc] ++ (with buildPackages.pkgs; @@ -44,11 +45,16 @@ stdenv.mkDerivation rec { PKG_CONFIG_PATH = "./pkgconfig"; CROSS_COMPILE = stdenv.cc.bintools.targetPrefix; ARCH = "mips"; # kernel uses "mips" here for both mips and mipsel + KBUILD_BUILD_HOST = "liminix.builder"; + dontStrip = true; dontPatchELF = true; - outputs = ["out" "modulesupport"]; + outputs = ["out" "headers"]; phases = [ + "unpackPhase" "butcherPkgconfig" + "extraPatchPhase" + "patchScripts" "configurePhase" "checkConfigurationPhase" "buildPhase" @@ -67,12 +73,16 @@ stdenv.mkDerivation rec { for i in pkgconfig/*.pc; do test -f $i && sed -i 's/^Libs:/Libs: -L''${libdir} /' $i;done ''; + patchScripts = '' + patchShebangs scripts/ + ''; + configurePhase = '' export KBUILD_OUTPUT=`pwd` cp ${kconfigFile} .config cp ${kconfigFile} .config.orig cp ${kconfigLocal} Kconfig.local - ( cd ${tree} && make V=1 olddefconfig ) + make V=1 olddefconfig ''; checkConfigurationPhase = '' @@ -84,18 +94,15 @@ stdenv.mkDerivation rec { echo "OK" ''; - KBUILD_BUILD_HOST = "liminix.builder"; buildPhase = '' - make -C ${tree} vmlinux modules_prepare + make vmlinux modules_prepare ''; installPhase = '' ${CROSS_COMPILE}strip -d vmlinux cp vmlinux $out - mkdir -p $modulesupport - cp .config $modulesupport/config - make clean - cp -a . $modulesupport + mkdir -p $headers + cp -a include .config $headers/ ''; }