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;