about summary refs log tree commit diff
path: root/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix')
-rw-r--r--modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix154
1 files changed, 154 insertions, 0 deletions
diff --git a/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix
new file mode 100644
index 000000000000..2f1d490277be
--- /dev/null
+++ b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix
@@ -0,0 +1,154 @@
+{ lib
+, pkgs
+, callPackage
+, writeShellScriptBin
+, writeText
+, removeReferencesTo
+, linuxPackagesFor
+, withRust ? false
+, _kernelPatches ? [ ]
+}:
+
+let
+  i = builtins.elemAt;
+
+  # parse <OPT> [ymn]|foo style configuration as found in a patch's extraConfig
+  # into a list of k, v tuples
+  parseExtraConfig = config:
+    let
+      lines =
+        builtins.filter (s: s != "") (lib.strings.splitString "\n" config);
+      parseLine = line: let
+        t = lib.strings.splitString " " line;
+        join = l: builtins.foldl' (a: b: "${a} ${b}")
+          (builtins.head l) (builtins.tail l);
+        v = if (builtins.length t) > 2 then join (builtins.tail t) else (i t 1);
+      in [ "CONFIG_${i t 0}" v ];
+    in map parseLine lines;
+
+  # parse <OPT>=lib.kernel.(yes|module|no)|lib.kernel.freeform "foo"
+  # style configuration as found in a patch's extraStructuredConfig into
+  # a list of k, v tuples
+  parseExtraStructuredConfig = config: lib.attrsets.mapAttrsToList
+    (k: v: [ "CONFIG_${k}" (v.tristate or v.freeform) ] ) config;
+
+  parsePatchConfig = { extraConfig ? "", extraStructuredConfig ? {}, ... }:
+    (parseExtraConfig extraConfig) ++
+    (parseExtraStructuredConfig extraStructuredConfig);
+
+  # parse CONFIG_<OPT>=[ymn]|"foo" style configuration as found in a config file
+  # into a list of k, v tuples
+  parseConfig = config:
+    let
+      parseLine = builtins.match ''(CONFIG_[[:upper:][:digit:]_]+)=(([ymn])|"([^"]*)")'';
+      # get either the [ymn] option or the "foo" option; whichever matched
+      t = l: let v = (i l 2); in [ (i l 0) (if v != null then v else (i l 3)) ];
+      lines = lib.strings.splitString "\n" config;
+    in map t (builtins.filter (l: l != null) (map parseLine lines));
+
+  origConfigfile = ./config;
+
+  linux-asahi-pkg = { stdenv, lib, fetchFromGitHub, fetchpatch, linuxKernel,
+      rustPlatform, rustc, rustfmt, rust-bindgen, ... } @ args:
+    let
+      origConfigText = builtins.readFile origConfigfile;
+
+      # extraConfig from all patches in order
+      extraConfig =
+        lib.fold (patch: ex: ex ++ (parsePatchConfig patch)) [] _kernelPatches;
+      # config file text for above
+      extraConfigText = let
+        text = k: v: if (v == "y") || (v == "m") || (v == "n")
+          then "${k}=${v}" else ''${k}="${v}"'';
+      in (map (t: text (i t 0) (i t 1)) extraConfig);
+
+      # final config as a text file path
+      configfile = if extraConfig == [] then origConfigfile else
+        writeText "config" ''
+          ${origConfigText}
+
+          # Patches
+          ${lib.strings.concatStringsSep "\n" extraConfigText}
+        '';
+      # final config as an attrset
+      configAttrs = let
+        makePair = t: lib.nameValuePair (i t 0) (i t 1);
+        configList = (parseConfig origConfigText) ++ extraConfig;
+      in builtins.listToAttrs (map makePair (lib.lists.reverseList configList));
+
+      # used to (ostensibly) keep compatibility for those running stable versions of nixos
+      rustOlder = version: withRust && (lib.versionOlder rustc.version version);
+      bindgenOlder = version: withRust && (lib.versionOlder rust-bindgen.unwrapped.version version);
+
+      # used to fix issues when nixpkgs gets ahead of the kernel
+      rustAtLeast = version: withRust && (lib.versionAtLeast rustc.version version);
+      bindgenAtLeast = version: withRust && (lib.versionAtLeast rust-bindgen.unwrapped.version version);
+    in
+    (linuxKernel.manualConfig rec {
+      inherit stdenv lib;
+
+      version = "6.6.0-asahi";
+      modDirVersion = version;
+      extraMeta.branch = "6.6";
+
+      src = fetchFromGitHub {
+        # tracking: https://github.com/AsahiLinux/linux/tree/asahi-wip (w/ fedora verification)
+        owner = "AsahiLinux";
+        repo = "linux";
+        rev = "asahi-6.6-16";
+        hash = "sha256-73ye5JE3YKRgrxGfdQN0+YMIVO1QAJeDuUjTcFhcwI0=";
+      };
+
+      kernelPatches = [
+        { name = "coreutils-fix";
+          patch = ./0001-fs-fcntl-accept-more-values-as-F_DUPFD_CLOEXEC-args.patch;
+        }
+        # speaker enablement; we assert on the relevant lsp-plugins patch
+        # before installing speakersafetyd to let the speakers work
+        { name = "speakers-1";
+          patch = fetchpatch {
+            url = "https://github.com/AsahiLinux/linux/commit/385ea7b5023486aba7919cec8b6b3f6a843a1013.patch";
+            hash = "sha256-u7IzhJbUgBPfhJXAcpHw1I6OPzPHc1UKYjH91Ep3QHQ=";
+          };
+        }
+        { name = "speakers-2";
+          patch = fetchpatch {
+            url = "https://github.com/AsahiLinux/linux/commit/6a24102c06c95951ab992e2d41336cc6d4bfdf23.patch";
+            hash = "sha256-wn5x2hN42/kCp/XHBvLWeNLfwlOBB+T6UeeMt2tSg3o=";
+          };
+        }
+      ] ++ lib.optionals (rustAtLeast "1.75.0") [
+        { name = "rustc-1.75.0";
+          patch = ./0001-check-in-new-alloc-for-1.75.0.patch;
+        }
+      ] ++ lib.optionals (rustAtLeast "1.76.0") [
+        { name = "rustc-1.76.0";
+          patch = ./rust_1_76_0.patch;
+        }
+      ] ++ _kernelPatches;
+
+      inherit configfile;
+      # hide Rust support from the nixpkgs infra to avoid it re-adding the rust packages.
+      # we can't use it until it's in stable and until we've evaluated the cross-compilation impact.
+      config = configAttrs // { "CONFIG_RUST" = "n"; };
+    } // (args.argsOverride or {})).overrideAttrs (old: if withRust then {
+      nativeBuildInputs = (old.nativeBuildInputs or []) ++ [
+        rust-bindgen
+        rustfmt
+        rustc
+        removeReferencesTo
+      ];
+      # HACK: references shouldn't have been there in the first place
+      # TODO: remove once 23.05 is obsolete
+      postFixup = (old.postFixup or "") + ''
+        if [ -f $dev/lib/modules/${old.version}/build/vmlinux ]; then
+          remove-references-to -t $out $dev/lib/modules/${old.version}/build/vmlinux
+        fi
+        remove-references-to -t $dev $out/Image
+      '';
+      RUST_LIB_SRC = rustPlatform.rustLibSrc;
+    } else {});
+
+  linux-asahi = (callPackage linux-asahi-pkg { });
+in lib.recurseIntoAttrs (linuxPackagesFor linux-asahi)
+