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_17 { 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.
I might not remember correctly but
lxc
came out around 2008
.
Docker in 2013
. The lxc
commands had the trend of dashes in their name — lxc-attach
, lxc-snapshot
,
lxc-copy
and so forth. It had lots of boilerplate and a steep learning curve.
Then lxd
arrived (in 2015?)
to make everything user friendly. lxd
is preferred. I still mostly use lxc
out of habit.
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 :-)
Offline friends, do you think that the Linux ecosystem is increasingly copying the bad parts of software distribution from Windows and macOS?
Surely typing/saying the below Alpine command to install Firefox is way easier than who knows what multi–stage process other operating systems require.
apk add firefox
Google’s search box (rather tongue in cheek) is the most popular command line
interface in use today. With ,
installing and running firefox
would just be a phrase equivalent that compiles
to:
firefox
On NixOS, we can already do stuff like that. Of course, NixOS lacks a translation/encapsulation layer for imperative to declarative specification — so user friendliness suffers dramatically.
It’s kinda odd being able to remember what things were like before Docker appeared. Docker is the software developer’s take on creating a Linux distribution. It’s useful, but the indirection of containers and pinning can be deadly. Avoiding unnecessary indirection is advantageous.