Launchd Research Sockets
-
gershwin-on-freebsd: livecd rework + launchd port — plan Phase 1 + 2 CI-green
Sequenced integration of freebsd-launchd's work into pkgdemon/gershwin-on-freebsd. Phase 1 landed (single-root unionfs + init_chroot pivot, CI boot-test gate, feat/libs-corebase). Phase 2 landed (launchd as PID 1 via Option D, bedrock plists from freebsd-launchd, gershwin-specific dshelper/loginwindow/gdomap plists, dhcpcd swap, no getty — LoginWindow is the login). Phase 3 polish (dbus, kmodloader, gdomap lo0 fix, dshelper daemonization, ASL, single-user) deferred.
-
FreeBSD launchd — porting plan (AF_UNIX sockets track) Superseded
Original non-Mach port of Apple's launchd — AF_UNIX/sockets only, GNUstep system-domain libs + launchd built inside a livecd staging chroot, boot-tested in qemu. Superseded by freebsd-launchd-mach (v2), which is now working end-to-end on stock FreeBSD-15 (mach.ko + libmach + userland
mach_msg, 19/19 smoke green). Kept for historical context and as the lineage of the gershwin-livecd integration; the child plans below were drafted against this track and inherit its superseded status.
-
FreeBSD launchd — service ordering Superseded
Cross-service ordering on freebsd-launchd: what makes
varrun → cron, syslogd-first, and dhcpcd-after-kmodloader work declaratively rather than by alphabetical-filename luck. netconfigd is one downstream consumer of the same primitives; the doc walks both layers. Superseded along with the sockets track.
-
FreeBSD kmodloader — porting plan Superseded
Apple-shaped clean-room daemon: every hardware-class kmod autoloads at boot or hot-plug. Closes the gap where stock FreeBSD doesn't aggressively bind GPU/NIC/USB drivers without manual
kld_list= editing. Superseded in the mach track by hwregd, which lifts devmatch's search_hints() parser into a daemon that reads /dev/devctl directly and kldload's on ?nomatch — same job, integrated with the Mach IORegistry instead of standing alone.
-
FreeBSD
mach.ko — out-of-tree kernel module feasibility (v1) Superseded
Predecessor investigation that led to freebsd-launchd-mach (v2). Earlier framing: build a minimal mach.ko from scratch covering the ~15-call subset configd and launchd's bootstrap actually use. Stable-KPI-only diet so the artifact rebuilds only at major FreeBSD bumps. Shipped from freebsd-launchd's CI as a per-major release tarball alongside the live ISO. Superseded by v2 once direct inspection of NextBSD and ravynOS revealed a working module already exists, but kept for the API-surface analysis (the configd Mach-surface inventory in §8 and the stable-KPI / KBI diet in §5 are cited in-body from v2).
Launchd Research Mach
-
freebsd-launchd-mach — pure-port track forking ravynOS's Mach + launchd stack (v2) Phase B Tier 1 + C1-C3 complete
FreeBSD modernization plan. Two-repo strategy: keep
freebsd-launchd on the AF_UNIX track unchanged; create a new freebsd-launchd-mach repo that extracts ravynOS's sys/compat/mach/ as an out-of-tree mach.ko, lifts their launchd / liblaunch / libxpc / libdispatch, integrates the configd Apple source already imported by freebsd-launchd, and reuses the existing CI / ISO scaffolding. Apple source covers only the system-services layer (Mach, launchd, configd, notifyd, asl, dispatch, xpc); GNUstep stays for the framework layer (Foundation, AppKit, libobjc2). Stays ELF; no dyld, no Mach-O execution, Linux compat unaffected. Status: mach.ko builds + kldloads on stock FreeBSD-15; 4 wired trap-family syscalls + libmach + lazy Mach init + end-to-end userland mach_msg proof; 19/19 smoke green, zero kernel patches.
-
launchctl CoreFoundation spike — picking the CF source for launchd-842
Picks the CoreFoundation source for the launchd-842 launchctl port. Apple's
launchctl.c is 4,549 LOC of CF-heavy code. Audits three candidates — gnustep/libs-base, gnustep/libs-corebase, swiftlang/swift-corelibs-foundation — against the exact symbol set launchctl.c uses, with a buy/build/skip decision per candidate. Settles the CF choice that the v2 plan's lede references.
-
libCoreFoundation ICU audit — do we need ICU on the ISO?
Decision-quality survey of ICU usage across 22 Apple-source components relevant to the launchd-adjacent system-services stack. Reverses the CF spike's §14.4 "install ICU as a build dep, keep all CF source files" call: no ICU on the ISO, with the caveat that two daemons (configd, IPConfiguration) and one library (PowerManagement) touch CF-ICU APIs in narrow cosmetic / debug paths that have direct libc-equivalent replacements. Superseded by the libicu port plan — CI execution surfaced 33 additional ICU call sites in CF the audit missed, forcing the decision to flip from Option A (drop) to Option C (vendor).
-
libicu port plan — vendoring Apple ICU into freebsd-launchd-mach
Concrete, agent-derived plan after the audit's Option A turned out to miss 33 ICU call sites (CFString grapheme detection, CFTimeZone localized names, CFBundle_Locale + the Apple-only
ualoc_localizationsToUse). Mid-plan vendor-source pivot: started with apple-oss-distributions/ICU, found that swift-corelibs CF actually expects apple/swift-foundation-icu (purpose-built, native _foundation_unicode/ namespace, Apache 2.0). Final shape: vendor swift-foundation-icu at src/swift-foundation-icu/, build via CMake to /usr/lib/system/libicucore.so (~40–50 MB installed, matching macOS's libicucore.dylib).
-
freebsd-launchd-842 — porting Apple's last open-source launchd Plan drafted
Data-grounded porting plan for Apple's
launchd-842.92.1 (2014, ~28.5k LOC, last open source pre-libxpc-split) onto our mach.ko + libsystem_kernel + libdispatch + libxpc + bootstrap_server stack. Drafted from four parallel research passes through the verbatim Apple source: build-system map (7 MIG .defs files), Mach/IPC gap analysis (audit-trailer materialization + dead-name notifications + port sets are the hard items), PID-1 vs daemon-mode split (single pid1_magic gate; per-user mode is the natural non-PID-1 analogue), and launchctl + control protocol (25 subcommands, launch_msg over Unix socket, CFPropertyList plist parsing). Phases I1 (build + exec only, LAUNCHD-BUILD-OK), I2 (core functionality with multiple test daemons: KeepAlive, StartInterval, WatchPaths, Sockets), then explicit user checkpoint before any PID 1 work.
-
freebsd-libxpc — porting Apple XPC onto our mach.ko
Phased porting plan for libxpc on FreeBSD. Phase 0 starts with a libdispatch Mach backend (new
event_mach_freebsd.c shipped as a patch to gershwin-developer); subsequent phases fork libxpc from ravynOS's tree, add a bootstrap server, swap freebsd-launchd's daemon for a clean Apple launchd-842.92.1 import, build a hybrid CoreFoundation library, and finally bring up configd. Audits related daemons (asl, notifyd, mDNSResponder, IPConfiguration, DiskArbitration). NSXPCConnection documented as a downstream GNUstep contribution.
-
Foundation / CoreFoundation spike for freebsd-libxpc
Companion spike: which Foundation and CoreFoundation implementations do downstream daemon ports actually need? Compares GNUstep
libs-corebase, Apple CF-Lite-1153.18 (2015), and swift-corelibs-foundation's CoreFoundation. Per-port symbol audit: configd (12,968 CF calls, 42 CFMachPort sites), SystemConfiguration framework (6,925 CF, 0 NS), asl/notifyd/libnotify (zero CF). Recommends hybrid: GNUstep value-type CF + a supplementary libCFRuntime.so sourced from swift-corelibs CF for the runtime parts (CFMachPort, CFRunLoop v1, CFPreferences, CFBundle plugin loader). libgnustep-base for Foundation; no swift-corelibs Foundation.
-
libdispatch Mach backend spike for freebsd-libxpc
Why we need to patch libdispatch on FreeBSD: empirical grep shows 5+ components use
DISPATCH_SOURCE_TYPE_MACH_RECV (libxpc, libnotify, notifyd, notifyutil, SystemConfiguration framework). Three options analyzed: patch libdispatch once, polling threads per consumer, or a small bridge library. Recommends Option 1. Includes the comprehensive "all in-scope apps" dispatch-dep matrix, the existing gershwin kqueue performance patches we inherit, install-path comparison (/System/Library/Libraries vs /usr/lib vs /usr/local/lib), Block.h coordination with FreeBSD pkgbase.
-
Install layout spike — per-component paths across four layouts
Per-component install-path matrix for every component we port:
mach.ko, libmach, libdispatch, libxpc, liblaunch, launchd (+launchctl), asl family (syslogd + aslmanager + libasl + syslog), notifyd (+libnotify + notifyutil), configd (+scutil + SystemConfiguration framework + plugins), CoreFoundation hybrid, mDNSResponder, IPConfiguration (+ipconfig + bootpd + helpers), DiskArbitration (framework + daemon + agent), Block.h, GNUstep stack. Four columns: Apple macOS / /usr/lib/system/ (Apple-like) / Gershwin /System/Library/ / FreeBSD base /usr/lib. Documents project policies: /Local/Library never /Library; GNUstep core always at /System/Library/; /System/Applications/ for system .app bundles; gershwin conditional-skip pattern; /System/Library/Tools/ as daemon alternative on every binary.
-
mach.ko syscall slot expansion — audit plan In review
freebsd-launchd-mach has wired 10 Mach syscalls into FreeBSD’s reserved
lkmnosys slot range (210–219); adding an 11th fails with ENFILE. Forward-demand estimate puts total Mach syscalls at 30–40 by the time launchd+configd+notifyd+asl are ported. This is an audit plan, not a design decision: outlines why the 10-slot limit exists, what Apple does differently (separate mach_trap_table with negative syscall numbers), the risk profile of each expansion path (RESERVED-slot claiming, multiplexer dispatcher, base-kernel patch), and the four sub-agent audits to run before picking a path.
-
freebsd-apple-userland-cmds — porting Apple userland onto FreeBSD v3 rule-flip
Data-grounded audit of nine Apple userland repos (bootstrap_cmds, file_cmds, shell_cmds, system_cmds, network_cmds, text_cmds, adv_cmds, PowerManagement, DiskArbitration). v3 (2026-05-26): retired the per-binary "port if Apple has integration advantage, skip otherwise" rule; new rule is "vendor every Apple userland repo we have open-source for, port all binaries, modify as needed." ~155 binaries in scope. Items requiring Apple-closed-source or Apple-OSS-archive fetch split off to dedicated scoping plans: hdiutil/hdik (closed; see hdiutil port plan), diskdev_cmds (mount/fsck/newfs; needs Apple OSS fetch + UFS2 forward-port), kext loader (needs XNU OSKext ported into mach.ko). Transitional
/usr/src manifest contracts from ~40 entries to ~13 FreeBSD-kernel-tied tools (kld*, mdconfig, geom, devfs-rules, dumpon/savecore, swapon).
-
srclist build strategy — which /usr/src tools build standalone investigation
Deep-dive investigation triggered by CI failure on PR #107 (build /rescue/ from /usr/src). Six parallel research-agent passes settled: (1) per-tool dep categorization (47/48 sampled tools build standalone), (2) complete pkg inventory (FreeBSD-runtime 187 bin / 96 dirs; utilities 604/330; rescue 148/0 new), (3) FreeBSD build infrastructure (full buildworld 45-90min cold; per-subdir make ~30s; leaf-only is right shape for ~15min CI), (4) drop-or-keep prereq matrix (only /sbin/ifconfig + rescue's ifconfig+ipf force generated-header libs), (5) deep per-srcdir scoping of FreeBSD-runtime (47 KEEP from 96), (6) deep per-srcdir scoping of FreeBSD-utilities (63 KEEP from ~330). Key reframing: Apple has no /rescue/ at all; ticket #104 framing was wrong — drop without replacing. Issue #104 + PR #107 closed 2026-05-26. For #105: runtime + utilities are separate pkgs, scoped separately; combined first-iter manifest = 110 entries (down from ~425 = 74% trim), ~18-19 min CI serial; no buildworld needed. Both ready-to-paste manifests in §9.2 + §10.3.
-
hdiutil / hdik port plan — four options for review decision pending
Decision document for
hdiutil/hdik/DiskImages on freebsd-launchd-mach. Spun out of userland-cmds v3 §16 deferred scoping after research into Darling's reimplementation revealed it covers ~7% of Apple's surface (attach + detach only, read-only, UDIF-only HFS+) and is GPL-3.0. Apple's hdiutil/hdik/DiskImages.framework are closed-source — never published. Four options laid out: A) clean-room MIT fresh-write in src/hdiutil/ matching Apple's documented ~30-subcommand surface, phased; B) vendor darling-dmg as-is (GPL-3.0, ~7% coverage, 1-2 weeks); C) vendor darling-dmg + extend (GPL-3.0 inherited by extensions); D) defer indefinitely (current v3 plan position). Decision matrix + cross-cutting concerns (GPLv3 vs Apple's no-GPLv3 posture, libdmg.so linking constraint, APFS path, md(4) binding) + phased scope if A or C selected. No decision made in the document — for review.
-
freebsd hardware registry + IOKit userland — porting plan Draft
FreeBSD-devd + FreeBSD-devmatch were removed at commit
88694f0, leaving no kldload-on-nomatch and no notification mechanism for hardware events. This plan builds hwregd as a registry-first cohesive block: Phase 0 (~3-4 wk) lifts devmatch's search_hints() parser into a daemon that reads /dev/devctl directly, kldload's on ?nomatch, and emits Mach events. Phase 1 (~5-6 wk) grows it into a full IORegistry + IOKit-shape Mach-RPC API. Then HardwareMatch launchd plist key (~1.5 wk) + IOKitUser facade K1+K2 (~6 wk). At step 4 devd+devmatch are fully replaced and ioreg -l works — this is the foundation block, ~4 months. Then a demand-driven decision point: configd+IPConfiguration (~7 wk, network mgmt) vs. powerd+IOKitUser K3 (~4 wk, power mgmt) vs. cuse-backed DriverKit-shape framework (~4-8 mo, native userspace drivers). Verdicts on related paths: kernel kext support skip (3-5 yr ABI emulation diversion); Apple DriverKit binary compat defer (8-18 mo).
-
FreeBSD configd — porting plan
Companion to launchd. Ports Apple's configd as
netconfigd: one daemon owns network state, hostname, DNS. Drops Mach IPC for GNUstep Distributed Objects; libdispatch for kernel events.
-
FreeBSD IPConfiguration — porting plan
Eventual replacement for dhcpcd. Ports Apple's IPConfiguration as a netconfigd plugin (DHCPv4 + DHCPv6 + IPv4LL + RA, ~57k LOC, 6-9 person-months). Currently deferred — dhcpcd works, the cost-benefit doesn't justify the port until netconfigd Phase 2-3 ships and a real reason surfaces.
-
FreeBSD WiFi management — Apple stack research
What macOS uses for WiFi (it's not
wpa_supplicant): wifid + Apple80211 + CoreWLAN, mostly closed source. Only the eap8021x EAP/802.1X code is open. We ship wpa_supplicant from ports; sketches a hypothetical wifid-fbsd wrapper if Apple-shape API symmetry ever matters. Includes a wifid-responsibility map (wpa_supplicant vs iwd) and a glossary (AWDL, Continuity, AirDrop, SAE, OWE, 802.11r/k/v, net80211 vs nl80211).
-
FreeBSD Bluetooth management — Apple stack research
How macOS Bluetooth works (a teardown of the fully closed
bluetoothd + IOBluetooth/CoreBluetooth + IOBluetoothFamily.kext stack, the Classic-vs-BLE split, and the proprietary MagicPairing/Continuity protocols). The most closed component yet — zero Apple open source, headers only. FreeBSD's Netgraph stack (ng_hci/hcsecd/sdpd/bthidd) is Classic-only with no BLE/GATT/SMP, and BlueZ can't rescue it (GPL + Linux-kernel-coupled). Weighs extend-Netgraph vs port-BlueZ vs greenfield-userland-LE, sketches a bluetoothd-fbsd, and ties into the AirDrop/Continuity two-radio (BLE discovery + AWDL transfer) story.
-
FreeBSD ASL — porting plan
Apple System Logger replacing FreeBSD's
/usr/sbin/syslogd. Structured log records (Sender/Facility/PID/Time queries without grep), binary-store + BSD-text dual output (tail /var/log/messages still works).
-
FreeBSD notifyd — porting plan
Apple's lightweight named-event pub/sub bus (
libnotify + notifyd). Cross-process event coordination for gershwin desktop — theme changes, network state, power events — via the same C API Apple-derived apps already speak.
-
FreeBSD hostnamed — porting plan v0 draft
Stops shipping
FreeBSD/amd64 (Amnesiac) as the Bonjour name. Clean-room daemon that synthesizes a hardware-derived default at first boot (ThinkPad-T420-8AB123, Mac-mini-F12345, …) from kenv + SMBIOS, sets kern.hostname, and publishes Apple's three-name shape (ComputerName / LocalHostName / HostName) to configd's SCDynamicStore so mDNSResponder has a real .local name to announce. Hybrid source: vendors Apple's Plugins/IPMonitor/set-hostname.c (~500 LOC, APSL 2.0) for the precedence/DHCP-option-12/reverse-DNS pipeline; clean-rooms the hardware-synthesis fallback that fills Setup Assistant's role on real Macs. Standalone (not a configd plugin) because this repo's configd has no .bundle loader yet — same trade hwregd / ipconfigd / diskarbitrationd already took.
-
FreeBSD Keychain — porting / alternatives plan Scoping
What macOS Keychain is (a launchd-managed
securityd/secd Mach daemon + Security.framework library + on-disk keychains + SEP), and the full option space for a NextBSD local secret store with Apple's SecItem API. Source is published (apple-oss-distributions/Security + securityd) but unbuildable — depends on closed corecrypto + SEP firmware. Seven alternatives weighed: full Security.framework port (rejected: closed crypto/SEP, 6–12+ mo), wrapping gnome-keyring/libsecret (fallback: drags in D-Bus + LGPL), KWallet, pass/gpg, PKCS#11 (key-class backend), plaintext plist (interim). Recommended: clean-room com.apple.securityd (keeps Apple's exact launchd label, matching the shipped com.apple.configd/notifyd) — launchd Mach/DO daemon implementing the public SecItem facade over an encrypted store with base libcrypto, optional TPM2 sealing as the SEP analog, pam_secd unlock-at-login tying into the PAM port. ~2–3 person-months for a usable subset. Honest threat model (software-only = gnome-keyring-grade, not SEP-grade). Not a commitment — starts when a real consumer (wifid-fbsd creds, mail/browser, network shares) lands; until then secrets stay inline in plaintext Network.plist.
-
FreeBSD PAM port — replacing FreeBSD-pam with Apple OpenPAM v1 ready to execute
Drops
FreeBSD-pam + FreeBSD-pam-lib packages from the image, replaces with Apple OpenPAM (framework + bundled pam_unix / pam_deny / pam_permit from apple-oss-distributions/OpenPAM/openpam/modules/) plus 5 standalone Apple modules from pam_modules (pam_self, pam_rootok, pam_uwtmp, pam_nologin, pam_env). Zero new module code authored — pure Apple-source vendoring. Trigger: pam_xdg session failure during hostnamed iter 1 RunAtLoad scan race; goal #2 is dropping XDG entirely. Apple’s upstream pam_unix.c (196 LOC, Dag-Erling Smørgrav, same upstream as FreeBSD’s) defers backend selection to NSS via getpwnam+crypt, so the gershwin-side nss_gershwin / dshelper path is transparent — no PAM-side knowledge of any specific directory. 4 iters: vendor OpenPAM → vendor 5 standalone modules → overlay /etc/pam.d/* + drop FreeBSD-pam packages → restore RunAtLoad=true on hostnamed+syslogd. Includes detailed FreeBSD-runtime + FreeBSD-rescue breakage analysis (none, provided the overlay only references modules we ship).
-
FreeBSD OpenDirectory port — scoping (deferred) Scoping only
Companion to the PAM port, capturing what porting Apple’s OD stack would entail before it’s a real need. Binding constraints:
opendirectoryd daemon source is CLOSED (no XPC wire-protocol headers, only the client framework apple-oss-distributions/OpenDirectory is open); Active Directory plugin is CLOSED (the other DS plugins LDAPv3/NIS/PasswordServer/NSL/etc. are open in their own repos); Tiger NetInfo open-source drop is incomplete (only common/ lib, daemons + CLIs were dropped). Inventory of what IS open (DirectoryService legacy daemon ~50k LOC C++/MIG, DSTools, Kerberos, SMBClient, samba) with realistic port-effort estimates. Three-way feature comparison: Tiger NetInfo vs Snow Leopard DirectoryService vs gershwin’s existing dshelper-based DirectoryServices. End-state analysis for OD-client (~6-8 weeks), AD-bind (~5-6 months incl. writing the closed AD plugin from scratch), OD-server-for-Macs (~2-3 months + ongoing crypto maintenance), AD-server-impersonation (not viable; that’s Samba 4’s territory). Not a commitment — revisited only when a real consumer (Kerberos SSO, AD bind, modern Macs binding to FreeBSD/Mach server, password policy needs) emerges. Until then the PAM port stands on its own; this plan is reference data.
-
FreeBSD mDNSResponder — porting plan
Bonjour / zeroconf service discovery:
.local hostnames, automatic printer / file-share discovery on the LAN. Surprise win — Apple's source already has a cross-platform mDNSPosix layer with zero Mach surface; the port is mostly a configuration exercise.
-
mDNS Network browse over Mach — the empty Network-list fix Plan ready
Course-corrects the porting plan above: the Workspace File Viewer's Network list is empty on NextBSD because the
dns_sd client protocol was never finished over Mach. The daemon advertises its own .local name (peers see it) but mach_bridge.c only claims the com.apple.mDNSResponder service and never serves it; libdns_sd ships as the AF_UNIX stub talking to a /var/run/mDNSResponder socket that never exists. Per the “Mach not sockets” doctrine: add a dns_sd.defs MIG IDL + real Mach server wired through EVFILT_MACHPORT, plus a Mach transport in libdns_sd. The File Viewer and NetworkBrowser.app share the same NSNetServiceBrowser backend, so the UI needs zero changes. From a 3-agent investigation + live probing of thinkpad-t460s. Primary repo: nextbsd-redux/nextbsd; Sharing-pane launchd shim is a separate follow-on in gershwin-components.
-
FreeBSD DiskArbitration — porting plan
Disk attach/detach events, mount/unmount/eject coordination, mount-policy approvals. Replaces ad-hoc
kqueue(EVFILT_FS) polling with Apple's clean event API. Workspace File Viewer's "Devices" sidebar wants this. The hard one: replaces IOKit with libgeom + devctl(4).
-
HFS+ kernel module port plan — vendoring Apple HFS to FreeBSD v1 draft
Port Apple's HFS+ filesystem as a vendored FreeBSD
hfs.ko + userland tools (mount_hfs, newfs_hfs, fsck_hfs). Targets read-write mount + journal + decmpfs. Headline find: a GSoC 2025 port (stupendoussuperpowers/freebsd_hfs, FreeBSD Foundation-mentored) already exists with RO+RW mount + basic VOPs working — saves ~3 engineer-months. Strategy: fork the GSoC port (which itself vendors apple-oss-distributions/hfs verbatim + adds a FreeBSD VFS compat shim) rather than starting from Linux hfsplus.ko (GPL-2 incompatible) or fresh-writing. 6-phase delivery (RO mount → RW → fsck → journal → decmpfs → mmap), ~3-4 engineer-months total, with MVP shortcut (Phases 1+3+5 = ~6-9 weeks) for native DMG-mounting. Scopes issue #73.
-
HFS+ bootloader plan — boot-132 vs libsa vs UFS-for-/boot recommendation: Option C
Companion to the HFS+ kmod plan. Addresses: how does the bootloader find the kernel if
/boot is HFS+? FreeBSD's stand/loader can read UFS/ZFS/ext2/cd9660/FAT/NFS but not HFS+. Three options: A) port Apple boot-132 (last released 2006, BIOS+i386-only, APSL 2.0) or modern derivatives (OpenCore BSD-3, Clover BSD-2) — all Darwin-platform loaders that would need ~3+ person-months to gut for FreeBSD handoff; B) add HFS+ reader to stand/libsa (~2-3 weeks, port Clover's LGPL VBoxHfs into libsa's fs_ops ABI); C) UFS for /boot, HFS+ for data — recommended, zero work, matches FreeBSD's default install layout. HFS+ kmod handles all post-boot HFS+ access regardless. Scopes issue #80.