191 lines
10 KiB
Markdown
191 lines
10 KiB
Markdown
# Dasung Paperlike 13K base-system integration
|
||
|
||
Development reference and historical context. For current operating instructions, use the [user manual](../README.md). Acceptance applies only to the source and artifacts identified in each record.
|
||
|
||
|
||
[Documentation index](README.md) · [First build](getting-started.md) · [Services](services.md)
|
||
|
||
FDS includes the Rust **dasungd** controller from the project's earlier
|
||
**Fix Dasung monitor black screen** task. It targets the user's **Paperlike 13K
|
||
grayscale**, serial `L56051794302`, with the confirmed 3200 × 2400 timing at about
|
||
37 Hz. This is core display support: its package is required for the base SYSTEM
|
||
image, and its service belongs to the base boot bundle, including console-only use.
|
||
It does not require an ENVIRONMENT cartridge, WindowMaker, or a graphical session.
|
||
|
||
**Implementation boundary:** the daemon, ARM package, and s6 service definitions
|
||
are included by the [rootfs assembler](rootfs.md). [M2 native init](init.md) starts
|
||
the controller in the base boot graph, including in the ARM VM with no monitor.
|
||
The [M4 boot path](boot.md) starts an early copy before SYSTEM exists, then stops
|
||
and reaps it before base s6 starts the normal daemon. Software handoff is tested
|
||
in a VM; physical Pi display and monitor recovery remain unverified. The final
|
||
s6 database is compiled at image build time.
|
||
|
||
## Build it on the workstation
|
||
|
||
Complete `make bootstrap` as described in [Your first build](getting-started.md),
|
||
then run from the repository root, as your regular user:
|
||
|
||
```sh
|
||
make dasung
|
||
make dasung-test
|
||
```
|
||
|
||
The first command prepares the additional C cross compiler inside the existing
|
||
Void build container, fetches the crates pinned in `Cargo.lock`, and cross-builds
|
||
static-musl `dasungd`. It verifies the ELF, builds the `fds-dasungd` XBPS overlay,
|
||
indexes the output, and compiles the actual s6 source into a validation database.
|
||
The second runs unit tests and a simulated serial monitor, then inspects the
|
||
package and compiles the service definitions extracted from that package. It also
|
||
runs that s6 graph with a native test binary, a read-only container root, and no
|
||
physical device access to check startup, logging, permissions, restart, and stop.
|
||
|
||
Python 3 is needed **only on the host for the simulator**. If absent on Arch,
|
||
install `python` with pacman. No Python interpreter is shipped for the daemon.
|
||
The first additional toolchain download is approximately 243 MB and needs roughly
|
||
1 GB of extra container space. Builds still depend on rolling Void binary inputs.
|
||
Run these commands sequentially with other FDS builds; they share the container.
|
||
|
||
| Output | Purpose |
|
||
| --- | --- |
|
||
| `out/dasungd` | Static AArch64 executable; no target glibc, musl, libusb, or libudev shared library dependency |
|
||
| `out/packages/fds-dasungd-0.1.0_1.aarch64.xbps` | Target package with executable, config, exact EDID, s6 source, udev rule, and licenses |
|
||
| `out/manifests/dasung-s6-database.txt` | Path to the service database compiled on the host for validation |
|
||
| `out/manifests/dasung-artifacts.sha256` | Executable and package hashes |
|
||
| `out/manifests/dasung-build-packages.txt` | Installed build-container input versions |
|
||
| `out/logs/dasung-build.log`, `dasung-checks.log` | Build and test evidence |
|
||
|
||
The standalone validation database contains only the Dasung subset. The M2
|
||
image assembler merges it with the init package and compiles the full current
|
||
graph while building the rootfs. No daemon is started on the workstation by these targets;
|
||
the integration test uses its own temporary socket and pseudo-terminal.
|
||
|
||
## What goes into the base system
|
||
|
||
`image/base-packages.list` makes `fds-dasungd` a mandatory hardware package.
|
||
`packages/fds-dasungd/template` is the active FDS-owned XBPS overlay. The upstream
|
||
Void tree remains pinned and unchanged. Source is maintained at `rust/dasungd/`;
|
||
the original task directory is not required for future builds.
|
||
|
||
The package installs:
|
||
|
||
- `/usr/bin/dasungd` and `/etc/dasungd.toml`.
|
||
- `/usr/lib/firmware/edid/dasung-paperlike13k-37hz.bin`.
|
||
- `/etc/s6-rc/source/dasungd`, its runtime-directory and log services, and the
|
||
`boot/contents.d/dasungd` membership entry.
|
||
- `/usr/lib/udev/rules.d/99-dasung-spi.rules`, adapted to eudev syntax.
|
||
- Documentation and the controller/libusb licenses.
|
||
|
||
s6 supervises the foreground daemon. A short oneshot creates private writable
|
||
runtime/log directories; it does not wait for the display. The daemon starts with
|
||
no monitor attached and retries discovery. Its initial service transition does
|
||
not wait for a monitor reply, a desktop, the network, or all cartridge bays.
|
||
The log service rotates a small log under `/run/log/dasungd`.
|
||
|
||
The init package adds a dependency on `runtime-fs` so the controller starts with
|
||
its kernel interfaces mounted. The service runs as root because it claims USB interfaces. Its socket
|
||
is under a root-owned mode-0750 directory; runtime control is restricted to root.
|
||
A future FDS CLI can expose selected operations through an explicit policy.
|
||
No world-writable USB rule, systemd unit, or runit service is installed.
|
||
|
||
## Confirmed profile and Pi-specific choices
|
||
|
||
| Property | Recorded value |
|
||
| --- | --- |
|
||
| Monitor | Paperlike 13K grayscale; `L56051794302` |
|
||
| Resolution | 3200 × 2400 |
|
||
| Pixel clock | **304210 kHz** (304.21 MHz) |
|
||
| Horizontal active / sync start / sync end / total | 3200 / 3248 / 3280 / 3360 |
|
||
| Vertical active / sync start / sync end / total | 2400 / 2423 / 2427 / 2447 |
|
||
| Sync polarities | Positive horizontal and vertical |
|
||
| EDID SHA-256 | `b6c1e0a8d315d9cf5c2fb83784a177530bcc085c2d0724dc7478a9c12449e4f4` |
|
||
| Control transport | USB UART `1a86:7523`, with companion SPI bridge `1a86:5512` |
|
||
| Startup parameters | Raw mode 1 and contrast 4, previously read back on this unit |
|
||
| Keepalive | `20 01` every two seconds; minimum 150 ms between command writes |
|
||
|
||
The video timing was confirmed on the original AMD workstation, **not on a Pi**.
|
||
The original USB-C video connection is not a Pi cabling prescription. Pi connector,
|
||
cable/adapter, mode acceptance, and picture stability require hardware validation.
|
||
For the current HDMI video plus USB control procedure, including separate monitor
|
||
power and a reversible native-EDID experiment, use the [display guide](../dasung.md).
|
||
Desktop 2× scaling is separate from EDID timing; a console uses its own font size.
|
||
|
||
FDS configures `display.enabled=false` and `hotplug="none"`: the daemon handles
|
||
USB control without applying the source project's AMD debugfs disconnect/reconnect
|
||
procedure. The Pi boot/display integration must supply the appropriate KMS/firmware
|
||
EDID configuration for its real connector. The Pi boot-volume builder now supplies
|
||
an unqualified firmware EDID override for this dedicated monitor; it does not
|
||
assume `DP-2` or a numbered HDMI connector. See the [boot guide](boot.md) for
|
||
the exact command line and the remaining physical mode test.
|
||
|
||
The daemon requires the configured monitor's DRM EDID and the matching USB
|
||
companion topology before claiming a device. Multiple matching UARTs are rejected;
|
||
`usb_path` can disambiguate a verified Pi topology. Do not substitute a blanket
|
||
match for all CH340 adapters or copy this unit's identity to a different monitor.
|
||
|
||
The original monitor's SPI driver interaction caused a dark picture after a power
|
||
cycle. `image/kernel/dasung.config` requires `CONFIG_SPI_CH341=n`; the Pi kernel
|
||
builder enforces this before boot, including the initramfs environment. The scoped
|
||
udev rule is secondary protection: it cannot prevent a built-in or already-loaded
|
||
SPI driver from probing. The daemon also reserves the companion interface without
|
||
sending SPI data and refuses to take it from an already-bound kernel driver.
|
||
|
||
## Runtime usage once installed in an FDS image
|
||
|
||
These are target commands, **not commands to run against the workstation's live
|
||
monitor during the build**:
|
||
|
||
```text
|
||
dasungd status
|
||
dasungd query
|
||
dasungd refresh
|
||
dasungd set contrast 4
|
||
dasungd set mode 1 --save
|
||
dasungd forget mode
|
||
```
|
||
|
||
`status` returns JSON including `connected`, `responsive`, reply age, and cached
|
||
parameters. A successful set means a packet was sent; use query/status to check
|
||
observed values. It is not proof of physical image quality. Color-model mode names
|
||
are not assigned to this grayscale monitor's raw numeric modes.
|
||
|
||
The default socket is `/run/dasungd/control.sock`. External programs can use its
|
||
newline-delimited JSON protocol; the daemon remains the only USB owner:
|
||
|
||
```json
|
||
{"op":"status"}
|
||
{"op":"set","parameter":"contrast","value":4,"save":true}
|
||
```
|
||
|
||
In FDS's current payload, saved overrides live in `/run/dasungd/settings.json`.
|
||
They survive a daemon restart **within the same boot**, but not power loss.
|
||
Mode 1/contrast 4 are persistent image configuration defaults. Once persistent
|
||
machine-state mounts are implemented, point `state_file` at that internal writable
|
||
storage to retain user overrides across boots. Do not put it on read-only SYSTEM
|
||
or make the base display daemon depend on a removable DATA cartridge.
|
||
|
||
## Dependencies and source provenance
|
||
|
||
The imported Rust dependencies are retained and pinned by the workspace lockfile:
|
||
`rusb` wraps USB access; `libc` supports Linux serial/locking calls; `ctrlc` handles
|
||
termination; `clap` provides CLI parsing; `serde`, `serde_json`, and `toml` support
|
||
configuration and the local socket; `anyhow` supplies contextual errors.
|
||
Transitive versions are recorded in `Cargo.lock`.
|
||
|
||
The `vendored` feature builds libusb from the pinned `libusb1-sys` crate. The Void
|
||
`cross-aarch64-linux-musl` toolchain supplies C headers/compiler for that library;
|
||
Rust's bundled musl target alone was enough for the old pure-Rust smoke-test, but
|
||
is insufficient for this C dependency. `LIBUSB_NO_PKG_CONFIG` and
|
||
`LIBUDEV_NO_PKG_CONFIG` prevent accidental host/shared-library linkage. libusb uses
|
||
its Linux netlink backend. No libusb/libudev shared runtime package is needed.
|
||
|
||
The target package depends on GNU coreutils for directory preparation, execline
|
||
for service launch, s6/s6-rc for supervision, and eudev for device rules. These
|
||
match the planned base userspace. The container's s6-rc is a build-time compiler,
|
||
not a target PID 1 running on Arch.
|
||
|
||
[Import provenance](../../rust/dasungd/IMPORT.md) records the original source hashes.
|
||
[Original validation](../../rust/dasungd/VALIDATION.md) records the live handoff and
|
||
remaining physical test. Protocol and reconnect tests use simulated hardware;
|
||
Pi boot, image quality, physical disconnect/reconnect, and corrected cold-power
|
||
recovery must still be verified on the actual target. No boot benchmark is claimed.
|