Look at this Makefile — then look at this NixOS package derivation. Appears simple but I couldn’t for the life of me divine how to quickly compile a custom/patched kernel module on NixOS. Abstractions… are very magical. The guide is cool and all, but it’s a better time investment to guesstimate the relationship between the higher/lower layer. This friendly example looks more like this in reality though ;-)
A NixOS configuration for a working sound driver on an A1418 Cirrus Logic CS8409/CS42L83.
{ stdenv, lib, fetchgit, linuxKernel, kernel ? linuxKernel.kernels.linux_5_15
, version ? "d0d785dc1859b09299bde6d0f1d6786a0d610e7f" }:
stdenv.mkDerivation {
inherit version;
name = "sna-hda-codec-cs8409-${version}-module-${kernel.modDirVersion}";
# Upstream: https://github.com/davidjo/snd_hda_macbookpro
src = fetchgit {
url = "https://github.com/egorenar/snd-hda-codec-cs8409.git";
rev = version;
sha256 = "sha256-0UeoERcYpM+ojeZ7dDIE3ruTIoHkkC+s7FcoEVUTR0w=";
};
hardeningDisable = [ "pic" ];
nativeBuildInputs = kernel.moduleBuildDependencies;
NIX_CFLAGS_COMPILE = [ "-g" "-Wall" "-Wno-unused-variable" "-Wno-unused-function" ];
makeFlags = kernel.makeFlags ++ [
"INSTALL_MOD_PATH=$(out)"
"KERNELRELEASE=${kernel.modDirVersion}"
"KERNEL_DIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
];
postPatch = ''
printf '
snd-hda-codec-cs8409-objs := patch_cs8409.o patch_cs8409-tables.o
obj-$(CONFIG_SND_HDA_CODEC_CS8409) += snd-hda-codec-cs8409.o
KBUILD_EXTRA_CFLAGS = "-DAPPLE_PINSENSE_FIXUP -DAPPLE_CODECS -DCONFIG_SND_HDA_RECONFIG=1"
KERNELRELEASE ?= $(shell uname -r)
KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build
PWD := $(shell pwd)
default:
make -C $(KERNEL_DIR) M=$(PWD) CFLAGS_MODULE=$(KBUILD_EXTRA_CFLAGS)
install:
make -C $(KERNEL_DIR) M=$(PWD) modules_install
' \
> Makefile
sed --in-place 's|<sound/cs42l42.h>|"${linuxKernel.kernels.linux_6_0.dev}/lib/modules/${linuxKernel.kernels.linux_6_0.modDirVersion}/source/include/sound/cs42l42.h"|' patch_cs8409.h
sed --in-place 's|hda_local.h|${kernel.dev}/lib/modules/${kernel.modDirVersion}/source/sound/pci/hda/hda_local.h|' patch_cs8409.h
sed --in-place 's|hda_jack.h|${kernel.dev}/lib/modules/${kernel.modDirVersion}/source/sound/pci/hda/hda_jack.h|' patch_cs8409.h
sed --in-place 's|hda_generic.h|${kernel.dev}/lib/modules/${kernel.modDirVersion}/source/sound/pci/hda/hda_generic.h|' patch_cs8409.h
sed --in-place 's|hda_auto_parser.h|${kernel.dev}/lib/modules/${kernel.modDirVersion}/source/sound/pci/hda/hda_auto_parser.h|' patch_cs8409.h
'';
meta = { platforms = lib.platforms.linux; };
}
Then build it as a extra/custom kernel module. The results of stumbling upon yet another troublesome device…
{ pkgs, ... }:
{
boot = {
extraModulePackages = [
(pkgs.callPackage ../packages/snd-hda-cs8409/default.nix {
kernel = pkgs.linux_5_15;
})
];
};
}
My default
nix
configuration on NixOS.
This configuration is more for building/debugging stuff and caching with
nix-serve
.
Usually my package version is locked since different
versions of
nix
can have some effects.
{ config, ... }:
{
nix = {
package = (import ../versions.nix).nix_2_12 { inherit config; };
settings = {
log-lines = 25; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-log-lines
fallback = true; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-fallback
tarball-ttl = 0; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-tarball-ttl
show-trace = true; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-show-trace
connect-timeout = 5; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-connect-timeout
auto-optimise-store = true; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-auto-optimise-store
narinfo-cache-negative-ttl = 0; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-narinfo-cache-negative-ttl
narinfo-cache-positive-ttl = 0; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-narinfo-cache-positive-ttl
builders-use-substitutes = true; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-builders-use-substitutes
min-free = 268435456; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-min-free (256 MB in Bytes)
max-free = 1073741824; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-max-free (1 GB in Bytes)
allowed-users = [ "root" "@wheel" ]; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-allowed-users
trusted-users = [ "root" "@wheel" ]; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-trusted-users
experimental-features = "nix-command flakes"; # https://nixos.org/manual/nix/unstable/command-ref/conf-file.html#conf-experimental-features
};
};
}
I thought about posting notes on Syncthing but then I’d have to tangentially talk about NixOS. NixOS is my main Linux distribution but Nix/NixOS/Flakes are too hard to write about and I fear they’ve ventured too far into the realm of over–engineering.
What do I mean by over–engineering? An over–engineered tool is one where even the simplest use cases are non–obvious (to most people) and this can happen when it tries to do too many things with “specificity”. The overall concept is elegant though (explainable in lay terms) and can be applied in other contexts.
I feel sorta conflicted about
my posted notes
on nixops
because
shortly after that I discovered
nixos-rebuild had remote deploys. Now
nixos-rebuild itself is just a
bash script
and taking a peek inside is well, you know.. enlightening. There’s even a
NixOS deployment tool written
in just nix. I use
nixos-rebuild…
nixos-rebuild switch \
--target-host "nix@remote.host" \
--build-host "localhost" \
--no-build-nix
The nix
packages collection has a
neat library repository. A small
nudge can
make it completely standalone.
Basically it allows experimenting quickly with configuration patterns for custom
stuff without an expensive evaluation.
After daily driving NixOS and the Nix for almost three years, it feels like it’ll be simplified by entities external to the project. It’s still in that academic phase (don’t do this/that) and needs software engineering .
That usually involves reducing boilerplate ruthlessly while
generalizing/capturing fundamental uses cases (setting implicit best current
practices). It’s reminiscent of lxc
just before docker
arrived for the
masses.
this blog is served to you by NixOS :-)
I’m just now realizing that there might be a schism within the Nix/NixOS ecosystem/community on old versus new interfaces. If that’s remotely true, then somewhere, a great holy war is at play. Here’s an article summary of the old versus the new interface that I stumbled upon recently.
This blog
is really really good for robust usage of
Nix/NixOS. I stumble upon it every so often.
Another excellent blog is
“How to Learn Nix” which
explores in excruciating detail the painful parts of nix
and its
documentation. Discovered that one recently.
What’s funny about the
NixOS/GNU Guix
design is that it tricks developers into writing their own system packages. That
would never happen on other Linux distributions. I’m slowly favoring Guix
though, since the new nix
flake interface
couples too tightly with git
.