1
0
forked from colin/nix-files

Compare commits

..

113 Commits

Author SHA1 Message Date
212e81d521 pinephone-pro-sound-minimal: remove extraneous i2c timings 2025-09-02 17:06:42 +00:00
6c137994e9 pinephone-pro-sound-minimal: remove unused in2-differential config; redundant #address/#size-cells 2025-09-02 16:42:58 +00:00
7a5df886a1 pinephone-pro-sound-minimal: remove Internal Earpiece, Headset Microphone routes
the Internal Microphone (i.e. not the headphones one) still works (did HP mic *ever* work?)
2025-09-02 16:37:39 +00:00
6393ec68da pinephone-pro-sound-minimal: remove Line In/Out Modem controls 2025-09-02 16:29:23 +00:00
1c4cd0aad5 pinephone-pro-sound-minimal: remove i2s0_2ch_bus override 2025-09-02 16:23:51 +00:00
acbbed7149 pinephone-pro-sound-minimal: remove the uart pinctrl
this means we get distortion at (very) high output levels again, but a simpler profile
2025-09-02 16:09:08 +00:00
71a515f235 pinephone-pro-sound-minimal: remove the unused hp-det pinctrl 2025-09-02 16:02:56 +00:00
7c14f46a4f pinephone-pro-sound-minimal: disable card-level hp-det-gpios
note that the 'Speakers' profile doesn't give sound when headphones actually are plugged in. the 'Headphones' profile does, of course
2025-09-02 15:54:41 +00:00
10cabf5056 moby: switch systemd-boot -> extlinux, until i figure out the audio issues 2025-09-02 09:20:05 +00:00
47ac5ca23c pinephone-pro: define an alternate, more minimal sound dtso
and yes, i actually tested this before committing this time
2025-09-02 09:04:55 +00:00
52b5626903 pinephone-pro-sound: add missing VCC-supplynode to speaker_amp 2025-09-02 04:02:40 +00:00
f645005b45 pinephone-pro: ship a binary helper to install (or update) u-boot on an existing (or new) device
moby is now updated to u-boot 2025.07
2025-09-01 22:25:48 +00:00
9979289be1 u-boot-pinephone-pro: refactor (build output is unchanged) 2025-09-01 20:21:07 +00:00
a1396fb273 move bootpart-systemd-boot installation into modules/image, so it reliably applies to hosts which need it 2025-09-01 20:20:43 +00:00
1c38797bad modules/image: fix extraGPTPadding; fix pinephone and pinephone-pro image installation 2025-09-01 20:19:46 +00:00
c66764fba5 hal/pine64-pinephone-pro: fix image build to not be truncated 2025-09-01 11:24:05 +00:00
7e7cac8ecd fix arm-trusted-firmware eval after apparent upstream refactoring to buildArmTrustedFirmware 2025-09-01 11:23:18 +00:00
e7a1ff8b3d rpi-400: note linux_rpi4 2025-09-01 09:51:59 +00:00
e43926eb25 nixpkgs: patches: remove commented-out, irrelevant rpm patch 2025-09-01 09:51:04 +00:00
4dbce1baae cross: update upstreaming status 2025-08-31 23:35:01 +00:00
55979b7e4e aarch64: enable vulkan-tools (it cross compiles) 2025-08-31 22:44:16 +00:00
fadcc1a842 hal/aarch64: only patch SUNXI_CCU=y on aarch64 PLUS preferBuiltin=false
maybe better to gate it on autoModules too?
2025-08-31 22:35:33 +00:00
5526bba05c nixpkgs-bootstrap: 2025-08-30 -> 2025-08-31 2025-08-31 22:07:43 +00:00
26412ee801 nixpkgs-wayland: 2025-08-30 -> 2025-08-31 2025-08-31 22:07:10 +00:00
3cdbd133f6 uassets: 2025-08-30 -> 2025-08-31 2025-08-31 22:06:44 +00:00
bd8c7c971a aarch64: kernel: remove forced BACKLIGHT_CLASS_DEVICE=y (fixed upstream)
fixed in nixpkgs 2024-12-27: <https://github.com/NixOS/nixpkgs/pull/367774>
2025-08-31 13:42:28 +00:00
4c4a24d08d bootpart-edk2-rpi: ship the rpi-400 dtb 2025-08-31 13:19:27 +00:00
86b037c835 modules/image: ship devicetree file, if configured 2025-08-31 12:57:15 +00:00
32ea5ad846 boot: re-enable nixpkgs default kernel modules
this doesn't fix cadey boot completely, but it gets it to fewer errors
2025-08-31 12:26:13 +00:00
3a1eec4308 edk2-rpi: swap raspberry logo with tianocore logo, to remove dependency on edk2-non-osi repo 2025-08-31 11:19:39 +00:00
e81a2498b7 bootpart-edk2-rpi: minimize custom config portions 2025-08-31 10:39:41 +00:00
5f8cfcb7e9 edk2-rpi: fix!
now it actually loads. havent tried booting the full systemd-boot enabled system though
2025-08-31 09:47:26 +00:00
13205492b4 bootpart-edk2-rpi: dont ship .dtb files 2025-08-31 09:04:18 +00:00
176ef307b2 rpi-400: try to boot via EDK2
however, my build of edk2 seems broken. drop the prebuilt RPI_EFI.fd into the resulting image, and it works ...
2025-08-31 08:58:43 +00:00
11293a4d0a bootpart-edk2-rpi: init
have not deployed this yet; untested
2025-08-31 08:20:17 +00:00
a34449faed nixpkgs-bootstrap: 2025-08-29 -> 2025-08-30 2025-08-30 21:12:42 +00:00
4f3b1dd361 nixpkgs-wayland: 2025-08-29 -> 2025-08-30 2025-08-30 21:10:15 +00:00
f7335634a1 euicc-manual: 2025-08-14 -> 2025-08-30 2025-08-30 21:10:01 +00:00
faa8a6968d uassets: 2025-08-29 -> 2025-08-30 2025-08-30 21:09:45 +00:00
fd54b70b36 edk2-rpi4: init 2025-08-30 05:16:36 +00:00
05b864143e todo.md: remove outdated comment about envelope/libadwaita 2025-08-30 01:32:18 +00:00
d9b82e8b1e moby: plumb deviceTree file through to systemd-boot
this fixes the lacking battery charge indication from the previous extlinux -> systemd-boot change
2025-08-30 01:22:52 +00:00
ad559acbd9 moby: switch extlinux -> systemd-boot
for the sake of consistency with my other platforms

u-boot boot order appears to be extlinux > script > efi_mgr > efi

note that after rebooting, battery shows 0%. unclear if systemd-boot somehow breaks charging, or just battery reporting, or if totally unrelated
2025-08-30 00:30:19 +00:00
4d4b28027c todo.md: remove outdated servo /boot size item 2025-08-29 20:56:19 +00:00
da52f21da2 remove commented-out generic-extlinux-compatible configs 2025-08-29 20:55:41 +00:00
fea85f438b servo: fix prosody
well, i know it works with the systemd hardening disabled. i'm assuming it'll work with that enabled too, but don't want to redeploy/restart the service right now
2025-08-29 19:46:42 +00:00
13db8bec76 nixpkgs: 2025-08-28 -> 2025-08-29 2025-08-29 16:17:17 +00:00
01e3ace398 nixpkgs-wayland: 2025-08-28 -> 2025-08-29 2025-08-29 16:17:03 +00:00
745ee33394 uassets: 2025-08-28 -> 2025-08-29 2025-08-29 16:16:49 +00:00
1c5c9b80eb nixpkgs: 2025-08-27 -> 2025-08-28; remove upstreamed newsflash cross code 2025-08-28 16:01:56 +00:00
94289c2253 nixpkgs-wayland: 2025-08-27 -> 2025-08-28 2025-08-28 16:00:27 +00:00
0c443fae25 uassets: 2025-08-26 -> 2025-08-28 2025-08-28 16:00:14 +00:00
a490a74390 cross: open PRs for all my rust cross patches 2025-08-28 01:57:17 +00:00
2e71e06c05 lemoa: inline the cross compilation fix 2025-08-27 18:43:49 +00:00
203832b5a8 envelope: 2024-09-13 -> 2025-05-17; inline the cross fixes 2025-08-27 18:37:55 +00:00
1204f4db69 cross: rewrite newsflash patch as a nixpkgs commit 2025-08-27 17:04:05 +00:00
a4b114fce2 nixpkgs: bump; rewrite snapshot patch as nixpkgs commit 2025-08-27 16:29:58 +00:00
7e17eb4056 nixpkgs-wayland: 2025-08-26 -> 2025-08-27 2025-08-27 15:52:50 +00:00
259d980a60 nixpkgs: 2025-08-26 0> 2025-08-27 2025-08-27 15:52:40 +00:00
5488486944 firefox: fix browserpass/native-messaging-hosts integration 2025-08-27 08:32:35 +00:00
969717b1fe firefox: disable safebrowsing and restrict app auto-updates even more aggressively
i don't think any auto-updating bit me, i'm just being pre-emptive
2025-08-27 07:55:45 +00:00
7391e34f77 cross: factor spot,video-trimmer build fixes into nixpkgs commits 2025-08-27 02:25:28 +00:00
7f45077485 cross: split delfin fix into nixpkgs patch 2025-08-27 01:12:25 +00:00
ceb7ccbc6d todo.md: task for migrating spot -> riff 2025-08-27 01:06:14 +00:00
9d63ec5dd2 hosts: remove references to lappy remote fs
this was causing mount timeouts on _every_ deploy
2025-08-27 00:00:21 +00:00
7ce93eae96 cross: fix papers via upstreamable patch 2025-08-26 23:52:58 +00:00
1277c73304 nixpkgs: update, drop upstreamed loupe/pwvucontrol cross patches 2025-08-26 18:14:55 +00:00
0550498cd1 nixpkgs/patches: remove redundant qemu patch, push coincurve upstream 2025-08-26 17:02:45 +00:00
023396a41e nixpkgs-bootstrap.staging: 2025-08-25 -> 2025-08-26 2025-08-26 15:44:27 +00:00
ebb335ef4c nixpkgs-wayland: 2025-08-25 -> 2025-08-26 2025-08-26 15:44:27 +00:00
fbb0046dda uvtools: 5.1.7 -> 5.2.0 2025-08-26 15:44:27 +00:00
59d4197bf5 uassets: 2025-08-25 -> 2025-08-26 2025-08-26 15:44:27 +00:00
90e4e20274 zimPackages.wikipedia_en_all_maxi: 2024-01 -> 2025-08 2025-08-26 15:44:27 +00:00
7ecd368e20 zimPackages.alpinelinux: 2025-07 -> 2025-08 2025-08-26 15:44:27 +00:00
79fc30da0e cross: push fractal/pwvucontrol/loupe patches upstream & update tracking statuses 2025-08-26 15:44:27 +00:00
23f3647cc5 nixpkgs-wayland: 2025-08-20 -> 2025-08-25 2025-08-26 15:44:27 +00:00
ad4910366d zimPackages.archlinux_en_all_maxi: 2025-07 -> 2025-08 2025-08-26 15:44:27 +00:00
609becadfe nixpkgs: 2025-08-18 -> 2025-08-26 2025-08-26 15:44:27 +00:00
3acabe60b6 uassets: 2025-08-20 -> 2025-08-25 2025-08-26 15:44:27 +00:00
87ec095b8a programs: typescript-language-server: link cache files into ephemeral storage 2025-08-26 15:44:27 +00:00
8831d8d1ac image: fix initrd path to be the /boot path instead of the /nix/store path 2025-08-22 02:58:09 +00:00
8b333a8887 doc/migrating-storage-device: show how to resize the fs 2025-08-22 02:58:09 +00:00
028d903e9c boot: package "mlabel", for changing FAT UUIDs 2025-08-22 02:20:05 +00:00
dfed5f070b servo: update fs UUIDs 2025-08-22 02:19:47 +00:00
b29ee5ac03 desko: gate ollama behind sane.maxBuildCost option 2025-08-21 02:43:35 +00:00
e700ff392f servo: gate costly services behind sane.maxBuildCost option 2025-08-21 02:42:58 +00:00
91578c0b78 snippets: add new links 2025-08-20 17:31:19 +00:00
b35656c9ae nixpkgs-wayland: 2025-08-19 -> 2025-08-20 2025-08-20 17:24:48 +00:00
726281a6dd uassets: 2025-08-19 -> 2025-08-20 2025-08-20 17:24:09 +00:00
f305027678 nvimpager: allow access to vimrc 2025-08-20 01:17:37 +00:00
2b69c07d12 nixpkgs-wayland: 2025-08-18 -> 2025-08-19 2025-08-19 08:35:30 +00:00
544b1e58e0 uassets: 2025-08-18 -> 2025-08-19 2025-08-19 08:35:18 +00:00
34c2d4f66f neovim: ship RC file as ~/.config/nvim/
this allows easier editing at runtime
2025-08-18 21:22:21 +00:00
4addf857b7 firefox: redirect "maps" search URL to Kagi by default 2025-08-18 19:39:31 +00:00
a3f6c148d3 nixpkgs: 2025-08-17 -> 2025-08-18 2025-08-18 15:25:24 +00:00
43a0abd68f nixpkgs-wayland: 2025-08-17 -> 2025-08-18 2025-08-18 15:25:15 +00:00
b3c4e96d6e syshud: 2025-07-26 -> 2025-08-18 2025-08-18 15:24:56 +00:00
ade5ce5339 uassets: 2025-08-17 -> 2025-08-18 2025-08-18 15:24:40 +00:00
e543034fcb overlays/cross: update upstreaming status 2025-08-17 21:25:15 +00:00
b5d96ed17b nixpkgs: 2026-08-16 -> 2025-08-17 2025-08-17 17:32:26 +00:00
003ce70cd7 nixpkgs-wayland: 2025-08-15 -> 2025-08-17 2025-08-17 17:32:16 +00:00
04f6964711 uassets: 2025-08-16 -> 2025-08-17 2025-08-17 17:31:59 +00:00
63cf19f839 nixpkgs: 2025-08-15 -> 2025-08-16 2025-08-16 21:05:35 +00:00
806a1aa294 nixpkgs-wayland: 2025-08-14 -> 2025-08-15 2025-08-16 20:13:28 +00:00
35a023f449 lpac: 2.2.1 -> 2.3.0 2025-08-16 17:06:56 +00:00
f0aec4416c uassets: 2025-08-15 -> 2025-08-16 2025-08-16 16:53:29 +00:00
e0bb1b7c62 servo: gitea: place only the most expensive repos behind Anubis 2025-08-16 08:15:47 +00:00
9847e0171c flowy: avoid invoking no-op efibootmgr operations 2025-08-16 08:05:55 +00:00
03a1638628 flowy: set nixos as default EFI boot entry, always 2025-08-16 07:55:35 +00:00
f7327bef3e servo: document the anubis openGraph setting 2025-08-16 07:04:56 +00:00
47fb8296db flowy: add bootloader entry to boot into Windows (but i still need to do more config to get Bitlocker to work w/o secure boot) 2025-08-16 07:02:37 +00:00
b409fbb5f7 systemd-boot: enable memtest and edk2 UEFI shell 2025-08-16 07:00:47 +00:00
84092395f4 Merge pull request 'patch-gitea-anubis-opengraph' (#6) from shelvacu/colins-nix-files:patch-gitea-anubis-opengraph into master
Reviewed-on: colin/nix-files#6
2025-08-16 07:00:22 +00:00
62 changed files with 1546 additions and 923 deletions

View File

@@ -57,7 +57,6 @@
## IMPROVEMENTS:
- servo: expand /boot to 2 GiB like all other hosts
- moby: port to systemd-boot
- sane-deadlines: show day of the week for upcoming items
- and only show on "first" terminal opened; not on Ctrl+N terminals
@@ -74,7 +73,6 @@
- can't do that because lots of applications don't handle URIs
- could workaround using a wrapper that downloads the file and then passes it to the program
- geary: replace with envelope
- likely requires updating envelope to a more recent version (for multi-accounting), and therefore updating libadwaita...
### security/resilience
- /mnt/desko/home, etc, shouldn't include secrets (~/private)
@@ -135,6 +133,7 @@
- Trivia Quiz (https://linuxphoneapps.org/games/io.github.nokse22.trivia-quiz/)
- sane-sync-music: remove empty dirs
- soulseek: install a CLI app usable over ssh
- moby: replace `spot` with its replacement, `riff` (<https://github.com/Diegovsky/riff>)
#### moby
- moby: port battery support to something upstreamable

View File

@@ -1,18 +1,18 @@
## migrating a host to a new drive
1. copy persistent data off of the host:
### 1. copy persistent data off of the host:
```sh
$ mkdir -p mnt old/persist
$ mount /dev/$old mnt
$ rsync -arv mnt/persist/ old/persist/
```
2. flash the new drive
### 2. flash the new drive
```
$ nix-build -A hosts.moby.img
$ dd if=$(readlink ./result) of=/dev/$new bs=4M oflag=direct conv=sync status=progress
```
3. expand the partition and filesystem
### 3.1. expand the partition
```sh
$ cfdisk /dev/$new
# scroll to the last partition
@@ -21,24 +21,29 @@ $ cfdisk /dev/$new
> Write
type "yes"
> Quit
$ btrfs filesystem resize max /dev/$new
```
### 3.2. expand the filesystem
```
$ mkdir -p /mnt/$new
$ mount /dev/$new /mnt/$new
$ btrfs filesystem resize max /mnt/$new
```
4. copy data onto the new host
### 4. copy data onto the new host
```
$ mkdir new
$ mount /dev/$new new
$ mkdir /mnt/$new
$ mount /dev/$new /mnt/$new
# if you want to use btrfs snapshots (e.g. snapper), then create the data directory as a subvolume:
$ sudo btrfs subvolume create new/persist
$ btrfs subvolume create /mnt/$new/persist
# restore the data
$ rsync -arv old/persist/ new/persist/
$ rsync -arv old/persist/ /mnt/$new/persist/
```
5. ensure/fix ownership
### 5. ensure/fix ownership
```
$ chmod -R a+rX new/nix
$ chmod -R a+rX /mnt/$new/nix
# or, let the nix daemon do it:
$ nix copy --no-check-sigs --to new $(nix-build -A hosts.moby)
$ nix copy --no-check-sigs --to /mnt/$new $(nix-build -A hosts.moby)
```
```
6. insert the disk into the system, and boot!
### 6. insert the disk into the system, and boot!

View File

@@ -13,7 +13,4 @@
# TODO: port to `sane.programs` interface
services.xserver.desktopManager.kodi.enable = true;
# /boot space is at a premium, especially with uncompressed kernels. default was 20.
# boot.loader.generic-extlinux-compatible.configurationLimit = 10;
}

View File

@@ -1,4 +1,4 @@
{ ... }:
{ config, lib, ... }:
{
imports = [
./fs.nix
@@ -27,7 +27,7 @@
sane.roles.client = true;
sane.roles.pc = true;
sane.roles.work = true;
sane.services.ollama.enable = true;
sane.services.ollama.enable = lib.mkIf (config.sane.maxBuildCost >= 3) true;
sane.services.wg-home.enable = true;
sane.ovpn.addrV4 = "172.26.55.21";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:20c1:a73c";

View File

@@ -1,4 +1,4 @@
{ ... }:
{ lib, pkgs, ... }:
{
imports = [
./fs.nix
@@ -22,4 +22,37 @@
sops.secrets.colin-passwd.neededForUsers = true;
sane.services.rsync-net.enable = true;
# add an entry to boot into Windows, as if it had been launched directly from the BIOS.
boot.loader.systemd-boot.rebootForBitlocker = true;
boot.loader.systemd-boot.windows.primary.efiDeviceHandle = "HD0b";
system.activationScripts.makeDefaultBootEntry = {
text = let
makeDefaultBootEntry = pkgs.writeShellApplication {
name = "makeDefaultBootEntry";
runtimeInputs = with pkgs; [
efibootmgr
gnugrep
];
text = ''
# configure the EFI firmware to boot into NixOS by default.
# do this by querying the active boot entry, and just making that be the default.
# this is needed on flowy because enabling secure boot / booting into Windows
# resets the default boot order; manually reconfiguring that is tiresome.
efi=$(efibootmgr)
bootCurrent=$(echo "$efi" | grep '^BootCurrent: ')
bootCurrent=''${bootCurrent/BootCurrent: /}
bootOrder=$(echo "$efi" | grep '^BootOrder: ')
bootOrder=''${bootOrder/BootOrder: /}
if ! [[ "$bootOrder" =~ ^"$bootCurrent", ]]; then
# booted entry was not the default,
# so prepend it to the boot order:
newBootOrder="$bootCurrent,$bootOrder"
(set -x; efibootmgr -o "$newBootOrder")
fi
'';
};
in lib.getExe makeDefaultBootEntry;
};
}

View File

@@ -58,10 +58,8 @@
sane.programs.mpv.config.defaultProfile = "fast";
# /boot space is at a premium, especially with uncompressed kernels. default was 20.
# boot.loader.generic-extlinux-compatible.configurationLimit = 10;
# TODO: switch to systemd-boot
# TODO: switch to systemd-boot once rt5640 audio works under it
boot.loader.generic-extlinux-compatible.enable = true;
# boot.loader.generic-extlinux-compatible.configurationLimit = 5;
boot.loader.systemd-boot.enable = false;
}

View File

@@ -16,7 +16,7 @@
fileSystems."/tmp".options = [ "size=32G" ];
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/cc81cca0-3cc7-4d82-a00c-6243af3e7776";
device = "/dev/disk/by-uuid/55555555-eeee-ffff-bbbb-000020250820";
fsType = "btrfs";
options = [
"compress=zstd"
@@ -25,7 +25,7 @@
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/6EE3-4171";
device = "/dev/disk/by-uuid/2025-0820";
fsType = "vfat";
};

View File

@@ -124,6 +124,7 @@
services.anubis.instances."git.uninsane.org" = {
settings.TARGET = "http://127.0.0.1:3000";
# allow IM clients/etc to show embeds/previews, else they just show "please verify you aren't a bot..."
botPolicy.openGraph.enabled = true;
};
@@ -133,8 +134,13 @@
# XXX(2025-07-24): gitea's still being crawled, even with robots.txt.
# the load is less than when Anthropic first started, but it's still pretty high (like 600%).
# place behind anubis to prevent AI crawlers from hogging my CPU (gitea is slow to render pages).
proxyPass = "http://unix:${config.services.anubis.instances."git.uninsane.org".settings.BIND}";
# proxyPass = "http://127.0.0.1:3000";
proxyPassHeavy = "http://unix:${config.services.anubis.instances."git.uninsane.org".settings.BIND}";
# but anubis breaks embeds, so only protect the expensive repos.
proxyPassLight = "http://127.0.0.1:3000";
proxyTo = proxy: root: {
proxyPass = proxy;
recommendedProxySettings = true;
};
in {
forceSSL = true; # gitea complains if served over a different protocol than its config file says
enableACME = true;
@@ -144,9 +150,20 @@
'';
locations."/" = {
inherit proxyPass;
proxyPass = proxyPassLight;
recommendedProxySettings = true;
};
# selectively proxy the heavyweight items through anubis.
# a typical interaction is:
# nginx:/colin/linux -> anubis:/colin/linux -> browser is served a loading page
# -> nginx:.within.website/x/cmd/anubis/api/pass-challenge?response=... -> anubis:.within.website/x/cmd/anubis/api/pass-challenge?response=... -> browser is forwarded to /colin/linux
# -> nginx:/colin/linux -> anubis:/colin/linux -> gitea:/colin/linux -> browser is served the actual content
locations."/.within.website/" = proxyTo proxyPassHeavy;
locations."/colin/linux" = proxyTo proxyPassHeavy;
locations."/colin/nixpkgs" = proxyTo proxyPassHeavy;
locations."/colin/opencellid-mirror" = proxyTo proxyPassHeavy;
locations."/colin/podcastindex-db-mirror" = proxyTo proxyPassHeavy;
# fuck you @anthropic
# locations."= /robots.txt".extraConfig = ''
# return 200 "User-agent: *\nDisallow: /\n";
@@ -154,7 +171,7 @@
# gitea serves all `raw` files as content-type: plain, but i'd like to serve them as their actual content type.
# or at least, enough to make specific pages viewable (serving unoriginal content as arbitrary content type is dangerous).
locations."~ ^/colin/phone-case-cq/raw/.*.html" = {
inherit proxyPass;
proxyPass = proxyPassLight;
recommendedProxySettings = true;
extraConfig = ''
proxy_hide_header Content-Type;
@@ -163,7 +180,7 @@
'';
};
locations."~ ^/colin/phone-case-cq/raw/.*.js" = {
inherit proxyPass;
proxyPass = proxyPassLight;
recommendedProxySettings = true;
extraConfig = ''
proxy_hide_header Content-Type;

View File

@@ -14,10 +14,11 @@
#
# N.B.: default install DOES NOT SUPPORT DLNA out of the box.
# one must install it as a "plugin", which can be done through the UI.
{ ... }:
{ config, lib, ... }:
# lib.mkIf false #< XXX(2024-11-17): disabled because it hasn't been working for months; web UI hangs on load, TVs see no files
{
config = lib.mkIf (config.sane.maxBuildCost >= 2) {
# https://jellyfin.org/docs/general/networking/index.html
sane.ports.ports."1900" = {
protocol = [ "udp" ];
@@ -168,4 +169,5 @@
};
sane.dns.zones."uninsane.org".inet.CNAME."jelly" = "native";
};
}

View File

@@ -1,5 +1,6 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
config = lib.mkIf (config.sane.maxBuildCost >= 3) {
sane.services.kiwix-serve = {
enable = true;
port = 8013;
@@ -37,4 +38,5 @@
};
sane.dns.zones."uninsane.org".inet.CNAME."w" = "native";
};
}

View File

@@ -3,7 +3,7 @@
# - <repo:LemmyNet/lemmy:docker/nginx.conf>
# - <repo:LemmyNet/lemmy-ansible:templates/nginx.conf>
{ lib, pkgs, ... }:
{ config, lib, pkgs, ... }:
let
uiPort = 1234; # default ui port is 1234
backendPort = 8536; # default backend port is 8536
@@ -24,6 +24,7 @@ let
media.video.max_frame_count = 30 * 60 * 60;
};
in {
config = lib.mkIf (config.sane.maxBuildCost >= 2) {
services.lemmy = {
enable = true;
settings.hostname = "lemmy.uninsane.org";
@@ -174,4 +175,5 @@ in {
serviceConfig.SystemCallArchitectures = "native";
serviceConfig.SystemCallFilter = [ "@system-service" ];
};
};
}

View File

@@ -14,6 +14,7 @@ let
# logLevel = "debug";
in
{
config = lib.mkIf (config.sane.maxBuildCost >= 2) {
sane.persist.sys.byStore.private = [
# contains media i've uploaded to the server
{ user = "pleroma"; group = "pleroma"; path = "/var/lib/pleroma"; method = "bind"; }
@@ -217,4 +218,5 @@ in
sops.secrets."pleroma_secrets" = {
owner = config.users.users.pleroma.name;
};
};
}

View File

@@ -41,6 +41,10 @@
# - maybe i need to setup stun/turn
#
# TODO:
# - MIGRATE TO NIXOS MODULE OPTIONS:
# - `services.prosody.ssl.`...
# - `services.prosody.log`
# - this decreases likelihood of breakage during future upgrades
# - enable push notifications (mod_cloud_notify)
# - optimize coturn (e.g. move off of the VPN!)
# - ensure muc is working
@@ -245,11 +249,11 @@ in
extraConfig = ''
local function readAll(file)
local f = assert(io.open(file, "rb"))
local f = Lua.assert(Lua.io.open(file, "rb"))
local content = f:read("*all")
f:close()
-- remove trailing newline
return string.gsub(content, "%s+", "")
return Lua.string.gsub(content, "%s+", "")
end
-- logging docs:
@@ -261,9 +265,11 @@ in
}
-- see: <https://prosody.im/doc/certificates#automatic_location>
-- try to solve: "certmanager: Error indexing certificate directory /etc/prosody/certs: cannot open /etc/prosody/certs: No such file or directory"
-- try to solve: "certmanager: Error indexing certificate directory /run/prosody/certs: cannot open /run/prosody/certs: No such file or directory"
-- only, this doesn't work because prosody doesn't like acme's naming scheme
-- certificates = "/var/lib/acme"
-- certificates = "/var/lib/acme/uninsane.org"
-- instead, point to /etc/prosody/certs and configure symlinks into this dir (see nix config)
certificates = "/etc/prosody/certs"
c2s_direct_tls_ports = { 5223 }
s2s_direct_tls_ports = { 5270 }

View File

@@ -1,14 +1,15 @@
{ lib, pkgs, ... }:
{ config, lib, pkgs, ... }:
{
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# useful emergency utils
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${lib.getExe' pkgs.btrfs-progs "btrfstune"}
copy_bin_and_libs ${lib.getExe' pkgs.util-linux "{cfdisk,lsblk,lscpu}"}
copy_bin_and_libs ${lib.getExe' pkgs.gptfdisk "{cgdisk,gdisk}"}
copy_bin_and_libs ${lib.getExe' pkgs.smartmontools "smartctl"}
copy_bin_and_libs ${lib.getExe' pkgs.e2fsprogs "resize2fs"}
copy_bin_and_libs ${lib.getExe' pkgs.gptfdisk "{cgdisk,gdisk}"}
copy_bin_and_libs ${lib.getExe' pkgs.mtools "mlabel"}
copy_bin_and_libs ${lib.getExe pkgs.nvme-cli}
copy_bin_and_libs ${lib.getExe' pkgs.smartmontools "smartctl"}
copy_bin_and_libs ${lib.getExe' pkgs.util-linux "{cfdisk,lsblk,lscpu}"}
'';
boot.kernelParams = [
"boot.shell_on_fail"
@@ -37,8 +38,16 @@
boot.consoleLogLevel = 7;
boot.loader.grub.enable = lib.mkDefault false;
# boot.loader.generic-extlinux-compatible.enable = lib.mkDefault true;
boot.loader.systemd-boot.enable = lib.mkDefault true;
boot.loader.systemd-boot.configurationLimit = lib.mkDefault 20;
boot.loader.systemd-boot.edk2-uefi-shell.enable = lib.mkDefault true;
boot.loader.systemd-boot.memtest86.enable = lib.mkDefault
(lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.memtest86plus);
warnings = lib.optionals (config.boot.loader.systemd-boot.enable && config.hardware.deviceTree.package != null && config.hardware.deviceTree.name == null) [
("systemd-boot enabled on a device-tree-enabled system but without configuring hardware.deviceTree.name: " +
"system will boot against the platform firmware's .dtb instead of the kernel's more up-to-date dtb")
];
hardware.enableAllFirmware = true; # firmware with licenses that don't allow for redistribution. fuck lawyers, fuck IP, give me the goddamn firmware.
# hardware.enableRedistributableFirmware = true; # proprietary but free-to-distribute firmware (extraneous to `enableAllFirmware` option)

View File

@@ -79,7 +79,7 @@ lib.mkMerge [
(ifSshAuthorized (remoteHome "crappy" {}))
(ifSshAuthorized (remoteHome "desko" {}))
(ifSshAuthorized (remoteHome "flowy" {}))
(ifSshAuthorized (remoteHome "lappy" {}))
# (ifSshAuthorized (remoteHome "lappy" {}))
(ifSshAuthorized (remoteHome "moby" { host = "moby-hn"; }))
(ifSshAuthorized (remoteHome "servo" {}))
]

View File

@@ -32,13 +32,13 @@
lan-ip = "10.78.79.56";
};
sane.hosts.by-name."lappy" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
wg-home.pubkey = "FTUWGw2p4/cEcrrIE86PWVnqctbv8OYpw8Gt3+dC/lk=";
wg-home.ip = "10.0.10.20";
lan-ip = "10.78.79.53";
};
# sane.hosts.by-name."lappy" = {
# ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
# ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
# wg-home.pubkey = "FTUWGw2p4/cEcrrIE86PWVnqctbv8OYpw8Gt3+dC/lk=";
# wg-home.ip = "10.0.10.20";
# lan-ip = "10.78.79.53";
# };
sane.hosts.by-name."moby" = {
# ssh.authorized = lib.mkDefault false; # moby's too easy to hijack: don't let it ssh places

View File

@@ -6,8 +6,9 @@ let
# nixpkgs' pam hardcodes unix_chkpwd path to the /run/wrappers one,
# but i don't want the wrapper, so undo that.
# ideally i would patch this via an overlay, but pam is in the bootstrap so that forces a full rebuild.
# see: <repo:nixos/nixpkgs:pkgs/by-name/li/linux-pam/package.nix>
postPatch = (upstream.postPatch or "") + ''
substituteInPlace modules/pam_unix/Makefile.am --replace-fail \
substituteInPlace modules/module-meson.build --replace-fail \
"/run/wrappers/bin/unix_chkpwd" "$out/bin/unix_chkpwd"
'';
});
@@ -215,8 +216,10 @@ in
# - USB keyboards: "uhci_hcd" "ehci_hcd" "ehci_pci" "ohci_hcd" "ohci_pci" "xhci_hcd" "xhci_pci" "usbhid" "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat" "hid_logitech_hidpp" "hid_logitech_dj" "hid_microsoft" "hid_cherry" "hid_corsair"
# - LVM: "dm_mod"
# - on x86 only: more keyboard stuff: "pcips2" "atkbd" "i8042"
boot.initrd.includeDefaultModules = lib.mkDefault false;
#
# however, including these modules seems relatively *harmless*,
# and it makes bringup of new systems a bit easier.
# boot.initrd.includeDefaultModules = lib.mkDefault false;
# see: <repo:nixos/nixpkgs:nixos/modules/virtualisation/nixos-containers.nix>
boot.enableContainers = lib.mkDefault false;

View File

@@ -1194,6 +1194,10 @@ in
typescript-language-server.buildCost = 2;
typescript-language-server.sandbox.whitelistPwd = true;
typescript-language-server.persist.byStore.ephemeral = [
".cache/typescript"
".npm" # .npm/{_cacache,_logs}
];
tumiki-fighters.buildCost = 1;
tumiki-fighters.sandbox.whitelistAudio = true;

View File

@@ -216,6 +216,7 @@
./tcpdump.nix
./tor-browser.nix
./tuba.nix
./u-boot-pinephone-pro
./unl0kr
./uptime.nix
./v4l-utils.nix

View File

@@ -16,6 +16,7 @@
<dt><a href="https://en.wikipedia.org/wiki/Special:Search?search=%s" shortcuturl="w">Search Wikipedia
<dt><a href="https://github.com/nixos/nixpkgs/pulls?q=%s" shortcuturl="pr">Search nixpkgs PRs
<dt><a href="https://github.com/search?type=repositories&q=%s" shortcuturl="gh">Search GitHub
<dt><a href="https://kagi.com/maps/infobox?q=%s" shortcuturl="maps">Search Kagi Maps
<dt><a href="https://kagi.com/search?q=%s" shortcuturl="kagi">Search with Kagi
<dt><a href="https://lib.rs/search?q=%s" shortcuturl="librs">Search lib.rs (Rust)
<dt><a href="https://myanimelist.net/search/all?cat=all&q=%s" shortcuturl="mal">Search MyAnimeList
@@ -35,7 +36,7 @@
<dt><a href="https://www.ebay.com/sch/i.html?_sacat=0&_nkw=%s" shortcuturl="ebay">Search eBay
<dt><a href="https://www.etsy.com/search?q=%s" shortcuturl="etsy">Search Etsy
<dt><a href="https://www.etymonline.com/search?q=%s" shortcuturl="etym">Search Etymonline
<dt><a href="https://www.google.com/maps/search/%s" shortcuturl="maps">Search Google Maps
<dt><a href="https://www.google.com/maps/search/%s" shortcuturl="gmaps">Search Google Maps
<dt><a href="https://www.google.com/search?q=%s" shortcuturl="g">Search Google
<dt><a href="https://www.google.com/search?q=%s&" shortcuturl="google">Search Google
<dt><a href="https://www.google.com/search?tbm=shop&q=%s" shortcuturl="shopping">Search Google Shopping

View File

@@ -43,6 +43,10 @@ in
"knowledge/secrets/accounts"
];
# firefox learns about this package by looking in ~/.mozilla/native-messaging-hosts
fs.".mozilla/native-messaging-hosts/com.github.browserpass.native.json".symlink.target
= "${browserpass}//lib/mozilla/native-messaging-hosts/com.github.browserpass.native.json";
# TODO: env.PASSWORD_STORE_DIR only needs to be present within the browser session.
# alternative to PASSWORD_STORE_DIR:
# fs.".password-store".symlink.target = "knowledge/secrets/accounts";

View File

@@ -16,7 +16,9 @@ let
cfg.addons
);
addonSuggestedPrograms = lib.map (n: config.sane.programs."${n}") addonSuggestedProgramNames;
addonHomePaths = lib.concatMap (p: p.sandbox.extraHomePaths) (addonSuggestedPrograms ++ nativeMessagingPrograms);
addonHomePaths = lib.concatMap
(p: p.sandbox.extraHomePaths ++ builtins.attrNames p.fs)
(addonSuggestedPrograms ++ nativeMessagingPrograms);
packageUnwrapped = let
unwrapped = pkgs.firefox-unwrapped // {
@@ -29,7 +31,8 @@ let
# inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
libName = "firefox";
inherit nativeMessagingHosts;
# XXX(2025-08-26): nativeMessagingHosts wrapping is broken! put things in ~/.mozilla/native-messaging-hosts/ instead.
# inherit nativeMessagingHosts;
nixExtensions = lib.concatMap (ext: lib.optional ext.enable ext.package) (builtins.attrValues cfg.addons);

View File

@@ -143,9 +143,20 @@ defaultPref("browser.shell.checkDefaultBrowser", false);
// disable extension updates
defaultPref("extensions.update.autoUpdateDefault", false);
defaultPref("extensions.update.enabled", false);
defaultPref("extensions.systemAddon.update.enabled", false);
// wipe the URIs used to check for updates, as a precaution.
defaultPref("extensions.update.url", "");
defaultPref("extensions.update.background.url", "");
defaultPref("extensions.systemAddon.update.url", "");
// also disable app-level auto-updates
defaultPref("app.update.auto", false);
// disable "safe browsing", in which my browser asks Google whether a site is malicious or not, for every site i visit (?)
defaultPref("browser.safebrowsing.blockedURIs.enabled", false);
defaultPref("browser.safebrowsing.downloads.enabled", false);
defaultPref("browser.safebrowsing.malware.enabled", false);
defaultPref("browser.safebrowsing.phishing.enabled", false);
// browser.engagement.sidebar-button.has-used
// browser.migration.version = 150

View File

@@ -36,7 +36,8 @@
sandbox.extraPaths = [
"/boot"
"/mnt/desko"
"/mnt/lappy"
"/mnt/flowy"
# "/mnt/lappy"
"/mnt/moby"
"/mnt/servo"
# "nix"

View File

@@ -67,12 +67,12 @@ in
viAlias = true;
vimAlias = true;
plugins = plugin-packages;
customRC = ''
${builtins.readFile ./vimrc}
# customRC = ''
# ${builtins.readFile ./vimrc}
""""" PLUGIN CONFIG
${plugin-configs}
'';
# """"" PLUGIN CONFIG
# ${plugin-configs}
# '';
};
neovim-unwrapped' = with pkgs; neovim-unwrapped.overrideAttrs (upstream: {
# fix cross compilation:
@@ -122,9 +122,17 @@ in
# due to <https://github.com/NixOS/nixpkgs/pull/344541>
rubyEnv = null;
withRuby = false;
wrapRc = false; #< don't force VIMINIT env var
postBuild = lib.replaceStrings [ "if ! $out/bin/nvim-wrapper " ] [ "if false " ] base.postBuild;
});
fs.".config/nvim/init.vim".symlink.text = ''
${builtins.readFile ./vimrc}
""""" PLUGIN CONFIG
${plugin-configs}
'';
# private because there could be sensitive things in the swap
persist.byStore.private = [ ".cache/vim-swap" ];
env.EDITOR = "vim";

View File

@@ -1,3 +1,6 @@
" ENV VARS
" VIMINIT=/path/to/init.vim to use a different vimrc
" let the terminal handle mouse events, that way i get OS-level ctrl+shift+c/etc
" this used to be default, until <https://github.com/neovim/neovim/pull/19290>
set mouse=

View File

@@ -1,4 +1,7 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.nvimpager;
in
{
sane.programs.nvimpager = {
packageUnwrapped = (pkgs.nvimpager.override {
@@ -10,6 +13,9 @@
suggestedPrograms = [ "neovim" ];
sandbox.extraHomePaths = [
".config/nvim"
];
sandbox.whitelistWayland = true; # for system clipboard integration
env.MANPAGER = "nvimpager";
@@ -21,4 +27,8 @@
env.MANWIDTH = "999";
env.MANROFFOPT = "-c";
};
sane.programs.man-db.sandbox.extraHomePaths = lib.mkIf cfg.enabled [
".config/nvim"
];
}

View File

@@ -11,6 +11,10 @@ let
type = lib.types.bool;
inherit default description;
};
i3ipc = pkgs.python3Packages.i3ipc.overridePythonAttrs {
# XXX(2025-08-25): tests are broken; remove once fixed
doCheck = false;
};
playerctl = pkgs.playerctl.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [
(pkgs.fetchpatch {
@@ -108,6 +112,9 @@ in
packageUnwrapped = (pkgs.nwg-panel.override {
inherit playerctl;
python3Packages = pkgs.python3Packages // {
inherit i3ipc;
};
}).overrideAttrs (base: {
# patches = (base.patches or []) ++ lib.optionals (!cfg.config.mediaPrevNext) [
# ./playerctl-no-prev-next.diff

View File

@@ -0,0 +1,21 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.u-boot-pinephone-pro;
in
{
sane.programs.u-boot-pinephone-pro = {
packageUnwrapped = pkgs.runCommandNoCC "u-boot-pinephone-pro-program" {
preferLocalBuild = true;
} ''
install -Dm644 ${pkgs.u-boot-pinephone-pro}/idbloader.img $out/share/boot/idbloader.img
install -Dm644 ${pkgs.u-boot-pinephone-pro}/u-boot.itb $out/share/boot/u-boot.itb
install -Dm755 ${./install-u-boot} $out/bin/install-u-boot
# ln -sv $out/bin/install-u-boot $out/share/boot/install-u-boot
'';
sandbox.autodetectCliPaths = "existingFile";
};
environment.pathsToLink = lib.mkIf cfg.enabled [
"/share/boot"
];
}

View File

@@ -0,0 +1,25 @@
#!/bin/sh
set -eu
drive=$1
if ! [[ -e "$drive" ]]; then
echo "usage: install-u-boot /dev/sdX"
exit 1
fi
bootfiles_dir=
for d in ${XDG_DATA_DIRS//:/ }; do
if [[ -e "$d/boot/idbloader.img" ]] && [[ -e "$d/boot/u-boot.itb" ]]; then
bootfiles_dir=$d/boot
fi
done
if [[ -z "$bootfiles_dir" ]]; then
echo "boot/{idbloader.img,u-boot.itb} not found on XDG_DATA_DIRS"
exit 1
fi
set -x
dd if="$bootfiles_dir/idbloader.img" of="$drive" bs=512 seek=64 conv=notrunc,sync oflag=direct status=progress
dd if="$bootfiles_dir/u-boot.itb" of="$drive" bs=512 seek=16384 conv=notrunc,sync oflag=direct status=progress

View File

@@ -65,7 +65,8 @@
sandbox.extraPaths = [
"/boot"
"/mnt/desko"
"/mnt/lappy"
"/mnt/flowy"
# "/mnt/lappy"
"/mnt/moby"
"/mnt/servo"
# "nix"

View File

@@ -116,9 +116,9 @@ in
# see: `man logind.conf`
# dont shutdown when power button is short-pressed (commonly done an accident, or by cats).
# but do on long-press: useful to gracefully power-off server.
services.logind.powerKey = "lock";
services.logind.powerKeyLongPress = "poweroff";
services.logind.lidSwitch = "lock";
services.logind.settings.Login.HandlePowerKey = "lock";
services.logind.settings.Login.HandlePowerKeyLongPress = "poweroff";
services.logind.settings.Login.HandleLidSwitch = "lock";
# under logind, 'uaccess' tag would grant the logged in user access to a device.
# outside logind, map uaccess tag -> plugdev group to grant that access.
services.udev.extraRules = ''

View File

@@ -11,6 +11,7 @@ in
config = lib.mkIf cfg.enable {
# disable the following non-essential programs which fail to cross compile
sane.programs.bash-language-server.enableFor = { system = false; user.colin = false; }; # bash neovim LSP: doesn't cross compile (2025-01-05; blocked by ShellCheck)
sane.programs.cargo.enableFor = { system = false; user.colin = false; }; #< does not cross compile (2025-08-25)
sane.programs.fcitx5.enableFor.user.colin = false; #< does not cross compile (2025-01-05; blocked by qtsvg)
sane.programs.firefox.config.addons.browserpass-extension.enable = false; #< does not cross compile
sane.programs.lua-language-server.enableFor = { system = false; user.colin = false; }; # lua neovim LSP: doesn't cross compile (2025-01-06)
@@ -19,23 +20,16 @@ in
sane.programs.nix-tree.enableFor = { system = false; user.colin = false; }; #< does not cross compile (2025-01-05; blocked by vty)
sane.programs.pyright.enableFor = { system = false; user.colin = false; }; #< python neovim LSP: doesn't cross compile (2025-01-05; unblocked)
sane.programs.typescript-language-server.enableFor = { system = false; user.colin = false; }; #< doesn't cross compile (2025-07-18; via `moreutils`)
sane.programs.vulkan-tools.enableFor = { system = false; user.colin = false; }; #< does not cross compile (2025-02-08)
boot.kernelPatches = [
boot.kernelPatches = lib.optionals (!pkgs.stdenv.hostPlatform.linux-kernel.preferBuiltin) [
{
# TODO: upstream into nixpkgs. <repo:nixos/nixpkgs:pkgs/os-specific/linux/kernel/common-config.nix>
name = "fix-module-builtin-mismatch";
patch = null;
structuredExtraConfig = with lib.kernel; {
# nixpkgs specifies `SUN8I_DE2_CCU = yes`, but that in turn requires `SUNXI_CCU = yes` and NOT `= module`
# symptom: config fails to eval
# symptom: Kconfig build fails
SUNXI_CCU = yes;
# nixpkgs specifies `DRM = yes`, which causes `DRM_PANEL=y`.
# in <repo:kernel.org/linux:include/drm/drm_panel.h> they branch based on if `CONFIG_BACKLIGHT_DEVICE` is a *builtin*,
# hence we need to build it as a builtin to actually have a backlight!
# same logic happens with nixpkgs `DRM_FBDEV_EMULATION = yes` => implies `CONFIG_DRM_KMS_HELPER=y`
# and <repo:kernel.org/linux:include/drm/display/drm_dp_helper.h>
BACKLIGHT_CLASS_DEVICE = yes;
};
}
];

View File

@@ -40,16 +40,31 @@ in
# boot.kernelPackages = pkgs.linuxPackagesFor myCustomKernel;
# boot.initrd.extraFiles."/lib".source = "${config.system.modulesTree}/lib";
# docs (pinephone specific; tow-boot instead of u-boot but close enough): <https://github.com/Tow-Boot/Tow-Boot/tree/development/boards/pine64-pinephoneA64>
# Pinephone Pro bootloader locations: <https://wiki.pine64.org/wiki/RK3399_boot_sequence#U-Boot_boot_sequence>
# we need space in the GPT header to place u-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate
sane.image.extraGPTPadding = 16 * 1024 * 1024;
sane.image.firstPartGap = 0;
# N.B.: the original PP expected idbloader to be at block 16.
# PPP expects idbloader to be at block 64.
# GPT header ends at block 34, which means PPP can use an ordinary partition table
# just with the first partition starting at e.g. 16 MiB instead of block 34.
# sane.image.extraGPTPadding = 16 * 1024 * 1024 - 34 * 512;
# sane.image.firstPartGap = 0;
sane.image.installBootloader = ''
dd if=${pkgs.u-boot-pinephone-pro}/idbloader.img of=$out bs=512 seek=64 oflag=direct conv=sync
dd if=${pkgs.u-boot-pinephone-pro}/u-boot.itb of=$out bs=512 seek=16384 oflag=direct conv=sync
uboot_itb_bytes=$(stat --printf="%s" ${pkgs.u-boot-pinephone-pro}/u-boot.itb)
uboot_ends=$(( $uboot_itb_bytes + 16384 * 512))
gap_ends=${builtins.toString config.sane.image.firstPartGap}
if ! (( $uboot_ends <= $gap_ends )); then
echo 'firstPartGap is too small to fit all of u-boot!'
false
fi
dd if=${pkgs.u-boot-pinephone-pro}/idbloader.img of=$out bs=512 seek=64 conv=notrunc
dd if=${pkgs.u-boot-pinephone-pro}/u-boot.itb of=$out bs=512 seek=16384 conv=notrunc
'';
sane.programs.sysadminUtils.suggestedPrograms = [
"u-boot-pinephone-pro"
];
sane.programs.alsa-ucm-conf.suggestedPrograms = [
"pine64-alsa-ucm" # upstreaming: https://github.com/alsa-project/alsa-ucm-conf/pull/375
];
@@ -88,6 +103,10 @@ in
}
];
#v N.B.: deviceTree.name is plumbed through /boot/loader/entries/.
#v if removed, systemd-boot will still (likely) boot, but DTB items known to the kernel
#v and not to the platform firmware (u-boot) will be missing (e.g. rk818/battery monitoring).
hardware.deviceTree.name = "rockchip/rk3399-pinephone-pro.dtb";
hardware.deviceTree.overlays = [
{
name = "rk3399-pinephone-pro-battery";
@@ -109,9 +128,15 @@ in
name = "rk3399-pinephone-pro-modem";
dtsFile = ./rk3399-pinephone-pro-modem.dtso;
}
# {
# name = "rk3399-pinephone-pro-sound";
# dtsFile = ./rk3399-pinephone-pro-sound.dtso;
# }
{
name = "rk3399-pinephone-pro-sound";
dtsFile = ./rk3399-pinephone-pro-sound.dtso;
# the complete sound dtso above works in extlinux, but fails under systemd-boot.
# this simpler sound config may be helpful in debugging.
name = "rk3399-pinephone-pro-sound-minimal";
dtsFile = ./rk3399-pinephone-pro-sound-minimal.dtso;
}
];
@@ -209,9 +234,12 @@ in
# from <repo:nixos/nixpkgs:nixos/modules/system/boot/kernel.nix> AKA pkgs.aggregateModules
# but configured to **ignore collisions**
system.modulesTree = lib.mkForce [(
(pkgs.aggregateModules
( config.boot.extraModulePackages ++ [ config.boot.kernelPackages.kernel ])
).overrideAttrs {
(pkgs.aggregateModules (
config.boot.extraModulePackages ++ [
(lib.getOutput "modules" config.boot.kernelPackages.kernel)
]
)).overrideAttrs {
name = "kernel-modules-merged-sane";
# earlier items override the contents of later items
ignoreCollisions = true;
# checkCollisionContents = false;

View File

@@ -0,0 +1,302 @@
// heavily based on megi's source tree.
// schematics for reference: <https://files.pine64.org/doc/PinePhonePro/PinephonePro-Schematic-V1.0-20211127.pdf>
// Realtek ALC5640 datasheet: <https://www.alldatasheet.com/datasheet-pdf/download/1132334/REALTEK/RT5640.html>
//
// ## DIGITAL RK3399 -> ALC5640 INTERFACE
// [RK3399]GPIO4_A0/I2S_CLK_d -> I2S_CLK -> MCLK[ALC5640]
// [RK3399]GPIO3_D0/I2S0_SCLK_d -> I2S0_SCLK -> BCLK1[ALC5640]
// [RK3399]GPIO3_D1/I2S0_LRCK_RX_d -> I2S0_LRCK_RX -> LRCLK1[ALC5640]
// [RK3399]GPIO3_D2/I2S0_LRCK_TX_d -> I2S0_LRCK_TX -> LRCLK1[ALC5640]
// (yes, I2S0_LRCK_TX and I2S0_LRCK_RX are both bridged to LRCLK1, but with separate resistors probably so they don't short)
// [RK3399]GPIO3_D7/I2S0_SDO0_d -> I2S0_SDO0 -> DACDAT1[ALC5640]
// [RK3399]GPIO3_D3/I2S0_SDI0_d <- I2S0_SDI0 <- ADCDAT1[ALC5640]
//
// the ALC5640 connects also to bluetooth, and the chip as a whole has
// - I2C1_SCL
// - I2C1_SDA
// i believe I2C1 is for control data, whereas I2S is strictly for the audio stream.
//
// ## ALC5640 <-> PHY interface
// [ALC5640]HPO_L -> HPOUTL -> NO2[UM4717] -> COM2[UM4717] -> HPO_L -> JA-3618-011 (jack, "EARPHONE")
// +----> INN[AW8737SCSR] -> SPK+/SPK-
// so, the codec's HPO_L output is sent to the SW-6 MUX (user-exposed, controls whether jack is audio or serial)
// AND it's sent to AW8737SCSR which *may* send it to the speaker.
// i think audio is *unconditionally* routed to the headphones, then.
// it's impossible to have headphones connected, and play *only* to the speaker.
// and it's up to the system to disable AW8737SCSR when the headphones are detected.
// [ALC5640]HPO_R -> HPOUTR [... same as above]
//
// [ALC5640]SPO_LP -> EAROUTP -> 1[J7202/earphone]
// [ALC5640]SPO_LN -> EAROUTN -> 2[J7202/earphone]
//
// ## amplifiers
// [RK3399]B3 -> SPK_CTL_H -> SHDN[AW8737SCSR]
//
// ## Headphone detection (RK3399)
// [RK3399]GPIO4_D4_d -> HP_DET_H -> HP_DET (circuit)
// - HP_DET is pulled to 3V0 when jack is *unplugged*, pulled to HPO_L when jack is plugged.
//
// ## REGULATORS
// - AVDD18_REF -> ALC5640
// - VCCA3V0_CODEC -> ALC5640
// - VCC_SPK -> ALC5640
// - VDD_CODEC -> ALC5640
// - AVDD18_CODEC -> ALC5640
// - VCCA1V8_CODEC -> ALC5640
//
// mainline offers at least these regulators:
// - vcc_sys (regulator-always-on)
// - vcc3v3_sys
// - vcca1v8_s3 (regulator-always-on)
// - vcc1v8_codec (pinctrl-0 = <&vcc1v8_codec_en>)
// - pinctrl routed to &{/pinctrl/sound}
// - nothing in-kernel references vcc1v8_codec_en ...
// megi changed this to regulator-always-on, regulator-boot-on, though
//
//
// note that the I2S pins described in the schematic above match ths `i2s0` defined in `rk3399-base.dtsi`,
// so in general the names should map 1:1
//
// the following in-kernel resources exist:
// - <sound/soc/codecs/rt5640.c>
// driver which is (i think?) loaded by `compatible = "realtek,rt5640"`
// - <Documentation/devicetree/bindings/sound/simple-card.yaml>
// for `compatible = "simple-audio-card"`
// - <arch/arm64/boot/dts/rockchip/rk3399-firefly.dts>
// other RK3399 device with audio configured
// - <Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml>
// regulator definition
// - <Documentation/devicetree/bindings/sound/rockchip-i2s.yaml>
// I2S audio definition
// for symbols like SCLK_I2S_8CH_OUT
#include <dt-bindings/clock/rk3399-cru.h>
// for RK_PD4, other pins
#include <dt-bindings/pinctrl/rockchip.h>
// for GPIO_ACTIVE_LOW
#include <dt-bindings/gpio/gpio.h>
/dts-v1/;
/plugin/;
/ {
/* ensure this overlay applies only to the correct board */
compatible = "pine64,pinephone-pro";
};
&{/} {
// megi says:
// > in1 - digital mic daughhterboard
// > in2 - headset mic
// > in3 - modem output (muxed with mono)
// > spol - earphone
// > hpo - heaphones
// > lout - modem input
// > spaker - amp enabled by SPK_CTL_H
//
// > mclk - GPIO4_A0/I2S_CLK
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "PinePhonePro";
simple-audio-card,format = "i2s";
// frequency scale between stream rate and codec mclk.
// megi assigned 24 MHz to i2c1, which i think means the sample rate of the codec would then be 93.75 kHz (so 46.875 kHz per channel?).
// mainline i2c1 frequence is 200 MHz.
// the device tree makes this tunable, but ALC5640 docs are written as if it's *always* 256.
// oh, perhaps i'm just *informing* the `simple-audio-card` of this fact,
// and it doesn't configure anything on the rt5640, but rather uses this to calculate its own sample rate.
simple-audio-card,mclk-fs = <256>;
// see schematic GPIO4_D4_d -> link HP_DET
// simple-audio-card,hp-det-gpio = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>;
// <sink>, <source>
// - these names i *think* come from <sound/soc/codecs/rt5640.c>,
// or i'm free to define new names for virtual nodes.
//
// HPOL/HPOR -> user kill switch SW1-6 -> headphone jack
// ALSO sent to the speaker amp
// SPOLP/SPOLN -> earphone (with only passives in between)
//
// naming ("Internal Earpiece") is chosen to be consistent with OG pinephone
// "Speaker Amp {INL,INR,OUTL,OUTR}" actually come from simple-audio-amplifier.
// - the speaker_amp dt node specifies "Speaker Amp" as its name-prefix,
// and <sound/soc/codecs/simple-amplifier.c> (i.e. simple-audio-amplifier) uses the INL/OUTL naming
//
// there may be some interplay between the widgets/routing defined here and the alsa configs though.
simple-audio-card,routing =
"Headphones", "HPOL",
"Headphones", "HPOR",
// Internal Speaker would normally go through the external amp.
// but i'm omitting the amp, so bridge it straight to HPOL/HPOR.
// Internal Speaker has to be defined here so that we can expose
// it as a pin-switch, as expected by the alsa UCM profile.
"Internal Speaker", "HPOL",
"Internal Speaker", "HPOR",
"DMIC1", "Internal Microphone";
// user-facing controls. e.g. when user selects "Headphone", activate the "Headphone Jack" path.
simple-audio-card,widgets =
"Microphone", "Internal Microphone",
"Headphone", "Headphones",
"Speaker", "Internal Speaker";
//v switch is required, for alsa UCM init
//v `amixer -c 0 cset name='Internal Speaker Switch' off`
//v if any one step of the profile EnableSequence errors, the rest of the sequence is aborted => no audio
simple-audio-card,pin-switches = "Internal Speaker";
// omitting hp-det-gpios enables ALL profiles to be switched manually (under Configuration tab of e.g. wiremix/pavucontrol)
// simple-audio-card,hp-det-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>;
//
// pinctrl-names = "default";
// pinctrl-0 = <&hp_det_pin>;
simple-audio-card,cpu {
sound-dai = <&i2s0>;
};
simple-audio-card,codec {
sound-dai = <&rt5640>;
// system-clock-frequency = <12288000>;
};
};
};
// declared in rk3399-pinephone-pro.dts
// TODO: spot check the routing on these... why are there two 1v8's in the device tree?
&vcc1v8_codec {
// enable power to the regulator, always
regulator-always-on;
regulator-boot-on;
};
&vcca1v8_codec {
// enable power to the regulator, always
regulator-always-on;
regulator-boot-on;
};
&vcca3v0_codec {
// enable power to the regulator, always
regulator-always-on;
regulator-boot-on;
};
// declared in rk3399-base.dtsi, as `i2c1: i2c@ff110000 { ... }`
&i2c1 {
status = "okay";
// ALC5640 datasheet specifies max i2c rate of 400kHz
// - max rise time: 300ns
// - max fall time: 300ns
clock-frequency = <400000>;
// from rk3399-firefly.dts
// note that i2c3 in pinephone-pro is defined as 450/15 rise/fall
// i2c-scl-rising-time-ns = <300>;
// i2c-scl-falling-time-ns = <15>;
// /i2c1 declares these things, but they aren't seen from the context of this overlay it seems
// this problem is actually mentioned here: <https://pine64.org/documentation/ROCKPro64/Software/Device_Tree_Overlays_on_Mainline/>
// #address-cells = <1>;
// #size-cells = <0>;
rt5640: rt5640@1c {
compatible = "realtek,rt5640";
// reg = address of the device (a.k.a register?). Documentation/devicetree/bindings/sound/rt5640.txt uses 0x1c in their example; megi uses it too.
reg = <0x1c>;
// `cru` = Clocks and Reset unit. declared in rk3399-base.dtsi as `cru: clock-controller@ff760000 { ... }`
// the names of the clocks this cru provides are hardcoded in <dt-bindings/clock/rk3399-cru.h>
// i don't know what "8CH_OUT" means here, but this is the *only* `I2S_*` clock, so it must be right?
// i think this feeds all the i2s clocks (via mux)
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
// assigned-clocks = <&cru SCLK_I2S0_8CH>; //< TODO
// assigned-clock-rates = <11289599>; //< TODO
// XXX: this differs from megi's kernel (which declares in3 as differential).
// the schematics show `IN2P` / `IN2N` as being differential inputs though, with no mention of "in3"
// realtek,in2-differential; //< IN2 = Headset Microphone
// realtek,in3-differential;
// megi has lout-differential, but schematic shows LOUT{R,L} => 4G_IN_{R,L} i.e. stereo.
// sounds like the *modem* misconfigures its end to be differential, though
// realtek,lout-differential;
// codec has ldo1-en connected to 1.8V via pull-up, i.e. permanently enabled, no GPIO?
// realtek,ldo1-en-gpios = VCCA1V8_CODEC;
// PDM_SDI1_MIC -> IN1P/DMIC1_DAT
realtek,dmic1-data-pin = <1>;
// realtek,dmic2-data-pin = <0>; //< presumed default
// [RK3399]GPIO4_D4_d -> HP_DET_H -> HP_DET
// i think jack detection is handled by the SoC, not by the codec chip.
// it appears that HP_DET is pulled to 3V0 when jack is unplugged,
// and pulled to HPO_L when the jack is plugged.
// realtek,jack-detect-source = <>;
//
//`jack-detect-source`:
// - 0: Jack Detect function is not used
// - 1: Use GPIO1 for jack-detect
// - 2: Use JD1_IN4P for jack-detect
// - 3: Use JD2_IN4N for jack-detect
// - 4: Use GPIO2 for jack-detect
// - 5: Use GPIO3 for jack-detect
// - 6: Use GPIO4 for jack-detect
// related: `realtek,jack-detect-not-inverted` (boolean property)
// realtek,jack-detect-source = <>;
// see: <https://www.kernel.org/doc/html/v6.11/sound/soc/dai.html>
// DAI = Digital Audio Interface, in this case I2S, a 4-wire protocol with TX, RX, BCLK, LRCLK.
// i think there's only one DAI on the board (the i2s DAI), and this is telling the driver the index of that DAI?
#sound-dai-cells = <0>;
// TODO: i think all of these can be removed? (they're specific to *megi's* rt5640 driver, and not mainline?)
// assigned-clocks = <&cru SCLK_I2S0_8CH>;
// assigned-clock-rates = <11289599>; // 44100 * 256
// // rt5645 describes avdd-supply, cpvdd-supply, but rt5640 does not.
// // <Documentation/devicetree/bindings/sound/realtek,rt5645.yaml>
// avdd-supply = <&vcca3v0_codec>;
// cpvdd-supply = <&vcca3v0_codec>;
// spkvdd-supply = <&vcc5v0_sys>;
// dbvdd-supply = <&vcca1v8_codec>;
};
};
// defined (as disabled) in rk3399-base.dtsi:
// - i2s0: i2s@ff880000
// compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s"
&i2s0 {
rockchip,playback-channels = <2>;
// builtin mic on IN1, headphone mic on IN2
rockchip,capture-channels = <2>;
// i2s0_2ch_bus is [RK3399]PD0,PD1,PD2,PD3,PD7,PA0
// maps to I2S0_SCLK,I2S0_LRCK_RX,I2S0_LRCK_TX,I2S0_SDI0,I2S0_SDO0,I2S_CLK
// 8ch_bus adds PD4,PD5,PD6
// maps to NC,NC,TP8
// pinctrl-0 = <&i2s0_2ch_bus>;
// upstream sets this to the following:
// pinctrl-0 = <&i2s0_8ch_bus>;
// pinctrl-1 = <&i2s0_8ch_bus_bclk_off>;
status = "okay";
};
// &pinctrl {
// // sound {
// // hp_det_pin: hp-det-pin {
// // // schematics specify a 100k pull-up to VCC_3V0 (defined as regulator-always-on in rk3399-pinephone-pro.dts)
// // rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
// // };
// // };
// uart2c {
// uart2c_xfer: uart2c-xfer {
// // headphone out interferes with debug UART2.
// // it seems that the amp tries to output negative signals, through the UM4717 MUX.
// // that MUX chooses between UART and audio, to route to the headphone jack.
// // unfortunately it's not designed to handle below-ground signals.
// // long-term fix is to mix a DC offset into the amp output.
// // until then, pull RX to *ground* instead of supply, so that it's less affected by (apparent) shorting with the HPOL channel.
// // or even just leave it without any pull resistor -- so far that seems to be pretty stable?
// // note that this only fixes the spurious UART/spurious SYSRQ errors,
// // it does not address the distortion likely caused by this.
// rockchip,pins =
// <4 RK_PC3 1 &pcfg_pull_none>, // UART2DBG_RX
// <4 RK_PC4 1 &pcfg_pull_none>; // UART2DBG_TX
// };
// };
// };
// TODO: what are `io_domains`?

View File

@@ -169,6 +169,9 @@
};
speaker_amp: audio-amplifier {
// vcc5v0_sys is supplied by the modem;
// speaker amplifier is therefore unpowered if modem is off
VCC-supply = <&vcc5v0_sys>;
compatible = "simple-audio-amplifier";
pinctrl-names = "default";
pinctrl-0 = <&spk_en>;

View File

@@ -104,7 +104,7 @@ in
# docs (pinephone specific; tow-boot instead of u-boot but close enough): <https://github.com/Tow-Boot/Tow-Boot/tree/development/boards/pine64-pinephoneA64>
# we need space in the GPT header to place u-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate
sane.image.extraGPTPadding = 16 * 1024 * 1024;
sane.image.extraGPTPadding = 16 * 1024 * 1024 - 34 * 512;
sane.image.firstPartGap = 0;
sane.image.installBootloader = ''
dd if=${pkgs.u-boot-pinephone}/u-boot-sunxi-with-spl.bin of=$out bs=1024 seek=8 conv=notrunc

View File

@@ -7,6 +7,18 @@ in
sane.hal.rpi-400.enable = lib.mkEnableOption "Raspberry Pi 400 hardware support";
};
config = lib.mkIf cfg.enable {
sane.image.extraBootFiles = [ pkgs.bootpart-u-boot-rpi-aarch64 ];
sane.image.extraBootFiles = [
# rpi bootrom -> edk2 -> systemd-boot
# edk2 exists here to provide the base UEFI environment which systemd-boot expects
pkgs.bootpart-edk2-rpi
];
#v used by systemd-boot
hardware.deviceTree.name = "broadcom/bcm2711-rpi-400.dtb";
# XXX(2025-08-31): stock kernel boots to initrd, but appears (?) to fail to mount root:
# mmc0: invalid bus width
# mmc0: error -22 whilst initialising SD card
# linux_rpi4 seems to do the same...
# boot.kernelPackages = pkgs.linuxKernel.packages.linux_rpi4;
};
}

View File

@@ -9,26 +9,26 @@ in
};
};
config = lib.mkIf cfg.enable {
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
"usb_storage" # rpi needed this to boot from usb storage, i think.
"nvme" # to boot from nvme devices
# efi_pstore evivars
# boot.initrd.availableKernelModules = [
# "xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
# "usb_storage" # rpi needed this to boot from usb storage, i think.
# "nvme" # to boot from nvme devices
# # efi_pstore evivars
# added (speculatively) 2024/05/21; these were implicitly being added by nixos/modules/system/boot/kernel.nix
# i've copied not all of them, but most
"mmc_block"
"dm_mod"
# USB keyboards
"uhci_hcd" "ehci_hcd" "ehci_pci" "ohci_hcd" "ohci_pci" "xhci_hcd" "xhci_pci" "usbhid" "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat" "hid_logitech_hidpp" "hid_logitech_dj" "hid_microsoft" "hid_cherry" "hid_corsair"
# x86 keyboard stuff
"pcips2" "atkbd" "i8042"
# stage-2 init needs rtc?
"rtc_cmos"
];
# # added (speculatively) 2024/05/21; these were implicitly being added by nixos/modules/system/boot/kernel.nix
# # i've copied not all of them, but most
# "mmc_block"
# "dm_mod"
# # USB keyboards
# "uhci_hcd" "ehci_hcd" "ehci_pci" "ohci_hcd" "ohci_pci" "xhci_hcd" "xhci_pci" "usbhid" "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat" "hid_logitech_hidpp" "hid_logitech_dj" "hid_microsoft" "hid_cherry" "hid_corsair"
# # x86 keyboard stuff
# "pcips2" "atkbd" "i8042"
# # stage-2 init needs rtc?
# "rtc_cmos"
# ];
hardware.cpu.amd.updateMicrocode = true; # desko
hardware.cpu.intel.updateMicrocode = true; # lappy
hardware.cpu.intel.updateMicrocode = true; # flowy, lappy
boot.extraModprobeConfig = ''
# allow nested virtualization. XXX(2025-06-24): required for my work (?)
@@ -37,7 +37,5 @@ in
options kvm_amd nested=1
options kvm_intel nested=1
'';
sane.image.extraBootFiles = [ pkgs.bootpart-systemd-boot ];
};
}

View File

@@ -280,8 +280,11 @@ in
bootFsImg
nixFsImg
];
firstPartGap = cfg.firstPartGap;
sectorSize = cfg.sectorSize;
inherit (cfg)
firstPartGap
sectorSize
extraGPTPadding
;
passthru = {
inherit bootFsImg nixFsImg;
};
@@ -307,8 +310,9 @@ in
mkdir -p $out
# 34 is the base GPT header size, as added to -p by cgpt.
# more precisely: PMBR (1 block) + Primary GPT header (1 block) + Primary GPT Table (32 blocks)
gptSize=$((34*512))
part0Start=$(( $gptSize + $firstPartGap ))
part0Start=$(( $extraGPTPadding + $gptSize + $firstPartGap ))
(
# solve for the size of the disk image
@@ -326,11 +330,11 @@ in
truncate -s $totalSize $out/disk.img
# Zeroes the GPT
cgpt create -z $out/disk.img
# Create the GPT with space if desired
cgpt create -p 0 $out/disk.img
( set -x ; cgpt create -z $out/disk.img )
# Create the GPT, optionally with some extra padding between the primary GPT header and the primary GPT table
( set -x ; cgpt create -p $(( $extraGPTPadding / $sectorSize )) $out/disk.img )
# Add the PMBR
cgpt boot -p $out/disk.img
( set -x ; cgpt boot -p $out/disk.img )
)
(
@@ -376,9 +380,10 @@ in
'' else ''
cp ${img}/disk.img $out
chmod +w $out
(
set -x
${cfg.installBootloader}
set +x
)
chmod -w $out
''
);
@@ -390,13 +395,15 @@ in
'')
]
++
lib.optionals config.boot.loader.systemd-boot.enable [
lib.optionals config.boot.loader.systemd-boot.enable ([
pkgs.bootpart-systemd-boot
# it'd be cool to use `config.system.build.installBootLoader` to install both the bootloader config AND the bootloader itself,
# but the combination of custom nixpkgs logic + systemd's sanity checking makes it near impossible to use
# outside a live system.
# so manually generate a bootloader entry:
(pkgs.runCommandLocal "populate-systemd-boot" {} ''
toplevel=${config.system.build.toplevel}
dtbpath=${if config.hardware.deviceTree.name != null then config.hardware.deviceTree.name else ""}
kernel_params=$(cat "$toplevel/kernel-params")
kernel=$(readlink "$toplevel/kernel")
@@ -411,14 +418,25 @@ in
efi_initrd="/EFI/nixos/$initrd_name.efi"
install -Dm644 "$initrd" "$out/$efi_initrd"
efi_dtb=
if [ -n "$dtbpath" ]; then
dtbs=$(readlink "$toplevel/dtbs")
dtbs_name="''${dtbs/\/nix\/store\//}"
dtbs_name="''${dtbs_name/\//-}"
# nixos-generated devicetree path is relative to /boot instead of being fully qualified, for some reason.
efi_dtb="EFI/nixos/$dtbs_name-$(basename $dtbpath).efi"
install -Dm644 "$dtbs/$dtbpath" "$out/$efi_dtb"
fi
mkdir -p $out/loader/entries
cat > $out/loader/entries/nixos-generation-0.conf <<EOF
title NixOS
sort-key nixos
version Generation 0 NixOS
linux $efi_kernel
initrd $initrd
initrd $efi_initrd
options init=$toplevel/init $kernel_params
''${efi_dtb:+devicetree $efi_dtb}
EOF
cat > $out/loader/loader.conf <<EOF
timeout 5
@@ -426,7 +444,7 @@ in
console-mode keep
EOF
'')
]
])
;
};
}

View File

@@ -1,39 +1,6 @@
# outstanding cross-compilation PRs/issues:
# - all: <https://github.com/NixOS/nixpkgs/labels/6.topic%3A%20cross-compilation>
# - qtsvg mixed deps: <https://github.com/NixOS/nixpkgs/issues/269756>
# - big Qt fix: <https://github.com/NixOS/nixpkgs/pull/267311>
#
# outstanding issues:
# - 2023/10/10: build python3 is pulled in by many things
# - nix why-depends --all /nix/store/8g3kd2jxifq10726p6317kh8srkdalf5-nixos-system-moby-23.11.20231011.dirty /nix/store/pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12/bin/python3.10
# - gstreamer-vaapi -> gstreamer-dev -> glib-dev
# - portfolio -> {glib,cairo,pygobject}-dev
# - komikku -> python3.10-brotlicffi -> python3.10-cffi
# - many others. python3.10-cffi seems to be the offender which infects 70% of consumers though
# - 2023/10/11: build ruby is pulled in by `neovim`:
# - nix why-depends --all /nix/store/rhli8vhscv93ikb43639c2ysy3a6dmzp-nixos-system-moby-23.11.20231011.30c7fd8 /nix/store/5xbwwbyjmc1xvjzhghk6r89rn4ylidv8-ruby-3.1.4
# - 2023/12/19: rustPlatform.cargoSetupHook outside of `buildRustPackage` or python packages is a mess
# - it doesn't populate `.cargo/config` with valid cross-compilation config
# - something to do with the way it's spliced: `nativeBuildInputs = [ rustPlatform.cargoSetupHook.__spliced.hostHost ]` (or hostTarget) WORKS
# - see <https://github.com/NixOS/nixpkgs/pull/260068> -- it's probably wrong.
# - WIP fix in `pr-cross-cargo`/`pr-cross-cargo2` nixpkgs branch.
# - sanity check by building `pkgsCross.aarch64-multiplatform.rav1e`, and the `fd` program mentioned in PR 260068
# - `pkgsCross.musl64.fd`
# - `pkgsStatic.fd`
# - this is way too tricky to enable cross compilation without breaking the musl stuff.
# - i lost a whole day trying to get it to work: don't do it!
#
# partially fixed:
# - 2023/10/11: build coreutils pulled in by rpm 4.18.1, but NOT by 4.19.0
# - nix why-depends --all /nix/store/gjwd2x507x7gjycl5q0nydd39d3nkwc5-dtrx-8.5.3-aarch64-unknown-linux-gnu /nix/store/y9gr7abwxvzcpg5g73vhnx1fpssr5frr-coreutils-9.3
#
# outstanding issues for software i don't have deployed:
# - gdk-pixbuf doesn't generate `gdk-pixbuf-thumbnailer` on cross
# - been this way since 2018: <https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/merge_requests/20>
# - as authored upstream, thumbnailer depends on loader.cache, and neither are built during cross compilation.
# - nixos manually builds loader.cache in postInstall (via emulator).
# - even though we have loader.cache, ordering means that thumbnailer still can't be built.
# - solution is probably to integrate meson's cross_file stuff, and pushing all this emulation upstream.
# tracking:
# - all cross compilation PRs: <https://github.com/NixOS/nixpkgs/labels/6.topic%3A%20cross-compilation>
# - potential idiom to fix cross cargo-inside-meson: <https://github.com/NixOS/nixpkgs/pull/434878>
final: prev:
let
@@ -85,63 +52,63 @@ let
typelibPath = pkgs: lib.concatStringsSep ":" (builtins.map (p: "${lib.getLib p}/lib/girepository-1.0") pkgs);
# `cargo` which adds the correct env vars and `--target` flag when invoked from meson build scripts
crossCargo = let
inherit (final.pkgsBuildHost) cargo;
inherit (final.rust.envVars) setEnv rustHostPlatformSpec;
in (final.pkgsBuildBuild.writeShellScriptBin "cargo" ''
targetDir=target
isFlavored=
outDir=
profile=
# crossCargo = let
# inherit (final.pkgsBuildHost) cargo;
# inherit (final.rust.envVars) setEnv rustHostPlatformSpec;
# in (final.pkgsBuildBuild.writeShellScriptBin "cargo" ''
# targetDir=target
# isFlavored=
# outDir=
# profile=
cargoArgs=("$@")
nextIsOutDir=
nextIsProfile=
nextIsTargetDir=
for arg in "''${cargoArgs[@]}"; do
if [[ -n "$nextIsOutDir" ]]; then
nextIsOutDir=
outDir="$arg"
elif [[ -n "$nextIsProfile" ]]; then
nextIsProfile=
profile="$arg"
elif [[ -n "$nextIsTargetDir" ]]; then
nextIsTargetDir=
targetDir="$arg"
elif [[ "$arg" = "build" ]]; then
isFlavored=1
elif [[ "$arg" = "--out-dir" ]]; then
nextIsOutDir=1
elif [[ "$arg" = "--profile" ]]; then
nextIsProfile=1
elif [[ "$arg" = "--release" ]]; then
profile=release
elif [[ "$arg" = "--target-dir" ]]; then
nextIsTargetDir=1
fi
done
# cargoArgs=("$@")
# nextIsOutDir=
# nextIsProfile=
# nextIsTargetDir=
# for arg in "''${cargoArgs[@]}"; do
# if [[ -n "$nextIsOutDir" ]]; then
# nextIsOutDir=
# outDir="$arg"
# elif [[ -n "$nextIsProfile" ]]; then
# nextIsProfile=
# profile="$arg"
# elif [[ -n "$nextIsTargetDir" ]]; then
# nextIsTargetDir=
# targetDir="$arg"
# elif [[ "$arg" = "build" ]]; then
# isFlavored=1
# elif [[ "$arg" = "--out-dir" ]]; then
# nextIsOutDir=1
# elif [[ "$arg" = "--profile" ]]; then
# nextIsProfile=1
# elif [[ "$arg" = "--release" ]]; then
# profile=release
# elif [[ "$arg" = "--target-dir" ]]; then
# nextIsTargetDir=1
# fi
# done
extraFlags=()
# extraFlags=()
# not all subcommands support flavored arguments like `--target`
if [ -n "$isFlavored" ]; then
# pass the target triple to cargo so it will cross compile
# and fix so it places outputs in the same directory as non-cross, see: <https://doc.rust-lang.org/cargo/guide/build-cache.html>
extraFlags+=(
--target "${rustHostPlatformSpec}"
-Z unstable-options
)
if [ -z "$outDir" ]; then
extraFlags+=(
--out-dir "$targetDir"/''${profile:-debug}
)
fi
fi
# # not all subcommands support flavored arguments like `--target`
# if [ -n "$isFlavored" ]; then
# # pass the target triple to cargo so it will cross compile
# # and fix so it places outputs in the same directory as non-cross, see: <https://doc.rust-lang.org/cargo/guide/build-cache.html>
# extraFlags+=(
# --target "${rustHostPlatformSpec}"
# -Z unstable-options
# )
# if [ -z "$outDir" ]; then
# extraFlags+=(
# --out-dir "$targetDir"/''${profile:-debug}
# )
# fi
# fi
exec ${setEnv} "${lib.getExe cargo}" "$@" "''${extraFlags[@]}"
'').overrideAttrs {
inherit (cargo) meta;
};
# exec ${setEnv} "${lib.getExe cargo}" "$@" "''${extraFlags[@]}"
# '').overrideAttrs {
# inherit (cargo) meta;
# };
in with final; {
# binutils = prev.binutils.override {
# # fix that resulting binary files would specify build #!sh as their interpreter.
@@ -153,7 +120,7 @@ in with final; {
# };
# 2025/07/27: upstreaming is unblocked, but a cleaner solution than this doesn't seem to exist yet
# 2025/08/31: upstreaming is unblocked, but a cleaner solution than this doesn't seem to exist yet
confy = prev.confy.overrideAttrs (upstream: {
# meson's `python.find_installation` method somehow just doesn't support cross compilation.
# - <https://mesonbuild.com/Python-module.html#find_installation>
@@ -171,10 +138,10 @@ in with final; {
'';
});
# 2025/07/27: upstreaming is unblocked
delfin = prev.delfin.override {
cargo = crossCargo;
};
# 2025/08/26: upstreaming is unblocked, on desko branch `pr-delfin-cross`
# delfin = prev.delfin.override {
# cargo = crossCargo;
# };
# 2025/07/27: upstreaming is unblocked
# dtrx = prev.dtrx.override {
@@ -185,18 +152,18 @@ in with final; {
# binutils = binutils-unwrapped;
# };
# 2025/07/27: upstreaming is unblocked
# envelope = prev.envelope.override {
# cargo = crossCargo;
# };
# 2025/08/31: upstreaming is blocked on mailutils -> gss -> shishi
# emacs = prev.emacs.override {
# nativeComp = false; # will be renamed to `withNativeCompilation` in future
# # future: we can specify 'action-if-cross-compiling' to actually invoke the test programs:
# # <https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Runtime.html>
# };
envelope = prev.envelope.override {
cargo = crossCargo; #< fixes openssl not being able to find its library
};
# 2025/07/27: upstreaming is unblocked
# 2025/08/31: upstreaming is unblocked
# firejail = prev.firejail.overrideAttrs (upstream: {
# # firejail executes its build outputs to produce the default filter list.
# # i think we *could* copy the default filters from pkgsBuildBuild, but that doesn't seem future proof
@@ -210,7 +177,7 @@ in with final; {
# '');
# });
# 2025/07/27: upstreaming is unblocked
# 2025/08/31: upstreaming is unblocked
# flare-signal = prev.flare-signal.overrideAttrs (upstream: {
# env = let
# inherit buildPackages stdenv rust;
@@ -232,21 +199,16 @@ in with final; {
# };
# });
# 2025/07/27: upstreaming is blocked by glycin-loaders
fractal = prev.fractal.override {
cargo = crossCargo;
};
# 2025/07/27: upstreaming is unblocked
glycin-loaders = prev.glycin-loaders.override {
cargo = crossCargo;
};
# 2025/08/26: upstreaming is unblocked, out for PR: <https://github.com/NixOS/nixpkgs/pull/437038>
# fractal = prev.fractal.override {
# cargo = crossCargo;
# };
# 2025/07/27: upstreaming is blocked on gnome-shell
# fixes: "gdbus-codegen not found or executable"
# gnome-session = mvToNativeInputs [ glib ] super.gnome-session;
# 2025/07/27: upstreaming is blocked on ibus, evolution-data-server -> gnome-online-accounts -> gvfs -> ...
# 2025/08/31: upstreaming is blocked on evolution-data-server -> gnome-online-accounts -> gvfs -> ... -> ruby
# gnome-shell = super.gnome-shell.overrideAttrs (orig: {
# # fixes "meson.build:128:0: ERROR: Program 'gjs' not found or not executable"
# # does not fix "_giscanner.cpython-310-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory" (python import failure)
@@ -271,11 +233,6 @@ in with final; {
# ];
# });
# 2025/07/27: upstreaming is unblocked
gnome-user-share = prev.gnome-user-share.override {
cargo = crossCargo;
};
# 2025/07/27: upstreaming is unblocked
# # gnustep is going to need a *lot* of work/domain-specific knowledge to truly cross-compile,
# gnustep-base = prev.gnustep-base.overrideAttrs (upstream: {
@@ -331,14 +288,7 @@ in with final; {
# nativeBuildInputs = lib.remove [ qt6.wrapQtAppsHook ] upstream.nativeBuildInputs;
# });
# 2025/07/27: upstreaming is unblocked -- but is this necessary?
# koreader = prev.koreader.overrideAttrs (upstream: {
# nativeBuildInputs = upstream.nativeBuildInputs ++ [
# autoPatchelfHook
# ];
# });
lemoa = prev.lemoa.override { cargo = crossCargo; };
# lemoa = prev.lemoa.override { cargo = crossCargo; };
# libsForQt5 = prev.libsForQt5.overrideScope (self: super: {
# # 2025/07/27: upstreaming is blocked on qtsvg
@@ -354,11 +304,6 @@ in with final; {
# callPackage = self.newScope { inherit (self) qtCompatVersion qtModule srcs; inherit stdenv; };
# });
# 2025/07/27: upstreaming blocked on glycin-loaders
loupe = prev.loupe.override {
cargo = crossCargo;
};
# 2024/11/19: upstreaming is unblocked
mepo = (prev.mepo.override {
# nixpkgs mepo correctly puts `zig_0_13.hook` in nativeBuildInputs,
@@ -397,46 +342,6 @@ in with final; {
# 2025/07/27: upstreaming is unblocked by deps; but turns out to not be this simple
# ncftp = addNativeInputs [ bintools ] prev.ncftp;
# 2025/07/27: upstreaming is unblocked
newsflash = (prev.newsflash.override {
cargo = crossCargo;
}).overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + ''
rm build.rs
export OUT_DIR=$(pwd)
# from build.rs:
glib-compile-resources --sourcedir=data/resources --target=icons.gresource data/resources/icons.gresource.xml
glib-compile-resources --sourcedir=data/resources --target=styles.gresource data/resources/styles.gresource.xml
substitute data/io.gitlab.news_flash.NewsFlash.appdata.xml.in.in \
data/resources/io.gitlab.news_flash.NewsFlash.appdata.xml \
--replace-fail '@appid@' 'io.gitlab.news_flash.NewsFlash'
glib-compile-resources --sourcedir=data/resources --target=appdata.gresource data/resources/appdata.gresource.xml
'';
env = let
ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
rustBuildPlatform = stdenv.buildPlatform.rust.rustcTarget;
rustTargetPlatform = stdenv.hostPlatform.rust.rustcTarget;
in (upstream.env or {}) // {
# taken from <pkgs/build-support/rust/hooks/default.nix>
# fixes "cargo:warning=aarch64-unknown-linux-gnu-gcc: error: unrecognized command-line option -m64"
# XXX: these aren't necessarily valid environment variables: the referenced nix file is more clever to get them to work.
"CC_${rustBuildPlatform}" = "${ccForBuild}";
"CXX_${rustBuildPlatform}" = "${cxxForBuild}";
"CC_${rustTargetPlatform}" = "${ccForHost}";
"CXX_${rustTargetPlatform}" = "${cxxForHost}";
# fails to fix "Failed to find OpenSSL development headers."
# OPENSSL_NO_VENDOR = 1;
# OPENSSL_LIB_DIR = "${lib.getLib openssl}/lib";
# OPENSSL_DIR = "${lib.getDev openssl}";
};
});
# fixes "properties/gresource.xml: Permission denied"
# - by providing glib-compile-resources
# 2025/07/27: upstreaming is blocked on gst-plugins-good, qtkeychain, qtmultimedia, qtquick3d, qt-jdenticon
@@ -506,7 +411,7 @@ in with final; {
# # buildInputs = lib.remove gnupg upstream.buildInputs;
# });
# 2025/07/27: upstreaming is unblocked, but most of this belongs in _oils_ repo
# 2025/08/31: upstreaming is unblocked, but most of this belongs in _oils_ repo
oils-for-unix = prev.oils-for-unix.overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + ''
substituteInPlace _build/oils.sh \
@@ -530,10 +435,10 @@ in with final; {
];
});
# 2025/07/27: upstreaming is blocked on gnome-user-share, nautilus
papers = prev.papers.override {
cargo = crossCargo;
};
# 2025/08/31: upstreaming is unblocked; out for review: <https://github.com/NixOS/nixpkgs/pull/437704>
# papers = prev.papers.override {
# cargo = crossCargo;
# };
# 2025/07/27: upstreaming is blocked on gnome-session (itself blocked on gnome-shell)
# phosh = prev.phosh.overrideAttrs (upstream: {
@@ -561,11 +466,6 @@ in with final; {
# ];
# } prev.phosh-mobile-settings;
# 2025/07/27: upstreaming is unblocked
pwvucontrol = prev.pwvucontrol.override {
cargo = crossCargo;
};
# pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
# (pyself: pysuper: {
# # 2025/07/23: upstreaming is unblocked, but solution is untested.
@@ -728,16 +628,16 @@ in with final; {
# # '';
# });
# 2025/07/27: upstreaming is blocked on glycin-loaders
snapshot = prev.snapshot.override {
# fixes "error: linker `cc` not found"
cargo = crossCargo;
};
# 2025/08/26: upstreaming is unblocked; implemented on desko `pr-snapshot-cross` branch
# snapshot = prev.snapshot.override {
# # fixes "error: linker `cc` not found"
# cargo = crossCargo;
# };
# 2025/07/27: upstreaming is unblocked
spot = prev.spot.override {
cargo = crossCargo;
};
# 2025/08/26: upstreaming is unblocked; patched on desko branch `pr-spot-cross`
# spot = prev.spot.override {
# cargo = crossCargo;
# };
# 2025/07/27: upstreaming is unblocked
# squeekboard = prev.squeekboard.overrideAttrs (upstream: {
@@ -783,7 +683,7 @@ in with final; {
# ];
# });
# 2025/07/27: upstreaming blocked on gvfs -> udisks -> libblockdev -> {thin-provisioning-tools,libndctl -> ... -> ruby}
# 2025/08/31: upstreaming blocked on gvfs -> udisks -> libblockdev -> {thin-provisioning-tools,libndctl -> ... -> ruby}
swaynotificationcenter = mvToNativeInputs [ buildPackages.wayland-scanner ] prev.swaynotificationcenter;
# 2025/07/27: upstreaming is unblocked
@@ -834,10 +734,10 @@ in with final; {
# });
# };
# 2025/05/01: upstreaming is unblocked
video-trimmer = prev.video-trimmer.override {
cargo = crossCargo;
};
# 2025/08/26: upstreaming is unblocked; implemented on desko branch `pr-video-trimmer-cross`
# video-trimmer = prev.video-trimmer.override {
# cargo = crossCargo;
# };
# 2025/01/13: upstreaming is blocked on arrow-cpp, python-pyarrow, python-contourpy, python-matplotlib, python-h5py, python-pandas, google-cloud-cpp
# visidata = prev.visidata.override {

View File

@@ -23,7 +23,7 @@ in
# DISABLE HDCP BLOB in pinephone pro.
# this is used by u-boot; requires redeploying the bootloader (the SPL, specifically).
# i can see that nixpkgs does process this option, but the hash of bl31.elf doesn't actually change
arm-trusted-firmware = super.arm-trusted-firmware.override {
buildArmTrustedFirmware = super.buildArmTrustedFirmware.override {
unfreeIncludeHDCPBlob = false;
};

View File

@@ -0,0 +1,14 @@
# sourced, with modifications, from <https://github.com/pftf/RPi4/blob/master/config.txt>
arm_64bit=1
# arm_boost=1
# N.B.: `enable_uart=1` is required for systemd-boot's `timeout` (i.e. auto-boot default entry) feature
enable_uart=1
# uart_2ndstage=1
enable_gic=1
armstub=RPI_EFI.fd
# disable_commandline_tags=1
# disable_overscan=1
# device_tree_address=0x3e0000
# device_tree_end=0x400000
# dtoverlay=miniuart-bt
# dtoverlay=upstream-pi4

View File

@@ -0,0 +1,30 @@
{
edk2-rpi4,
raspberrypifw,
runCommandLocal,
}:
runCommandLocal "bootpart-edk2-rpi" {
meta = {
description = ''
unmanaged files to place in /boot on a Raspberry Pi 400 system.
these files are not enough on their own to boot a kernel,
but only to boot an EFI application.
best paired with systemd-boot (via `bootpart-systemd-boot`), or perhaps u-boot (untested).
'';
platforms = [
"aarch64-linux"
];
};
} ''
install -Dm644 ${edk2-rpi4}/RPI_EFI.fd $out/RPI_EFI.fd
install -Dm644 ${./config.txt} $out/config.txt
install -Dm644 ${raspberrypifw}/share/raspberrypi/boot/fixup4.dat $out/fixup4.dat
install -Dm644 ${raspberrypifw}/share/raspberrypi/boot/start4.elf $out/start4.elf
# N.B.: there are weird incompatibilities between raspberrypifw (start4.elf) and edk2.
# it seems that if the two binaries are on different versions, then the dtb resolves some discrepencies:
# - allows systemd-boot to autoboot after 5s (else, it lacks its countdown ... uart problems?)
# but generally, omitting this .dtb probably won't totally break the boot.
install -Dm644 ${raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-400.dtb $out/bcm2711-rpi-400.dtb
# install -Dm644 ${raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-4-b.dtb $out/bcm2711-rpi-4-b.dtb
# install -Dm644 ${raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-cm4.dtb $out/bcm2711-rpi-cm4.dtb
''

View File

@@ -0,0 +1,133 @@
# WHEN UPDATING:
# - check the tag in <repo:nixos/nixpkgs:pkgs/by-name/ed/edk2/package.nix>
# e.g. edk2-stable202505
# - figure the date, via `cd edk2 && git show edk2-stable202505`
# - pin the other repos to the closest commit
# consider updating to the known-good commits from <https://github.com/pftf/RPi4>
{
acpica-tools,
buildArmTrustedFirmware,
edk2,
fetchFromGitHub,
lib,
}:
let
armTrustedFirmwareRpi4 = buildArmTrustedFirmware rec {
# see: <repo:tianocore/edk2-non-osi:Platform/RaspberryPi/RPi4/TrustedFirmware/Readme.md>
# says they build it with:
# > make PLAT=rpi4 RPI3_PRELOADED_DTB_BASE=0x1F0000 PRELOADED_BL33_BASE=0x20000 SUPPORT_VFP=1 SMC_PCI_SUPPORT=1 DEBUG=0 all
# see also <repo:ARM-software/arm-trusted-firmware:plat/rpi/rpi4/platform.mk>
platform = "rpi4";
extraMeta.platforms = [ "aarch64-linux" ];
filesToInstall = [ "build/${platform}/release/bl31.bin" ];
# platformCanUseHDCPBlob = true;
extraMakeFlags = [
# these are the flags which tianocore, pftf build with.
# RPI3_PRELOADED_DTB_BASE: "Auxiliary build option needed when using `RPI3_DIRECT_LINUX_BOOT=1`. This option allows to specify the location of a DTB in memory."
# "RPI3_PRELOADED_DTB_BASE=0x1F0000"
# PRELOADED_BL33_BASE: "Used to specify the fixed address of a BL33 binary that has been preloaded by earlier boot stages (VPU). Useful for bundling BL31 and BL33 in the same `armstub` image (e.g. TF-A + EDK2)."
# IOW: ATF and EDK2 need to agree on the value of PRELOADED_BL33_BASE!
"PRELOADED_BL33_BASE=0x20000"
# SUPPORT_VFP: "allow Vector Floating Point operations in EL3".
# where EL3 is the part of TFA which stays resident in the CPU;
# ATF lowers to EL2 before passing control to the next boot stage;
# i'd guess this is an (optional) optimization of some sort?
# "SUPPORT_VFP=1"
# SMC_PCI_SUPPORT: ATF rpi4/platform.mk defaults this to 0 and says "SMCCC PCI support (should be enabled for ACPI builds)".
# "SMC_PCI_SUPPORT=1"
];
};
edk2-platforms = fetchFromGitHub {
owner = "tianocore";
repo = "edk2-platforms";
name = "edk2-platforms";
rev = "6153891ee3b4e80e0340236f0eec0228746bacc0"; # 2025-05-25
hash = "sha256-EuM6MXc39IJB8QAkW/DFagz2wLI1EYftvayP45oHz0I=";
};
# edk2-src = fetchFromGitHub {
# owner = "tianocore";
# repo = "edk2";
# name = "edk2";
# # fetchSubmodules = true;
# rev = "060bb0e5a75946729defa4824fa899cf4cc0528b";
# # hash = "sha256-gafZ+iyJ0IpGpe3ucPw/Ap/3ZrY3gCNSJEpAqgBAzRY=";
# };
# edk2-non-osi = fetchFromGitHub {
# owner = "tianocore";
# repo = "edk2-non-osi";
# name = "edk2-non-osi";
# rev = "0544808c623bb73252310b1e5ef887caaf08c34b"; # 2024-03-14
# hash = "sha256-09D1p7xHT6rLxgdw7flT3gEWNKqxOhM2Q643t0nw9ww=";
# # rev = "3415f616e08a0d9c7bd264cab674929a7b0f5e33"; # 2025-08-04
# };
in edk2.mkDerivation "Platform/RaspberryPi/RPi4/RPi4.dsc" {
pname = "edk2-rpi4";
inherit (edk2) version;
nativeBuildInputs = [
acpica-tools
];
srcs = [
edk2.src
edk2-platforms
];
sourceRoot = edk2.src.name;
postPatch = ''
# patch out the raspberry pi logo from the boot process, so as to remove dependency
# on separate edk2-non-osi repo (which i would otherwise have to keep in sync)...
# to instead build WITH the raspberry logo, remove these patches and set
# PACKAGES_PATH=$edk2:$edk2-platforms:$edk2-non-osi
#
# N.B.: can either comment out the `LogoDxe.inf` lines, to build with no logo,
# or point them to a different in-tree Logo (e.g. AMD, Intel, or tianocore (i.e. MdeModulePkg)).
substituteInPlace ../edk2-platforms/Platform/RaspberryPi/RPi4/RPi4.fdf \
--replace-fail \
'INF Platform/RaspberryPi/Drivers/LogoDxe/LogoDxe.inf' \
'INF MdeModulePkg/Logo/LogoDxe.inf'
substituteInPlace ../edk2-platforms/Platform/RaspberryPi/RPi4/RPi4.dsc \
--replace-fail \
'Platform/RaspberryPi/Drivers/LogoDxe/LogoDxe.inf' \
'MdeModulePkg/Logo/LogoDxe.inf'
export PACKAGES_PATH=$(pwd):$(pwd)/../edk2-platforms
'';
installPhase = ''
runHook preInstall
install -Dm644 Build/RPi4/RELEASE*/FV/RPI_EFI.fd $out/RPI_EFI.fd
runHook postInstall
'';
buildFlags = [
"-DTFA_BUILD_ARTIFACTS=${armTrustedFirmwareRpi4}" #< or, place bl31.bin at Platform/RaspberryPi/RPi4/TrustedFirmware
# flags taken from <https://github.com/pftf/RPi4/blob/master/.github/workflows/linux_edk2.yml#L63>
# in practice, none seem to be required
# "-DSECURE_BOOT_ENABLE=TRUE"
# "-DINCLUDE_TFTP_COMMAND=TRUE"
# "-DNETWORK_ISCSI_ENABLE=TRUE"
# "-DSMC_PCI_SUPPORT=1"
# "-DNETWORK_TLS_ENABLE=FALSE"
# "-DNETWORK_ALLOW_HTTP_CONNECTIONS=TRUE"
];
# fixes `error: -Wformat-security ignored without -Wformat`
env.NIX_CFLAGS_COMPILE = "-Wformat";
passthru = {
inherit
# edk2-non-osi
edk2-platforms
# edk2-src
armTrustedFirmwareRpi4
;
};
meta = {
maintainers = with lib.maintainers; [
colinsane
];
platforms = [ "aarch64-linux" ];
};
}

View File

@@ -9,9 +9,11 @@
libsoup_3,
meson,
ninja,
nix-update-script,
openssl,
pkg-config,
python3,
rust,
rustPlatform,
rustc,
stdenv,
@@ -19,20 +21,21 @@
wrapGAppsHook4,
}:
stdenv.mkDerivation {
stdenv.mkDerivation (finalAttrs: {
pname = "envelope";
version = "0.1.0-unstable-2024-09-13";
version = "0.1.0-unstable-2025-05-17";
src = fetchFromGitLab {
domain = "gitlab.gnome.org";
owner = "felinira";
repo = "envelope";
rev = "11ce86da13793787a25e48ca23322b33fcf8bf34"; # last commit before libadwaita 1.6
hash = "sha256-EX309RhisBx27TscMsibEvqCSCUSukTgf4Xs1Vws4YY=";
rev = "e2a8a56aa9b68d82486b99790b86322715d2a6db";
hash = "sha256-osVShCaKKoGhxWCjaYcMkOji8e0oETgDaDpCAfHauwQ=";
};
cargoDeps = rustPlatform.importCargoLock {
lockFile = ./Cargo.lock;
cargoDeps = rustPlatform.fetchCargoVendor {
inherit (finalAttrs) pname version src;
hash = "sha256-8pK8cw9nYJmmybYRL+PUCK8FvUUPbyFp7oYYF461KPc=";
};
nativeBuildInputs = [
@@ -58,10 +61,21 @@ stdenv.mkDerivation {
postPatch = ''
patchShebangs --build build-aux/meson-cargo-manifest.py
# versions prior to c3f5ed4f (2024-10-13) didn't embed Cargo.lock
cp ${./Cargo.lock} Cargo.lock
substituteInPlace src/meson.build \
--replace-fail \
"'src' / rust_target / meson.project_name()" \
"'src' / '${stdenv.hostPlatform.rust.cargoShortTarget}' / rust_target / meson.project_name()"
'';
env."CC_${stdenv.buildPlatform.rust.rustcTarget}" = rust.envVars.ccForBuild; #< fixes cross build of sql-macros proc-macro
env.CARGO_BUILD_TARGET = stdenv.hostPlatform.rust.rustcTargetSpec;
env.OPENSSL_NO_VENDOR = true; #< speculative, to use the nixos openssl
env.RUSTC_BOOTSTRAP = 1; #< fixes 'error[E0554]: `#![feature]` may not be used on the stable release channel'
# env.LIBSQLITE3_SYS_USE_PKG_CONFIG = 1; #< TODO: use nixos libsqlite instead of pre-packaged one
passthru.updateScript = nix-update-script { };
meta = with lib; {
description = "a mobile-first email client for the GNOME ecosystem";
homepage = "https://gitlab.gnome.org/felinira/envelope/";
@@ -70,4 +84,4 @@ stdenv.mkDerivation {
platforms = platforms.linux;
mainProgram = "envelope";
};
}
})

View File

@@ -11,13 +11,13 @@
}:
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "euicc-manual";
version = "0-unstable-2025-08-14";
version = "0-unstable-2025-08-30";
# XXX: their gitea downloads are broken, so use fetchgit
src = fetchgit {
url = "https://gitea.osmocom.org/sim-card/euicc-manual";
rev = "b9ca1371f6849ec5724f5374a11bb380b7a762a6";
hash = "sha256-4Bveo+4rpwRjmUrneN7ObJekQ3W2woai8Pe8JWlp9QM=";
rev = "af14e4ca642048367a655994ac31341756429f5d";
hash = "sha256-CXu4yWnCDu8X8gSWe6QsVD9w2zI0SZMOoKkVRi0/eDM=";
};
nativeBuildInputs = [

View File

@@ -33,6 +33,12 @@ stdenv.mkDerivation rec {
hash = "sha256-ALoxT+RLL4omJ7quWDJVdXgevaO8i8q/29FFFudIRV4=";
};
postPatch = ''
substituteInPlace src/meson.build --replace-fail \
"'target' / rust_target / meson.project_name()" \
"'target' / '${stdenv.hostPlatform.rust.cargoShortTarget}' / rust_target / meson.project_name()"
'';
nativeBuildInputs = [
cargo
desktop-file-utils
@@ -49,6 +55,8 @@ stdenv.mkDerivation rec {
openssl
];
env.CARGO_BUILD_TARGET = stdenv.hostPlatform.rust.rustcTargetSpec;
passthru.updateScript = gitUpdater {
rev-prefix = "v";
};

View File

@@ -14,12 +14,12 @@
stdenv.mkDerivation (finalAttrs: {
pname = "lpac";
version = "2.2.1";
version = "2.3.0";
src = fetchFromGitHub {
owner = "estkme-group";
repo = "lpac";
rev = "v${finalAttrs.version}";
hash = "sha256-dxoYuX3dNj4piXQBqU4w1ICeyOGid35c+6ZITQiN6wA=";
hash = "sha256-ALne5sHB6ff7cHAWe0rFwpP/Yz4EhZBiOrgdM2B8+OE=";
};
# options:

View File

@@ -14,8 +14,8 @@
mkNixpkgs ? import ./mkNixpkgs.nix {},
}:
mkNixpkgs {
rev = "6207745fb2fb83330b7193fed31337050b075f40";
sha256 = "sha256-NfKklCRVBW979loK3FIXjYYMO2oGfFx/ozfg37oWRcc=";
version = "unstable-2025-08-15";
rev = "70ec3948a7f996d279bd77c66420027268b98aeb";
sha256 = "sha256-gwYhaTGhEeYlEYTR7Bhewam6wRKrMu3SODZE4f/cg0Y=";
version = "unstable-2025-08-31";
branch = "master";
}

View File

@@ -45,51 +45,52 @@ in
# TODO: enable, once i can tolerate a mass rebuild
# (fetchpatch' {
# # 2025-08-06: merged into staging
# name = "v4l-utils: fix cross-compilation";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/429900";
# hash = "sha256-oH9jTG38mWpjwf/LH3MTCrBm2NC4WTRPki2mUhCc5WQ=";
# })
# (fetchpatch' {
# name = "libpcap: enable dbus, rdma, bluetooth features";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/429225";
# hash = "sha256-cALgj+7eXd3H4WAmW6CIcxWRC3D4PoY2PWNsDxK+G9g=";
# })
# (fetchpatch' {
# # 2025-07-15: merged into staging
# name = "treewide: populate arch and platform for more node packages";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/422938";
# hash = "sha256-lN99K0k9dCUBFXc99XB97cZSVDu5A74pHL40vw9cobY=";
# })
# XXX(2025-07-25): master & staging have diverged that the above patch doesn't apply correctly;
# manually recreate the patches against master:
(fetchpatch' {
name = "nodejs: split destCPU into stdenv.$platform.node";
saneCommit = "1fd1d40033deb51bc74ecf11b401cf2ffde5aae3";
hash = "sha256-LGp9HzUINI5iTQ3UtggUNWS4zaYhakUI3OqM6rPiYr0=";
})
(fetchpatch' {
name = "treewide: replace node platform mapping with stdenv.hostPlatform.node.{arch,platform}";
saneCommit = "57bac5daa19c55a547f60271a7b48c59337ec12f";
hash = "sha256-DBenl7O4KuQ1I6jmB66upufYSUdYHRkqRdqRT9stbys=";
})
(fetchpatch' {
name = "buildNpmPackage: push npm_config_* options into npmHooks.npmConfigHook";
saneCommit = "f84ef10710b6634f5bcc4c7bc4764ecfd6e8dec5";
hash = "sha256-BHwtNvSGaqBRzUj0mP3JqAfygxjiKoX3lh4z9+B4UWk=";
})
(fetchpatch' {
name = "pnpm.configHook: set npm_config_{arch,platform}";
saneCommit = "38d2a3d80502ad63686ca886f4438d2942fbddb6";
hash = "sha256-0grq9Os9XD+voupAQuB48WBptH5oM/qYX5iEdmuVqMQ=";
})
(fetchpatch' {
name = "signal-desktop: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/423089";
# hash = "sha256-609snDT1Ru69ZTWfzu4PnhY0pj3xghPr8w880j7JZ5k=";
hash = "sha256-bVMOanUcYNPf2JbaWS9ga+0jAwuZQSfMKlwtNRp9tYU=";
hash = "sha256-4VEKjZsI7XW+/gbq3fn3bjjciPKtd2IU8SH4CsqqJ6Y=";
})
(fetchpatch' {
name = "fractal: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/437038";
hash = "sha256-B7s2aNVony+G7FW2PaR7FVO7zzWa7SiLONWRGrsXA3A=";
})
(fetchpatch' {
name = "gmobile: set strictDeps, fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/437700";
# saneCommit = "223b327fcc0775212bcc30a0bfb57c90ce5e3251";
hash = "sha256-3zxCtRlliCpaDbJBV4hioQG7ehFvA9Co1JQdGStY1Js=";
})
(fetchpatch' {
# desko nixpkgs branch: `pr-papers-cross`
name = "papers: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/437704";
# saneCommit = "eaed8b1530ce9eb9f674677003866d2d793b90fa";
hash = "sha256-G+2I7FMVN7WJio1ufwRZ0F13X/LViNdH1zfR4qqN46Y=";
})
(fetchpatch' {
# desko nixpkgs branch: `pr-delfin-cross`
name = "delfin: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/437748";
# saneCommit = "b19145967431b49849d7dc5e0657322134297a24";
hash = "sha256-R5hAfUmNsLnNpx26ZFZWqA0dLiYR/4pBMwfJrOBC+l0=";
})
(fetchpatch' {
# desko nixpkgs branch: `pr-snapshot-cross`
name = "snapshot: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/437708";
# saneCommit = "9bf01eef452d46c2990cdc872017f1015892ea7d";
hash = "sha256-nzqbRP9wHyDnwKyaATZ5mSyn68qgRvs4pEtAkhauiMM=";
})
# (fetchpatch' {
@@ -135,12 +136,6 @@ in
# hash = "sha256-UyZaNNp84zKShuo6zu0nfZ2FygHGcmV63Ww4Y4CtCF0=";
# })
# (fetchpatch' {
# name = "rpm: 4.18.1 -> 4.19.0";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/260558";
# hash = "sha256-kwod+6SbUZechzbmu1D4Hlh6pYiPD18wcqetk0OIOrA=";
# })
# (fetchpatch' {
# # XXX: doesn't cleanly apply; fetch `firefox-pmos-mobile` branch from my git instead
# name = "firefox-pmos-mobile: init at -pmos-2.2.0";

View File

@@ -2,8 +2,8 @@
mkNixpkgs ? import ./mkNixpkgs.nix {},
}:
mkNixpkgs {
rev = "c0e9e1afcfdb5fcd0ae7466a20a9c1ced45ce8a1";
sha256 = "sha256-njAuNOzJKhK4lAuabibqWqsziLZVCMQJmDZRm5MYbbQ=";
version = "unstable-2025-08-15";
rev = "b6e3a2d6af4a1b9c25104fcf7a24fa7d702a626d";
sha256 = "sha256-Y2NtoHYeYJydIvBBhAxvuLqP0tB5KsGprLrlgBAHaCI=";
version = "unstable-2025-08-31";
branch = "staging-next";
}

View File

@@ -2,8 +2,8 @@
mkNixpkgs ? import ./mkNixpkgs.nix {},
}:
mkNixpkgs {
rev = "664c1d7072fbafa4c806ac6b22f9a6eee221cfcf";
sha256 = "sha256-Y7DnNNQLKLdQwIwAEyGQPPcqDDLiCZcuJnQ9f/mWigM=";
version = "unstable-2025-08-15";
rev = "8ba2cb563c7bd53a8a6e37d3f9530aa1f3757a38";
sha256 = "sha256-MXmCtJpYNURZSxeU3SEvecw9ln8sv3GZXHM4gskwVz0=";
version = "unstable-2025-08-31";
branch = "staging";
}

View File

@@ -7,8 +7,8 @@ let
src = fetchFromGitHub {
owner = "nix-community";
repo = "nixpkgs-wayland";
rev = "9c452b9ea8e584d5085629e2b76703c94df64b6f";
hash = "sha256-THPRayZls0/4rZSw4R5B7evCbGVr5AN3SQQZSgYpIiA=";
rev = "60f64e8511aeca7cdd967ef42746845c89321ef7";
hash = "sha256-ghByh4Imm2FCMGhTkdyy74DBJIqRgZTDqB77YcnQFSs=";
};
flake = import "${src}/flake.nix";
evaluated = flake.outputs {
@@ -25,7 +25,7 @@ let
in src.overrideAttrs (base: {
# attributes required by update scripts
pname = "nixpkgs-wayland";
version = "0-unstable-2025-08-14";
version = "0-unstable-2025-08-31";
src = src;
# passthru only nixpkgs-wayland's own packages -- not the whole nixpkgs-with-nixpkgs-wayland-as-overlay:

View File

@@ -14,13 +14,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "syshud";
version = "0-unstable-2025-07-26";
version = "0-unstable-2025-08-18";
src = fetchFromGitHub {
owner = "System64fumo";
repo = "syshud";
rev = "d954c124280b71f80930046a11e390a814c1b229";
hash = "sha256-FUPnIUl9x0eZmhls4CmPGg4kZb1MNmKU5BKecFDQdHM=";
rev = "6dbf17bb953342c844517d1b4eb672cbae7a1566";
hash = "sha256-T9tWmgDIcmmRXAeWR7Pfjalkl6xogtuz1qfsSAuQmkg=";
};
postPatch = ''

View File

@@ -6,8 +6,7 @@
armTrustedFirmwareRK3399,
buildUBoot,
}:
(buildUBoot {
buildUBoot {
defconfig = "pinephone-pro-rk3399_defconfig";
filesToInstall = [
"idbloader.img" #< entry point: place it at sector 64 & it'll load whatever's at sector 16384 into RAM and jump to it
@@ -24,7 +23,7 @@
"u-boot-nodtb.bin"
"u-boot.sym"
];
}).overrideAttrs (upstream: {
# default baud rate is 1500000, which is too fast for some USB <-> serial adapters to do
# CONFIG_DM_RNG is needed to seed the kernel, and avoid "KASLR disabled due to lack of seed"
extraConfig = ''
@@ -32,6 +31,13 @@
CONFIG_DM_RNG=y
'';
# XXX: RK3399 ships a blob for HDCP (media copy protection) in the trusted firmware.
# that can be removed with:
# `(arm-trusted-firmware.override { unfreeIncludeHDCPBlob = false; }).armTrustedFirmwareRK3399`, if so desired.
BL31 = "${armTrustedFirmwareRK3399}/bl31.elf";
}
# ).overrideAttrs (upstream: {
# default layout is:
# scriptaddr = 0x00500000
# script_offset_f = 0xffe000
@@ -51,11 +57,4 @@
# --replace-fail ramdisk_addr_r=0x06000000 ramdisk_addr_r=0x0a000000 \
# --replace-fail kernel_comp_addr_r=0x08000000 kernel_comp_addr_r=0x0c000000
# '';
env = (upstream.env or {}) // {
# XXX: RK3399 ships a blob for HDCP (media copy protection) in the trusted firmware.
# that can be removed with:
# `(arm-trusted-firmware.override { unfreeIncludeHDCPBlob = false; }).armTrustedFirmwareRK3399`, if so desired.
BL31 = "${armTrustedFirmwareRK3399}/bl31.elf";
};
})
# })

View File

@@ -6,12 +6,12 @@
}:
stdenvNoCC.mkDerivation {
pname = "uassets";
version = "0-unstable-2025-08-15";
version = "0-unstable-2025-08-31";
src = fetchFromGitHub {
owner = "uBlockOrigin";
repo = "uAssets";
rev = "e1dd6d5aa73d9dc6d7a123ef585ba5d082bb6fa8";
hash = "sha256-rGZWU2OXWjyweyWjST8CgpriEUB1Sa2wd3/FJ1cVMlw=";
rev = "f46c97622c978dbe59a942fc649f0eddb3deeb39";
hash = "sha256-dDtN7WUBbJGbWCSFpVE2NkcFpZXO9RJKJy15Pa18xXE=";
};
dontBuild = true;

View File

@@ -7,12 +7,12 @@
}:
buildDotnetModule rec {
pname = "UVtools";
version = "5.1.7";
version = "5.2.0";
src = fetchFromGitHub {
owner = "sn4k3";
repo = "UVtools";
rev = "v${version}";
hash = "sha256-+3E8Ts+rv72Jq4jLcmyU3KUP7U0k6Ruo5+Dn0hdj+Yg=";
hash = "sha256-4o+F56E80GElRb4DfmOv6mqwQ8+23E0aj/RjGr7Pg8U=";
};
nugetDeps = ./deps.json;

View File

@@ -1,6 +1,6 @@
{ mkVersionedHttpZim }: mkVersionedHttpZim {
owner = "other";
pname = "alpinelinux_en_all_maxi";
version = "2025-07";
hash = "sha256-B99/UhqhKsVqphXRuRFDTD4eIY6/MqkO0pfNKGadbsg=";
version = "2025-08";
hash = "sha256-/MW3BAvEnsWfIZawkRq8qKhaLzPivAByWE9qIEPP4wo=";
}

View File

@@ -1,6 +1,6 @@
{ mkVersionedHttpZim }: mkVersionedHttpZim {
owner = "other";
pname = "archlinux_en_all_maxi";
version = "2025-07";
hash = "sha256-Hz2KpptYh0j5f88AyIpy0JaT+qhAegZHOCdaIz22NHo=";
version = "2025-08";
hash = "sha256-++r0i57yLDEwVFj0fQm96zSW4kRgbtUkyq86c+Lz2FQ=";
}

View File

@@ -1,6 +1,6 @@
{ mkVersionedHttpZim }: mkVersionedHttpZim {
owner = "wikipedia";
pname = "wikipedia_en_all_maxi";
version = "2024-01";
hash = "sha256-GrRFV3TSFhm9fCFxhFOSD3EQnzBAPZJh96NPefh6p4Q=";
version = "2025-08";
hash = "sha256-OqVTmcWvputcJHcZTg0CLAUnYWQIvGRMIiTtMo2mLfs=";
}

View File

@@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:cAS8NgkT6wpTvwdL0EydbEpW4M+r0PTz2/rsRda2ZyeG3jSPKXe9ls+g6S0akOi0HWP870zd3geuMOP6UdfShFaC609GeoUkYIbTLTp66xwlERl8BkBHl/nopli1x7f9bQg3HomovTWBshloYnDT/+IPqU3R8PJk8KEmEs2ClhcjtUMu3AUejIXM1asxO7kTdOGyZ/ykOcr1sMaY50qjle1RtfZTLMipdgxUFuziEM1CisyN4ch1se6kJBxH3HydwOoZb3UxoTly99XlH+qUwfuEjOtBUdXrQAClMv5EiR9znvGwahdEagW4Y2gbOhyFpENgf8nMwK+ocAKCI66zook5RkYkMmQvPh0e2q42GmWnGArmRvO6LEMgYtqPmqDNwJz3GtZjlELbHpSxJ9DtDx06h1gLsV7A3wtkJ24fIgQDKPr1DOtr5TiZ5DnjhXdRakL7+3CWLJcBTKHdZ6bxAwgvwuEXWJmedG3nOgmwitpixjLrGEx0pxNjI6BQuLqthRBc8Bww8kUKwMAEbD9NzvKgmzW4nOy8GSdJ3uPG6dQCXQ1iCvV0E2VZ9Nx9MoCxq5/hMYRS7VMLDlN2xEOR1TRDiaIrGG2LOzJOhsjVtRi+5EUzXYVGL52MnAi+UTF9HRsC8E+M5G5ZAZbnw3J0vRCt+gaBUQ0j6DY9Wl5+Jp/3qVi6Avc9WMR8psTi/pVsIQKOxa4cfsQJ/X14Rb8D+I2OjeE88xBl43sztNYzK3u9oJLZsJ+ZiNQWpnpBSZtjkPcg/zgZPKWZjafCMY+fxT3o0H7h9hO4rnJHZg6TzVayjrCDps5fQAuapzvRPUs5Q80gO1/m3pyg9AnZrIZudhhCGVsrPh8rKjsSiNV1GZkciLmzMUiqLrjBMkaW1N72cua9vm6UqnriMyK5rGgPDw5SWisAXNab0ZRS1nsgSxNSiHsZe+nbwIu89ubgVaz/B2yeOQ1AnBedUZbRxzzaUnjt0xAxByBJunAELyLwMr2zRBwM3VVn4VcPx506Dg/T4V/GgYVAcQdA/OeF0cZidmDdV2XdZgZjH+9Jv5crlh2sRwc+1zskE45Nh/2WW0wA2MZ8RKeUOMGAa6rXbFoxx4YKUJxWgwGzg4hyhdNHdwcImG4/ocpdgcJ2b1aIv5CXCL4kBkMIegfTqKzVmEwu0BqAhiBJ4Z9LD/62mUUcQE7kfD5AmV1Xb4RxJEayXIbeUclasJ8Hg45Aqpz5jlbYebYLo+0bSFPO/fHQdLaEijElq7yET19EkRa3qkI8MIaZQr7BNViQL+wcCgOaGFAprZPXsOz7J4T9RVdhuuXPKpGUXK8nkCY7eUM0k+arEoxO/vAssKHByVmCIL+QxBqYDTvH35zR4/zkSMPkWGL0+Dw13/aUdAkHMLPqp4gSfcwH75ryzq4qLousbIbUnvL46KRZvAFQGjMKX3wb2z8jmQrq//hU/TUU8juX5ZewEkfZ4iQ/QsoR4ZEevEnJDu/r8bfZxkzHPG25joCv5SoGoP38a8jNmfxFX1zTCMRbHG+V6FNGlfZeF1B0o9Fg26Pmt3LQtkAujRUFJ7VjgsQhkPhwO6JiKghuwMnf61NmSK3ZXjV93StPcgVZFu3ug8jweFfkW99JPcvVWtGhoX+E/QGbrcSj6/AOhDI=,iv:a8KXOScK1IMw7eZzvDPoVCk2sqFMuLbsoMvTg5S8wYA=,tag:MccSEjjn2kVWxL9hhPOGSA==,type:str]",
"data": "ENC[AES256_GCM,data:5pzAWnh/9NKq2G++E9knqRXMDzrdtqi0N//uJsAzfcm/yid+Cb/3XykosHZzNS9whVloOxNXrSuiVsc9RH0lAWVuKbr4LP/s0TjX1r0sn/NCFtrpsyQ6BN4LzAVnw35Hx4T+zFSQyx+Iu4tjm+o3iyXo8FBV2NIG/TiQ8rt6ErBlJSLS+qifUF616hDW9rPHMyrZI7KNV5juOFLVZy7mRQ3hvq9JeYocKohWFROluDORTryn5z+BO3IMmBSwE2/a8d48d/zdFz7pf+l2xjJFvWdi9yXW6hw2V7FtS3DdTVQUew2oMRdU27sHrqhrJf84P5jclDGLggTQvpxV79kJDNfxNggRNwIa/RUSI8ayrnn3MbRSEudnbXGocigCdS10CgbHnrVxhscGEur5qgMDilOxFFlOoXIc8tUC3Au/44bzHyGCqsKvu3eggPMxhuLdE3mFzr24LMhGQ6nDd95VcvwVvWVRzMnYpGXezoin/WcIVKWWYpyCsyOF6XLa5ueTkZ22C2A6aKNGIdtApAkKJ01bxJc38SAcnRkh5MQObD3Ty3u7cXmN3QPRASPvysJ9Cc0w1l5s6tHpjyk+DOqAT0kN65Cq22PqncwQzt1wxp3UcQ7tqavzW0GSIKVtG/H4OjNL6MkF7NFelvo9AaaDh7RNAAq8VT18rzD3MOVlSwRAWmoz5HJTgqk6SyaltkuOsgsbP7Zbih60u5ww5SOuC+JCNVnyel6qWd4QlJO+ycnqjaVJM+1kdbd6RNuqUXLE7N8shcEJ0F7/FqSbOLUQyZ4KmIib/8UL1mcY83xSqn9LnmCoQfSxuehzgHtRmF9BCWq+2zjrWOKslQAIC5ECCQGIEf/2ooyFj0lh3djbe60nDP6PeXq0ffyw4m5XGhRQe0nyf9AQy8VpVAvmbq29DzcC+5dPEBKr326dLajHFfXMIURxpu4yx4B69HXMAX837MXrHXUCYNe8X5UObmRwGFkJ6e6VysFbJe/DzBfEKZMPysj49juPuviWDpvj8ZquHhF5mBjMjfUJLQYY/gdlV1MzJSmMAYrraKh669r1J1yoe/V+CM8vJFKjQMlh3eU/sb08JBhGIiW9uQYxQoCrtQK2qIZcK3U/QAzkMm+mp45D8T4w6w03jbHqjyoYHdufppxI2kDbPOM/k/8/amvr5ZTgwXOQU9CTVOG3cE7jQ3pTErwcOK8/MYbmP45U+2kgLRRSFmKxuUv0bVA94I3TL4ErtQKwpa+7QhVepPVz0n5NcYN59jnm7FQpuv8lVDuVL8ToNriC8MLg4+uM8WxYZHTjXqF6DP+Arrua4SYxsSt0YA1cCiwt5BVMP2jjS20yRe7/WeVWQOg6mCZex47e6u4B7yro30Cfx/BofRt2JK0998mJUhORl2RyWL4UUoDxQn6ryaupcxnwZMnSyEihUHKMNommzYnZvVqE0pmoPdx7gKwTAaFr+oCeAAX0spKgTJyeEGqQyElh/JwJLgY6QAHOR+HrSroyIsI3DHoSLBAZ74CiD8xEInwR0Y5R4Hr0B2+kerqBV3MxEsUoBjRwLmtpTZUKlRjYWIoindfS9YC45m+l/2QUxb7+BnlcYYNuGdru6pl2DEMpFRQHCHwV5udgz8CEC4NGgozUcMKwUNTLlPe0TMVJC3HAPa5CEx7DmYqkGoBR8lrZarxdch7pZhXvCTqnAWSKCOBkCUK5dy0ecfyarmIAiKof+VkMlcwUu1G+X6pp9Ug8bYB6,iv:xjXwI1aZB6RJL+BYkIGhSG9kiiWZQqcxQuz9qEQGMFA=,tag:8+PSWNXVHjleuEle5/qFMQ==,type:str]",
"sops": {
"age": [
{
@@ -47,8 +47,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0VWdCWG9DdUliajJLdjZ1\nWW03QmNpb1hoUHRjK0s1UWdrdmFLcGQ4aUZvCmIxWEZxVGV3OGhIOEVxMGE0Q3lh\nY0F6dE9aWkJwR3lYaFBJYkhOeVQxYWcKLS0tIHlrZGZqTjh4dSswcWd5Y2J6WFpi\nVVdDNWUzWDRzcGtHdTZiS3RuYjFsemsKy1LW/DgYHGyBxl4ejrZBuN/g794cuMld\nr5W8k3IWBIk0HT1km9fMiW4zV+KgcrF312k/p6poo/pdGJ8e8kYsGw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-08-09T16:48:48Z",
"mac": "ENC[AES256_GCM,data:lctLfwra+yCkgVyke4l3L5fqDQu6VTMspG48l54lOLYYEQGGYw/V+HDI6GdKVywvGfnthzf8C9LSTRJrD3gKv/Q9a4piaTCTabZ43s0rk5jRCRuUgW7dJqH2nYqZ4AZB2C3DqQn4tCUoRW0PQsZTv+jIwu+jethbn/mb81j2kGc=,iv:WgflsIi5zPGl6bn6A7W2Dvi3XMzck/LNsz/nKV1mLAk=,tag:+sn6kLAiiuXD9wk52VS0KQ==,type:str]",
"lastmodified": "2025-08-20T17:31:03Z",
"mac": "ENC[AES256_GCM,data:U86dC8cNZWILAGf/0WA/JOCq+pCIoKSzsUKgW89hNQJe0sUDgRPo23uvwWa6C/2YuSlP5Jv5ofp0hO6a39dJ83iQibyOIrf0VArRRy8whu1kn/bwIhWxWL7mF6WhKgKmPLy8BX2h0zAp6EL+ct9JdYPb2gdoXrfl0f0R0BDUnL8=,iv:80e1zdyRaPPeDSvfejFd/LjusL6aoKb9F/VTp46l0Kc=,tag:jMHHxG3Ycy5fr74BQnaBEg==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}