-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnextbsd-research.html
More file actions
197 lines (193 loc) · 41.1 KB
/
Copy pathnextbsd-research.html
File metadata and controls
197 lines (193 loc) · 41.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>NextBSD Research · Joe Maloney</title>
<style>
body {
font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif;
max-width: 760px;
margin: 40px auto;
padding: 0 20px;
color: #222;
line-height: 1.6;
}
header {
border-bottom: 1px solid #ccc;
padding-bottom: 16px;
margin-bottom: 24px;
}
h1 { font-size: 1.8em; margin: 0 0 4px; }
header p { margin: 0; color: #666; }
h2 {
font-size: 1.25em;
margin-top: 2em;
border-bottom: 1px solid #eee;
padding-bottom: 4px;
}
ul { padding-left: 20px; }
li { margin-bottom: 8px; }
a { color: #0366d6; text-decoration: none; }
a:hover { text-decoration: underline; }
.guides li { margin-bottom: 12px; }
.guides .desc { color: #666; font-size: 0.92em; display: block; }
footer {
margin-top: 3em;
padding-top: 16px;
border-top: 1px solid #eee;
color: #888;
font-size: 0.9em;
}
</style>
</head>
<body>
<header>
<h1>NextBSD Research</h1>
<p><a href="index.html">← Back to home</a> · <a href="https://github.com/pkgdemon">github.com/pkgdemon</a></p>
</header>
<h2>NextBSD</h2>
<ul class="guides">
<li>
<a href="nextbsd-gershwin-libdispatch-unification.html?v=20260709c">NextBSD & Gershwin — uniquely name the base <code>libdispatch</code> fork <span class="pill info">Research / decision</span></a>
<span class="desc">Why the Gershwin global menu stopped following app-switches on NextBSD, and how it grew <strong>two</strong> builds of <code>libdispatch</code>. Root cause: NextBSD’s Mach-enabled <code>libdispatch</code> compiles <code>EV_UDATA_SPECIFIC</code> as <code>0x0100</code>, which on FreeBSD kqueue collides with <code>EV_FORCEONESHOT</code> — so the menu’s file-descriptor watch fired <em>once</em> and was never re-armed (and the “second login fixes it” clue was a red herring: a stale active-window value left on the never-restarted login X display). <strong>Settled by on-hardware testing:</strong> the base can’t move to Gershwin’s stock build (six components need Mach sources and won’t link), and Gershwin can’t move to the Mach build — the menu still fails <em>even with</em> the <code>event.c</code>/<code>event_kevent.c</code> kqueue patches. So both builds must exist; the only real bug is that they <em>share the name</em> <code>libdispatch.so</code>. From a multi-agent audit across <code>nextbsd-userland</code>, <code>gershwin-developer</code>, and <code>gershwin-components</code>: the fix is a single rename — give the <strong>base NextBSD fork</strong> the unique soname <code>libsystem_dispatch.so</code> (a build-harness change; the fork is permanently owned and never synced with Apple again) and relink the base consumers onto it, while Gershwin’s <strong>stock Apple <code>libdispatch.so</code> is never touched</strong>. Distinct names also kill the original <code>launchctl</code>/<code>dbus</code>/<code>sshd</code> “Undefined symbol” poisoning. Safety rule: no single process loads both, guarded by a CI <code>DT_NEEDED</code> check — safe because the only base lib Gershwin consumes, <code>libdns_sd</code>, is a dispatch-free AF_UNIX stub. Includes a plain-language “how to read the per-library disposition” guide, the full disposition table, mDNS reconciliation, risks, and open questions. Companion to the fork-necessity review below.</span>
</li>
<li>
<a href="nextbsd-libdispatch-mach-fork-review.html?v=20260709">Is the NextBSD Mach <code>libdispatch</code> fork still needed? <span class="pill info">Research / review</span></a>
<span class="desc">The prerequisite question behind the rename decision above: can NextBSD just drop its Mach <code>libdispatch</code> fork and use Gershwin’s stock build everywhere? <strong>No</strong> — six production components (<code>libxpc</code>, <code>launchd</code>, <code>notifyd</code>, and friends) depend on <code>libdispatch</code>’s Mach sources (<code>DISPATCH_SOURCE_TYPE_MACH_RECV</code> / <code>dispatch_mach_t</code>), and a stock <code>HAVE_MACH=0</code> build can’t even compile or link them; swapping would break boot and all XPC IPC. But the instinct is half-right: the “fork” is barely a fork — a handful of compile-time deltas over stock — which is exactly why it can safely coexist with Gershwin’s stock copy once it carries a distinct soname. Component-by-component review of what actually needs Mach and why the fork earns its keep.</span>
</li>
<li>
<a href="nextbsd-quiet-console-plan.html?v=20260704">NextBSD quiet console — kernel/IOKit spew off ttyv0, and an optional boot splash <span class="pill info">Plan / mockups</span></a>
<span class="desc">Make the login console behave like macOS: no kernel / IOKit / driver text on <strong>ttyv0</strong> on a normal boot (or on USB-eject), but full output under <code>boot -v</code>, everything still in <code>dmesg</code>+syslog, and panics always visible. <strong>The surprise: FreeBSD already does all the hard parts</strong> — every kernel <code>printf</code> splits into an always-captured <code>TOLOG</code> sink and a <code>cn_mute</code>-gated <code>TOCONS</code> sink, <code>panic()</code> force-unmutes, and <code>RB_MUTE</code>/<code>RB_MUTEMSGS</code> self-cancel under <code>RB_VERBOSE</code>. So the base case is a <strong>one-line loader change</strong> (<code>boot_mute="YES"</code> in the nextbsd-overlays fragment); the only real work is making <strong>CI boot verbose</strong> so the boot-test still sees its markers. Closes with a feasibility read on an <strong>Apple-style boot splash</strong> and four to-scale mockups (grey/black × static/spinner, real nextbsd.org cube + a CSS 12-spoke throbber) — framed as a layer on top of <a href="https://github.com/nextbsd-redux/nextbsd/issues/272">#272</a> (seamless <code>vt(4)</code>→drm-fbdev deferred takeover), since a splash shipped before #272 would flash to black when the GPU driver attaches. Ticket nextbsd#363.</span>
</li>
<li>
<a href="nextbsd-path-domain-conformance-plan.html?v=20260702">NextBSD path-domain conformance — adopt the gershwin four-domain layout <span class="pill info">Plan / audit</span></a>
<span class="desc">Bounded follow-up to the layout spike (that decision tabled): conform NextBSD's paths to gershwin's four domains — <strong>every bare Apple <code>/Library/X</code> becomes <code>/Local/Library/X</code></strong>; <code>/System/Library</code> stays. Org-wide audit of <strong>all 9 <code>nextbsd-redux</code> repos</strong>: six clean, <code>freebsd-src</code> out of scope by rule, and the rename surface confined to the Darwin userland source — ~12 runtime-behavioral sites across 6 subsystems (launchd PID-1 scan, SCPreferences, CoreFoundation, kext_tools, ASL). <strong>Headline finding:</strong> that source is <em>duplicated byte-for-byte</em> across <code>nextbsd-userland/src</code> (CI cross-build) and <code>nextbsd/src</code> (the ISO builder, which compiles its own copy), so the change is doubled and must land in lockstep. Includes the two hardcoded <code>strlen</code> traps (20→26, 14), the judgment calls (StartupItems/Logs/Spotlight), and the full <code>file:line</code> surface. Planning only.</span>
</li>
<li>
<a href="nextbsd-system-path-layout-spike.html?v=20260702b">NextBSD system path layout — the Gershwin layout vs a POSIX layout <span class="pill info">Research / spike</span></a>
<span class="desc">Gershwin ships an <em>official named</em> <code>tools-make</code> FilesystemLayout (<code>--with-layout=gershwin</code>) that roots the desktop at <code>/System</code> — and it collides with NextBSD on <strong>two exact directories</strong>: <code>/System/Library/Libraries</code> (Gershwin's ObjC install target vs NextBSD's rtld Lever-B search path) and <code>/System/Library/LaunchDaemons</code> (Gershwin's session plists interleave with NextBSD's 11 boot daemons). Gershwin's own <code>make uninstall</code> already refuses <code>rm -rf /System</code> on NextBSD. So: keep the domains and move <em>Gershwin</em> off <code>/System</code> (a Gershwin-layout fork — not NextBSD's call), or move <em>NextBSD</em> to POSIX paths (<code>/etc/launchd.d</code>, <code>/usr/local/etc/launchd.d</code>, <code>/boot/kernel/extensions</code>, <code>/var/db</code>) so <code>rm -rf /System</code> removes only the desktop? From a 3-agent source sweep + on-target verification: full per-path inventory, both layouts side-by-side, honest cost accounting, and the exact <code>file:line</code> change surface. Key findings: <strong>no <code>/System/Library/Frameworks</code></strong> on the NextBSD side (libs in <code>/usr/lib/system</code> — no dyld/ABI knot), the <strong>kernel is filesystem-blind for kexts</strong> (zero kernel changes), and the kext <strong>cache self-disables</strong> on the move. Planning only.</span>
</li>
<li>
<a href="nextbsd-userland-repo-plan.html?v=20260621">A cross-built <code>nextbsd-userland</code> repo — split the Apple stack out, slim <code>nextbsd</code> to an ISO assembler <span class="pill pill-warn">Plan ready</span></a>
<span class="desc">Move NextBSD's ~2,260 lines of in-<code>chroot</code> Apple-userland compilation out of <code>nextbsd/build.sh</code> into a new <code>nextbsd-userland</code> repo that cross-compiles on a Linux host (like <code>nextbsd-freebsd-compat</code>), publishes a 4th rolling <code>continuous</code> artifact, and drops the in-image build toolchain (<code>cmake</code>/<code>ninja</code>/<code>pkgconf</code>/<code>llvm19</code>) entirely — leaving <code>nextbsd</code> a thin assembler (download 4 tarballs → layer → uzip → ISO, ~3,245→~700 lines). From a 3-agent scope. Key feasibility wins: only <strong>2</strong> components are CMake (<code>libdispatch</code>, <code>swift-foundation-icu</code>); the other <strong>18+ are <code>bsd.lib.mk</code> Makefiles that cross-compile in <code>make.py buildenv</code> with zero source changes</strong>. The real work is harness-level: stage the sysroot from compat's <code>continuous</code>, relocate two build-time runs of cross binaries (<code>test_corefoundation</code>/<code>kextdeps</code>) to the boot-test, replace ~26 <code>chroot ldd/ldconfig</code> checks with <code>readelf</code>, and write 2 CMake cross-toolchain files. Phased rollout (parallel non-cascading → dual-source flag → flip cascade → delete) keeps the green chain intact.</span>
</li>
<li>
<a href="nextbsd-freebsd-compat-audit.html?v=20260621">FreeBSD-compat 3-way audit — what we install, overwrite, and could port from Apple <span class="pill pill-warn">Audit</span></a>
<span class="desc">Every one of the 99 components the <code>nextbsd-freebsd-compat</code> closure installs into the NextBSD base (<code>srclist.txt</code>), cross-referenced against (1) what NextBSD overwrites with Apple-sourced code and (2) what could be ported from Apple open source instead — each with a port-difficulty rating (Trivial→Impractical). From a 4-agent audit. Headlines: <strong>0/99 currently overwritten</strong> (Apple's <code>reboot</code>/<code>shutdown</code>/<code>login</code>/<code>su</code>/mtree are vendored from <code>system_cmds</code>/<code>shell_cmds</code>/<code>file_cmds</code> but <em>deferred</em> behind IOPMLib/BSM shims); <code>libbsm</code> already <em>is</em> Apple's OpenBSM; the UFS tooling (<code>newfs</code>/<code>tunefs</code>/<code>fsck_ffs</code>) is <strong>Impractical</strong> because Apple has no UFS code (only newfs_hfs/apfs); the libc/loader ABI is Mach-O-incompatible; and <code>krb5</code> is MIT (not Apple's Heimdal), so that “easy Apple port” doesn’t exist.</span>
</li>
<li>
<a href="nextbsd-drop-ci-cache-plan.html?v=20260621">Drop CI caching & purge caches across the build chain <span class="pill pill-warn">Plan ready</span></a>
<span class="desc">Remove every caching layer from the <code>nextbsd-redux</code> build chain (ccache in kernel/compat/modules, the distfiles cache in <code>nextbsd</code>, the Docker BuildKit GHA layer cache in <code>nextbsd-kernel-toolchain</code>) via direct commits in build-chain order, then purge the stored caches. From a 3-agent investigation with a key correction: dropping ccache is not just deleting the cache step — each <code>make.py</code> wires the cache in via <code>--cross-bindir=${CCACHE_CROSS_BINDIR}</code>, so every call must be repointed to <code>${CROSS_BINDIR}</code> (the real Clang 19) or the build rebuilds its own LLVM. And the premise correction that matters: the “<code>freebsd-version</code> stuck at 15.0” symptom was <strong>not</strong> a ccache replay (the kernel sets <code>RELEASE</code> to a timestamp and keeps <code>REVISION</code> stock at 15.0 by design, so <code>vers.c</code> always misses) — it came from a stale baked GHCR toolchain image plus genuine version pins (<code>nextbsd-kernel-modules</code> on <code>releng/15.0</code>, <code>build.sh</code> default <code>15.0</code>), none of which a cache purge touches. Cache-drop buys determinism; the version fix is the toolchain-image refresh + the <a href="nextbsd-drm612-upgrade-plan.html">15.1 base bump</a>.</span>
</li>
<li>
<a href="nextbsd-drm612-upgrade-plan.html?v=20260618">NextBSD graphics — bumping <code>drm-kmod</code> 6.6 → 6.12 (and the 15.1 gate) <span class="pill pill-warn">Decision plan</span></a>
<span class="desc">Can we move the Intel/AMD/Radeon kexts to the Linux-6.12 DRM backport, and do we need FreeBSD 15.1? A three-agent review of the ports tree, <code>freebsd-src</code> LinuxKPI, and the NextBSD graphics build. Answers: (1) <strong>yes</strong>, <code>graphics/drm-612-kmod</code> exists (DRM from Linux 6.12 LTS, <code>6.12.85</code>); (2) <strong>yes, 15.1 is mandatory</strong> — the port hard-requires <code>__FreeBSD_version ≥ 1500509</code> and NextBSD’s <code>releng/15.0</code> (<code>1500068</code>) is excluded by the port’s <code>IGNORE</code> clause and lacks the 6.12 LinuxKPI symbols (<code>fd_file()</code>, <code>fop_flags</code>, the <code><linux/unaligned.h></code> move, 6.12 <code>kvrealloc()</code>, expanded folio/dma-mapping/xarray) present on 15.1 and absent from 15.0; (3) the kext bump itself is a one-line <code>--branch 6.6-lts→6.12-lts</code> flip + <code>FW_TAG</code> bump, but it’s <strong>gated on moving the kernel base 15.0→15.1</strong> (pkg ABI <code>FreeBSD:15</code> preserved). Covers NextBSD’s current build (drm-kmod 6.6-lts, baked LinuxKPI, per-vendor firmware bundling), the decoupled date-versioned <code>gpu-firmware</code>, the 6.6→6.12 hardware delta (Meteor/Arrow Lake i915, newer amdgpu — but <strong>still no Xe2 / Battlemage / Lunar Lake</strong>), a sequenced two-ticket plan, and the baked-<code>MODULE_DEPEND</code>/firmware-size risks.</span>
</li>
<li>
<a href="nextbsd-15.1-drm612-execution-plan.html?v=20260619">NextBSD — executing the <code>releng/15.1</code> bump & <code>drm-kmod</code> 6.12 (per-repo runbook) <span class="pill pill-warn">Execution plan</span></a>
<span class="desc">The execution follow-on to the decision plan above: it takes the verdict as settled (<code>drm-612-kmod</code> hard-requires <code>__FreeBSD_version ≥ 1500509</code>, so <code>releng/15.1</code> is mandatory, pkg ABI <code>FreeBSD:15:amd64</code> preserved) and answers <strong>exactly what to change, in which repo, in what order, and what to verify</strong> for issues <a href="https://github.com/nextbsd-redux/nextbsd/issues/336">#336</a> (base 15.0→15.1) and <a href="https://github.com/nextbsd-redux/nextbsd/issues/337">#337</a> (graphics kexts 6.6→6.12 + firmware). From a six-agent scope of the whole build chain: the dispatch topology, per-repo scope across the six <code>nextbsd-redux</code> repos (<code>freebsd-src</code> sync fork, <code>nextbsd-kernel-toolchain</code>, <code>nextbsd-kernel</code>, <code>nextbsd-kernel-modules</code> where both tickets land, <code>nextbsd-freebsd-compat</code>, and the <code>nextbsd</code> ISO assembler), a seven-step ordered runbook (sync → manual checkpoint → toolchain → kernel → base → kext bump → assemble & boot-test), a ranked risk register, and acceptance criteria mapped to the tickets.</span>
</li>
<li>
<a href="nextbsd-input-touch-driver-spike.html?v=20260618">NextBSD input & touch drivers — <code>hms</code> vs <code>utouch</code> spike <span class="pill info">Research / spike</span></a>
<span class="desc">A four-agent code review of <code>freebsd-src</code> and <code>wulf7/utouch</code> answering whether choosing <code>hms</code> over <code>utouch</code> loses any device support — <strong>no</strong>: same author, <code>hms</code> is the in-base successor and a strict superset (relative + I2C mice <em>plus</em> the absolute VM-tablet pointers utouch existed for), and utouch’s own README says “deprecated on 13+, use <code>hms(4)</code>.” The historical “base didn’t work” pain was a default-OFF config (<code>hw.usb.usbhid.enable</code>) flipped ON in 15.0, not a missing driver. Covers why NextBSD must <em>compile in</em> the leaves (no <code>.ko</code> tree to auto-load — GENERIC ships only the keyboard leaves + transports), the <code>hms</code>/<code>ums</code> mouse path with absolute-axis handling and the <code>sysmouse</code>/<code>HUG_TWHEEL</code>/<code>INPUT_PROP_DIRECT</code> gaps, the touch/touchpad/pen stack (<code>hmt</code>/<code>hpen</code>/<code>iichid</code>+<code>ig4</code>/<code>ietp</code>/<code>hconf</code>, with <code>IICHID_SAMPLING</code> mandatory on amd64), QEMU/KVM (USB tablet works, no native <code>virtio-input</code> guest driver), Microsoft Surface (IPTS/ITHC/SAM — won’t work in base), Lenovo ThinkPad I2C-HID + PS/2 TrackPoint, the import timeline (D27777 → 13.0 → 15.0 default-on), and the exact <code>config/NEXTBSD</code> lines to bake in. Background for issue #335 / PR nextbsd-kernel#46.</span>
</li>
<li>
<a href="nextbsd-unionfs-inode-collision-fix-plan.html?v=20260616">NextBSD unionfs inode-collision fix — design plan <span class="pill info">Design / proposal</span></a>
<span class="desc">Permanent kernel-side fix for issue #332: the live unionfs root gives every layer the same <code>st_dev</code> and passes underlying inode numbers through, so an upper-layer header and an unrelated lower-layer header collide on <code>(st_dev, st_ino)</code> — and clang, which keys <code>#pragma once</code>/<code>#import</code>/include-guard dedup on file identity not path, silently skips the second (the <code>GS_EXPORT</code> / <code>cups_lang_t</code> / <code>OBJC_PUBLIC</code> / <code>encode_NSInteger</code> failures, none reproducible on stock FreeBSD). No clang flag can fix it (upstream LLVM calls it a filesystem bug). Fix modelled on Linux overlayfs <code>xino</code>: keep one <code>st_dev</code>, reserve the high bit of the 64-bit fileid as a layer tag in <code>unionfs_getattr()</code>, mirror it onto <code>d_fileno</code> in <code>unionfs_readdir()</code> (two layers ⇒ collision-free by construction). Exact <code>union_vnops.c</code>/<code>union.h</code> touch points, alternatives (per-layer <code>st_dev</code>, separate build FS, the inode-bust sweep), a full <strong>risks & implications</strong> section (32-bit <code>ino_t</code> EOVERFLOW, readdir bounce-buffer cost, copy-up churn, ZFS bit-63 exhaustion, NFS export), a deliberate-overlap kyua regression test + collision detector, and rollout. Retires the inode-bust build-script workaround.</span>
</li>
<li>
<a href="nextbsd-initramfs-boot-research.html?v=20260611">Why a live ISO won’t boot under Ventoy / iPXE — the initramfs research <span class="pill info">Research</span></a>
<span class="desc">Why the FreeBSD ISO fails under Ventoy/iPXE (and sometimes real hardware): the bootloader–kernel handoff wall — <code>/dev/iso9660/<LABEL></code> is created by the <em>kernel</em> after the loader has handed off and exited, so swapping bootloaders (GRUB, Apple’s boot-132) can’t help, and at <code>ExitBootServices</code> the firmware Block I/O dies (amd64 long mode can’t call <code>INT 13h</code> either). Two physics classes: real block devices (CD/DVD/dd-USB/VM — work, modulo discovery timing) vs. firmware-emulated/fragmented media (Ventoy/iPXE/MEMDISK — the kernel can’t re-reach them). How Linux <em>actually</em> fixes it — the initramfs, not a mounted ISO: reconstruct from the real stick (exFAT loop-mount / <code>dm-linear</code>) for Ventoy, network-fetch (dracut <code>livenet</code> / casper <code>netboot=url</code> / NFS / iSCSI+iBFT) for iPXE. The NextBSD equivalent: <code>mfsroot</code>+<code>/init</code> <em>is</em> the initramfs — turn <code>/init</code> into an ordered probe. Includes the <code>geom_ventoy</code> (BSD-2-Clause) / exFAT-gap / <code>isboot</code> assessment, a phased plan, and the single-user disambiguation test for real hardware. Background for #288.</span>
</li>
<li>
<a href="nextbsd-server-installer-design.html?v=20260608">NextBSD Server Installer — dialog-based installer design <span class="pill pill-warn">Design doc</span></a>
<span class="desc">Screen-by-screen design for a text-mode, dialog-driven server installer — amber-on-black TUI mockups for each phase rendered as illustrative box-drawing renders. Flow: <strong>Install / Upgrade</strong> (Upgrade gated until an existing install is probed), <strong>whole-disk selection</strong> showing volume labels + filesystem type broken out per disk (not just device ids), <strong>account + hostname</strong> (username/password/confirm with a hostname auto-suggested as <code>joe-thinkpad-t460</code> from username + DMI model, still editable), a <strong><code>cpdup</code> clone</strong> progress gauge (live filesystem cloned to the destination volume, no archive extraction), and a <strong>finish</strong> screen with Reboot / Shutdown. Build identity follows the <code>continuous</code> rolling release (timestamp + short commit). Includes the hostname-derivation logic, disk-column source mapping, and a palette/visual-language reference for a <code>bsddialog(1)</code> / ncurses implementation.</span>
</li>
<li>
<a href="nextbsd-ci-pipeline-plan.html?v=20260603">NextBSD CI Pipeline Plan <span class="pill ok">Live</span></a>
<span class="desc">Automated FreeBSD cross-build pipeline on GitHub Actions free-tier Linux runners: daily fork sync, Docker-layered toolchain containers on GHCR, kernel/modules/base cross-builds, and the <code>nextbsd</code> ISO assembler. Targets <code>releng/15.0</code> for pkg ABI compatibility; zero self-hosted runners, no open ports. <strong>Now live end-to-end</strong> and refactored around rolling, CI-gated <code>continuous</code> releases (producers publish on green <code>main</code>; consumers ingest the release, never in-flight PR artifacts), with PR validation on every repo, arm64 base parity, and a PR-only kernel boot smoke test. See §0 for the June 2026 status.</span>
</li>
<li>
<a href="gershwin-on-nextbsd-iso-pipeline-plan.html?v=20260617">Gershwin on NextBSD — build & live-ISO pipeline <span class="pill pill-warn">Design plan</span></a>
<span class="desc">How the (currently empty) <code>pkgdemon/gershwin-on-nextbsd</code> repo grabs the latest NextBSD <code>.img.zip</code>, builds the Gershwin desktop into its rootfs, and repackages the result into a live ISO that boots identically to NextBSD’s own — 2-stage MFS, on-demand uzip, unionfs, and <code>vfs.pivot</code>. Covers why the repackage must run inside a FreeBSD VM, the repo layout, the <code>build-iso.yml</code> pipeline and live-ISO repackage stage, and the three launchd services (<code>loginwindow</code>, <code>dshelper</code>, <code>gdomap</code>) the desktop overlay must ship.</span>
</li>
<li>
<a href="gershwin-developer-nextbsd-ci-plan.html?v=20260617">gershwin-developer — NextBSD build CI (vmactions chroot) <span class="pill pill-warn">Plan</span></a>
<span class="desc">Add a fourth build target to <code>gershwin-developer</code>’s <code>build.yml</code> — alongside FreeBSD, Arch, and Debian — that verifies Gershwin compiles on NextBSD. The trick earlier lacked: don’t boot the NextBSD image, chroot-build into its rootfs inside a FreeBSD VM. Documents where the job fits in <code>build.yml</code>, the one make-or-break risk, and what the check does and doesn’t prove. The job scrapped two iterations ago, now actually feasible.</span>
</li>
<li>
<a href="nextbsd-linux-crossbuild-image-plan.html?v=20260602">NextBSD — cross-build the Apple userland + image on native Linux <span class="pill pill-warn">Single-PR plan</span></a>
<span class="desc">Move the NextBSD image build off the <code>vmactions/freebsd-vm</code> qemu VM (~17 min) onto a native Linux runner that cross-compiles the entire Apple/Darwin userland for FreeBSD with Clang 19 — zero FreeBSD packages, no chroot, the bootable UFS image assembled on Linux, <code>qemu</code> used only to boot-test (which already runs on ubuntu). Reuses the proven cross-build pattern from <code>nextbsd-kernel-toolchain</code> / <code>-kernel</code> / <code>-kernel-modules</code> / <code>-freebsd-compat</code>. Component-by-component plan for all 32 <code>src/</code> components + <code>mach.ko</code>, the two net-new CMake toolchain files (libdispatch, ICU), Linux image assembly (makefs/mkimg), and a boot-contract parity oracle. Unlocks a faster arm64 ISO as a free matrix leg.</span>
</li>
<li>
<a href="nextbsd-ci-testing-strategy-plan.html?v=20260603">NextBSD CI — testing coupled cross-repo changes (strategy options) <span class="pill pill-warn">Decision plan</span> <span class="pill ok">Backbone shipped</span></a>
<span class="desc">How to boot-test changes that span two repos <em>before either merges</em> — motivating case: a <code>nextbsd-kernel</code> PR raising the dynamic syscall-slot limit plus a <code>nextbsd</code> PR dropping <code>mach.ko</code>’s syscall multiplexor. Visual comparison of five strategies (continuous-release + latest-green pin, artifact-override inputs, full monorepo, partial monorepo, hybrid integration meta-workflow) with a per-stage <strong>time-to-test</strong> cost model across today’s VM and native-cross worlds, a ratings matrix, and a NOW-vs-after-crossbuild recommendation. Confirms 5 current CI gaps (no PR triggers / no kernel boot test / latest-main-only ingest / a modules patch-ref desync / arm64 asymmetry).</span>
</li>
<li>
<a href="freebsd-mach-kmod-syscall-slots-impl-plan.html?v=20260603">mach.ko syscall slots — implementation plan (widen the band, drop the mux) <span class="pill ok">Plan ready</span></a>
<span class="desc">Now that NextBSD ships its own kernel, the fix for the 10-slot Mach syscall ceiling is to widen FreeBSD’s <code>lkmnosys</code> band in the <code>NEXTBSD</code> kernel (a <code>syscalls.master</code> patch in nextbsd-kernel) so each Mach trap gets its own slot and the multiplexor goes away. Measured need ~32 slots; provision ~48. Includes a measured effort-scope of the XNU-style separate trap table (the kernel hook is a cheap C-only change, but first-of-its-kind on FreeBSD and its Apple-canonical-number benefit is moot because libmach resolves by name), and confirms IOKit needs no XNU <code>libsyscall</code>. Two-PR rollout: widen the band, then drop the mux. Supersedes the audit spike’s “kernel-patch disqualified” verdict.</span>
</li>
<li>
<a href="freebsd-hwregd-busystate-impl-plan.html?v=20260603">IOKit busyState / waitQuiet — implementation plan (Apple-shape kmod autoload) <span class="pill ok">Plan ready</span></a>
<span class="desc">The “right way” to drive kmod autoload: a real device-quiescence signal (<code>IOServiceWaitQuiet</code> / <code>IORegistryEntryGetBusyState</code> / <code>IOKitWaitQuiet</code>) over Mach, replacing FreeBSD’s devctl-plus-a-timer heuristic. A balanced <code>device_match_start</code>/<code>device_match_end</code> hook wrapping <code>device_probe_and_attach()</code> in the <code>NEXTBSD</code> kernel feeds a mach.ko <code>bus_busy</code> counter + a <code>mach_wait_quiet</code> syscall; hwregd flips on quiescence and libIOKit implements the Apple APIs. Makes concrete (and corrects the counter design of) the deferred plan in the #67 options doc, now that NextBSD ships its own kernel. Tracked by #176; two-PR rollout like the syscall work.</span>
</li>
<li>
<a href="freebsd-ko-to-kext-conversion-plan.html?v=20260603">FreeBSD <code>.ko</code> → Apple <code>.kext</code> conversion <span class="pill pill-warn">Plan</span></a>
<span class="desc">Convert NextBSD’s kernel modules from FreeBSD <code>.ko</code> to Apple <code>.kext</code> bundles in <code>/System/Library/Extensions</code> — the Apple-shaped <em>format</em>, established before the kextd loader port. Code-grounded 3-agent scope: a <code>.kext</code> bundle wraps the unmodified <code>.ko</code> (still <code>kld</code>-loaded), <code>Info.plist</code> <code>IOKitPersonalities</code> generated from <code>MODULE_PNP_INFO</code> feed the userspace matcher NextBSD already has (libIOKit→hwregd); a full XNU <code>OSKext</code> is explicitly out of scope (the path ravynOS left FreeBSD for). Includes the firmware answer (gpu <code>.ko</code>-firmware vs wifi <code>/boot/firmware</code> → <code>Contents/Resources</code>) and the boot-critical caveat. Novel — nobody packages <code>.ko</code> as <code>.kext</code> today.</span>
</li>
<li>
<a href="nextbsd-apple-device-matching-plan.html?v=20260603">Eliminating standalone hwregd — Apple-shaped device matching & autoload <span class="pill pill-warn">Convergence plan</span></a>
<span class="desc">How to retire NextBSD’s standalone devctl-socket + timer <code>hwregd</code> daemon and converge toward Apple’s shape — in-kernel matching + match-notifications & <code>busyState</code>/<code>waitQuiet</code> over Mach + a launchd-activated loader (Apple keeps <code>kextd</code>/<code>kernelmanagerd</code>; the win is event-driven, not zero daemons). Umbrella over #67 (settle window), #176 (busyState), and #168 (<code>EVFILT_MACHPORT</code> / fold into configd). Phased roadmap from a 3-agent scope of Apple XNU/IOKit + kext_tools, the NextBSD hwregd/configd/launchd/mach.ko tree, and FreeBSD kqueue internals.</span>
</li>
<li>
<a href="nextbsd-graphics-plan.html?v=20260609">NextBSD graphics — virtual-GPU DRM kexts, an end-to-end CI test, and the NVIDIA/VirtualBox tracks <span class="pill pill-warn">Porting plan</span></a>
<span class="desc">The drm-kmod → Intel/AMD/Radeon kexts autoload via the in-kernel matcher, but that path is untested end-to-end — qemu emulates no real GPU. Port a <em>virtual</em>-GPU DRM driver (bochs first — it binds qemu’s default <code>-vga std</code> as a raw <code>IOPCIPrimaryMatch</code> node) to unlock KMS-in-VMs <em>and</em> the first true match→autoload→bind CI test. Scopes bochs/vboxvideo/virtio-gpu/vmwgfx, the shared blocker (drm-kmod’s missing <code>drm_gem_vram</code>/<code>shmem</code> helpers → a <code>drm_extra_helpers.ko</code>), the repo split (unmodified <code>drm-kmod</code> fork + a <code>nextbsd-graphics</code> kext factory + a recipe-only NVIDIA-legacy repo), and a phased roadmap. From a 7-agent scope.</span>
</li>
<li>
<a href="nextbsd-nvidia-kext-porting-plan.html?v=20260711">NextBSD graphics — porting the NVIDIA driver as per-branch co-existing kexts <span class="pill pill-warn">Porting plan</span></a>
<span class="desc">The dedicated follow-on to the graphics plan’s NVIDIA track: one <code>NVIDIAGraphics<NNN>.kext</code> per FreeBSD nvidia branch (595/580/470/390/340/304), tiered by method — <strong>drm-kms</strong> (595/580, bind <code>drmn</code>, <code>/dev/dri</code>), <strong>modeset-only</strong> (470/390), <strong>core-only</strong> (340/304) — each carrying its own de-overlapped PCI match table and (595/580 only) raw GSP firmware, built from NVIDIA’s driver tarball like FreeBSD’s nvidia ports (which ship as binary pkgs). From a 9-agent research+review workflow that caught four defects: a kext wraps multiple <code>.ko</code>s so <code>CFBundleExecutable</code> is the <em>top</em> of the <code>MODULE_DEPEND</code> chain per tier (not uniformly <code>nvidia</code>); 390 is modeset-only not core-only; 595 is the proprietary module with GSP default-off (not open-modules/GSP-mandatory); firmware is raw blobs in <code>Resources/firmware/</code>. The permanent wall: every branch’s core is module <code>nvidia</code>, so <strong>one branch resident per kernel</strong> — multi-GPU works only if a single branch covers all cards. Since validated against real source: matcher confirmed PCI-id personalities; one kext per <code>.ko</code> chained; <code>nvidia-drm-612-kmod</code>/595.84 confirmed real; the drm-kmod stack (Intel/AMD/Radeon + NVIDIA) shares one <code>drm.ko</code> core so going 6.12 moves all four together (gated on the 15.1 base). Step 1 (<code>gen-nvidia-personalities</code>) merged as nextbsd-kernel-modules#17.</span>
</li>
<li>
<a href="nextbsd-inkernel-iokit-feasibility.html?v=20260605">In-kernel IOKit for NextBSD — feasibility & the matching-location decision <span class="pill pill-warn">Decision doc</span></a>
<span class="desc">The single fork under the kextd milestone: does driver–device <strong>matching</strong> live in the kernel (Apple-faithful — the kernel decides, kextd just loads) or in userland (faster, but a divergence)? Deep 2-agent review of FreeBSD newbus internals + Apple’s XNU IOKit / IOCatalogue / kextd, with per-option effort & risk and the “do I edit the kernel to add device IDs?” clarification (no — IDs live in kext personalities). Companion to the hwregd convergence plan; for joint review before any kextd code.</span>
</li>
<li>
<a href="nextbsd-evfilt-machport-native-plan.html?v=20260608">Native <code>EVFILT_MACHPORT</code> migration & pipe-bridge removal — #168 plan <span class="pill pill-warn">Plan ready</span></a>
<span class="desc">Move <em>all</em> Mach-event delivery onto the kernel’s native <code>EVFILT_MACHPORT</code> filter (slot -16) and <strong>delete the module-era pipe-bridge</strong> (task #39 Path B: <code>register_event_bell</code> + self-pipe + <code>EVFILT_READ</code>) — the workaround from when a <code>.ko</code> couldn’t add a kqueue filter slot, now obsolete since <code>patches/0003</code> reserves the slot. Synthesized from a 7-agent survey of nextbsd-kernel + nextbsd + freebsd-src. Root-causes the PR #250 boot panic (a use-after-free on the port set in <code>filt_machportattach</code> — drops the pset lock with no reference, then <code>knlist_add</code> touches freed/reallocated memory at <code>0x70</code> under concurrent <code>move_member</code>, amplified by uninitialized worker-thread Mach state, #148) and gives the exact kernel fix. Fixes task #41 (unreliable <code>DISPATCH_SOURCE_TYPE_MACH_RECV</code>) at the root, retiring the <code>pthread</code>+<code>mach_msg</code> polling loops in <code>sc_link_watch</code>/<code>IOKitNotify</code>/<code>SCNotify</code>. 6-stage PR-gated rollout + a new concurrency stress test that reproduces the panic.</span>
</li>
<li>
<a href="mdns-network-browse-mach-plan.html?v=20260621">mDNS Network browse over Mach — the empty Network-list fix <span class="pill pill-warn">Plan ready</span></a>
<span class="desc">A concrete consumer of the <code>EVFILT_MACHPORT</code> doctrine above. The Workspace File Viewer’s <strong>Network</strong> sidebar is empty on NextBSD: <code>mDNSResponder</code> advertises its own <code>.local</code> name (peers see <code>ThinkPad-T460s</code>) but the <code>dns_sd</code> <em>client</em> protocol was never finished over Mach — <code>mach_bridge.c</code> only claims <code>com.apple.mDNSResponder</code> and discards the receive right, and <code>libdns_sd</code> ships as the AF_UNIX stub bound to a <code>/var/run/mDNSResponder</code> socket the <code>nobody</code> daemon can never create. Fix (Mach, not sockets): a <code>dns_sd.defs</code> MIG IDL + real Mach server wired through <code>EVFILT_MACHPORT</code>, plus a Mach client transport in <code>libdns_sd</code>. File Viewer and NetworkBrowser.app share the same <code>NSNetServiceBrowser</code> backend, so the UI needs zero changes. Primary repo: <code>nextbsd-redux/nextbsd</code> (<code>src/mDNSResponder/</code>); Sharing-pane launchd shim is a separate follow-on in <code>gershwin-desktop/gershwin-components</code>. Filed under <a href="launchd-research.html">Launchd → Mach</a>.</span>
</li>
<li>
<a href="nextbsd-mach-builtin-plan.html?v=20260603">mach.ko → kernel built-in (<code>options COMPAT_MACH</code>) <span class="pill pill-warn">Scoping</span></a>
<span class="desc">Compile the out-of-tree Mach module <em>into</em> the <code>NEXTBSD</code> kernel instead of loading it as a <code>.ko</code> — the answer to “how do we load <code>mach.ko</code> once <code>loader.conf</code> is gone?” and the foundational step of #180 (eliminate <code>loader.conf</code>). Mostly build-system wiring: the MIG server stubs are pre-committed (no codegen in the kernel build) and the syscalls already register via a <code>SYSINIT</code>/<code>kern_syscall_register</code> (no <code>syscalls.master</code> regen). Source migrates <code>nextbsd/src/mach_kmod</code> → <code>nextbsd-kernel</code> <code>sys/compat/mach/</code>, wired by a small <code>sys/conf/{options,files}</code> patch; the fork is never touched. Gated by the boot smoke test.</span>
</li>
<li>
<a href="nextbsd-kext-proof-of-concept-plan.html?v=20260603">Prove kexts work — minimal kextload + converter + PR CI <span class="pill pill-warn">Scoping</span></a>
<span class="desc">Walking-skeleton proof that a FreeBSD <code>.ko</code> wrapped as a <code>.kext</code> loads via an Apple-shaped tool, gated by CI. Cheap because <code>nextbsd</code> already ships <code>CFBundle</code> (opens the bundle + Info.plist) and <code>libIOKit</code> — so the proof needs <em>no</em> <code>OSKext</code>: a minimal <code>kextload</code>/<code>kextstat</code>/<code>kextunload</code> trio over <code>kld</code> (Phase 1, in <code>nextbsd</code>) + a converter and PR CI that <code>kextload</code>s one leaf module in a booted VM (Phase 2, in <code>nextbsd-kernel-modules</code>). The full <code>kext_tools</code>/<code>OSKext</code> port is deferred but ticketed so it isn’t lost. Approach (a) chosen. <span class="pill ok">Proven & merged</span></span>
</li>
<li>
<a href="nextbsd-oskext-port-plan.html?v=20260604">Faithful kext_tools / OSKext port <span class="pill pill-warn">Plan (#182)</span></a>
<span class="desc">Port Apple’s real <code>OSKext</code> engine (bundle discovery, dependency-graph resolution, validation, personalities) onto NextBSD with a <code>kld</code> backend — the faithful follow-on to the PoC, gating bulk conversion (#179) and kextd (#177). Code-grounded scope: <code>OSKext.c</code> ≈ 21k LOC but ~75% ports unchanged (CFBundle parsing, dep-graph math, validation); only ~25% re-backs from XNU (<code>kext_request</code>→<code>kldload</code>, <code>IOCatalogueSendData</code>→hwregd, KXLD/mkext deleted). Pre-SIP base avoids codesign/kernelcache. Multi-week, phased; Phase 1 (dependency resolution) is the first shippable milestone.</span>
</li>
<li>
<a href="nextbsd-kld-to-kext-naming-plan.html?v=20260607">kld → kext: naming + categorization <span class="pill pill-warn">Plan (#179)</span></a>
<span class="desc">Groundwork for the bulk <code>.ko</code>→<code>.kext</code> conversion: a complete catalog of all 474 FreeBSD kernel modules in the tree — what each is, its category (driver / filesystem / network / crypto / KPI / …), and a proposed Apple-style <code>org.nextbsd.*</code> bundle id + <code>.kext</code> name. Built from a read-only review of <code>freebsd-src/sys/modules</code> by parallel agents. Surfaces the open decisions before #179: naming style, kext-vs-built-into-kernel split, sub-component/firmware handling, exclusions.</span>
<ul>
<li>
<a href="nextbsd-kld-to-kext-catalog.html?v=20260607">Raw module catalog — all 474 modules</a>
<span class="desc">The unedited, first-pass per-module table behind the naming plan: one row per <code>sys/modules/</code> entry — ko name, dir, category, purpose, proposed bundle id + <code>.kext</code> name, notes. Kept verbatim as the groundwork record the polished plan was distilled from.</span>
</li>
</ul>
</li>
</ul>
<footer>
<p><a href="index.html">← Back to home</a></p>
</footer>
</body>
</html>