Files
nix-config/packages/linux-cachyos/prepare.nix
2026-03-10 10:51:32 -05:00

609 lines
17 KiB
Nix

{
cachyConfig,
fetchFromGitHub,
fetchurl,
lib,
stdenv,
kernel,
ogKernelConfigfile,
commonMakeFlags,
# Rust toolchain — only injected when cachyConfig.withRust is true
rustc ? null,
rustBindgen ? null,
rustLibSrc ? null,
}:
let
version =
if cachyConfig.taste == "linux-cachyos-asahi" then
cachyConfig.versions.linux.version
else if stdenv.isAarch64 then
"6.12.47"
else
cachyConfig.versions.linux.version;
majorMinor = lib.versions.majorMinor version;
patches-src = fetchFromGitHub {
owner = "CachyOS";
repo = "kernel-patches";
inherit (cachyConfig.versions.patches) rev hash;
};
config-src = fetchFromGitHub {
owner = "CachyOS";
repo = "linux-cachyos";
inherit (cachyConfig.versions.config) rev hash;
};
src =
if cachyConfig.taste == "linux-cachyos-asahi" then
fetchFromGitHub {
owner = cachyConfig.versions.linux.owner;
repo = cachyConfig.versions.linux.repo;
rev = cachyConfig.versions.linux.rev;
inherit (cachyConfig.versions.linux) hash;
}
else if stdenv.isAarch64 then
let
tag = "stable_20250916";
hash = "sha256-Rjn+eWl5cLcc9wgjS3HYVaWM5eKMN3pPfPbsu+QGR/M=";
in
fetchurl {
url = "https://github.com/raspberrypi/linux/archive/refs/tags/${tag}.tar.gz";
hash = hash;
}
else if cachyConfig.taste == "linux-cachyos-rc" then
# Use the CachyOS pre-tagged release when a tag is specified; it includes
# upstream interim patches that the CachyOS kernel-patches are written against.
# Fall back to the vanilla torvalds tarball when no tag is set.
if cachyConfig.versions.linux ? tag then
fetchurl {
url = "https://github.com/CachyOS/linux/releases/download/${cachyConfig.versions.linux.tag}/${cachyConfig.versions.linux.tag}.tar.gz";
inherit (cachyConfig.versions.linux) hash;
}
else
fetchurl {
url = "https://git.kernel.org/torvalds/t/linux-${version}.tar.gz";
inherit (cachyConfig.versions.linux) hash;
}
else
fetchurl {
url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${
if version == "${majorMinor}.0" then majorMinor else version
}.tar.xz";
inherit (cachyConfig.versions.linux) hash;
};
schedPatches =
if cachyConfig.cpuSched == "eevdf" then
[ ]
else if cachyConfig.cpuSched == "hardened" then
[ ] # BORE disabled in CachyOS/linux-cachyos/commit/4ffae8ab9947f35495dfa7b62b7a22f023488dfb
else if (cachyConfig.cpuSched == "cachyos" || cachyConfig.cpuSched == "sched-ext") then
lib.optionals (lib.strings.versionOlder majorMinor "6.12") [
"${patches-src}/${majorMinor}/sched/0001-sched-ext.patch"
]
++ lib.optionals (cachyConfig.cpuSched == "cachyos" && version != "6.17-rc1") [
"${patches-src}/${majorMinor}/sched/0001-bore-cachy.patch"
]
else
throw "Unsupported cachyos _cpu_sched=${toString cachyConfig.cpuSched}";
patches = [
"${patches-src}/${majorMinor}/all/0001-cachyos-base-all.patch"
]
++ schedPatches
++ lib.optional (
cachyConfig.cpuSched == "hardened"
) "${patches-src}/${majorMinor}/misc/0001-hardened.patch";
# There are some configurations set by the PKGBUILD
pkgbuildConfig =
with cachyConfig;
basicCachyConfig
++ mArchConfig
++ cpuSchedConfig
++ [
"-m CONFIG_CRYPTO_BLAKE2B"
# _nr_cpus, defaults to empty, which later set this
"--set-val NR_CPUS 320"
# _per_gov, defaults to empty [but PERSONAL CHANGE to "y"]
"-d CPU_FREQ_DEFAULT_GOV_SCHEDUTIL"
"-e CPU_FREQ_DEFAULT_GOV_PERFORMANCE"
# _tcp_bbr3, defaults to "y"
"-m TCP_CONG_CUBIC"
"-d DEFAULT_CUBIC"
"-e TCP_CONG_BBR"
"-e DEFAULT_BBR"
"--set-str DEFAULT_TCP_CONG bbr"
"-m NET_SCH_FQ_CODEL"
"-e NET_SCH_FQ"
"-d DEFAULT_FQ_CODEL"
"-e DEFAULT_FQ"
"--set-str DEFAULT_NET_SCH fq"
# Nixpkgs don't support this
"-d CONFIG_SECURITY_TOMOYO"
]
++ ltoConfig
++ ticksHzConfig
++ tickRateConfig
++ preemptConfig
++ [
# _cc_harder, defaults to "y"
"-d CC_OPTIMIZE_FOR_PERFORMANCE"
"-e CC_OPTIMIZE_FOR_PERFORMANCE_O3"
# _lru_config, defaults to "standard"
"-e LRU_GEN"
"-e LRU_GEN_ENABLED"
"-d LRU_GEN_STATS"
# _vma_config, defaults to "standard"
"-e PER_VMA_LOCK"
"-d PER_VMA_LOCK_STATS"
"-m BCACHEFS_FS"
]
++ hugePagesConfig
++ damonConfig
++ ntSyncConfig
++ hdrConfig
++ disableDebug
++ pageSizeConfig
++ asahiPlatformConfig;
# _cachy_config, defaults to "y"
basicCachyConfig = lib.optional cachyConfig.basicCachy "-e CACHY";
# _processor_opt config, defaults to ""
mArchConfig =
if cachyConfig.mArch == null then
[ ]
else if cachyConfig.mArch == "NATIVE" then
[
"-d GENERIC_CPU"
"-d MZEN4"
"-e X86_NATIVE_CPU"
]
else if cachyConfig.mArch == "ZEN4" then
[
"-d GENERIC_CPU"
"-e MZEN4"
"-d X86_NATIVE_CPU"
]
else if builtins.match "GENERIC_V[1-4]" cachyConfig.mArch != null then
let
v = lib.strings.removePrefix "GENERIC_V" cachyConfig.mArch;
in
[
"-e GENERIC_CPU"
"-d MZEN4"
"-d X86_NATIVE_CPU"
"--set-val X86_64_VERSION ${v}"
]
else
throw "Unsuppoted cachyos mArch";
# _cpusched, defaults to "cachyos"
cpuSchedConfig =
if cachyConfig.cpuSched == "eevdf" then
[ ]
else if cachyConfig.cpuSched == "hardened" then
[ "-e SCHED_BORE" ]
else if cachyConfig.cpuSched == "sched-ext" then
[ "-e SCHED_CLASS_EXT" ]
else if cachyConfig.cpuSched == "cachyos" then
[
"-e SCHED_BORE"
"-e SCHED_CLASS_EXT"
]
else
throw "Unsupported cachyos scheduler";
# _HZ_ticks, defaults to "500"
ticksHzConfig =
if cachyConfig.ticksHz == 300 then
[
"-e HZ_300"
"--set-val HZ 300"
]
else
[
"-d HZ_300"
"--set-val HZ ${toString cachyConfig.ticksHz}"
"-e HZ_${toString cachyConfig.ticksHz}"
];
# _use_llvm_lto, defaults to "none"
ltoConfig =
if cachyConfig.useLTO == "thin" then
[
"-e LTO"
"-e LTO_CLANG"
"-e ARCH_SUPPORTS_LTO_CLANG"
"-e ARCH_SUPPORTS_LTO_CLANG_THIN"
"-d LTO_NONE"
"-e HAS_LTO_CLANG"
"-d LTO_CLANG_FULL"
"-e LTO_CLANG_THIN"
"-e HAVE_GCC_PLUGINS"
]
else if cachyConfig.useLTO == "full" then
[
"-e LTO"
"-e LTO_CLANG"
"-e ARCH_SUPPORTS_LTO_CLANG"
"-e ARCH_SUPPORTS_LTO_CLANG_THIN"
"-d LTO_NONE"
"-e HAS_LTO_CLANG"
"-e LTO_CLANG_FULL"
"-d LTO_CLANG_THIN"
"-e HAVE_GCC_PLUGINS"
]
else if cachyConfig.useLTO == "none" then
[ ]
else
throw "Unsupported cachyos _use_llvm_lto";
# _tickrate defaults to "full"
tickRateConfig =
if cachyConfig.tickRate == "idle" then
[
"-d HZ_PERIODIC"
"-d NO_HZ_FULL"
"-e NO_HZ_IDLE"
"-e NO_HZ"
"-e NO_HZ_COMMON"
]
else if cachyConfig.tickRate == "full" then
[
"-d HZ_PERIODIC"
"-d NO_HZ_IDLE"
"-d CONTEXT_TRACKING_FORCE"
"-e NO_HZ_FULL_NODEF"
"-e NO_HZ_FULL"
"-e NO_HZ"
"-e NO_HZ_COMMON"
"-e CONTEXT_TRACKING"
]
else
throw "Unsupported cachyos _tickrate";
# _preempt, defaults to "full"
preemptConfig =
if cachyConfig.preempt == "full" then
[
"-e PREEMPT_BUILD"
"-d PREEMPT_NONE"
"-d PREEMPT_VOLUNTARY"
"-e PREEMPT"
"-e PREEMPT_COUNT"
"-e PREEMPTION"
"-e PREEMPT_DYNAMIC"
]
else if cachyConfig.preempt == "server" then
[
"-e PREEMPT_NONE_BUILD"
"-e PREEMPT_NONE"
"-d PREEMPT_VOLUNTARY"
"-d PREEMPT"
"-d PREEMPTION"
"-d PREEMPT_DYNAMIC"
]
else
throw "Unsupported cachyos _preempt";
# _hugepage, defaults to "always"
hugePagesConfig =
if cachyConfig.hugePages == "always" then
[
"-d TRANSPARENT_HUGEPAGE_MADVISE"
"-e TRANSPARENT_HUGEPAGE_ALWAYS"
]
else if cachyConfig.hugePages == "madvise" then
[
"-d TRANSPARENT_HUGEPAGE_ALWAYS"
"-e TRANSPARENT_HUGEPAGE_MADVISE"
]
else
throw "Unsupported cachyos _hugepage";
pageSizeConfig =
if cachyConfig.pageSize == "16k" then
[
"-e CONFIG_SRAM"
"-e CONFIG_HISI_HIKEY_USB"
"-e CONFIG_OPEN_DICE"
"-e CONFIG_VCPU_STALL_DETECTOR"
"-e CONFIG_EEPROM_AT25"
"-e CONFIG_EEPROM_93XX46"
"-e CONFIG_TI_ST"
"-e CONFIG_SENSORS_LIS3_SPI"
"-e CONFIG_ECHO"
# RP1
"-e CONFIG_FIRMWARE_RP1"
"-e CONFIG_RP1_PIO"
"-e CONFIG_WS2812_PIO_RP1"
"-e CONFIG_PWM_PIO_RP1"
"-e CONFIG_PWM_RP1"
"-e CONFIG_PINCTRL_RP1"
"-e CONFIG_MFD_RP1"
"-e CONFIG_SENSORS_RP1_ADC"
"-e CONFIG_VIDEO_RP1_CFE"
"-e CONFIG_DRM_RP1_DSI"
"-e CONFIG_DRM_RP1_DPI"
"-e CONFIG_DRM_RP1_VEC"
"-e CONFIG_SND_RP1_AUDIO_OUT"
"-e CONFIG_COMMON_CLK_RP1"
"-e CONFIG_COMMON_CLK_RP1_SDIO"
"-e CONFIG_MBOX_RP1"
"-e CONFIG_PINCTRL_BCM2712"
"-e CONFIG_PINCTRL_BCM2835"
"-e CONFIG_ARCH_BCM"
"-e CONFIG_ARCH_BCM2835"
"-e CONFIG_ARCH_BRCMSTB"
"-e CONFIG_AHCI_BRCM"
"-e CONFIG_BRCMUTIL"
"-e CONFIG_BRCMSMAC"
"-e CONFIG_BRCMFMAC"
"-e CONFIG_BRCMFMAC_PROTO_BCDC"
"-e CONFIG_BRCMFMAC_PROTO_MSGBUF"
"-e CONFIG_BRCMFMAC_SDIO"
"-e CONFIG_BRCMFMAC_USB"
"-e CONFIG_BRCMFMAC_PCIE"
"-e CONFIG_BRCMDBG"
"-e CONFIG_BRCM_CHAR_DRIVERS"
"-e CONFIG_BCM2708_VCMEM"
"-e CONFIG_BCM_VCIO"
"-e CONFIG_GPIO_BCM_VIRT"
"-e CONFIG_GPIO_BRCMSTB"
"-e CONFIG_BRCM_USB_PINMAP"
"-e CONFIG_MMC_SDHCI_BRCMSTB"
"-e CONFIG_RTC_DRV_BRCMSTB"
"-e CONFIG_SOC_BRCMSTB"
"-e CONFIG_PWM_BRCMSTB"
"-e CONFIG_BCM2712_MIP"
"-e CONFIG_BCM7120_L2_IRQ"
"-e CONFIG_BRCMSTB_L2_IRQ"
"-e CONFIG_RESET_BRCMSTB"
"-e CONFIG_RESET_BRCMSTB_RESCAL"
"-e CONFIG_PHY_BRCM_USB"
"-e CONFIG_ARCH_BRCMSTB"
"-e CONFIG_ARM_BRCMSTB_AVS_CPUFREQ"
# Raspberry Pi
"-d CONFIG_ARM64_4K_PAGES"
"-e CONFIG_ARM64_16K_PAGES"
"-e CONFIG_ARM_RASPBERRYPI_CPUFREQ"
"-e CONFIG_RASPBERRYPI_FIRMWARE"
"-e CONFIG_TOUCHSCREEN_RASPBERRYPI_FW"
"-e CONFIG_RASPBERRYPI_GPIOMEM"
"-e CONFIG_GPIO_RASPBERRYPI_EXP"
"-e CONFIG_SENSORS_RASPBERRYPI_HWMON"
"-e CONFIG_MFD_RASPBERRYPI_POE_HAT"
"-e CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY"
"-e CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2"
"-e CONFIG_VIDEO_RASPBERRYPI_PISP_BE"
"-e CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN"
"-e CONFIG_CLK_RASPBERRYPI"
"-e CONFIG_RASPBERRYPI_POWER"
"-e CONFIG_PWM_RASPBERRYPI_POE"
"-e CONFIG_RESET_RASPBERRYPI"
"-e CONFIG_ARCH_HAS_RESET_CONTROLLER"
"-e CONFIG_NVMEM_RASPBERRYPI_OTP"
"-e CONFIG_CPUFREQ_DT"
"-e CONFIG_CPUFREQ_DT_PLATDEV"
"-e CONFIG_ARM_SCPI_CPUFREQ"
"-e CONFIG_ARM_BRCMSTB_AVS_CPUFREQ"
"-e CONFIG_ARM_RASPBERRYPI_CPUFREQ"
"-e CONFIG_ARM_SCMI_CPUFREQ"
"-e KVM"
"-e NET_9P_USBG"
"-e GPIO_PALMAS"
"-e CROS_EC_PROTO"
]
else if cachyConfig.pageSize == "4k" then
[ ]
else
throw "Unsupported cachyos _hugepage";
# Apple Silicon (Asahi) platform drivers
# Mirrors the options set in the asahi-alarm/PKGBUILDs linux-asahi config.
# ARCH_APPLE is the root Kconfig symbol; everything else gates on it.
# olddefconfig will auto-select most sub-options once ARCH_APPLE is on,
# but the hardware-specific drivers are listed explicitly so they aren't
# left as =m when we want them built-in, or omitted entirely.
asahiPlatformConfig = lib.optionals (cachyConfig.taste == "linux-cachyos-asahi") [
# Rust support — must come before any symbol that depends on it
"-e RUST"
# SoC platform — root symbol; must come first
"-e ARCH_APPLE"
# Interrupt controller
"-e APPLE_AIC"
# IOMMU (required for PCIe, GPU, and NVMe)
"-e APPLE_DART"
# RTKit coprocessor framework (required by GPU, audio, SEP)
"-e APPLE_RTKIT"
"-e APPLE_RTKIT_HELPER"
"-e APPLE_MAILBOX"
# Rust-based mailbox/rtkit (present in 6.18 Asahi tree)
"-e RUST_APPLE_MAILBOX"
"-e RUST_APPLE_RTKIT"
# Power management
"-e APPLE_PMGR_PWRSTATE"
"-e APPLE_PMGR_MISC"
# DMA controller (required by audio)
"-e APPLE_ADMAC"
# Security / SART (required by NVMe)
"-e APPLE_SART"
"-e APPLE_SEP"
# Storage
"-e NVME_APPLE"
# PCIe
"-e PCIE_APPLE"
# CPU frequency / idle
"-e ARM_APPLE_SOC_CPUFREQ"
"-e ARM_APPLE_CPUIDLE"
# Pin control
"-e PINCTRL_APPLE_GPIO"
# Display (DCP)
"-m DRM_APPLE"
"-e DRM_APPLE_AUDIO"
# GPU (Asahi AGX Rust driver)
"-e DRM_ASAHI"
# Audio
"-m SND_SOC_APPLE_MCA"
"-m SND_SOC_APPLE_MACAUDIO"
"-m SND_SOC_APPLE_AOP_AUDIO"
# Misc Apple SoC peripherals
"-e APPLE_DOCKCHANNEL"
"-e APPLE_WATCHDOG"
"-m APPLE_SIO"
"-m APPLE_AOP"
"-e APPLE_M1_CPU_PMU"
# 16K pages — Apple Silicon runs with 16K page granule
"-d ARM64_4K_PAGES"
"-e ARM64_16K_PAGES"
# NR_CPUS: Apple Silicon has at most ~16 cores; 64 is the Asahi default
"--set-val NR_CPUS 64"
];
# _damon, defaults to empty
damonConfig = lib.optionals cachyConfig.withDAMON [
"-e DAMON"
"-e DAMON_VADDR"
"-e DAMON_DBGFS"
"-e DAMON_SYSFS"
"-e DAMON_PADDR"
"-e DAMON_RECLAIM"
"-e DAMON_LRU_SORT"
];
# _ntsync, defaults to empty
ntSyncConfig = lib.optionals cachyConfig.withNTSync [ "-m NTSYNC" ];
# custom made
hdrConfig = lib.optionals cachyConfig.withHDR [ "-e AMD_PRIVATE_COLOR" ];
# https://github.com/CachyOS/linux-cachyos/issues/187
disableDebug =
lib.optionals
(
cachyConfig.withoutDebug && cachyConfig.cpuSched != "sched-ext" && cachyConfig.cpuSched != "cachyos"
)
[
"-d DEBUG_INFO"
"-d DEBUG_INFO_BTF"
"-d DEBUG_INFO_DWARF4"
"-d DEBUG_INFO_DWARF5"
"-d PAHOLE_HAS_SPLIT_BTF"
"-d DEBUG_INFO_BTF_MODULES"
"-d SLUB_DEBUG"
"-d PM_DEBUG"
"-d PM_ADVANCED_DEBUG"
"-d PM_SLEEP_DEBUG"
"-d ACPI_DEBUG"
"-d SCHED_DEBUG"
"-d LATENCYTOP"
"-d DEBUG_PREEMPT"
];
# Asahi uses the LTS config base since it tracks the same 6.18 kernel series
configTaste =
if cachyConfig.taste == "linux-cachyos-asahi" then "linux-cachyos-lts" else cachyConfig.taste;
# Rust toolchain — needed so `make olddefconfig` can probe rustc and set
# RUSTC_VERSION correctly, which gates CONFIG_RUST and all rust-dependent
# symbols (DRM_ASAHI, APPLE_SEP, etc.)
rustNativeBuildInputs = lib.optionals cachyConfig.withRust [
rustc
rustBindgen
];
in
stdenv.mkDerivation (finalAttrs: {
inherit src patches;
name = "linux-cachyos-config";
nativeBuildInputs = kernel.nativeBuildInputs ++ kernel.buildInputs ++ rustNativeBuildInputs;
# Apply each patch with --forward (skip already-applied/reversed hunks) and
# --fuzz=3 (tolerate minor context differences due to kernel version skew).
# Use || true so that "hunk ignored" exit-1 from already-merged patches does
# not abort the build; genuine failures are still visible in the log.
patchPhase = ''
runHook prePatch
for p in $patches; do
echo "applying patch $p"
patch -p1 --forward --fuzz=3 < "$p" || true
done
runHook postPatch
'';
makeFlags = commonMakeFlags;
env = lib.optionalAttrs cachyConfig.withRust {
RUST_LIB_SRC = rustLibSrc;
KRUSTFLAGS = "--remap-path-prefix ${rustLibSrc}=/";
};
postPhase = ''
${finalAttrs.passthru.extraVerPatch}
'';
buildPhase = ''
runHook preBuild
echo ${cachyConfig.taste}
cp "${config-src}/${configTaste}/config" ".config"
make $makeFlags olddefconfig
patchShebangs scripts/config
scripts/config ${lib.concatStringsSep " " pkgbuildConfig}
make $makeFlags olddefconfig
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp .config $out
runHook postInstall
'';
meta = ogKernelConfigfile.meta // {
platforms = [
"x86_64-linux"
"aarch64-linux"
];
};
passthru = {
inherit cachyConfig commonMakeFlags stdenv;
kernelPatches = patches;
extraVerPatch = ''
sed -Ei"" 's/EXTRAVERSION = ?(.*)$/EXTRAVERSION = \1${cachyConfig.versions.suffix}/g' Makefile
'';
};
})