Packaging out-of-tree kernel module ch341

I’m trying to build the driver for oxocard. Unfortunately nixos-rebuild fails

# nixos-rebuild switch --upgrade
...
building '/nix/store/w2bs2dz4p8x10s5mqfjv848rfgxdckv5-CH341SER-1.8-2024-10-24.drv'...
Running phase: unpackPhase
unpacking source archive /nix/store/paqbxfskkaaknd0f052p18dh2rf9y1sc-CH341SER_LINUX
source root is ./CH341SER_LINUX/driver
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
make -C /nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/build  M=/build/CH341SER_LINUX/driver  
make[1]: Entering directory '/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/build'
make[2]: Entering directory '/build/CH341SER_LINUX/driver'
  CC [M]  ch341.o
ch341.c:58:10: fatal error: asm/unaligned.h: No such file or directory
   58 | #include <asm/unaligned.h>
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.
make[4]: *** [/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/source/scripts/Makefile.build:207: ch341.o] Error 1
make[3]: *** [/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/source/Makefile:1994: .] Error 2
make[2]: *** [/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/source/Makefile:251: __sub-make] Error 2
make[2]: Leaving directory '/build/CH341SER_LINUX/driver'
make[1]: *** [/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/source/Makefile:251: __sub-make] Error 2
make[1]: Leaving directory '/nix/store/1wjcww3hgrf7ymfmss9zw2g13b03rg2k-linux-6.14-dev/lib/modules/6.14.0/build'
make: *** [Makefile:7: default] Error 2
error: builder for '/nix/store/w2bs2dz4p8x10s5mqfjv848rfgxdckv5-CH341SER-1.8-2024-10-24.drv' failed with exit code 2
error: 1 dependencies of derivation '/nix/store/h4vj69yr1h1m22g30109c5h38x4zwqb0-linux-6.14-modules.drv' failed to build
error: 1 dependencies of derivation '/nix/store/fcglyi13jsfi3b094visxd3w19m793lf-nixos-system-ls03064-24.11.716288.d02d88f8de5b.drv' failed to build

Any idea what could be lacking in my configuration to fix the asm/unaligned.h error?

  • hadware-configuration.nix
  boot.kernelPackages = pkgs.linuxPackages_latest.extend ( self: super: {
    ch341 = self.callPackage ./CH341SER.nix {};
  } );
  • CH341SER.nix
{ lib
, stdenv
, kernel
}:

# https://wiki.nixos.org/wiki/Linux_kernel#Out-of-tree_kernel_modules
stdenv.mkDerivation rec {
  pname = "CH341SER";
  version = "1.8-2024-10-24";
  src = ./CH341SER_LINUX;

  sourceRoot = "./CH341SER_LINUX/driver";
  hardeningDisable = [ "pic" "format" ];                                    # Disable hardening for kernel modules
  nativeBuildInputs = kernel.moduleBuildDependencies;                       # Include kernel build dependencies

  # Explicitly pass KERNELDIR to the Makefile
  buildPhase = ''
    make KERNELDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build default
  '';

  installPhase = ''
    make KERNELDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build install
  '';

  meta = {
    homepage = "https://www.wch-ic.com/downloads/CH341SER_LINUX_ZIP.html";
    description = "Linux driver for USB to serial port, supports CH340 and CH341, supports 32/64-bit operating systems.";
    license = lib.licenses.gpl2Only;
    maintainers = [ ];
    platforms = [ "x86_64-linux" ];
  };
}
1 Like

Use a kernel which is before https://github.com/torvalds/linux/commit/5f60d5f6bbc12e782fac78110b0ee62698f3b576 i.e. before 6.12

2 Likes

Thank you for the hint!
I was able to build and use the driver with this little change in ch341.c

git diff ch341.c 
diff --git a/etc/nixos/CH341SER_LINUX/driver/ch341.c b/etc/nixos/CH341SER_LINUX/driver/ch341.c
index 36a20ce..0f9a789 100644
--- a/etc/nixos/CH341SER_LINUX/driver/ch341.c
+++ b/etc/nixos/CH341SER_LINUX/driver/ch341.c
@@ -55,7 +55,7 @@
 #include <linux/usb/cdc.h>
 #include <linux/version.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
 #include <linux/sched/signal.h>

and amendment in CH341SER.nix

  installPhase = ''
    mkdir -vp $out/lib/modules/${kernel.modDirVersion}/kernel/drivers/usb/serial/
    cp -fv ./ch341.ko $out/lib/modules/${kernel.modDirVersion}/kernel/drivers/usb/serial/
  '';