# make out-of-tree modules given a backported kernel source tree { extraConfig ? {} , drivers ? [ ] , kernel-backport , stdenv , writeText , klibBuild ? null , buildPackages , fetchFromGitHub , liminix , lib }: let arch = stdenv.hostPlatform.linuxArch; openwrtSrc = fetchFromGitHub { name = "openwrt-source"; repo = "openwrt"; owner = "openwrt"; rev = "a5265497a4f6da158e95d6a450cb2cb6dc085cab"; hash = "sha256-YYi4gkpLjbOK7bM2MGQjAyEBuXJ9JNXoz/JEmYf8xE8="; }; inherit (liminix.services) oneshot longrun; inherit (lib.lists) foldl; configs = { ath9k.kconfig = { WLAN_VENDOR_ATH = "y"; ATH_COMMON = "m"; ATH9K = "m"; ATH9K_AHB = "y"; BACKPORTED_ATH9K_AHB = "y"; }; ath9k_pci = { module = "ath9k"; kconfig = { WLAN_VENDOR_ATH = "y"; ATH_COMMON = "m"; ATH9K = "m"; ATH9K_PCI = "y"; }; }; ath10k_pci.kconfig = { WLAN_VENDOR_ATH = "y"; ATH_COMMON = "m"; ATH10K = "m"; ATH10K_PCI = "y"; ATH10K_DEBUG = "y"; }; rt2800soc.kconfig = { WLAN_VENDOR_RALINK = "y"; RT2800SOC = "m"; RT2X00 = "m"; }; mt7603e.kconfig = { # XXX find a better name for this WLAN_VENDOR_RALINK = "y"; WLAN_VENDOR_MEDIATEK = "y"; MT7603E = "y"; }; mt7915e.kconfig = { MT7915E = "m"; }; mt7615e.kconfig = { MT7615E = "m"; MT7622_WMAC = "y"; }; mac80211_hwsim.kconfig = { MAC80211_HWSIM = "y"; }; }; kconfig = (foldl (config: d: (config // configs.${d}.kconfig)) { WLAN = "y"; CFG80211 = "m"; MAC80211 = "m"; # (nixwrt comment) I am reluctant to have to enable this but # can't transmit on 5GHz bands without it (they are all marked # NO-IR) CFG80211_CERTIFICATION_ONUS = "y"; # (nixwrt comment) can't get signed regdb to work rn, it just # gives me "loaded regulatory.db is malformed or signature is # missing/invalid" CFG80211_REQUIRE_SIGNED_REGDB = "n"; # depends on ONUS CFG80211_CRDA_SUPPORT = "n"; MAC80211_MESH = "y"; } drivers) // extraConfig; writeConfig = name : config: writeText name (builtins.concatStringsSep "\n" (lib.mapAttrsToList (name: value: (if value == "n" then "# CPTCFG_${name} is not set" else "CPTCFG_${name}=${value}")) config )); kconfigFile = writeConfig "backports_kconfig" kconfig; src = kernel-backport; CROSS_COMPILE = stdenv.cc.bintools.targetPrefix; CC = "${buildPackages.stdenv.cc}/bin/gcc"; module = stdenv.mkDerivation { name = "mac80211"; inherit src; hardeningDisable = ["all"]; nativeBuildInputs = [buildPackages.stdenv.cc] ++ (with buildPackages.pkgs; [bc bison flex pkg-config openssl which kmod cpio ]); inherit CC CROSS_COMPILE; ARCH = arch; dontStrip = true; dontPatchELF = true; phases = [ "unpackPhase" "patchFromOpenwrt" "configurePhase" "checkConfigurationPhase" "buildPhase" "installPhase" ]; patchFromOpenwrt = '' mac80211=${openwrtSrc}/package/kernel/mac80211 echo $mac80211 for i in $(ls $mac80211/patches/build/ | grep -v 015-ipw200); do echo $i; (patch -p1 -N <$mac80211/patches/build/$i) done for i in $(ls $mac80211/patches/rt2x00/ | grep -v 009-rt2x00-don-t | grep -v 013-rt2x00-set-correct | grep -v 014 | grep -v 015 | grep -v 016); do echo $i; (patch -p1 -N <$mac80211/patches/rt2x00/$i) done for i in $mac80211/patches/ath/*; do echo $i; (patch -p1 -N <$i) ;done for i in $mac80211/patches/ath9k/*; do echo $i; (patch -p1 -N <$i) ;done ''; configurePhase = '' cp ${kconfigFile} .config cp ${kconfigFile} .config.orig chmod +w .config .config.orig make V=1 CC=${CC} SHELL=`type -p bash` LEX=flex KLIB_BUILD=${klibBuild} olddefconfig ''; checkConfigurationPhase = '' echo Checking required config items: if comm -2 -3 <(awk -F= '/CPTCFG/ {print $1}' ${kconfigFile} |sort) <(awk -F= '/CPTCFG/ {print $1}' .config|sort) |grep '.' ; then echo -e "^^^ Some configuration lost :-(\nPerhaps you have mutually incompatible settings, or have disabled options on which these depend.\n" exit 0 fi echo "OK" ''; KBUILD_BUILD_HOST = "liminix.builder"; buildPhase = '' patchShebangs scripts/ echo ${klibBuild} make V=1 SHELL=`type -p bash` KLIB_BUILD=${klibBuild} modules find . -name \*.ko | xargs ${CROSS_COMPILE}strip --strip-debug ''; installPhase = '' mkdir -p $out/lib/modules/0.0 find . -name \*.ko | cpio --make-directories -p $out/lib/modules/0.0 depmod -b $out -v 0.0 touch $out/load.sh for i in ${lib.concatStringsSep " " (map (d: let c = { module = d; } // configs.${d} ; in c.module) drivers)}; do modprobe -S 0.0 -d $out --show-depends $i >> $out/load.sh done tac < $out/load.sh | sed 's/^insmod/rmmod/g' > $out/unload.sh ''; }; in oneshot { name = "wlan.module"; up = "sh ${module}/load.sh"; down = "sh ${module}/unload.sh"; }