1
0
forked from colin/nix-files

Compare commits

...

105 Commits

Author SHA1 Message Date
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 1553 additions and 923 deletions

View File

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

View File

@@ -1,18 +1,18 @@
## migrating a host to a new drive ## migrating a host to a new drive
1. copy persistent data off of the host: ### 1. copy persistent data off of the host:
```sh ```sh
$ mkdir -p mnt old/persist $ mkdir -p mnt old/persist
$ mount /dev/$old mnt $ mount /dev/$old mnt
$ rsync -arv mnt/persist/ old/persist/ $ rsync -arv mnt/persist/ old/persist/
``` ```
2. flash the new drive ### 2. flash the new drive
``` ```
$ nix-build -A hosts.moby.img $ nix-build -A hosts.moby.img
$ dd if=$(readlink ./result) of=/dev/$new bs=4M oflag=direct conv=sync status=progress $ 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 ```sh
$ cfdisk /dev/$new $ cfdisk /dev/$new
# scroll to the last partition # scroll to the last partition
@@ -21,24 +21,29 @@ $ cfdisk /dev/$new
> Write > Write
type "yes" type "yes"
> Quit > 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 $ mkdir /mnt/$new
$ mount /dev/$new new $ mount /dev/$new /mnt/$new
# if you want to use btrfs snapshots (e.g. snapper), then create the data directory as a subvolume: # 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 # 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: # 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 # TODO: port to `sane.programs` interface
services.xserver.desktopManager.kodi.enable = true; 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 = [ imports = [
./fs.nix ./fs.nix
@@ -27,7 +27,7 @@
sane.roles.client = true; sane.roles.client = true;
sane.roles.pc = true; sane.roles.pc = true;
sane.roles.work = 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.services.wg-home.enable = true;
sane.ovpn.addrV4 = "172.26.55.21"; sane.ovpn.addrV4 = "172.26.55.21";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:20c1:a73c"; # sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:20c1:a73c";

View File

@@ -1,4 +1,4 @@
{ ... }: { lib, pkgs, ... }:
{ {
imports = [ imports = [
./fs.nix ./fs.nix
@@ -22,4 +22,37 @@
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;
sane.services.rsync-net.enable = 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"; sane.programs.mpv.config.defaultProfile = "fast";
# /boot space is at a premium, especially with uncompressed kernels. default was 20. # TODO: switch to systemd-boot once rt5640 audio works under it
# boot.loader.generic-extlinux-compatible.configurationLimit = 10;
# TODO: switch to systemd-boot
boot.loader.generic-extlinux-compatible.enable = true; boot.loader.generic-extlinux-compatible.enable = true;
# boot.loader.generic-extlinux-compatible.configurationLimit = 5;
boot.loader.systemd-boot.enable = false; boot.loader.systemd-boot.enable = false;
} }

View File

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

View File

@@ -124,6 +124,7 @@
services.anubis.instances."git.uninsane.org" = { services.anubis.instances."git.uninsane.org" = {
settings.TARGET = "http://127.0.0.1:3000"; 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; botPolicy.openGraph.enabled = true;
}; };
@@ -133,8 +134,13 @@
# XXX(2025-07-24): gitea's still being crawled, even with robots.txt. # 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%). # 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). # 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}"; proxyPassHeavy = "http://unix:${config.services.anubis.instances."git.uninsane.org".settings.BIND}";
# proxyPass = "http://127.0.0.1:3000"; # 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 { in {
forceSSL = true; # gitea complains if served over a different protocol than its config file says forceSSL = true; # gitea complains if served over a different protocol than its config file says
enableACME = true; enableACME = true;
@@ -144,9 +150,20 @@
''; '';
locations."/" = { locations."/" = {
inherit proxyPass; proxyPass = proxyPassLight;
recommendedProxySettings = true; 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 # fuck you @anthropic
# locations."= /robots.txt".extraConfig = '' # locations."= /robots.txt".extraConfig = ''
# return 200 "User-agent: *\nDisallow: /\n"; # 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. # 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). # 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" = { locations."~ ^/colin/phone-case-cq/raw/.*.html" = {
inherit proxyPass; proxyPass = proxyPassLight;
recommendedProxySettings = true; recommendedProxySettings = true;
extraConfig = '' extraConfig = ''
proxy_hide_header Content-Type; proxy_hide_header Content-Type;
@@ -163,7 +180,7 @@
''; '';
}; };
locations."~ ^/colin/phone-case-cq/raw/.*.js" = { locations."~ ^/colin/phone-case-cq/raw/.*.js" = {
inherit proxyPass; proxyPass = proxyPassLight;
recommendedProxySettings = true; recommendedProxySettings = true;
extraConfig = '' extraConfig = ''
proxy_hide_header Content-Type; proxy_hide_header Content-Type;

View File

@@ -14,10 +14,11 @@
# #
# N.B.: default install DOES NOT SUPPORT DLNA out of the box. # 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. # 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 # 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 # https://jellyfin.org/docs/general/networking/index.html
sane.ports.ports."1900" = { sane.ports.ports."1900" = {
protocol = [ "udp" ]; protocol = [ "udp" ];
@@ -168,4 +169,5 @@
}; };
sane.dns.zones."uninsane.org".inet.CNAME."jelly" = "native"; 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 = { sane.services.kiwix-serve = {
enable = true; enable = true;
port = 8013; port = 8013;
@@ -37,4 +38,5 @@
}; };
sane.dns.zones."uninsane.org".inet.CNAME."w" = "native"; sane.dns.zones."uninsane.org".inet.CNAME."w" = "native";
};
} }

View File

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

View File

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

View File

@@ -41,6 +41,10 @@
# - maybe i need to setup stun/turn # - maybe i need to setup stun/turn
# #
# TODO: # 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) # - enable push notifications (mod_cloud_notify)
# - optimize coturn (e.g. move off of the VPN!) # - optimize coturn (e.g. move off of the VPN!)
# - ensure muc is working # - ensure muc is working
@@ -245,11 +249,11 @@ in
extraConfig = '' extraConfig = ''
local function readAll(file) 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") local content = f:read("*all")
f:close() f:close()
-- remove trailing newline -- remove trailing newline
return string.gsub(content, "%s+", "") return Lua.string.gsub(content, "%s+", "")
end end
-- logging docs: -- logging docs:
@@ -261,9 +265,11 @@ in
} }
-- see: <https://prosody.im/doc/certificates#automatic_location> -- 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 -- 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 } c2s_direct_tls_ports = { 5223 }
s2s_direct_tls_ports = { 5270 } s2s_direct_tls_ports = { 5270 }

View File

@@ -1,14 +1,15 @@
{ lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ]; boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# useful emergency utils # useful emergency utils
boot.initrd.extraUtilsCommands = '' boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${lib.getExe' pkgs.btrfs-progs "btrfstune"} 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.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.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.kernelParams = [
"boot.shell_on_fail" "boot.shell_on_fail"
@@ -37,8 +38,16 @@
boot.consoleLogLevel = 7; boot.consoleLogLevel = 7;
boot.loader.grub.enable = lib.mkDefault false; 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.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.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) # 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 "crappy" {}))
(ifSshAuthorized (remoteHome "desko" {})) (ifSshAuthorized (remoteHome "desko" {}))
(ifSshAuthorized (remoteHome "flowy" {})) (ifSshAuthorized (remoteHome "flowy" {}))
(ifSshAuthorized (remoteHome "lappy" {})) # (ifSshAuthorized (remoteHome "lappy" {}))
(ifSshAuthorized (remoteHome "moby" { host = "moby-hn"; })) (ifSshAuthorized (remoteHome "moby" { host = "moby-hn"; }))
(ifSshAuthorized (remoteHome "servo" {})) (ifSshAuthorized (remoteHome "servo" {}))
] ]

View File

@@ -32,13 +32,13 @@
lan-ip = "10.78.79.56"; lan-ip = "10.78.79.56";
}; };
sane.hosts.by-name."lappy" = { # sane.hosts.by-name."lappy" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu"; # ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc"; # ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
wg-home.pubkey = "FTUWGw2p4/cEcrrIE86PWVnqctbv8OYpw8Gt3+dC/lk="; # wg-home.pubkey = "FTUWGw2p4/cEcrrIE86PWVnqctbv8OYpw8Gt3+dC/lk=";
wg-home.ip = "10.0.10.20"; # wg-home.ip = "10.0.10.20";
lan-ip = "10.78.79.53"; # lan-ip = "10.78.79.53";
}; # };
sane.hosts.by-name."moby" = { sane.hosts.by-name."moby" = {
# ssh.authorized = lib.mkDefault false; # moby's too easy to hijack: don't let it ssh places # 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, # nixpkgs' pam hardcodes unix_chkpwd path to the /run/wrappers one,
# but i don't want the wrapper, so undo that. # 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. # 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 "") + '' 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" "/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" # - 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" # - LVM: "dm_mod"
# - on x86 only: more keyboard stuff: "pcips2" "atkbd" "i8042" # - 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> # see: <repo:nixos/nixpkgs:nixos/modules/virtualisation/nixos-containers.nix>
boot.enableContainers = lib.mkDefault false; boot.enableContainers = lib.mkDefault false;

View File

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

View File

@@ -216,6 +216,7 @@
./tcpdump.nix ./tcpdump.nix
./tor-browser.nix ./tor-browser.nix
./tuba.nix ./tuba.nix
./u-boot-pinephone-pro
./unl0kr ./unl0kr
./uptime.nix ./uptime.nix
./v4l-utils.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://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/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://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://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://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 <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.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.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.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="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?q=%s&" shortcuturl="google">Search Google
<dt><a href="https://www.google.com/search?tbm=shop&q=%s" shortcuturl="shopping">Search Google Shopping <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" "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. # TODO: env.PASSWORD_STORE_DIR only needs to be present within the browser session.
# alternative to PASSWORD_STORE_DIR: # alternative to PASSWORD_STORE_DIR:
# fs.".password-store".symlink.target = "knowledge/secrets/accounts"; # fs.".password-store".symlink.target = "knowledge/secrets/accounts";

View File

@@ -16,7 +16,9 @@ let
cfg.addons cfg.addons
); );
addonSuggestedPrograms = lib.map (n: config.sane.programs."${n}") addonSuggestedProgramNames; 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 packageUnwrapped = let
unwrapped = pkgs.firefox-unwrapped // { unwrapped = pkgs.firefox-unwrapped // {
@@ -29,7 +31,8 @@ let
# inherit the default librewolf.cfg # inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg # it can be further customized via ~/.librewolf/librewolf.overrides.cfg
libName = "firefox"; 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); 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 // disable extension updates
defaultPref("extensions.update.autoUpdateDefault", false); defaultPref("extensions.update.autoUpdateDefault", false);
defaultPref("extensions.update.enabled", false); defaultPref("extensions.update.enabled", false);
defaultPref("extensions.systemAddon.update.enabled", false);
// wipe the URIs used to check for updates, as a precaution. // wipe the URIs used to check for updates, as a precaution.
defaultPref("extensions.update.url", ""); defaultPref("extensions.update.url", "");
defaultPref("extensions.update.background.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.engagement.sidebar-button.has-used
// browser.migration.version = 150 // browser.migration.version = 150

View File

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

View File

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

View File

@@ -1,4 +1,7 @@
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
let
cfg = config.sane.programs.nvimpager;
in
{ {
sane.programs.nvimpager = { sane.programs.nvimpager = {
packageUnwrapped = (pkgs.nvimpager.override { packageUnwrapped = (pkgs.nvimpager.override {
@@ -10,6 +13,9 @@
suggestedPrograms = [ "neovim" ]; suggestedPrograms = [ "neovim" ];
sandbox.extraHomePaths = [
".config/nvim"
];
sandbox.whitelistWayland = true; # for system clipboard integration sandbox.whitelistWayland = true; # for system clipboard integration
env.MANPAGER = "nvimpager"; env.MANPAGER = "nvimpager";
@@ -21,4 +27,8 @@
env.MANWIDTH = "999"; env.MANWIDTH = "999";
env.MANROFFOPT = "-c"; 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; type = lib.types.bool;
inherit default description; 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: { playerctl = pkgs.playerctl.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [ patches = (upstream.patches or []) ++ [
(pkgs.fetchpatch { (pkgs.fetchpatch {
@@ -108,6 +112,9 @@ in
packageUnwrapped = (pkgs.nwg-panel.override { packageUnwrapped = (pkgs.nwg-panel.override {
inherit playerctl; inherit playerctl;
python3Packages = pkgs.python3Packages // {
inherit i3ipc;
};
}).overrideAttrs (base: { }).overrideAttrs (base: {
# patches = (base.patches or []) ++ lib.optionals (!cfg.config.mediaPrevNext) [ # patches = (base.patches or []) ++ lib.optionals (!cfg.config.mediaPrevNext) [
# ./playerctl-no-prev-next.diff # ./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 = [ sandbox.extraPaths = [
"/boot" "/boot"
"/mnt/desko" "/mnt/desko"
"/mnt/lappy" "/mnt/flowy"
# "/mnt/lappy"
"/mnt/moby" "/mnt/moby"
"/mnt/servo" "/mnt/servo"
# "nix" # "nix"

View File

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

View File

@@ -11,6 +11,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# disable the following non-essential programs which fail to cross compile # 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.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.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.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) 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.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.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.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> # TODO: upstream into nixpkgs. <repo:nixos/nixpkgs:pkgs/os-specific/linux/kernel/common-config.nix>
name = "fix-module-builtin-mismatch"; name = "fix-module-builtin-mismatch";
patch = null; patch = null;
structuredExtraConfig = with lib.kernel; { structuredExtraConfig = with lib.kernel; {
# nixpkgs specifies `SUN8I_DE2_CCU = yes`, but that in turn requires `SUNXI_CCU = yes` and NOT `= module` # 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; 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.kernelPackages = pkgs.linuxPackagesFor myCustomKernel;
# boot.initrd.extraFiles."/lib".source = "${config.system.modulesTree}/lib"; # 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. # we need space in the GPT header to place u-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate # only actually need 1 MB, but better to over-allocate than under-allocate
sane.image.extraGPTPadding = 16 * 1024 * 1024; # N.B.: the original PP expected idbloader to be at block 16.
sane.image.firstPartGap = 0; # 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 = '' sane.image.installBootloader = ''
dd if=${pkgs.u-boot-pinephone-pro}/idbloader.img of=$out bs=512 seek=64 oflag=direct conv=sync uboot_itb_bytes=$(stat --printf="%s" ${pkgs.u-boot-pinephone-pro}/u-boot.itb)
dd if=${pkgs.u-boot-pinephone-pro}/u-boot.itb of=$out bs=512 seek=16384 oflag=direct conv=sync 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 = [ sane.programs.alsa-ucm-conf.suggestedPrograms = [
"pine64-alsa-ucm" # upstreaming: https://github.com/alsa-project/alsa-ucm-conf/pull/375 "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 = [ hardware.deviceTree.overlays = [
{ {
name = "rk3399-pinephone-pro-battery"; name = "rk3399-pinephone-pro-battery";
@@ -109,9 +128,15 @@ in
name = "rk3399-pinephone-pro-modem"; name = "rk3399-pinephone-pro-modem";
dtsFile = ./rk3399-pinephone-pro-modem.dtso; dtsFile = ./rk3399-pinephone-pro-modem.dtso;
} }
# {
# name = "rk3399-pinephone-pro-sound";
# dtsFile = ./rk3399-pinephone-pro-sound.dtso;
# }
{ {
name = "rk3399-pinephone-pro-sound"; # the complete sound dtso above works in extlinux, but fails under systemd-boot.
dtsFile = ./rk3399-pinephone-pro-sound.dtso; # 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 # from <repo:nixos/nixpkgs:nixos/modules/system/boot/kernel.nix> AKA pkgs.aggregateModules
# but configured to **ignore collisions** # but configured to **ignore collisions**
system.modulesTree = lib.mkForce [( system.modulesTree = lib.mkForce [(
(pkgs.aggregateModules (pkgs.aggregateModules (
( config.boot.extraModulePackages ++ [ config.boot.kernelPackages.kernel ]) config.boot.extraModulePackages ++ [
).overrideAttrs { (lib.getOutput "modules" config.boot.kernelPackages.kernel)
]
)).overrideAttrs {
name = "kernel-modules-merged-sane";
# earlier items override the contents of later items # earlier items override the contents of later items
ignoreCollisions = true; ignoreCollisions = true;
# checkCollisionContents = false; # checkCollisionContents = false;

View File

@@ -0,0 +1,309 @@
// 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",
// TODO: can i make it so that *everything* goes out over HPOL/HPOR?
// SPO_LP/SPO_LN -> EAROUTP -> EARPHONE (labeled in the "Mic" section of schematic)
"Internal Earpiece", "SPOLP",
"Internal Earpiece", "SPOLN",
// Internal Speaker would normally go through the external amp.
// but i'm omitting the amp, so bridge it straight to HPOL/HPOR
"Internal Speaker", "HPOL",
"Internal Speaker", "HPOR",
"DMIC1", "Internal Microphone",
"Headset Microphone", "MICBIAS1",
"IN2P", "Headset Microphone",
"Line Out Modem", "LOUTL",
"Line Out Modem", "LOUTR",
"IN3P", "Line In Modem",
"IN3N", "Line In Modem";
// user-facing controls. e.g. when user selects "Headphone", activate the "Headphone Jack" path.
simple-audio-card,widgets =
"Microphone", "Headset Microphone",
"Microphone", "Internal Microphone",
"Headphone", "Headphones",
"Speaker", "Internal Earpiece",
"Speaker", "Internal Speaker",
"Line", "Line In Modem",
"Line", "Line Out Modem";
simple-audio-card,pin-switches = "Internal Speaker"; //< TODO; try removing
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;
// 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>; //< TODO: remove
// 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 { 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"; compatible = "simple-audio-amplifier";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&spk_en>; 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> # 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. # we need space in the GPT header to place u-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate # 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.firstPartGap = 0;
sane.image.installBootloader = '' sane.image.installBootloader = ''
dd if=${pkgs.u-boot-pinephone}/u-boot-sunxi-with-spl.bin of=$out bs=1024 seek=8 conv=notrunc 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"; sane.hal.rpi-400.enable = lib.mkEnableOption "Raspberry Pi 400 hardware support";
}; };
config = lib.mkIf cfg.enable { 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 { config = lib.mkIf cfg.enable {
boot.initrd.availableKernelModules = [ # boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults # "xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
"usb_storage" # rpi needed this to boot from usb storage, i think. # "usb_storage" # rpi needed this to boot from usb storage, i think.
"nvme" # to boot from nvme devices # "nvme" # to boot from nvme devices
# efi_pstore evivars # # efi_pstore evivars
# added (speculatively) 2024/05/21; these were implicitly being added by nixos/modules/system/boot/kernel.nix # # 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 # # i've copied not all of them, but most
"mmc_block" # "mmc_block"
"dm_mod" # "dm_mod"
# USB keyboards # # 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" # "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 # # x86 keyboard stuff
"pcips2" "atkbd" "i8042" # "pcips2" "atkbd" "i8042"
# stage-2 init needs rtc? # # stage-2 init needs rtc?
"rtc_cmos" # "rtc_cmos"
]; # ];
hardware.cpu.amd.updateMicrocode = true; # desko hardware.cpu.amd.updateMicrocode = true; # desko
hardware.cpu.intel.updateMicrocode = true; # lappy hardware.cpu.intel.updateMicrocode = true; # flowy, lappy
boot.extraModprobeConfig = '' boot.extraModprobeConfig = ''
# allow nested virtualization. XXX(2025-06-24): required for my work (?) # allow nested virtualization. XXX(2025-06-24): required for my work (?)
@@ -37,7 +37,5 @@ in
options kvm_amd nested=1 options kvm_amd nested=1
options kvm_intel nested=1 options kvm_intel nested=1
''; '';
sane.image.extraBootFiles = [ pkgs.bootpart-systemd-boot ];
}; };
} }

View File

@@ -280,8 +280,11 @@ in
bootFsImg bootFsImg
nixFsImg nixFsImg
]; ];
firstPartGap = cfg.firstPartGap; inherit (cfg)
sectorSize = cfg.sectorSize; firstPartGap
sectorSize
extraGPTPadding
;
passthru = { passthru = {
inherit bootFsImg nixFsImg; inherit bootFsImg nixFsImg;
}; };
@@ -307,8 +310,9 @@ in
mkdir -p $out mkdir -p $out
# 34 is the base GPT header size, as added to -p by cgpt. # 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)) gptSize=$((34*512))
part0Start=$(( $gptSize + $firstPartGap )) part0Start=$(( $extraGPTPadding + $gptSize + $firstPartGap ))
( (
# solve for the size of the disk image # solve for the size of the disk image
@@ -326,11 +330,11 @@ in
truncate -s $totalSize $out/disk.img truncate -s $totalSize $out/disk.img
# Zeroes the GPT # Zeroes the GPT
cgpt create -z $out/disk.img ( set -x ; cgpt create -z $out/disk.img )
# Create the GPT with space if desired # Create the GPT, optionally with some extra padding between the primary GPT header and the primary GPT table
cgpt create -p 0 $out/disk.img ( set -x ; cgpt create -p $(( $extraGPTPadding / $sectorSize )) $out/disk.img )
# Add the PMBR # Add the PMBR
cgpt boot -p $out/disk.img ( set -x ; cgpt boot -p $out/disk.img )
) )
( (
@@ -376,9 +380,10 @@ in
'' else '' '' else ''
cp ${img}/disk.img $out cp ${img}/disk.img $out
chmod +w $out chmod +w $out
(
set -x set -x
${cfg.installBootloader} ${cfg.installBootloader}
set +x )
chmod -w $out 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, # 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 # but the combination of custom nixpkgs logic + systemd's sanity checking makes it near impossible to use
# outside a live system. # outside a live system.
# so manually generate a bootloader entry: # so manually generate a bootloader entry:
(pkgs.runCommandLocal "populate-systemd-boot" {} '' (pkgs.runCommandLocal "populate-systemd-boot" {} ''
toplevel=${config.system.build.toplevel} 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_params=$(cat "$toplevel/kernel-params")
kernel=$(readlink "$toplevel/kernel") kernel=$(readlink "$toplevel/kernel")
@@ -411,14 +418,25 @@ in
efi_initrd="/EFI/nixos/$initrd_name.efi" efi_initrd="/EFI/nixos/$initrd_name.efi"
install -Dm644 "$initrd" "$out/$efi_initrd" 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 mkdir -p $out/loader/entries
cat > $out/loader/entries/nixos-generation-0.conf <<EOF cat > $out/loader/entries/nixos-generation-0.conf <<EOF
title NixOS title NixOS
sort-key nixos sort-key nixos
version Generation 0 NixOS version Generation 0 NixOS
linux $efi_kernel linux $efi_kernel
initrd $initrd initrd $efi_initrd
options init=$toplevel/init $kernel_params options init=$toplevel/init $kernel_params
''${efi_dtb:+devicetree $efi_dtb}
EOF EOF
cat > $out/loader/loader.conf <<EOF cat > $out/loader/loader.conf <<EOF
timeout 5 timeout 5
@@ -426,7 +444,7 @@ in
console-mode keep console-mode keep
EOF EOF
'') '')
] ])
; ;
}; };
} }

View File

@@ -1,39 +1,6 @@
# outstanding cross-compilation PRs/issues: # tracking:
# - all: <https://github.com/NixOS/nixpkgs/labels/6.topic%3A%20cross-compilation> # - all cross compilation PRs: <https://github.com/NixOS/nixpkgs/labels/6.topic%3A%20cross-compilation>
# - qtsvg mixed deps: <https://github.com/NixOS/nixpkgs/issues/269756> # - potential idiom to fix cross cargo-inside-meson: <https://github.com/NixOS/nixpkgs/pull/434878>
# - 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.
final: prev: final: prev:
let let
@@ -85,63 +52,63 @@ let
typelibPath = pkgs: lib.concatStringsSep ":" (builtins.map (p: "${lib.getLib p}/lib/girepository-1.0") pkgs); 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 # `cargo` which adds the correct env vars and `--target` flag when invoked from meson build scripts
crossCargo = let # crossCargo = let
inherit (final.pkgsBuildHost) cargo; # inherit (final.pkgsBuildHost) cargo;
inherit (final.rust.envVars) setEnv rustHostPlatformSpec; # inherit (final.rust.envVars) setEnv rustHostPlatformSpec;
in (final.pkgsBuildBuild.writeShellScriptBin "cargo" '' # in (final.pkgsBuildBuild.writeShellScriptBin "cargo" ''
targetDir=target # targetDir=target
isFlavored= # isFlavored=
outDir= # outDir=
profile= # profile=
cargoArgs=("$@") # cargoArgs=("$@")
nextIsOutDir= # nextIsOutDir=
nextIsProfile= # nextIsProfile=
nextIsTargetDir= # nextIsTargetDir=
for arg in "''${cargoArgs[@]}"; do # for arg in "''${cargoArgs[@]}"; do
if [[ -n "$nextIsOutDir" ]]; then # if [[ -n "$nextIsOutDir" ]]; then
nextIsOutDir= # nextIsOutDir=
outDir="$arg" # outDir="$arg"
elif [[ -n "$nextIsProfile" ]]; then # elif [[ -n "$nextIsProfile" ]]; then
nextIsProfile= # nextIsProfile=
profile="$arg" # profile="$arg"
elif [[ -n "$nextIsTargetDir" ]]; then # elif [[ -n "$nextIsTargetDir" ]]; then
nextIsTargetDir= # nextIsTargetDir=
targetDir="$arg" # targetDir="$arg"
elif [[ "$arg" = "build" ]]; then # elif [[ "$arg" = "build" ]]; then
isFlavored=1 # isFlavored=1
elif [[ "$arg" = "--out-dir" ]]; then # elif [[ "$arg" = "--out-dir" ]]; then
nextIsOutDir=1 # nextIsOutDir=1
elif [[ "$arg" = "--profile" ]]; then # elif [[ "$arg" = "--profile" ]]; then
nextIsProfile=1 # nextIsProfile=1
elif [[ "$arg" = "--release" ]]; then # elif [[ "$arg" = "--release" ]]; then
profile=release # profile=release
elif [[ "$arg" = "--target-dir" ]]; then # elif [[ "$arg" = "--target-dir" ]]; then
nextIsTargetDir=1 # nextIsTargetDir=1
fi # fi
done # done
extraFlags=() # extraFlags=()
# not all subcommands support flavored arguments like `--target` # # not all subcommands support flavored arguments like `--target`
if [ -n "$isFlavored" ]; then # if [ -n "$isFlavored" ]; then
# pass the target triple to cargo so it will cross compile # # 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> # # 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+=( # extraFlags+=(
--target "${rustHostPlatformSpec}" # --target "${rustHostPlatformSpec}"
-Z unstable-options # -Z unstable-options
) # )
if [ -z "$outDir" ]; then # if [ -z "$outDir" ]; then
extraFlags+=( # extraFlags+=(
--out-dir "$targetDir"/''${profile:-debug} # --out-dir "$targetDir"/''${profile:-debug}
) # )
fi # fi
fi # fi
exec ${setEnv} "${lib.getExe cargo}" "$@" "''${extraFlags[@]}" # exec ${setEnv} "${lib.getExe cargo}" "$@" "''${extraFlags[@]}"
'').overrideAttrs { # '').overrideAttrs {
inherit (cargo) meta; # inherit (cargo) meta;
}; # };
in with final; { in with final; {
# binutils = prev.binutils.override { # binutils = prev.binutils.override {
# # fix that resulting binary files would specify build #!sh as their interpreter. # # 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: { confy = prev.confy.overrideAttrs (upstream: {
# meson's `python.find_installation` method somehow just doesn't support cross compilation. # meson's `python.find_installation` method somehow just doesn't support cross compilation.
# - <https://mesonbuild.com/Python-module.html#find_installation> # - <https://mesonbuild.com/Python-module.html#find_installation>
@@ -171,10 +138,10 @@ in with final; {
''; '';
}); });
# 2025/07/27: upstreaming is unblocked # 2025/08/26: upstreaming is unblocked, on desko branch `pr-delfin-cross`
delfin = prev.delfin.override { # delfin = prev.delfin.override {
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/07/27: upstreaming is unblocked # 2025/07/27: upstreaming is unblocked
# dtrx = prev.dtrx.override { # dtrx = prev.dtrx.override {
@@ -185,18 +152,18 @@ in with final; {
# binutils = binutils-unwrapped; # 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 { # emacs = prev.emacs.override {
# nativeComp = false; # will be renamed to `withNativeCompilation` in future # nativeComp = false; # will be renamed to `withNativeCompilation` in future
# # future: we can specify 'action-if-cross-compiling' to actually invoke the test programs: # # 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> # # <https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Runtime.html>
# }; # };
envelope = prev.envelope.override { # 2025/08/31: upstreaming is unblocked
cargo = crossCargo; #< fixes openssl not being able to find its library
};
# 2025/07/27: upstreaming is unblocked
# firejail = prev.firejail.overrideAttrs (upstream: { # firejail = prev.firejail.overrideAttrs (upstream: {
# # firejail executes its build outputs to produce the default filter list. # # 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 # # 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: { # flare-signal = prev.flare-signal.overrideAttrs (upstream: {
# env = let # env = let
# inherit buildPackages stdenv rust; # inherit buildPackages stdenv rust;
@@ -232,21 +199,16 @@ in with final; {
# }; # };
# }); # });
# 2025/07/27: upstreaming is blocked by glycin-loaders # 2025/08/26: upstreaming is unblocked, out for PR: <https://github.com/NixOS/nixpkgs/pull/437038>
fractal = prev.fractal.override { # fractal = prev.fractal.override {
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/07/27: upstreaming is unblocked
glycin-loaders = prev.glycin-loaders.override {
cargo = crossCargo;
};
# 2025/07/27: upstreaming is blocked on gnome-shell # 2025/07/27: upstreaming is blocked on gnome-shell
# fixes: "gdbus-codegen not found or executable" # fixes: "gdbus-codegen not found or executable"
# gnome-session = mvToNativeInputs [ glib ] super.gnome-session; # 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: { # gnome-shell = super.gnome-shell.overrideAttrs (orig: {
# # fixes "meson.build:128:0: ERROR: Program 'gjs' not found or not executable" # # 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) # # 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 # 2025/07/27: upstreaming is unblocked
# # gnustep is going to need a *lot* of work/domain-specific knowledge to truly cross-compile, # # gnustep is going to need a *lot* of work/domain-specific knowledge to truly cross-compile,
# gnustep-base = prev.gnustep-base.overrideAttrs (upstream: { # gnustep-base = prev.gnustep-base.overrideAttrs (upstream: {
@@ -331,14 +288,7 @@ in with final; {
# nativeBuildInputs = lib.remove [ qt6.wrapQtAppsHook ] upstream.nativeBuildInputs; # nativeBuildInputs = lib.remove [ qt6.wrapQtAppsHook ] upstream.nativeBuildInputs;
# }); # });
# 2025/07/27: upstreaming is unblocked -- but is this necessary? # lemoa = prev.lemoa.override { cargo = crossCargo; };
# koreader = prev.koreader.overrideAttrs (upstream: {
# nativeBuildInputs = upstream.nativeBuildInputs ++ [
# autoPatchelfHook
# ];
# });
lemoa = prev.lemoa.override { cargo = crossCargo; };
# libsForQt5 = prev.libsForQt5.overrideScope (self: super: { # libsForQt5 = prev.libsForQt5.overrideScope (self: super: {
# # 2025/07/27: upstreaming is blocked on qtsvg # # 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; }; # 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 # 2024/11/19: upstreaming is unblocked
mepo = (prev.mepo.override { mepo = (prev.mepo.override {
# nixpkgs mepo correctly puts `zig_0_13.hook` in nativeBuildInputs, # 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 # 2025/07/27: upstreaming is unblocked by deps; but turns out to not be this simple
# ncftp = addNativeInputs [ bintools ] prev.ncftp; # 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" # fixes "properties/gresource.xml: Permission denied"
# - by providing glib-compile-resources # - by providing glib-compile-resources
# 2025/07/27: upstreaming is blocked on gst-plugins-good, qtkeychain, qtmultimedia, qtquick3d, qt-jdenticon # 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; # # 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: { oils-for-unix = prev.oils-for-unix.overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + '' postPatch = (upstream.postPatch or "") + ''
substituteInPlace _build/oils.sh \ substituteInPlace _build/oils.sh \
@@ -530,10 +435,10 @@ in with final; {
]; ];
}); });
# 2025/07/27: upstreaming is blocked on gnome-user-share, nautilus # 2025/08/31: upstreaming is unblocked; out for review: <https://github.com/NixOS/nixpkgs/pull/437704>
papers = prev.papers.override { # papers = prev.papers.override {
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/07/27: upstreaming is blocked on gnome-session (itself blocked on gnome-shell) # 2025/07/27: upstreaming is blocked on gnome-session (itself blocked on gnome-shell)
# phosh = prev.phosh.overrideAttrs (upstream: { # phosh = prev.phosh.overrideAttrs (upstream: {
@@ -561,11 +466,6 @@ in with final; {
# ]; # ];
# } prev.phosh-mobile-settings; # } prev.phosh-mobile-settings;
# 2025/07/27: upstreaming is unblocked
pwvucontrol = prev.pwvucontrol.override {
cargo = crossCargo;
};
# pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ # pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
# (pyself: pysuper: { # (pyself: pysuper: {
# # 2025/07/23: upstreaming is unblocked, but solution is untested. # # 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 # 2025/08/26: upstreaming is unblocked; implemented on desko `pr-snapshot-cross` branch
snapshot = prev.snapshot.override { # snapshot = prev.snapshot.override {
# fixes "error: linker `cc` not found" # # fixes "error: linker `cc` not found"
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/07/27: upstreaming is unblocked # 2025/08/26: upstreaming is unblocked; patched on desko branch `pr-spot-cross`
spot = prev.spot.override { # spot = prev.spot.override {
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/07/27: upstreaming is unblocked # 2025/07/27: upstreaming is unblocked
# squeekboard = prev.squeekboard.overrideAttrs (upstream: { # 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; swaynotificationcenter = mvToNativeInputs [ buildPackages.wayland-scanner ] prev.swaynotificationcenter;
# 2025/07/27: upstreaming is unblocked # 2025/07/27: upstreaming is unblocked
@@ -834,10 +734,10 @@ in with final; {
# }); # });
# }; # };
# 2025/05/01: upstreaming is unblocked # 2025/08/26: upstreaming is unblocked; implemented on desko branch `pr-video-trimmer-cross`
video-trimmer = prev.video-trimmer.override { # video-trimmer = prev.video-trimmer.override {
cargo = crossCargo; # cargo = crossCargo;
}; # };
# 2025/01/13: upstreaming is blocked on arrow-cpp, python-pyarrow, python-contourpy, python-matplotlib, python-h5py, python-pandas, google-cloud-cpp # 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 { # visidata = prev.visidata.override {

View File

@@ -23,7 +23,7 @@ in
# DISABLE HDCP BLOB in pinephone pro. # DISABLE HDCP BLOB in pinephone pro.
# this is used by u-boot; requires redeploying the bootloader (the SPL, specifically). # 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 # 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; 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, libsoup_3,
meson, meson,
ninja, ninja,
nix-update-script,
openssl, openssl,
pkg-config, pkg-config,
python3, python3,
rust,
rustPlatform, rustPlatform,
rustc, rustc,
stdenv, stdenv,
@@ -19,20 +21,21 @@
wrapGAppsHook4, wrapGAppsHook4,
}: }:
stdenv.mkDerivation { stdenv.mkDerivation (finalAttrs: {
pname = "envelope"; pname = "envelope";
version = "0.1.0-unstable-2024-09-13"; version = "0.1.0-unstable-2025-05-17";
src = fetchFromGitLab { src = fetchFromGitLab {
domain = "gitlab.gnome.org"; domain = "gitlab.gnome.org";
owner = "felinira"; owner = "felinira";
repo = "envelope"; repo = "envelope";
rev = "11ce86da13793787a25e48ca23322b33fcf8bf34"; # last commit before libadwaita 1.6 rev = "e2a8a56aa9b68d82486b99790b86322715d2a6db";
hash = "sha256-EX309RhisBx27TscMsibEvqCSCUSukTgf4Xs1Vws4YY="; hash = "sha256-osVShCaKKoGhxWCjaYcMkOji8e0oETgDaDpCAfHauwQ=";
}; };
cargoDeps = rustPlatform.importCargoLock { cargoDeps = rustPlatform.fetchCargoVendor {
lockFile = ./Cargo.lock; inherit (finalAttrs) pname version src;
hash = "sha256-8pK8cw9nYJmmybYRL+PUCK8FvUUPbyFp7oYYF461KPc=";
}; };
nativeBuildInputs = [ nativeBuildInputs = [
@@ -58,10 +61,21 @@ stdenv.mkDerivation {
postPatch = '' postPatch = ''
patchShebangs --build build-aux/meson-cargo-manifest.py 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; { meta = with lib; {
description = "a mobile-first email client for the GNOME ecosystem"; description = "a mobile-first email client for the GNOME ecosystem";
homepage = "https://gitlab.gnome.org/felinira/envelope/"; homepage = "https://gitlab.gnome.org/felinira/envelope/";
@@ -70,4 +84,4 @@ stdenv.mkDerivation {
platforms = platforms.linux; platforms = platforms.linux;
mainProgram = "envelope"; mainProgram = "envelope";
}; };
} })

View File

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

View File

@@ -33,6 +33,12 @@ stdenv.mkDerivation rec {
hash = "sha256-ALoxT+RLL4omJ7quWDJVdXgevaO8i8q/29FFFudIRV4="; 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 = [ nativeBuildInputs = [
cargo cargo
desktop-file-utils desktop-file-utils
@@ -49,6 +55,8 @@ stdenv.mkDerivation rec {
openssl openssl
]; ];
env.CARGO_BUILD_TARGET = stdenv.hostPlatform.rust.rustcTargetSpec;
passthru.updateScript = gitUpdater { passthru.updateScript = gitUpdater {
rev-prefix = "v"; rev-prefix = "v";
}; };

View File

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

View File

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

View File

@@ -45,51 +45,52 @@ in
# TODO: enable, once i can tolerate a mass rebuild # TODO: enable, once i can tolerate a mass rebuild
# (fetchpatch' { # (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"; # name = "libpcap: enable dbus, rdma, bluetooth features";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/429225"; # prUrl = "https://github.com/NixOS/nixpkgs/pull/429225";
# hash = "sha256-cALgj+7eXd3H4WAmW6CIcxWRC3D4PoY2PWNsDxK+G9g="; # 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' { (fetchpatch' {
name = "signal-desktop: fix cross compilation"; name = "signal-desktop: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/423089"; prUrl = "https://github.com/NixOS/nixpkgs/pull/423089";
# hash = "sha256-609snDT1Ru69ZTWfzu4PnhY0pj3xghPr8w880j7JZ5k="; hash = "sha256-4VEKjZsI7XW+/gbq3fn3bjjciPKtd2IU8SH4CsqqJ6Y=";
hash = "sha256-bVMOanUcYNPf2JbaWS9ga+0jAwuZQSfMKlwtNRp9tYU="; })
(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' { # (fetchpatch' {
@@ -135,12 +136,6 @@ in
# hash = "sha256-UyZaNNp84zKShuo6zu0nfZ2FygHGcmV63Ww4Y4CtCF0="; # 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' { # (fetchpatch' {
# # XXX: doesn't cleanly apply; fetch `firefox-pmos-mobile` branch from my git instead # # XXX: doesn't cleanly apply; fetch `firefox-pmos-mobile` branch from my git instead
# name = "firefox-pmos-mobile: init at -pmos-2.2.0"; # name = "firefox-pmos-mobile: init at -pmos-2.2.0";

View File

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

View File

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

View File

@@ -7,8 +7,8 @@ let
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "nix-community"; owner = "nix-community";
repo = "nixpkgs-wayland"; repo = "nixpkgs-wayland";
rev = "9c452b9ea8e584d5085629e2b76703c94df64b6f"; rev = "60f64e8511aeca7cdd967ef42746845c89321ef7";
hash = "sha256-THPRayZls0/4rZSw4R5B7evCbGVr5AN3SQQZSgYpIiA="; hash = "sha256-ghByh4Imm2FCMGhTkdyy74DBJIqRgZTDqB77YcnQFSs=";
}; };
flake = import "${src}/flake.nix"; flake = import "${src}/flake.nix";
evaluated = flake.outputs { evaluated = flake.outputs {
@@ -25,7 +25,7 @@ let
in src.overrideAttrs (base: { in src.overrideAttrs (base: {
# attributes required by update scripts # attributes required by update scripts
pname = "nixpkgs-wayland"; pname = "nixpkgs-wayland";
version = "0-unstable-2025-08-14"; version = "0-unstable-2025-08-31";
src = src; src = src;
# passthru only nixpkgs-wayland's own packages -- not the whole nixpkgs-with-nixpkgs-wayland-as-overlay: # 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: { stdenv.mkDerivation (finalAttrs: {
pname = "syshud"; pname = "syshud";
version = "0-unstable-2025-07-26"; version = "0-unstable-2025-08-18";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "System64fumo"; owner = "System64fumo";
repo = "syshud"; repo = "syshud";
rev = "d954c124280b71f80930046a11e390a814c1b229"; rev = "6dbf17bb953342c844517d1b4eb672cbae7a1566";
hash = "sha256-FUPnIUl9x0eZmhls4CmPGg4kZb1MNmKU5BKecFDQdHM="; hash = "sha256-T9tWmgDIcmmRXAeWR7Pfjalkl6xogtuz1qfsSAuQmkg=";
}; };
postPatch = '' postPatch = ''

View File

@@ -6,8 +6,7 @@
armTrustedFirmwareRK3399, armTrustedFirmwareRK3399,
buildUBoot, buildUBoot,
}: }:
buildUBoot {
(buildUBoot {
defconfig = "pinephone-pro-rk3399_defconfig"; defconfig = "pinephone-pro-rk3399_defconfig";
filesToInstall = [ filesToInstall = [
"idbloader.img" #< entry point: place it at sector 64 & it'll load whatever's at sector 16384 into RAM and jump to it "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-nodtb.bin"
"u-boot.sym" "u-boot.sym"
]; ];
}).overrideAttrs (upstream: {
# default baud rate is 1500000, which is too fast for some USB <-> serial adapters to do # 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" # CONFIG_DM_RNG is needed to seed the kernel, and avoid "KASLR disabled due to lack of seed"
extraConfig = '' extraConfig = ''
@@ -32,6 +31,13 @@
CONFIG_DM_RNG=y 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: # default layout is:
# scriptaddr = 0x00500000 # scriptaddr = 0x00500000
# script_offset_f = 0xffe000 # script_offset_f = 0xffe000
@@ -51,11 +57,4 @@
# --replace-fail ramdisk_addr_r=0x06000000 ramdisk_addr_r=0x0a000000 \ # --replace-fail ramdisk_addr_r=0x06000000 ramdisk_addr_r=0x0a000000 \
# --replace-fail kernel_comp_addr_r=0x08000000 kernel_comp_addr_r=0x0c000000 # --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 { stdenvNoCC.mkDerivation {
pname = "uassets"; pname = "uassets";
version = "0-unstable-2025-08-15"; version = "0-unstable-2025-08-31";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "uBlockOrigin"; owner = "uBlockOrigin";
repo = "uAssets"; repo = "uAssets";
rev = "e1dd6d5aa73d9dc6d7a123ef585ba5d082bb6fa8"; rev = "f46c97622c978dbe59a942fc649f0eddb3deeb39";
hash = "sha256-rGZWU2OXWjyweyWjST8CgpriEUB1Sa2wd3/FJ1cVMlw="; hash = "sha256-dDtN7WUBbJGbWCSFpVE2NkcFpZXO9RJKJy15Pa18xXE=";
}; };
dontBuild = true; dontBuild = true;

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{ mkVersionedHttpZim }: mkVersionedHttpZim { { mkVersionedHttpZim }: mkVersionedHttpZim {
owner = "wikipedia"; owner = "wikipedia";
pname = "wikipedia_en_all_maxi"; pname = "wikipedia_en_all_maxi";
version = "2024-01"; version = "2025-08";
hash = "sha256-GrRFV3TSFhm9fCFxhFOSD3EQnzBAPZJh96NPefh6p4Q="; 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": { "sops": {
"age": [ "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" "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", "lastmodified": "2025-08-20T17:31:03Z",
"mac": "ENC[AES256_GCM,data:lctLfwra+yCkgVyke4l3L5fqDQu6VTMspG48l54lOLYYEQGGYw/V+HDI6GdKVywvGfnthzf8C9LSTRJrD3gKv/Q9a4piaTCTabZ43s0rk5jRCRuUgW7dJqH2nYqZ4AZB2C3DqQn4tCUoRW0PQsZTv+jIwu+jethbn/mb81j2kGc=,iv:WgflsIi5zPGl6bn6A7W2Dvi3XMzck/LNsz/nKV1mLAk=,tag:+sn6kLAiiuXD9wk52VS0KQ==,type:str]", "mac": "ENC[AES256_GCM,data:U86dC8cNZWILAGf/0WA/JOCq+pCIoKSzsUKgW89hNQJe0sUDgRPo23uvwWa6C/2YuSlP5Jv5ofp0hO6a39dJ83iQibyOIrf0VArRRy8whu1kn/bwIhWxWL7mF6WhKgKmPLy8BX2h0zAp6EL+ct9JdYPb2gdoXrfl0f0R0BDUnL8=,iv:80e1zdyRaPPeDSvfejFd/LjusL6aoKb9F/VTp46l0Kc=,tag:jMHHxG3Ycy5fr74BQnaBEg==,type:str]",
"unencrypted_suffix": "_unencrypted", "unencrypted_suffix": "_unencrypted",
"version": "3.10.2" "version": "3.10.2"
} }