I am trying to create a custom package containing `libfprint` drivers/firmware

Hi there. I am still new to NixOS, but I really like to concept. I am already running my home server on NixOS, and I now also installed it on my Dell Latitude 7440.

In order to learn about NixOS and to get my laptop fingerprint reader working, I decided to create a custom package. I am using the original source of the Dell/Broadcom drivers: ~oem-solutions-engineers/libfprint-2-tod1-broadcom/+git/libfprint-2-tod1-broadcom - [no description]

This source (specifically the upstream branch) is also used in Arch Linux, so I know they work for my fingerprint scanner.

With the help of the documentation and ChatGPT I manager to create a working default.nix. The nix-build is working, and the contents of the result folder is looking good. But when I install it using nix-env --install /nix/store/RANDOMBUILDFOLDER it installs the package without any errors, but it looks like the package does not actually install the files in de required folder.

I feel like I am really close to a working package, but that I am missing some crucial NixOS “gotcha’s”. I also compared my default.nix with some of the already existing libfprint packages (like nixpkgs/pkgs/development/libraries/libfprint-2-tod1-goodix/default.nix at 8d18fe9184beffc6c48fc04b1ad210d4a2c2e556 · NixOS/nixpkgs · GitHub), but I cannot find any obvious differences.

Here is my current default.nix:

{ stdenv, lib, fetchgit, libfprint-tod }:

stdenv.mkDerivation {
  pname = "libfprint-2-tod1-broadcom";
  version = "5.12.018.0";

  src = fetchgit {
    url = "https://git.launchpad.net/~oem-solutions-engineers/libfprint-2-tod1-broadcom/+git/libfprint-2-tod1-broadcom";
    rev = "refs/heads/upstream";
    sha256 = "sha256-ezjmbyHoop3oNSPRR/q8HKTi8xFDPrTJY1PV5Quyock=";
  };

  buildInputs = [ libfprint-tod ];

  installPhase = ''
    runHook preInstall

    # Create directories
    install -Dm755 -d "$out/lib/libfprint-2/tod-1/"
    install -Dm755 -d "$out/lib/udev/rules.d/"
    install -Dm755 -d "$out/lib/fprint/fw/cv3/"
    install -Dm755 -d "$out/lib/fprint/fw/cv3plus/"

    # Install driver library
    install -Dm755 usr/lib/x86_64-linux-gnu/libfprint-2/tod-1/libfprint-2-tod-1-broadcom.so "$out/lib/libfprint-2/tod-1/"

    # Install udev rules
    install -Dm755 lib/udev/rules.d/60-libfprint-2-device-broadcom.rules "$out/lib/udev/rules.d/"

    # Install firmware files
    cp -r var/lib/fprint/fw/* "$out/lib/fprint/fw/"

    # Install license
    install -Dm644 ./LICENCE.broadcom "$out/share/licenses/$pname/LICENSE"

    runHook postInstall
  '';

  passthru.driverPath = "/lib/libfprint-2/tod-1";

  meta = with lib; {
    description = "Proprietary driver for the fingerprint reader on the Dell Latitude 7300 and up";
    homepage = "https://git.launchpad.net/~oem-solutions-engineers/libfprint-2-tod1-broadcom/+git/libfprint-2-tod1-broadcom/";
    license = licenses.unfree;
    platforms = platforms.linux;
    maintainers = with maintainers; [ "Saeverix" ];
  };
}

And this is the contents of the result folder after building:

result:
lib  share

result/lib:
fprint  libfprint-2  udev

result/lib/fprint:
fw

result/lib/fprint/fw:
bcmCitadel_1.otp  bcmCitadel_7.otp  bcm_cv_clearscd.bin  bcm_cv_current_version.txt  bcmDeviceFirmwareCitadel_1.bin  bcmDeviceFirmwareCitadel_7.bin  bcmsbiCitadelA0_1.otp  bcmsbiCitadelA0_7.otp  cv3  cv3plus  key.pem

result/lib/fprint/fw/cv3:
bcmCitadel_1.otp  bcmCitadel_7.otp  bcm_cv_clearscd.bin  bcm_cv_current_version.txt  bcmDeviceFirmwareCitadel_1.bin  bcmDeviceFirmwareCitadel_7.bin  bcmsbiCitadelA0_1.otp  bcmsbiCitadelA0_7.otp  key.pem

result/lib/fprint/fw/cv3plus:
bcmCitadel_1.otp  bcmCitadel_7.otp  bcm_cv_clearscd.bin  bcm_cv_current_version.txt  bcmDeviceFirmwareCitadel_1.bin  bcmDeviceFirmwareCitadel_7.bin  bcmsbiCitadelB0_1.otp  bcmsbiCitadelB0_7.otp  key.pem

result/lib/libfprint-2:
tod-1

result/lib/libfprint-2/tod-1:
libfprint-2-tod-1-broadcom.so

result/lib/udev:
rules.d

result/lib/udev/rules.d:
60-libfprint-2-device-broadcom.rules

result/share:
licenses

result/share/licenses:
libfprint-2-tod1-broadcom

result/share/licenses/libfprint-2-tod1-broadcom:
LICENSE

I hope you can push me in the right direction to get this package working, so I can eventually also create a pull request to merge it into Nixpkgs. If you need more information, please let me know.

1 Like

I never did this, but perhaps try installing it into your configuration via boot.extraModulePackages instead of nix-env (which is kind of an anti-pattern).

I tried 2-3 different ways of loading the package using configuration.nix, but none of them worked.
I tried the following method (and variations of it):

environment.systemPackages = with pkgs; [
  (pkgs.callPackage /path/to/your/package/default.nix {})
];

No errors, but sadly none of the methods installed the package correctly. That’s why I eventually ended up with the anti-pattern way of installing the package directly (and uninstalling it afterwards).

Currently I am lost in what might be causing the issue. Could it be wrong destination folders? Could it be a wrong way of creating/compiling the package? Or is it not possible to test a “libraries/firmware” package the normal way?

environment.systemPackages is for packages that provide these paths:

At this point I would dig through nixpkgs for NixOS modules that add kernel modules to see what NixOS options they use.

That’s basically what I did. I compared my default.nix with all of the libfprint-2-tod1 packages, for example this one: nixpkgs/pkgs/development/libraries/libfprint-2-tod1-goodix-550a/default.nix at 8d18fe9184beffc6c48fc04b1ad210d4a2c2e556 · NixOS/nixpkgs · GitHub

All of those packages look the same, and install just fine. But they all have one difference compared to my default.nix: They don’t install firmware files, only drivers and udev rules.

I wish there was some way of debugging the installation of a package. Where it would explicitly say: Installing “these files” in “these locations”. I tried using nixos-rebuild switch --trace, but that does not give any useful information.

I guess I will have a look at packages installing firmware files, but I am really hoping for someone looking at the provided files that can say “Ah yes, you need to do this/that to fix it”.

Hold on, that is a package. What I suggested you take a look at are NixOS modules.

@mightyiam I wanted to give you an update, since you did try and put me in the right direction. In the meantime I found an already existing package by a person that managed to fix the issue using a C wrapper. Pretty complex, and I did not think of that solution myself.

The package added support for the specific fingerprint reader that I use, but initially I could not find it because it’s still in the unstable channel: NixOS Search

Anyways, thank you for your help and time.

2 Likes