Splash handoff trial, 2026-09-22
The runtime U-Boot flag and conditional kernel path now preserve the stage-1 logo until Linux reaches its serial prompt, with the shell held back. The first Sway modeset still produces incorrect physical geometry/colors. This is partial progress; a usable splash-to-shell handoff is not verified.
The trial used the source-built daily image documented in
daily-shell-image-3f397a6.md, including U-Boot
patch 0005 and the c99a14f0q7wzfqplpzk223f79i7rjbp0 kernel. Only the
known logo asset and a temporary systemd.mask=shell.service boot argument
were installed. No flash or full readback was performed; no second card was
used. Preparation records the asset hash.
Stage 1 to idle Linux
100-second physical recording, boot transcript, serial inspection, and frame at 90 seconds.
The logo is still visible at the Linux prompt. /chosen/canaan,stage1-splash
is present, /dev/fb0 is absent, and the kernel logs stage 1 splash: leaving fbdev unset. Sway is masked. There is no panel prepare call at this stage;
the proposed expectation of a prepare-skip message before the first modeset
was incorrect. That message appears only when a DRM client actually starts.
USB is attached and the reboot is serial initiated, not a power-on or battery
trial. The video does not establish calibrated panel-motion statistics.
First Sway modeset
22-second physical recording, console, native screenshot, and physical frame at 18 seconds.
A temporary copy of the image shell unit, named shell-handoff, starts Sway
with its normal configuration. The kernel logs canaan_panel_prepare: left as stage 1 set it, while the PHY polls report 0x1529 != 0x1fbd. The service is
active and the native screenshot has the correct control order. The physical
panel wraps System to the left and changes the bar/title colors. Preserving
reset and skipping panel initialization alone therefore does not fix the
handoff. Retained VO/DSI state is under investigation; no cause is established.
This tests the real compositor’s first modeset, not the planned matching-logo DRM buffer. No seamless-transition or dark-frame duration claim is made.
Restore transcript puts back the original boot
arguments and removes the experimental logo before recovery. The temporary
unit is under /run and disappears at reboot. The daily image continues to
select panelConsole=true and omit the logo.
The normal recovery boot returned to
Linux; inspection records active shell and
seatd with no drop-ins, no splash flag, /dev/fb0 restored and no shell mask in
the command line. The recovery photograph
shows the correct control order and colors again.
Read-only register diagnostic
tools/vo-registers.c, built with nix/vo-registers.nix, snapshots only named
VO/DSI registers from the pinned register headers and device-tree addresses.
It contains no write path. The target build used the same flake’s cross pkgs:
nix build --impure --expr 'let f = builtins.getFlake "<absolute-worktree>"; in f.nixosConfigurations.k230.pkgs.callPackage ./nix/vo-registers.nix {}' --option max-jobs 1 --option cores 1
The helper compiled with -Wall -Wextra -Werror, was transferred with hash
verification, and was run on the no-logo control boot. The running kernel
refused its mmap with Operation not permitted.
A preceding read attempt through dd
returned Bad address. Neither transcript contains successful register values.
Comparison of actual normal/splash register state remains unverified; the
probe failure is not evidence that a particular register caused the defect.
Successful comparison with temporary diagnostic boot arguments
The kernel permitted the same read-only probe after temporarily adding
iomem=relaxed. This is a diagnostic boot setting, not an image default.
The control preparation,
control boot, and
normal snapshot record the
no-logo boot. The logo preparation,
logo boot, and
logo snapshot record the same
image with the known logo installed and Sway running.
All sampled registers match except the framebuffer address and
VO_OSD4_ADDR_SEL_MODE at VO offset 0x8a0: the normal boot reads 0x1100,
while the logo boot reads 0x0100. The framebuffer addresses are 0x1e300000
and 0x1e200000, respectively, and can vary with allocation. Both snapshots
have RGB565 format 2, stride 0x8e, DMA control 0x4f, and identical sampled
DSI timing values. Later repeated control reads found both address-selection values during a
correctly rendered session (see the phase diagnostic below). The single-pair
difference does not establish a cause of the physical defect; the probe samples
only a subset of registers, and no corrective write was attempted.
The restoration transcript restores the original boot arguments and removes the logo before the recovery reboot.
Recovery inspection confirms the original
command line without iomem=relaxed, no logo or splash flag, /dev/fb0 present,
and active shell and seatd services.
Address-select source audit and next diagnostic
The pinned Linux drivers/gpu/drm/canaan/canaan_vo.c writes 0x100 directly
to VO_OSD0_7_ADDR_SEL_MODE_REG_OFFSET in canaan_vo_update_osd(). The
U-Boot RM69A10 path in 0004-rm69a10-logo-port.patch writes 0x1100 to its
same OSD4 register. Neither the pinned Linux canaan_vo_regs.h nor the
vendor U-Boot display_logo.h defines individual bits for that register, so
the source does not establish whether bit 12 is writable mode state, a latch,
or a readback/status bit. The earlier research’s description of the value as
flip-related reports a LILYGO change; it is not a hardware-register semantic.
The missing-logo path gives no U-Boot explanation for the normal snapshot’s
0x1100: _k230_display_logo_load_pic() returns before display power or
st7701_init() when /logo.xrgb is absent, so it cannot write the OSD4
register. That leaves a reset/default or unobserved Linux/hardware transition.
No corrective register write is justified from these snapshots alone.
tools/vo-registers.c now reads the complete named OSD4 buffer block,
VO_OSD4_BD_CTL, DMA setup, mix/alpha/background/dither/CLUT, and the two
global conversion controls. It remains read-only. Collect it at the retained
stage-1 frame, immediately after the first Linux atomic commit, and steady
Sway to distinguish a hardware/latch transition from a software writer.
Separate retained-logo, Linux-owner and compositor phases
The 2026-09-22 follow-up uses the verified daily image from
daily-shell-image.md, source image commit 7a83afa,
system n5lqa24jxmlw5sn1q89y58js3ag7p859. It adds only temporary boot arguments
iomem=relaxed systemd.mask=shell.service, the known immutable logo copied to
/boot/logo.xrgb, and read-only/runtime diagnostic tools. No flash, kernel
replacement, home restoration, or MMIO write probe was involved.
The extended read-only probe is
/nix/store/a3mf5xjpvxyg6imsjycgpaznz74d1gzc-k230-vo-registers-riscv64-unknown-linux-gnu-0.1/bin/vo-registers.
The control snapshot and
four repeated reads establish that
VO_OSD4_ADDR_SEL_MODE changes between 0x100 and 0x1100 during normal,
correct display operation with the same framebuffer address. This invalidates
the earlier single-pair address-mode hypothesis; no forced register write is
justified.
The retained U-Boot frame snapshot and first Linux owner commit show:
| Register group | Retained stage 1 | Linux RG16 owner |
|---|---|---|
| VO and OSD4 Y window | 04df0010 | 04e00011 |
| RGB-to-YUV / YUV-to-RGB | 0 / 0 | 00010101 / 1 |
| OSD4 format / stride | 3 / 11c | 2 / 8e |
| OSD4 DMA | 40 | 4f |
| Buffer addresses | all 10000000 | all 1e300000 |
| Sampled DSI video timing | identical | identical |
The first Linux commit still logs two PHY status timeouts (1529 != 1fbd),
then reports successful RG16 framebuffer 49 scanout. These samples cannot
establish internal panel state or the cause of a visual defect.
The diagnostic owner uses the repository’s unchanged drm-splash.c, built
with only DEFAULT_ASSET=/tmp/logo.xrgb to make the same source logo available
on the daily image. Its output is
/nix/store/hk73za1q6bc327lv4zx4d524xxxrq2s0-k230-drm-splash-riscv64-unknown-linux-gnu-0.1.
The 25-second first-owner recording
shows the logo, but camera startup raced the serial start; it is not proof of
uninterrupted first-modeset continuity.
The subsequent owner-to-Sway recording starts four seconds before the serial handoff command. The console and registers show the owner dropping DRM master, retaining framebuffer 49, detecting its replacement, and exiting. The physical panel shows Apps, Windows, Keyboard, System in the same order and colors as the native screenshot. The earlier direct-to-Sway wrapped-control defect is absent in this trial. This is a manually staged warm-boot diagnostic, not yet an automatic image-service or power-on handoff proof.
Source reinspection also corrects the original design’s first-enable reset
claim: in the pinned prepared drivers/gpu/drm/canaan/canaan_vo.c,
canaan_vo_enable_crtc() initializes VO and timing without calling
k230_display_rst(). The explicit block reset is in canaan_vo_disable_crtc().
The drm_atomic_helper_commit_tail_rpm path enables modesets before updating
planes; DSI/PHY reprogramming still occurs during encoder enable. A bypass of
that initialization is not justified by the successful staged-owner trial.
Controlled repeat: the geometry fault is intermittent
A second warm boot repeated the same owner and Sway commands with the camera given four seconds to start. The 40-second recording shows a correct retained logo initially, a wrapped logo after the first Linux owner modeset, and a wrapped/color-shifted Sway display. Extracted frames show retained stage 1 at 0.5 seconds, Linux owner at 10 seconds, and Sway at 35 seconds. Compare the earlier correct physical Sway frame. The camera has glare and an oblique angle; it clearly distinguishes these large geometry changes but does not establish calibrated color accuracy.
The repeat console reports successful owner scanout and successor replacement, while the native screenshot is correct. Software success and a correct compositor buffer therefore do not prove correct physical scanout. The owner route is not a fix: first-mode takeover can succeed or fail without a source/image change. No seamless-handoff task is closed and no dark-frame-duration claim is made.
The daily boot arguments were restored and the
temporary logo removed. The experimental service copy exists only under
/run and disappears on reboot. The next diagnostic is a source-isolated,
first-enable preservation trial; it is not part of the daily image.
The recovery boot,
inspection, and
physical frame
confirm the restored normal configuration: no diagnostic arguments, no logo or
splash flag, /dev/fb0 present, and shell, seatd and firewall active.
First-enable preservation image trial
The diagnostic image trial records three correctly arranged automatic shell boots, visible successive color updates, and the same-kernel missing-logo console fallback. It also records a measured approximately 1.1–1.2 second camera-visible dark gap before Sway content. The candidate remains separate from the daily default; seamless handoff is not proved.
Initial compositor scene candidate
The first scene trial removed the previous long dark interval from the sampled transition but failed to retire its logo node because it expected the wrong bar layer. The corrected candidate uses the actual mapped Swaybar panel, records both seed and removal, and again shows no dark frame in the dense warm-boot transition samples. The carried kernel and optional compositor build successfully; the daily defaults remain the console and ordinary Sway. This is progress toward the power-on handoff requirement, not its final acceptance or a claim of uninterrupted animation.
The keyboard visibility follow-up completes the candidate’s filmed keyboard show/hide regression at a farther camera focus, without claiming finger accuracy or complete label readability. The U-Boot motion measurement attempt was rejected by the existing registration tool because only two markers were usable. No calibrated motion figure or task 3.7 completion is claimed.
Controlled first modeset with preservation enabled
The controlled trial separates an idle Linux boot from the first DRM owner and the later Sway start. At the idle prompt, the physical logo remains visible, fbdev is absent and the DRM client table is empty. Starting the unchanged immutable logo owner produces an RG16 scanout on connector 48 / CRTC 46; the matching boot’s kernel journal records first VO/DSI preservation and the one-shot panel-prepare skip. The owner retains its framebuffer until Sway replaces it, and Sway records both initial-scene seed and retirement.
The camera audit supplies the physical transition result and its limits: all 420 captured frames from 2–16 seconds retain the logo during first-owner startup. All 18 frames from 22.45–23.05 seconds cover the later shell handoff, with the last logo-only frame at approximately 22.82 seconds and the first shell bar at 22.85 seconds. Neither interval contains a captured dark frame. The matching kernel log records the prepare skip rather than full panel initialization, and the panel remains usable. Task 4.4 is complete; its dark-interval fallback is not triggered by this result. This is a same-card warm-boot experiment, not the outstanding second-card or complete power-on procedure. The saved boot arguments were restored before the display experiment, and a normal reboot removed the temporary units and returned automatic shell startup.
Mainline kernel handoff on the board, 2026-10-12
the-mainline-kernel-keeps-the-boot-splash tasks 2.3 and 2.4, recorded in
docs/evidence/mainline-boot-splash/board/README.md (warm reboots, not
power-on, by operator decision):
- 2.3 idle kernel (shell, seatd and
k230-drm-splashmasked for one boot):canaan,stage1-splashin/proc/device-tree/chosen, “stage 1 splash: leaving fbdev unset”, no panel prepare line,ls /dev/fb0fails, no/dev/driholder (mainline-boot-splash/board/idle-kernel-serial-excerpt.txt); logo on the glass at the prompt (mainline-boot-splash/board/splash-at-idle-kernel-prompt.jpg). - 2.4 frame timings: film1 logo 16.37-80.93 s, compositor first frame 80.97 s; film7 (installed default autoboot) logo 42.43-121.93 s, compositor 121.97 s; no frame between, and the Linux splash owner’s takeover does not change the image. Every splash boot also showed 1-4-frame scanout glitches of the logo in early userspace (not dark frames); cause open as task 4.1.