main/postmarketos-duranium: new aport
Duranium is an immutable variant of postmarketOS that uses systemd's image-based OS model: dm-verity verified /usr, A/B slots managed by systemd-sysupdate, LUKS2-encrypted root, and systemd-boot with UKIs. This package ships systemd-repart, systemd-sysusers, tmpfiles, and first-boot service configuration needed at runtime in both the initramfs and the booted system, as well as sysupdate transfer definitions for finding and upgrading images. Build-time repart and sysupdate config lives in the mkosi config repo[1]. The pmOS initramfs is not used. Rather than re-implement partition setup, verity, factory reset, and switch_root in shell script and risk regressions for mutable pmOS installs, an initramfs is built by mkosi containing systemd. This lets the standard systemd initrd machinery handle everything, with no modifications to the pmOS initramfs required. On Android devices, subpartition logic from the pmOS initramfs is essentially copied into a new systemd unit that runs in the initramfs and sets up subpartitions so that they are available to tooling that runs later in the boot process. In the future, this functionality should be moved upstream into systemd. Boot flows: "Normal boot": the verified /usr partition is mounted and the LUKS root partition is unlocked (empty passphrase by default, with fallback to a graphical unlock prompt for user-set passphrases). switch_root hands off to the real rootfs. "First boot": systemd-repart creates the root partition, always as a LUKS volume with an empty passphrase. After switch_root, a first-boot app runs before the display manager to collect a username and password, create the user account, and optionally set a LUKS passphrase. The passphrase can also be changed later via systemd-cryptenroll or cryptsetup. "Factory reset": detected in the initramfs by systemd, which uses systemd-repart to wipe and recreate the root partition. Boot then continues with the first boot flow above. Factory reset can be triggered while booting in the rootfs by starting a systemd unit that configures an EFI variable to signal to the initramfs on next boot. Signed-off-by: Clayton Craft <craftyguy@postmarketos.org> Part-of: <https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/7059>
This commit is contained in:
parent
97fcae383a
commit
dceffe8a46
38 changed files with 649 additions and 0 deletions
165
main/postmarketos-duranium/APKBUILD
Normal file
165
main/postmarketos-duranium/APKBUILD
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
maintainer="Clayton Craft <clayton@craftyguy.net>"
|
||||
pkgname=postmarketos-duranium
|
||||
pkgver=1
|
||||
pkgrel=0
|
||||
pkgdesc="Configuration files for building and booting immutable postmarketOS images"
|
||||
url="https://wiki.postmarketos.org/wiki/Duranium_(Immutable_postmarketOS)"
|
||||
options="!check" # no tests
|
||||
depends="
|
||||
f0rmz
|
||||
shadow
|
||||
tar
|
||||
"
|
||||
# x86: f0rmz
|
||||
arch="noarch !x86"
|
||||
license="GPL-3.0-or-later"
|
||||
replaces="systemd" # For overwriting tmpfiles.d/{opt,var}.conf
|
||||
subpackages="$pkgname-initramfs"
|
||||
|
||||
_source644="
|
||||
etc/crypttab
|
||||
usr/lib/modprobe.d/no-firmware.conf
|
||||
usr/lib/repart.d/00-esp.conf
|
||||
usr/lib/repart.d/10-usr-verity-sig.conf
|
||||
usr/lib/repart.d/11-usr-verity.conf
|
||||
usr/lib/repart.d/12-usr.conf
|
||||
usr/lib/repart.d/20-usr-verity-sig.conf
|
||||
usr/lib/repart.d/21-usr-verity.conf
|
||||
usr/lib/repart.d/22-usr.conf
|
||||
usr/lib/repart.d/30-root.conf
|
||||
usr/lib/systemd/initrd-preset/80-duranium.preset
|
||||
usr/lib/systemd/system-preset/80-duranium.preset
|
||||
usr/lib/systemd/system/duranium-firstboot.service
|
||||
usr/lib/systemd/system/getty@.service.d/wait-firstboot.conf
|
||||
usr/lib/systemd/system/initramfs-buffyboard.service
|
||||
usr/lib/systemd/system/initramfs-telnetd.service
|
||||
usr/lib/systemd/system/initramfs-unudhcpd.service
|
||||
usr/lib/systemd/system/initramfs-usb-gadget.service
|
||||
usr/lib/systemd/system/mount-subpartitions.service
|
||||
usr/lib/systemd/system/systemd-cryptsetup@.service.d/factory-reset-ordering.conf
|
||||
usr/lib/systemd/system/unl0kr-agent.path.d/plymouth-handoff.conf
|
||||
usr/lib/systemd/system/unl0kr-agent.service.d/conflicts-console.conf
|
||||
usr/lib/systemd/system/unl0kr-agent.service.d/plymouth-handoff.conf
|
||||
usr/lib/sysupdate.d/10-usr-verity-sig.transfer
|
||||
usr/lib/sysupdate.d/11-usr-verity.transfer
|
||||
usr/lib/sysupdate.d/12-usr.transfer
|
||||
usr/lib/sysupdate.d/20-uki.transfer
|
||||
usr/lib/sysusers.d/10-pmos-user.conf
|
||||
usr/lib/tmpfiles.d/opt.conf
|
||||
usr/lib/tmpfiles.d/var.conf
|
||||
usr/lib/udev/rules.d/90-udisks-ignore-verity-hack.rules
|
||||
usr/share/duranium/f0rmz-firstboot.conf
|
||||
"
|
||||
|
||||
_source755="
|
||||
etc/profile.d/99-local-bin.sh
|
||||
usr/libexec/duranium/first-boot
|
||||
usr/libexec/duranium/mount-subpartitions
|
||||
usr/libexec/duranium/usb-gadget-setup
|
||||
"
|
||||
|
||||
# Avoid filename based checksum conflicts by including the whole path:
|
||||
# https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10013
|
||||
flatpath() {
|
||||
local i
|
||||
for i in $@; do
|
||||
echo "rootfs-$i" | sed s./.-.g
|
||||
done
|
||||
}
|
||||
source="
|
||||
$(flatpath $_source440 $_source600 $_source644 $_source755)
|
||||
dev-gpt-auto-root-no-timeout.conf
|
||||
"
|
||||
|
||||
package() {
|
||||
for i in $_source644; do
|
||||
install -Dm644 "$srcdir/$(flatpath "$i")" "$pkgdir/$i"
|
||||
done
|
||||
for i in $_source755; do
|
||||
install -Dm755 "$srcdir/$(flatpath "$i")" "$pkgdir/$i"
|
||||
done
|
||||
}
|
||||
|
||||
initramfs() {
|
||||
# musl-utils: for ldconfig.service
|
||||
# scanelf: for ldconfig.service
|
||||
# util-linux-login: for sulogin in emergency/debug shell
|
||||
depends="
|
||||
buffyboard
|
||||
busybox-extras
|
||||
device-mapper
|
||||
device-mapper-udev
|
||||
e2fsprogs
|
||||
musl-utils
|
||||
postmarketos-bootsplash
|
||||
scanelf
|
||||
unl0kr-agent
|
||||
unudhcpd
|
||||
util-linux-login
|
||||
"
|
||||
|
||||
amove etc/crypttab
|
||||
amove usr/lib/modprobe.d/no-firmware.conf
|
||||
amove usr/lib/systemd/initrd-preset/80-duranium.preset
|
||||
amove usr/lib/systemd/system/initramfs-buffyboard.service
|
||||
amove usr/lib/systemd/system/initramfs-telnetd.service
|
||||
amove usr/lib/systemd/system/initramfs-unudhcpd.service
|
||||
amove usr/lib/systemd/system/initramfs-usb-gadget.service
|
||||
amove usr/lib/systemd/system/mount-subpartitions.service
|
||||
amove usr/lib/systemd/system/systemd-cryptsetup@.service.d/factory-reset-ordering.conf
|
||||
amove usr/lib/systemd/system/unl0kr-agent.path.d/plymouth-handoff.conf
|
||||
amove usr/lib/systemd/system/unl0kr-agent.service.d/conflicts-console.conf
|
||||
amove usr/lib/systemd/system/unl0kr-agent.service.d/plymouth-handoff.conf
|
||||
|
||||
amove usr/libexec/duranium/mount-subpartitions
|
||||
amove usr/libexec/duranium/usb-gadget-setup
|
||||
|
||||
# mask plymouth password agent, since we use unl0kr for prompting
|
||||
mkdir -p "$subpkgdir/etc/systemd/system"
|
||||
ln -s /dev/null "$subpkgdir/etc/systemd/system/systemd-ask-password-plymouth.path"
|
||||
|
||||
# normally this would be just another flatpath file but trying to get abuild
|
||||
# to work with a file that has \ in the name is torture.
|
||||
install -Dm644 "$srcdir"/dev-gpt-auto-root-no-timeout.conf \
|
||||
"$subpkgdir"/usr/lib/systemd/system/dev-gpt\\x2dauto\\x2droot.device.d/no-timeout.conf
|
||||
}
|
||||
|
||||
sha512sums="
|
||||
ac441c8a690b89a92c2d7db37145e54d918bb9838a45cf76d20de82d46848a80477a8035d9cbaa39fb6ea4747c2762789f71736aa11a78e3adcca0c339dc5677 rootfs-etc-crypttab
|
||||
ce3f39aa5ed95065306a42bbab6b405bcb90446e206c25509bda64ed2866d80d5168ac225baeb2a50a66e17cbb9b32f26b4a5ec1e042b5f0bf40f6907f4e4d82 rootfs-usr-lib-modprobe.d-no-firmware.conf
|
||||
b0f320f2ea81c29fa9030abac998e725e098c74bb2ffb76ee2711da4c88615ad46a0e5359b98198648879551781580a0128b57a2ef1ca6a3e03448b01f533065 rootfs-usr-lib-repart.d-00-esp.conf
|
||||
be7f90bd96fcad6ccf2b434a4b9ce9bc620b63558df0eddd088d86bcbeb778ff097b6d7db0a021d4322bb2ff908eb65f41840e10b11a479e15986a0b02331bf0 rootfs-usr-lib-repart.d-10-usr-verity-sig.conf
|
||||
8dab35b6c5b61936a8a5f7c6872efe77550f70603a90286c874e9b3c12b25214823c89dd32517b0733110a2f92d0908d0adb6a7bff68f83163d2882e4167b4f6 rootfs-usr-lib-repart.d-11-usr-verity.conf
|
||||
a2ebcf35620a8c2dcd06dff50b6d17b02e8b688f98c6f7e1bb9727733df20742669cb3926a003ccdb1091bc8a337fdc39cc774de509f1b155f3bd3b45a86f8ef rootfs-usr-lib-repart.d-12-usr.conf
|
||||
f5688dbd32ae55ea19f5cafff614f2cfc775c1c7078191d4081b254ed25dad58ac5bed0084e5e07aae192591f3b166aae6e5d1ae4eb585f6b1773f03104eee88 rootfs-usr-lib-repart.d-20-usr-verity-sig.conf
|
||||
730aa98894ec4586d5a97b2faed5ec30ae6679b9ebf4e6dd7e1d4f039279691040232ba30d0f88b4a2696131618b17753d0d8262b88d4ff6f1f120cbd0d22acd rootfs-usr-lib-repart.d-21-usr-verity.conf
|
||||
d88e87fb22b8efdc2617e8a3d52102032ce2b0dbde0e7d40a8d7679f507acc9cea271faa7004f96611631dfa0351cd5175dc1574f907176c9e4ebc5561b9a6d6 rootfs-usr-lib-repart.d-22-usr.conf
|
||||
84036b008042766e89bc02ecb7d77b52f80973a385a21faa1fbb2348ff0c216c302e29bd52c6cb40e5e547ad58aa955e06a9e94bd2ca0c512903a200f44c9a63 rootfs-usr-lib-repart.d-30-root.conf
|
||||
65437794433fea0842a5ac7a528f3416d06e21bb85e796279ef6280f225e97b8836685b5a034fd0cd01db0134a74f23131bcc32bb8c386cc8c5fd80febaefaa1 rootfs-usr-lib-systemd-initrd-preset-80-duranium.preset
|
||||
ee8a7a857bb409c7abe55bfaae1bc1cfb7e08f80b1ae22c804f6c012e643c090bfb2a11692e8bb633bd1685f3fd8a0a4789cb67d286fd9d6420032a2285854cd rootfs-usr-lib-systemd-system-preset-80-duranium.preset
|
||||
09dd75ce4d6790af5156fadea0b948b13a5f36ab1162c45b4a58a5c6b4061d6871610cc3384252422b28bfd7836b95cd7ca857277113abacc0083ecdd6cfff1f rootfs-usr-lib-systemd-system-duranium-firstboot.service
|
||||
16fc787401e1fbbd1421257781270d2be6cb879ab9cc99412044df25af72c5525567f7b7f1066f022c0b7e03dd33c62f2d871fed9e9121ed309564c207795c38 rootfs-usr-lib-systemd-system-getty@.service.d-wait-firstboot.conf
|
||||
786a057e3f1eab37773b5255a5abde060b6bc6f42fd2cdaa82ce678263db6177ca30b49decb795293a4a0ccaf02346684acd0469cc8222898c43768376f2218d rootfs-usr-lib-systemd-system-initramfs-buffyboard.service
|
||||
4f303c5d7cb7054e8bb6e109aa3f4337098b19a6b5a8c6b0b1e1033889d8b1f85a87a0086b67f6f9c62fc93aeca0c59e50def12fff33b79fb7819657b5b820ec rootfs-usr-lib-systemd-system-initramfs-telnetd.service
|
||||
7620e15cebb92c06a662bea095122793b8928b37c8b73fb060f2c882ac9c40419cc3e9eacafab2d04f8089a6fd32c1aa46f9247c54ee60adca87a796262bc37a rootfs-usr-lib-systemd-system-initramfs-unudhcpd.service
|
||||
9c0eb915c09fc3d8de3a1a486f3e2202be05b11ba924d13349a70d93355ca0c72fe2417504e4b7e0c74aa1bb7f5ae77e3497f09dd67e48c0b8f2432f382f2f38 rootfs-usr-lib-systemd-system-initramfs-usb-gadget.service
|
||||
221844a2fe5af2c9c675d7d7c118f3db82afbf8b28db77ea049db74813b62881fe40ada30630f5fd777c6503e2936e22251be75e278635274fe6ac08eba8e56b rootfs-usr-lib-systemd-system-mount-subpartitions.service
|
||||
101b1af9f26fe57f8be1f0353d8146724aaad4c80e790b85559e0d7ce10a1b9169429b112fc17dafde4902e26617ced00b3540a3999c50b606f3ff7564759464 rootfs-usr-lib-systemd-system-systemd-cryptsetup@.service.d-factory-reset-ordering.conf
|
||||
612e50282c0ceb7676d8e62853e99bd693103fc59098d8ac91173538ff1c3fa8b69d3eebeaa6390df7c8f9cc62fddae1ca2d35d07d97e60b40b660bc62bf049b rootfs-usr-lib-systemd-system-unl0kr-agent.path.d-plymouth-handoff.conf
|
||||
b1aa826b83fbb5d606b5dc37a4db67a7233519e0ac953325395dd7f3b7e303d206f6297e51a749d07ee173ccbc4ccf055e92888e38345783d4f4c7687a6a9870 rootfs-usr-lib-systemd-system-unl0kr-agent.service.d-conflicts-console.conf
|
||||
017fe2d6298842b24498000c98e851b441da4edf91cadf2bfc0542a46364f105eda9a5ca772c87e7bd4749e101833fdb43604081b7ab26ebea426559f9de418e rootfs-usr-lib-systemd-system-unl0kr-agent.service.d-plymouth-handoff.conf
|
||||
2e4d532a0d996d8e68007b6036b4564ca3d654dd91cadd80ed904536d0c3ed1e019b4081f7bdb6d128e695cacfe6949bfb20c074b95d10ef25f948f8eb307e24 rootfs-usr-lib-sysupdate.d-10-usr-verity-sig.transfer
|
||||
2dbe55c05b8237ad85c4f333a8c02eec26aad14032f159830696ad9b9c6442d624b0190b2e6780e4b8aed590eb12d0c7454d39ab739e55d420300cdba2a78f58 rootfs-usr-lib-sysupdate.d-11-usr-verity.transfer
|
||||
14df73dfc786a249b300f8998b1f51301834cf058b65c95701b1350f112d2c3deed3b8db9ba439bd90537cef533f148d187bd73961707dca12ef84735e2d5595 rootfs-usr-lib-sysupdate.d-12-usr.transfer
|
||||
4ffb2be01cb033c1282b6661052250937e1ac457cec3900b075d0dcdf59de7dcb2eb927c39db0e96468a90b03fed0a4e6db0d99f62d714c31a29d4684e79751f rootfs-usr-lib-sysupdate.d-20-uki.transfer
|
||||
fa1c3dd727fd20d16d18695d58dd10ec335d64ece00152346c84ae750ed5ade8faf5ba11747135d79972dd1a3f4f1ab496ae9425ebcf7232a4203ca9396fa7e0 rootfs-usr-lib-sysusers.d-10-pmos-user.conf
|
||||
0779c6d5959aef0e325adb69f3e0720a3f271f474c0f14e9c830f015c923c432d07222a24ce722a3ea58670d2eff3536d45bcaf7ae848b587676f1586a348e0e rootfs-usr-lib-tmpfiles.d-opt.conf
|
||||
7d98cb314472d7db64599c8abfc2e21ef6437b0c5bf407f0c21a42ec2f14f660fb3aef64c99a13aada124a822a85d8e4a6674838d1fe07719774331121d5414b rootfs-usr-lib-tmpfiles.d-var.conf
|
||||
ede57bf8696dce4ee295dc2a1dfe31dec415e7ce994600ce3bf7386ac1ad63797a6c5a88434ca0cc854cdad6618647845126b1f8757c48f83ce308d394b8c68d rootfs-usr-lib-udev-rules.d-90-udisks-ignore-verity-hack.rules
|
||||
7f2b98edc7b485129ea862c5c852422e8996ffe0a2bdae3160b6c94667b4e345a1792164e3143d58cb1a51c3c6981381ad7610d709aba210bb61a0c883455476 rootfs-usr-share-duranium-f0rmz-firstboot.conf
|
||||
765797421f9123cdcf85e1496d01884cce1c8c304d15369b7eee32a8fc5abcd860dc5856c0d493f1cd3c6ad2a0ccdc4d6ba7d2ae356f0fc824dc16cdb84ebf37 rootfs-etc-profile.d-99-local-bin.sh
|
||||
6661a981a3c2e549f0f1a12d4777f662eb88aa581608529f6e75a5d448b78fcb709812a4291d5708da840ba72d6cbf48375485d3ecd900d252efd2eb4a9e170c rootfs-usr-libexec-duranium-first-boot
|
||||
bb3ec1693f88a61563876cd069b49351861a31c15b1795702031e5beb4e89cefe302644c1ea9d0bb74746aa97007664c1782857900e2b85dd71182e95efd66ae rootfs-usr-libexec-duranium-mount-subpartitions
|
||||
9912109374399bf6df4d45c05baff5b3c424e05380b81b2be5b55e28e95f07bda71b5a4f7345a40498c1b11df465a9f4410e740d119ab98543ce28b75c53eb0f rootfs-usr-libexec-duranium-usb-gadget-setup
|
||||
ca5b767d4bbc5857c2282124fee3082fafaca8e735ab2077112060e67a37afdb521c28c81fc3b548f114e857aaa702169ee77fab8b7b37c44b5233c83a94afd4 dev-gpt-auto-root-no-timeout.conf
|
||||
"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# systemd-gpt-auto-generator does not set JobTimeoutSec=infinity on
|
||||
# dev-gpt-auto-root.device, so if the user takes longer than
|
||||
# DefaultDeviceTimeoutSec (90s) to enter their LUKS passphrase, the device
|
||||
# unit times out and the system falls into the emergency shell.
|
||||
# Workaround for: https://github.com/systemd/systemd/issues/35870
|
||||
[Unit]
|
||||
JobTimeoutSec=infinity
|
||||
2
main/postmarketos-duranium/rootfs-etc-crypttab
Normal file
2
main/postmarketos-duranium/rootfs-etc-crypttab
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# For auto-unlocking the volume if the default/empty passphrase is set
|
||||
root PARTLABEL=pmOS_root /dev/null luks,keyfile-timeout=0
|
||||
|
|
@ -0,0 +1 @@
|
|||
export PATH="$PATH:$HOME/.local/bin"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# List of modules that require firmware, and should not be loaded
|
||||
# in the initramfs
|
||||
|
||||
blacklist ath11k
|
||||
blacklist ipa
|
||||
blacklist qcom_q6v5_pas
|
||||
blacklist venus_core
|
||||
blacklist btqca
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[Partition]
|
||||
Type=esp
|
||||
Format=vfat
|
||||
CopyFiles=/boot:/
|
||||
SizeMinBytes=1G
|
||||
SizeMaxBytes=1G
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[Partition]
|
||||
Type=usr-verity-sig
|
||||
Label=%M_%A_vts
|
||||
CopyBlocks=auto
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[Partition]
|
||||
Type=usr-verity
|
||||
Label=%M_%A_vty
|
||||
CopyBlocks=auto
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[Partition]
|
||||
Type=usr
|
||||
Label=%M_%A_usr
|
||||
CopyBlocks=auto
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[Partition]
|
||||
Type=usr-verity-sig
|
||||
Label=_empty
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[Partition]
|
||||
Type=usr-verity
|
||||
Label=_empty
|
||||
NoAuto=1
|
||||
SizeMinBytes=400M
|
||||
SizeMaxBytes=400M
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[Partition]
|
||||
Type=usr
|
||||
Label=_empty
|
||||
NoAuto=1
|
||||
SizeMinBytes=5G
|
||||
SizeMaxBytes=5G
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
[Partition]
|
||||
Type=root
|
||||
Format=ext4
|
||||
Encrypt=key-file
|
||||
SizeMinBytes=1G
|
||||
Weight=20000
|
||||
FactoryReset=yes
|
||||
Label=pmOS_root
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
enable initramfs-buffyboard.service
|
||||
enable initramfs-telnetd.service
|
||||
enable initramfs-unudhcpd.service
|
||||
enable initramfs-usb-gadget.service
|
||||
enable mount-subpartitions.service
|
||||
enable unl0kr-agent.path
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=Duranium First Boot Setup
|
||||
ConditionPathExists=!/etc/default_user
|
||||
After=plymouth-quit.service
|
||||
Before=display-manager.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/duranium/first-boot
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
RequiredBy=display-manager.service
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Unit]
|
||||
After=duranium-firstboot.service
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=Framebuffer Touchscreen Keyboard (initramfs)
|
||||
DefaultDependencies=no
|
||||
ConditionPathExists=/dev/fb0
|
||||
After=modprobe@uinput.service
|
||||
Requires=modprobe@uinput.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/buffyboard
|
||||
|
||||
[Install]
|
||||
WantedBy=emergency.target
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=Telnet Debug Shell (initramfs)
|
||||
DefaultDependencies=no
|
||||
After=initramfs-unudhcpd.service
|
||||
ConditionPathExists=/run/usb-gadget-iface
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# FIXME: network addresses should be configurable, perhaps via cmdline param
|
||||
ExecStart=/usr/sbin/telnetd -b 172.16.42.1:23 -F -l /bin/sh
|
||||
|
||||
[Install]
|
||||
WantedBy=emergency.target
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=DHCP Server for USB Gadget (initramfs)
|
||||
DefaultDependencies=no
|
||||
After=initramfs-usb-gadget.service
|
||||
ConditionPathExists=/run/usb-gadget-iface
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# FIXME: network addresses should be configurable, perhaps via cmdline param
|
||||
ExecStart=/bin/sh -c 'unudhcpd -i "$(cat /run/usb-gadget-iface)" -s 172.16.42.1 -c 172.16.42.2'
|
||||
|
||||
[Install]
|
||||
WantedBy=emergency.target
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=USB Gadget Network Setup (initramfs)
|
||||
DefaultDependencies=no
|
||||
After=systemd-modules-load.service sys-kernel-config.mount modprobe@libcomposite.service
|
||||
Requires=sys-kernel-config.mount modprobe@libcomposite.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/libexec/duranium/usb-gadget-setup
|
||||
StandardOutput=journal+console
|
||||
StandardError=journal+console
|
||||
|
||||
[Install]
|
||||
WantedBy=emergency.target
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[Unit]
|
||||
Description=Mount Subpartitions
|
||||
DefaultDependencies=no
|
||||
After=systemd-udev-settle.service
|
||||
Before=systemd-repart.service
|
||||
Before=initrd-root-device.target
|
||||
Before=systemd-veritysetup@.service
|
||||
Before=systemd-cryptsetup@.service
|
||||
OnFailure=emergency.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/duranium/mount-subpartitions
|
||||
|
||||
[Install]
|
||||
WantedBy=initrd.target
|
||||
|
|
@ -0,0 +1 @@
|
|||
enable duranium-firstboot.service
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[Unit]
|
||||
# make sure factory reset (which includes running repart) is done
|
||||
After=factory-reset-now.target
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[Unit]
|
||||
# This unit's upstream has ConditionPathExists=!/run/plymouth/pid so the path
|
||||
# watcher would *not* start if plymouth is running. Plymouth handoff
|
||||
# (deactivate/reactivate) is handled in the unl0kr-agent.service drop-in.
|
||||
ConditionPathExists=
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Unit]
|
||||
Conflicts=systemd-ask-password-console.service systemd-ask-password-console.path
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[Unit]
|
||||
ConditionPathExists=
|
||||
|
||||
[Service]
|
||||
ExecStartPre=-sh -c 'plymouth --ping && plymouth deactivate'
|
||||
ExecStopPost=-sh -c 'plymouth --ping && plymouth reactivate'
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a-verity-sig.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_vts
|
||||
MatchPartitionType=usr-verity-sig
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a-verity.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_vty
|
||||
MatchPartitionType=usr-verity
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_usr
|
||||
MatchPartitionType=usr
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.efi
|
||||
|
||||
[Target]
|
||||
Type=regular-file
|
||||
Path=/EFI/Linux
|
||||
PathRelativeTo=boot
|
||||
MatchPattern=%M_%W_%w_@v+@l-@d.efi \
|
||||
%M_%W_%w_@v+@l.efi \
|
||||
%M_%W_%w_@v.efi
|
||||
Mode=0600
|
||||
TriesLeft=3
|
||||
TriesDone=0
|
||||
InstancesMax=2
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
g audio - -
|
||||
g input - -
|
||||
g netdev - -
|
||||
g plugdev - -
|
||||
g video - -
|
||||
g wheel - -
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Populate /opt from factory defaults
|
||||
# The 'C' directive copies if destination doesn't exist (works since /opt is empty on first boot)
|
||||
|
||||
# Copy entire /opt structure from factory on first boot
|
||||
C /opt - - - - /usr/share/factory/opt
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Populate /var from factory defaults
|
||||
# The 'C' directive copies if destination doesn't exist (works since /var is empty on first boot)
|
||||
|
||||
# Copy entire /var structure from factory on first boot
|
||||
C+ /var - - - - /usr/share/factory/var
|
||||
|
||||
# Additional runtime directories that may not exist in factory
|
||||
d /var/run 0755 root root -
|
||||
L /run - - - - /var/run
|
||||
|
||||
# Ensure critical runtime directories exist
|
||||
d /var/log/journal 2755 root systemd-journal -
|
||||
d /var/log/journal/%m 2755 root systemd-journal -
|
||||
d /var/tmp 1777 root root -
|
||||
d /var/cache 0755 root root -
|
||||
d /var/lib 0755 root root -
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# FIXME: udisks2 (or udiskie) insist on trying to unlock verity hash partitions,
|
||||
# probably because ID_FS_USAGE="crypto" or something. This just tells udisks to
|
||||
# ignore the verity hash device...
|
||||
|
||||
SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="DM_verity_hash", ENV{ID_FS_USAGE}=="crypto", ENV{UDISKS_IGNORE}="1"
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Parse output from f0rmz UI
|
||||
# Sets: firstboot_username, firstboot_password
|
||||
get_firstboot_config() {
|
||||
local output
|
||||
# f0rmz emits 15/SIGTERM on success...
|
||||
output=$(f0rmz -C /usr/share/duranium/f0rmz-firstboot.conf || true)
|
||||
if [ -z "$output" ] || ! echo "$output" | grep -q "username="; then
|
||||
echo "ERROR: running f0rmz configuration UI failed!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while IFS= read -r line; do
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
case "$key" in
|
||||
username) firstboot_username="$value" ;;
|
||||
password) firstboot_password="$value" ;;
|
||||
fde_passphrase) firstboot_fde_passphrase="$value" ;;
|
||||
esac
|
||||
done <<EOF
|
||||
$output
|
||||
EOF
|
||||
}
|
||||
|
||||
get_luks_device() {
|
||||
local dm_name
|
||||
dm_name=$(findmnt -n -o SOURCE / | sed 's|/dev/mapper/||')
|
||||
cryptsetup status "$dm_name" | awk '/device:/{print $2}'
|
||||
}
|
||||
|
||||
get_firstboot_config
|
||||
|
||||
useradd \
|
||||
--comment "Default User" \
|
||||
--create-home \
|
||||
--user-group \
|
||||
--shell /bin/sh \
|
||||
--groups audio,input,netdev,plugdev,video,wheel,render \
|
||||
"$firstboot_username"
|
||||
|
||||
# set user password
|
||||
printf '%s:%s' "$firstboot_username" "$firstboot_password" | chpasswd
|
||||
|
||||
# Keep this at the end so it can also act as the sentinel file for running the
|
||||
# first boot setup, e.g. if this is the first boot or the above operations are
|
||||
# interrupted
|
||||
printf '%s\n' "$firstboot_username" > /etc/default_user
|
||||
|
||||
# Re-trigger generators after creating the default user, because some UIs
|
||||
# (plasma mobile, tinydm) are system daemons that run as the default user, and
|
||||
# the generator depends on /etc/default_user to work properly. It will have run
|
||||
# previously during first boot, before this firstboot app ran, and would have
|
||||
# used the wrong UID in the unit override it generated.
|
||||
systemctl daemon-reload
|
||||
|
||||
if [ -z "$firstboot_fde_passphrase" ]; then
|
||||
echo "No FDE passphrase given, not changing default/empty passphrase"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# replace empty LUKS passphrase slot with user's passphrase
|
||||
luks_dev=$(get_luks_device)
|
||||
systemd-run --pipe \
|
||||
--property="SetCredential=cryptenroll.new-passphrase:${firstboot_fde_passphrase}" \
|
||||
-- \
|
||||
systemd-cryptenroll --unlock-key-file=/dev/null --wipe-slot=empty --password "$luks_dev"
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Read ESP UUID from EFI variable
|
||||
mount -t efivarfs efivarfs /sys/firmware/efi/efivars 2>/dev/null || true
|
||||
efi_var="$(find /sys/firmware/efi/efivars -name 'LoaderDevicePartUUID-*' 2>/dev/null | head -n1)"
|
||||
|
||||
if [ ! -e "$efi_var" ]; then
|
||||
echo "ERROR: LoaderDevicePartUUID EFI variable not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
esp_uuid="$(dd if="$efi_var" bs=1 skip=4 2>/dev/null | tr -d '\0' | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
if [ -z "$esp_uuid" ]; then
|
||||
echo "ERROR: Failed to read ESP UUID from EFI variable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "ESP UUID from EFI: $esp_uuid"
|
||||
|
||||
losetup_args="-Pfv --show --direct-io=on"
|
||||
|
||||
attempt_start="$(cut -d. -f1 /proc/uptime)"
|
||||
wait_seconds=10
|
||||
|
||||
echo "Scanning for subpartition container (timeout: ${wait_seconds}s)..."
|
||||
|
||||
while true; do
|
||||
if [ -b "/dev/disk/by-partuuid/$esp_uuid" ]; then
|
||||
echo "ESP partition already visible, no subpartition mounting needed"
|
||||
exit 0
|
||||
fi
|
||||
for dev in /sys/class/block/*/partition; do
|
||||
[ -e "$dev" ] || continue
|
||||
partition="/dev/$(basename "$(dirname "$dev")")"
|
||||
[ -b "$partition" ] || continue
|
||||
|
||||
if sfdisk --dump "$partition" 2>/dev/null | grep -qi "$esp_uuid"; then
|
||||
sector_size="$(lsblk -ndo PHY-SEC "$partition" 2>/dev/null)"
|
||||
if [ -n "$sector_size" ]; then
|
||||
# not strictly required if it's 512 (the default for losetup)
|
||||
# but doing this anyways saves us from a potentially risky
|
||||
# numerical comparison to a parsed string value
|
||||
losetup_args="$losetup_args --sector-size $sector_size"
|
||||
fi
|
||||
echo "Found subpartition container: $partition"
|
||||
# shellcheck disable=SC2086
|
||||
loop_dev="$(losetup $losetup_args "$partition")"
|
||||
if [ -z "$loop_dev" ]; then
|
||||
echo "ERROR: losetup failed for $partition"
|
||||
exit 1
|
||||
fi
|
||||
echo "Mounted subpartitions via $loop_dev"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
now="$(cut -d. -f1 /proc/uptime)"
|
||||
if [ "$now" -ge $(( attempt_start + wait_seconds )) ]; then
|
||||
echo "ERROR: subpartition container not found after ${wait_seconds}s"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 0.1
|
||||
done
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#!/bin/sh
|
||||
# FIXME: vendor/product IDs, USB function, and network addresses should be
|
||||
# configurable, perhaps via a config file or kernel cmdline parameters.
|
||||
|
||||
CONFIGFS="/sys/kernel/config/usb_gadget"
|
||||
HOST_IP="172.16.42.1"
|
||||
|
||||
# No UDC = no gadget support (e.g. laptop), exit silently
|
||||
if [ -z "$(ls /sys/class/udc 2>/dev/null)" ]; then
|
||||
echo "No UDC found, skipping USB gadget setup"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! mountpoint -q /sys/kernel/config; then
|
||||
modprobe configfs
|
||||
mount -t configfs configfs /sys/kernel/config
|
||||
fi
|
||||
|
||||
GADGET="$CONFIGFS/g1"
|
||||
mkdir -p "$GADGET"
|
||||
|
||||
echo "0x1d6b" > "$GADGET/idVendor" # Linux Foundation
|
||||
echo "0x0104" > "$GADGET/idProduct" # Multifunction Composite Gadget
|
||||
|
||||
mkdir -p "$GADGET/strings/0x409"
|
||||
echo "postmarketOS" > "$GADGET/strings/0x409/manufacturer"
|
||||
echo "Duranium Debug" > "$GADGET/strings/0x409/product"
|
||||
echo "duranium-debug" > "$GADGET/strings/0x409/serialnumber"
|
||||
|
||||
# Try ncm first, fall back to rndis
|
||||
USB_FUNCTION="ncm.usb0"
|
||||
if ! mkdir -p "$GADGET/functions/$USB_FUNCTION" 2>/dev/null; then
|
||||
USB_FUNCTION="rndis.usb0"
|
||||
mkdir -p "$GADGET/functions/$USB_FUNCTION"
|
||||
fi
|
||||
|
||||
# Set a random host-side MAC so the host doesn't get confused across reboots
|
||||
# NOTE: should eventually be configurable or derived from device identity
|
||||
RANDOM_MAC="$(dd if=/dev/urandom bs=6 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n' | sed 's/\(..\)/\1:/g;s/:$//')"
|
||||
# locally administered, unicast
|
||||
BYTE1="$(printf '%02x' $(( 0x$(echo "$RANDOM_MAC" | cut -c1-2) | 0x02 & 0xfe )))"
|
||||
RANDOM_MAC="${BYTE1}$(echo "$RANDOM_MAC" | cut -c3-)"
|
||||
|
||||
mkdir -p "$GADGET/configs/c.1/strings/0x409"
|
||||
echo "USB network" > "$GADGET/configs/c.1/strings/0x409/configuration"
|
||||
ln -sf "$GADGET/functions/$USB_FUNCTION" "$GADGET/configs/c.1/"
|
||||
|
||||
UDC="$(for _udc in /sys/class/udc/*/; do basename "$_udc"; break; done)"
|
||||
echo "$UDC" > "$GADGET/UDC"
|
||||
|
||||
# Wait briefly for the interface to appear
|
||||
IFACE=""
|
||||
for _ in $(seq 1 20); do
|
||||
IFACE="$(cat "$GADGET/functions/$USB_FUNCTION/ifname" 2>/dev/null || true)"
|
||||
[ -n "$IFACE" ] && break
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if [ -z "$IFACE" ]; then
|
||||
echo "ERROR: USB gadget interface did not appear"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ip link set "$IFACE" up
|
||||
ip addr add "$HOST_IP/24" dev "$IFACE"
|
||||
|
||||
echo "$IFACE" > /run/usb-gadget-iface
|
||||
echo "USB gadget up on $IFACE ($HOST_IP)"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[intro]
|
||||
title=Welcome to postmarketOS!
|
||||
body=The next few screens will assist you with setting up your device.
|
||||
|
||||
[form.username]
|
||||
type=text
|
||||
label=Please enter a new username
|
||||
required=true
|
||||
|
||||
[form.password]
|
||||
type=password
|
||||
label=Set a password for the account
|
||||
required=true
|
||||
|
||||
[form.fde_passphrase]
|
||||
type=password
|
||||
label=Set a passphrase for disk encryption (optional)
|
||||
required=false
|
||||
Loading…
Add table
Add a link
Reference in a new issue