IPv6 on, forgetest dual-stack, the release rootfs sheds 22 MB

The distro keeps its ipv6 feature (busybox networking and ifupdown
inet6, openssh, ntp and rsyslog follow); forgetest binds "::" by
default, one dual-stack socket that still serves IPv4. The release
image drops nano (with it file and the libmagic database, 8.7 MB; the
dev image keeps nano), the udev hardware database (7.7 MB of USB and
PCI identities for buses the board lacks, via BAD_RECOMMENDATIONS) and
urllib3's pyOpenSSL/cryptography recommendation (6 MB; nothing imports
them, TLS goes through the standard library). BRINGUP item 21 records
the round and the bench checks it owes; item 16 gets its re-measure
plan on the UP kernel with the performance governor.

Coverage: image.* covers the rootfs composition and the distro conf
(platform); forgetest's own suite covers the server.
This commit is contained in:
ScottW514
2026-08-24 15:40:19 -04:00
parent dd6f459d7b
commit 326c3e758b
7 changed files with 54 additions and 11 deletions
+28 -4
View File
@@ -1271,6 +1271,14 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
modes, 4.1× and 16.4× fewer bytes); frame rate only spaces the stalls out,
and the existing `FORGECTRL_STREAM_FPS` cap skips demosaic and encode but
still dequeues every frame. Shares the bench slot with item 8.
To re-measure on the next image before spending more on it: the kernel
is now UP (no SMP locking) with the performance governor as the only
governor (no 396 MHz idle floor, no ondemand sampling delay), and the
video offload's hardware frame skip halves the dequeues the cache
maintenance rides on. The same drill (a GRBL job with the stream live,
the run's `clamped` count and `min margin`) decides whether the camera
gate is still owed or the item closes.
17. **Laser power model: dose by FIRE-bit density.** grblHAL maps S onto the
analog PWM duty (`$30`/`$31` → `$35`/`$36`, written raw into PWMSAR against
the 127-count period). `$35` now ships at 16, the measured lasing
@@ -1528,10 +1536,26 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
a virtual console. The crash record is proven: a forced `sysrq-c`
panicked, rebooted on the timeout, and the next boot read back
`dmesg-ramoops-0` and `console-ramoops-0` with no ECC errors (the
first boot's header-init lines did not repeat). Still owed: a GRBL job
on the image, then the acceptance campaign (platform change). The `spi_device_id` table for
`glowforge,pic` (kernel-module-glowforge) is not in this image; it lands
with the module's next pin bump.
first boot's header-init lines did not repeat). The `spi_device_id`
table for `glowforge,pic` is pinned into the next build (its boot
warning goes with it). Still owed: a GRBL job on the image, then the
acceptance campaign (platform change).
A second round rides the next image, host-proven and unflashed: the
kernel is UP (`SMP` off) with performance as its only cpufreq governor;
spi-imx no longer logs the absent DMA channel (patch 0014) and the
module no longer logs a run request on an empty ring (grblHAL treats it
as the ordinary race it is); `consoleblank=0` is gone from the boot
arguments; only `wl18xx-fw-4.bin` and `wl18xx-conf.bin` ship for the
WL1805 (the current factory image's set); IPv6 is on end to end
(distro feature, `udhcpc6` from the `wlan0 inet6` stanza, forgectrl,
grblHAL's TCP:23 and forgetest listening dual-stack); the log export
carries `/sys/fs/pstore`; and the release rootfs drops nano/libmagic,
the udev hardware database and urllib3's pyOpenSSL chain (~22 MB).
Owed on the bench: boot (dmesg without the three lines), a GUA on
wlan0 with each port answered over IPv6, `scaling_governor` reading
performance, Wi-Fi up without the NVS warning, an export that contains
the sysrq record, then the item-16 drill and the campaign.
**Deliberately not gated:** an armed GRBL job after an underrun cuts at the
stale origin unless homing is required (GRBL mode permits unhomed cutting; the
+2 -2
View File
@@ -1,6 +1,6 @@
"""forgetest daemon entry point.
python3 -m forgetest [--port 8090] [--host 0.0.0.0] [--manifest PATH]
python3 -m forgetest [--port 8090] [--host ::] [--manifest PATH]
Environment: FORGETEST_DATA (state directory, default /data/forgetest),
FORGETEST_MANIFEST, FORGETEST_BENCH_DIR, FORGETEST_MARKER, and the hw.py
@@ -24,7 +24,7 @@ from .runner import Runner, configure_journal
def main(argv=None):
ap = argparse.ArgumentParser(prog="forgetest")
ap.add_argument("--port", type=int, default=int(os.environ.get("FORGETEST_PORT") or 8090))
ap.add_argument("--host", default=os.environ.get("FORGETEST_HOST") or "0.0.0.0")
ap.add_argument("--host", default=os.environ.get("FORGETEST_HOST") or "::")
ap.add_argument("--manifest", default=None)
ap.add_argument("--version", action="version", version="forgetest %s" % VERSION)
args = ap.parse_args(argv)
+9 -2
View File
@@ -38,6 +38,7 @@ import re
import secrets
import sys
import urllib.parse
import socket
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from . import artifact as _artifact
@@ -327,9 +328,15 @@ class Handler(BaseHTTPRequestHandler):
self._deny(500, "%s: %s" % (type(e).__name__, e))
def make_server(app, host="0.0.0.0", port=8090):
def make_server(app, host="::", port=8090):
handler = type("ForgetestHandler", (Handler,), {"app": app})
ThreadingHTTPServer.allow_reuse_address = True
srv = ThreadingHTTPServer((host, port), handler)
# An IPv6 bind address (the default "::") gives one dual-stack socket
# that serves IPv4 clients too; a dotted address keeps the IPv4 family.
server_cls = ThreadingHTTPServer
if ":" in host:
server_cls = type("ForgetestServer6", (ThreadingHTTPServer,),
{"address_family": socket.AF_INET6})
srv = server_cls((host, port), handler)
srv.daemon_threads = True
return srv
+4 -1
View File
@@ -5,7 +5,7 @@ DISTRO_NAME = "OpenGlow/ForgeFIRM"
DISTRO_VERSION = "0.0.0"
DISTRO_FEATURES:remove = " \
3g alsa avahi bluetooth bluez5 ext2 ipv6 irda nfc nfs pci pcmcia \
3g alsa avahi bluetooth bluez5 ext2 irda nfc nfs pci pcmcia \
pulseaudio vulkan wayland x11 zeroconf "
# opengl stays: forgectrl's camera demosaic runs as GLES2 fragment
@@ -15,6 +15,9 @@ DISTRO_FEATURES:remove = " \
# (both remain removed above), so the cost is the libraries and the one
# driver, not a graphics stack.
PACKAGECONFIG:pn-mesa = "opengl gles egl gbm gallium etnaviv"
# udev's hardware database is USB and PCI vendor/product identities (7.7 MB);
# the board has neither bus.
BAD_RECOMMENDATIONS += "eudev-hwdb"
# System logger: rsyslog replaces busybox syslogd/klogd. Every ForgeFIRM
# process logs through it and it is the only log writer (one directory
@@ -0,0 +1,6 @@
# urllib3's optional pyOpenSSL/cryptography backend is not used here: the cloud
# client and the machine glue talk TLS through the standard library's ssl
# module (nothing imports OpenSSL or cryptography). Dropping the two runtime
# recommendations takes cryptography, pyOpenSSL, cffi, pycparser and ply
# (about 6 MB) off the rootfs.
RDEPENDS:${PN}:remove = "python3-cryptography python3-pyopenssl"
@@ -12,6 +12,7 @@ IMAGE_INSTALL += " \
forgetest \
python3-gfutilities-emulator \
htop \
nano \
"
# debug-tweaks (passwordless root, root SSH login) belongs ONLY to the dev
@@ -10,8 +10,10 @@ DESCRIPTION = "OpenGlow/ForgeFIRM image for Glowforge"
# (gfui-client connects to Glowforge's servers). Removing it here (override
# only; the shared glowforge-image base is untouched) also sidesteps its
# do_package failure. Its role is filled locally by forgectrl and the
# controllers below.
IMAGE_INSTALL:remove = "gfui-client"
# controllers below. nano is a bench convenience (the dev image keeps it);
# on the release rootfs it costs 8.7 MB, most of it libmagic and its
# database, which nothing else here uses.
IMAGE_INSTALL:remove = "gfui-client nano"
# grblhal-glowforge: the grblHAL motion controller (Grbl over TCP:23).
# forgectrl: the ForgeFIRM machine-services daemon (HTTP :8080): controller