P79 makes the Linux console bidirectional. The kernel was already
using earlycon=sbi console=hvc0, so output flowed through
SBI_CONSOLE_PUTCHAR. Input did not: stage-0 firmware always returned
-1 from SBI_CONSOLE_GETCHAR.
The new path is intentionally direct:
host FIFO -> Verilator queue -> chip MMIO FIFO -> SBI getchar -> hvc0 -> /init read(0)
That keeps the proof focused on console transport. No UART device tree node, no Linux driver, no BusyBox yet.
Captured run
The smoke run rebuilt the local Linux 6.12.85 Image with P79’s
initramfs, booted to /init, queued four commands, and stopped after
the expected PID 1 exit panic.
P79 Linux host TTY ready
type 'help' or 'exit'
p79> help
commands: help hello status exit
p79> status
console=hvc0, input=SBI getchar, host bridge=MMIO FIFO
p79> hello
hello from a Linux userspace tty on the chip
p79> exit
exiting PID 1; Linux should panic after this
Kernel panic - not syncing: Attempted to kill init
Harness accounting:
[harness] === run ended after 59905843 post-load cycles ===
[harness] stopped after kernel panic milestone
[harness] input bytes read=23 delivered=23 queued=0
What changed
| layer | new behavior |
|---|---|
| RTL | 16-entry host input FIFO at 0x10001008/0x1000100c |
| firmware | SBI_CONSOLE_GETCHAR pops one byte from that FIFO |
| harness | reads host bytes from captured/input.fifo and waits for host_input_ready |
| userspace | no-libc /init reads fd 0 and writes fd 1 through Linux syscalls |
The host-side queue matters. Scripted input can arrive before Linux gets to userspace; the harness holds those bytes and only hands them to the chip when the 16-entry RTL FIFO has room.
BusyBox
BusyBox is the right next step for a useful Linux environment. P79 does not try to prove BusyBox at the same time as console input. The better sequence is:
- Prove stdin reaches Linux userspace. P79 did that.
- Package BusyBox as
/initor under an initramfs root. - Decide whether to keep HVC-over-SBI or add a real UART/console device model for Linux.
Verification
cd projects/79_linux_host_tty/userspace
make
cd /mnt/MediaVolume/home/jadams/src/linux-rv32-build/linux-6.12.85
./scripts/config --set-str INITRAMFS_SOURCE \
/mnt/MediaVolume/home/jadams/src/gitlab.daringbit.com/josh/librelane-playground/projects/79_linux_host_tty/userspace/initramfs.cpio
make ARCH=riscv olddefconfig
make ARCH=riscv -j$(nproc) Image
cd /mnt/MediaVolume/home/jadams/src/gitlab.daringbit.com/josh/librelane-playground/projects/79_linux_host_tty/test
make tty-smoke \
KERNEL_IMAGE=/mnt/MediaVolume/home/jadams/src/linux-rv32-build/linux-6.12.85/arch/riscv/boot/Image
Honest Status
| check | status |
|---|---|
| Verilator model builds | PASS |
Tiny RV32 /init builds | PASS |
Linux boots to /init | PASS |
| Host FIFO bytes reach chip MMIO FIFO | PASS |
| SBI getchar returns queued host bytes | PASS |
Linux userspace reads stdin from /dev/console | PASS |
| Scripted commands produce expected stdout | PASS |
| BusyBox initramfs | NOT RUN |
| F/D architectural compliance | NOT RUN |
| LibreLane hardening | NOT RUN |
What just happened?
The homemade-chip Linux console stopped being print-only. A host shell can now send bytes into a running Linux userspace process through the same HVC console Linux already used for output.