From 03886d127eb212b5195c2f2665414426fbb550c5 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 12 Dec 2024 22:49:49 +0700 Subject: [PATCH] add kernel cross build support for faster builds on x86_64-linux This adds the option `raspberry-pi-nix.kernel-build-system`, which can be used to drastically decrease the build times. Description of the option: The build system to compile the kernel on. Only the linux kernel will be cross compiled, while most of the derivations are still pulled from cache.nixos.org. Use this if you cannot or don't want to use the nix-community cache and either: - you are building on an x86_64 system using binfmt_misc for aarch64-linux. - or if your x86_64 builder has a better CPU than your aarch64 builder. --- README.md | 4 ++++ overlays/default.nix | 23 ++++++++++++++++++++--- rpi/default.nix | 20 +++++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8c94ef9..913fab4 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,10 @@ use to avoid compiling linux yourself. The cache can be found at https://nix-community.cachix.org, and you can follow the instructions there to use this cache. +## Cross compiling the kernel +This can be useful if you cannot or don't want to use the nix-community cache and you do not have a fast aarch64-linux remote builder. +In this case, set `raspberry-pi-nix.kernel-build-system = "x86_64-linux"` to cross compile the kernel natively on your x86_64-linux machine. + ## Building an sd-card image Include the provided `sd-image` nixos module this flake provides, then an image diff --git a/overlays/default.nix b/overlays/default.nix index 162330c..3c11d95 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -26,13 +26,13 @@ let boards = [ "bcm2711" "bcm2712" ]; # Helpers for building the `pkgs.rpi-kernels' map. - rpi-kernel = { version, board }: + rpi-kernel = { version, board, pkgs ? final }: let kernel = builtins.getAttr version versions; version-slug = builtins.replaceStrings [ "v" "_" ] [ "" "." ] version; in { - "${version}"."${board}" = (final.buildLinux { + "${version}"."${board}" = (pkgs.buildLinux { modDirVersion = version-slug; version = version-slug; pname = "linux-rpi"; @@ -70,9 +70,21 @@ let ''; }); }; + rpi-kernels = builtins.foldl' (b: a: final.lib.recursiveUpdate b (rpi-kernel a)) { }; + + rip-kernels-cross = buildSystem: builtins.foldl' + (b: a: final.lib.recursiveUpdate b (rpi-kernel ( + a // { + pkgs = import final.pkgs.path { + system = buildSystem; + crossSystem = "aarch64-linux"; + }; + } + ))) + { }; in { # disable firmware compression so that brcm firmware can be found at @@ -114,11 +126,16 @@ in } // { # rpi kernels and firmware are available at - # `pkgs.rpi-kernels..'. + # `pkgs.rpi-kernels..'. # # For example: `pkgs.rpi-kernels.v6_6_54.bcm2712' rpi-kernels = rpi-kernels ( final.lib.cartesianProduct { board = boards; version = (builtins.attrNames versions); } ); + + rpi-kernels-cross = buildSystem: rip-kernels-cross buildSystem ( + final.lib.cartesianProduct + { board = boards; version = (builtins.attrNames versions); } + ); } diff --git a/rpi/default.nix b/rpi/default.nix index 5900692..5a8f565 100644 --- a/rpi/default.nix +++ b/rpi/default.nix @@ -18,6 +18,20 @@ in type = types.str; description = "Kernel version to build."; }; + kernel-build-system = mkOption { + type = types.nullOr (types.enum [ "x86_64-linux" ]); + default = null; + description = '' + The build system to compile the kernel on. + + Only the linux kernel will be cross compiled, while most of the derivations are still pulled from cache.nixos.org. + + Use this if you cannot or don't want to use the nix-community cache and either: + - you are building on an x86_64 system using binfmt_misc for aarch64-linux. + - or if your x86_64 builder has a better CPU than your aarch64 builder. + ''; + example = "x86_64-linux"; + }; board = mkOption { type = types.enum [ "bcm2711" "bcm2712" ]; description = '' @@ -334,7 +348,11 @@ in "reset-raspberrypi" # required for vl805 firmware to load ]; }; - kernelPackages = pkgs.linuxPackagesFor pkgs.rpi-kernels."${version}"."${board}"; + kernelPackages = + if cfg.kernel-build-system == null then + pkgs.linuxPackagesFor pkgs.rpi-kernels."${version}"."${board}" + else + pkgs.linuxPackagesFor (pkgs.rpi-kernels-cross cfg.kernel-build-system)."${version}"."${board}"; loader = { grub.enable = lib.mkDefault false; initScript.enable = !cfg.uboot.enable;