diff --git a/README.md b/README.md index e8d120d..0758ce6 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ If you want to construct your own `linuxPackages` attrset with `linuxKernel.pack { pkgs, ... }: { nixpkgs.overlays = [ self.overlay ]; - boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest; + boot.kernelPackages = pkgs.linuxKernel.packagesFor pkgs.cachyosKernels.linux-cachyos-latest; # ZFS config boot.supportedFilesystems.zfs = true; @@ -124,3 +124,31 @@ If you want to construct your own `linuxPackages` attrset with `linuxKernel.pack }; } ``` + +## How to apply CachyOS patches on your own kernel + +The kernels provided in this flake can be overridden to use your own kernel source. This is helpful if you want to use a kernel version not available in Nixpkgs. + +```nix +{ + kernel = pkgs.cachyosKernels.linux-cachyos-latest.override { + pname = "linux-cachyos-with-custom-source"; + version = "6.12.34"; + src = pkgs.fetchurl { + # ... + }; + # Additional args are available. See kernel-cachyos/mkCachyKernel.nix + }; + + # For non-LTO kernels + kernelPackages = pkgs.linuxKernel.packagesFor kernel; + + # helpers.nix provides a few utilities for building kernel with LTO. + # I haven't figured out a clean way to expose it in flakes. + helpers = pkgs.callPackage "${inputs.nix-cachyos-kernel.outPath}/helpers.nix" {}; + + # For LTO kernels, helpers.kernelModuleLLVMOverride fixes compilation for some + # out-of-tree modules in nixpkgs. + kernelPackagesWithLTOFix = helpers.kernelModuleLLVMOverride (pkgs.linuxKernel.packagesFor kernel); +} +``` diff --git a/flake.nix b/flake.nix index bdab133..0c2196b 100644 --- a/flake.nix +++ b/flake.nix @@ -28,17 +28,21 @@ loadPackages = pkgs: let - kernels = + load = + path: lib.removeAttrs - (pkgs.callPackage ./kernel-cachyos { + (pkgs.callPackage path { inherit inputs; }) [ "override" "overrideDerivation" ]; + kernels = load ./kernel-cachyos; + packages = load ./kernel-cachyos/packages.nix; in kernels + // packages // { zfs-cachyos = pkgs.callPackage ./zfs-cachyos { inherit inputs; diff --git a/helpers.nix b/helpers.nix index e1a66e2..b85b5f9 100644 --- a/helpers.nix +++ b/helpers.nix @@ -77,5 +77,4 @@ rec { v ) prev ); - } diff --git a/kernel-cachyos/default.nix b/kernel-cachyos/default.nix index 9acb4e8..240954e 100644 --- a/kernel-cachyos/default.nix +++ b/kernel-cachyos/default.nix @@ -8,39 +8,32 @@ }: let mkCachyKernel = callPackage ./mkCachyKernel.nix { inherit inputs; }; - - batch = - { - pnameSuffix, - version, - src, - configVariant, - ... - }: - [ - (mkCachyKernel { - pnameSuffix = "${pnameSuffix}"; - inherit version src configVariant; - lto = false; - }) - (mkCachyKernel { - pnameSuffix = "${pnameSuffix}-lto"; - inherit version src configVariant; - lto = true; - }) - ]; - - batches = [ - (batch { - pnameSuffix = "latest"; +in +builtins.listToAttrs ( + builtins.map (v: lib.nameValuePair v.pname v) [ + (mkCachyKernel { + pname = "linux-cachyos-latest"; inherit (linux_latest) version src; configVariant = "linux-cachyos"; + lto = false; }) - (batch { - pnameSuffix = "lts"; + (mkCachyKernel { + pname = "linux-cachyos-latest-lto"; + inherit (linux_latest) version src; + configVariant = "linux-cachyos"; + lto = true; + }) + (mkCachyKernel { + pname = "linux-cachyos-lts"; inherit (linux) version src; configVariant = "linux-cachyos-lts"; + lto = false; }) - ]; -in -builtins.listToAttrs (lib.flatten batches) + (mkCachyKernel { + pname = "linux-cachyos-lts-lto"; + inherit (linux) version src; + configVariant = "linux-cachyos-lts"; + lto = true; + }) + ] +) diff --git a/kernel-cachyos/mkCachyKernel.nix b/kernel-cachyos/mkCachyKernel.nix index acae195..401e029 100644 --- a/kernel-cachyos/mkCachyKernel.nix +++ b/kernel-cachyos/mkCachyKernel.nix @@ -5,102 +5,120 @@ buildLinux, stdenv, kernelPatches, - linuxKernel, ... }: -{ - pnameSuffix, - version, - src, - configVariant, - lto, -}: -let - helpers = callPackage ../helpers.nix { }; - inherit (helpers) stdenvLLVM ltoMakeflags kernelModuleLLVMOverride; +lib.makeOverridable ( + { + pname, + version, + src, - splitted = lib.splitString "-" version; - ver0 = builtins.elemAt splitted 0; - major = lib.versions.pad 2 ver0; + # Kernel config variant to be used as defconfig, e.g. "linux-cachyos-lts". + # See https://github.com/CachyOS/linux-cachyos for available values. + configVariant, - cachyosConfigFile = "${inputs.cachyos-kernel.outPath}/${configVariant}/config"; + # Set to true to enable Clang+ThinLTO. + lto, - # buildLinux doesn't accept postPatch, so adding config file early here - patchedSrc = stdenv.mkDerivation { - pname = "linux-cachyos-${pnameSuffix}-src"; - inherit version src; - patches = [ - kernelPatches.bridge_stp_helper.patch - kernelPatches.request_key_helper.patch - "${inputs.cachyos-kernel-patches.outPath}/${major}/all/0001-cachyos-base-all.patch" - ]; - postPatch = '' - for DIR in arch/*/configs; do - install -Dm644 ${cachyosConfigFile} $DIR/cachyos_defconfig - done - ''; - dontConfigure = true; - dontBuild = true; - dontFixup = true; - installPhase = '' - mkdir -p $out - cp -r * $out/ - ''; - }; + # Patches to be applied in patchedSrc phase. This is different from buildLinux's kernelPatches. + prePatch ? "", + patches ? [ ], + postPatch ? "", - kernelPackage = buildLinux { - pname = "linux-cachyos-${pnameSuffix}"; - inherit version; - src = patchedSrc; - stdenv = if lto then stdenvLLVM else stdenv; + # See nixpkgs/pkgs/os-specific/linux/kernel/generic.nix for additional options. + # Additional args are passed to buildLinux. + ... + }@args: + let + helpers = callPackage ../helpers.nix { }; + inherit (helpers) stdenvLLVM ltoMakeflags; - extraMakeFlags = lib.optionals lto ltoMakeflags; + splitted = lib.splitString "-" version; + ver0 = builtins.elemAt splitted 0; + major = lib.versions.pad 2 ver0; - defconfig = "cachyos_defconfig"; + cachyosConfigFile = "${inputs.cachyos-kernel.outPath}/${configVariant}/config"; + cachyosPatch = "${inputs.cachyos-kernel-patches.outPath}/${major}/all/0001-cachyos-base-all.patch"; - # Clang has some incompatibilities with NixOS's default kernel config - ignoreConfigErrors = lto; - - structuredExtraConfig = - with lib.kernel; - ( - { - NR_CPUS = lib.mkForce (option (freeform "8192")); - - # Follow NixOS default config to not break etc overlay - OVERLAY_FS = module; - OVERLAY_FS_REDIRECT_DIR = no; - OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW = yes; - OVERLAY_FS_INDEX = no; - OVERLAY_FS_XINO_AUTO = no; - OVERLAY_FS_METACOPY = no; - OVERLAY_FS_DEBUG = no; - } - // lib.optionalAttrs lto { - LTO_NONE = no; - LTO_CLANG_THIN = yes; - } - ); - - extraMeta = { - description = "Linux CachyOS Kernel" + lib.optionalString lto " with Clang+ThinLTO"; + # buildLinux doesn't accept postPatch, so adding config file early here + patchedSrc = stdenv.mkDerivation { + pname = "${pname}-src"; + inherit version src prePatch; + patches = [ + kernelPatches.bridge_stp_helper.patch + kernelPatches.request_key_helper.patch + cachyosPatch + ] + ++ patches; + postPatch = '' + for DIR in arch/*/configs; do + install -Dm644 ${cachyosConfigFile} $DIR/cachyos_defconfig + done + '' + + postPatch; + dontConfigure = true; + dontBuild = true; + dontFixup = true; + installPhase = '' + mkdir -p $out + cp -r * $out/ + ''; }; - }; + in + buildLinux ( + (lib.removeAttrs args [ + "pname" + "version" + "src" + "configVariant" + "lto" + "prePatch" + "patches" + "postPatch" + ]) + // { + inherit pname version; + src = patchedSrc; + stdenv = args.stdenv or (if lto then stdenvLLVM else stdenv); - zfsPackage = callPackage ../zfs-cachyos { - inherit inputs; - kernel = kernelPackage; - }; -in -[ - (lib.nameValuePair "linux-cachyos-${pnameSuffix}" kernelPackage) - (lib.nameValuePair "linuxPackages-cachyos-${pnameSuffix}" ( - kernelModuleLLVMOverride ( - (linuxKernel.packagesFor kernelPackage).extend ( - final: prev: { - zfs_cachyos = zfsPackage; - } - ) - ) - )) -] + extraMakeFlags = (lib.optionals lto ltoMakeflags) ++ (args.extraMakeFlags or [ ]); + + defconfig = args.defconfig or "cachyos_defconfig"; + + # Clang has some incompatibilities with NixOS's default kernel config + ignoreConfigErrors = args.ignoreConfigErrors or lto; + + structuredExtraConfig = + with lib.kernel; + ( + { + NR_CPUS = lib.mkForce (option (freeform "8192")); + + # Follow NixOS default config to not break etc overlay + OVERLAY_FS = module; + OVERLAY_FS_REDIRECT_DIR = no; + OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW = yes; + OVERLAY_FS_INDEX = no; + OVERLAY_FS_XINO_AUTO = no; + OVERLAY_FS_METACOPY = no; + OVERLAY_FS_DEBUG = no; + } + // (lib.optionalAttrs lto { + LTO_NONE = no; + LTO_CLANG_THIN = yes; + }) + // (args.structuredExtraConfig or { }) + ); + + extraMeta = { + description = "Linux CachyOS Kernel" + lib.optionalString lto " with Clang+ThinLTO"; + } + // (args.extraMeta or { }); + + extraPassthru = { + inherit cachyosConfigFile cachyosPatch; + } + // (args.extraPassthru or { }); + } + ) +) diff --git a/kernel-cachyos/packages.nix b/kernel-cachyos/packages.nix index b6a3ed4..5341992 100644 --- a/kernel-cachyos/packages.nix +++ b/kernel-cachyos/packages.nix @@ -1,14 +1,31 @@ { - mode ? null, + inputs, callPackage, lib, linuxKernel, - sources, ... }: let - kernels = callPackage ./default.nix { inherit mode sources; }; + helpers = callPackage ../helpers.nix { }; + inherit (helpers) kernelModuleLLVMOverride; + + kernels = lib.filterAttrs (_: lib.isDerivation) (callPackage ./. { inherit inputs; }); in -lib.mapAttrs (n: v: linuxKernel.packagesFor v) ( - lib.filterAttrs (n: nv: !lib.hasSuffix "configfile" n) kernels -) +lib.mapAttrs' ( + n: v: + let + zfsPackage = callPackage ../zfs-cachyos { + inherit inputs; + kernel = v; + }; + + packages = kernelModuleLLVMOverride ( + (linuxKernel.packagesFor v).extend ( + final: prev: { + zfs_cachyos = zfsPackage; + } + ) + ); + in + lib.nameValuePair "linuxPackages-${lib.removePrefix "linux-" n}" packages +) kernels