Built with EMERGENCY_CONSOLE_ENABLED=1 and booted with no identity logged
in, the prompt printed "ok> ok" without end, 1.4 million times in 200
seconds (logs/20261013-210442). sk_console_readline() gave up at once
whenever no identity was present. The production build answers that by
going silent until a login; the bring-up build, which needs no login,
took it as an empty line and asked again. The give-up is now the
production build's only.
Found rehearsing boards/BRINGUP.md; it predates the console change of
c9519173 (the image built from the commit before that did the same).
The riscv64 bring-up build, no thumbdrive, three lines typed
(logs/20261013-235129): one prompt that waits, and 3, 56 and 81.
Acceptance of the production build, one QEMU at a time: amd64
(-235255), aarch64 (-235411), riscv64 (-235620) to the zuse prompt, no
unknown word, hash 0x08873e0f44b7cb2a on all three.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
287 lines
18 KiB
Markdown
287 lines
18 KiB
Markdown
# Board bring-up checklist
|
|
|
|
Written 2026-10-13, before any of the four boards has been booted. It is what to do on the day
|
|
a board is on the bench, and what has to be true before that day is worth having.
|
|
|
|
Nothing here has been done on hardware. Every statement about the code was checked in the code
|
|
on the date above; where it comes from a document instead, the document is named. When a board
|
|
has been booted, its results go in `docs/fabric/FABRIC-3.md` (sections III, IV, V) and its
|
|
`README.md` here, and this file is corrected.
|
|
|
|
The four boards: `SER5` (amd64), `RASPI` (Pi 5, aarch64), `MILKV` (Mars, riscv64), `ZYNQ7020`
|
|
(ARMv7, no port yet). See `boards/README.md` for what each image is.
|
|
|
|
---
|
|
|
|
## 1. What stands between today and a first boot
|
|
|
|
Found while writing this checklist. Items marked **blocks first boot** will stop a board
|
|
showing anything, or stop it being typed to; they are worth closing before the bench day.
|
|
None has been fixed: each needs your word.
|
|
|
|
### 1.1 All boards
|
|
|
|
| # | What | Where | Effect on hardware |
|
|
|---|---|---|---|
|
|
| A1 | **The USB controller driver matches one device only**: QEMU's `qemu-xhci`, vendor `1B36`, device `000D`. | `kernel/include/starkernel/xhci.h:34`, `kernel/src/usb/xhci.c:44` | No real board's USB controller is found. No thumbdrive, so no identity can log in or be minted. |
|
|
| A2 | **No prompt without a login.** The production default, `EMERGENCY_CONSOLE_ENABLED=n`, keeps the system headless until an identity logs in by thumbdrive. | `Kconfig.heartbeat:68`; `FABRIC-3.md` VIII.1 | With A1, the v3 system never shows a prompt on hardware. A bring-up build must set `EMERGENCY_CONSOLE_ENABLED=1`. |
|
|
| A3 | **There is no USB keyboard driver.** Keys come from the i8042 PS/2 controller (amd64), a virtio keyboard (riscv64, QEMU only), or the serial port. | `kernel/src/arch/amd64/i8042.c`, `kernel/src/kernel_main.c:773`, `kernel/src/hal/console.c` | A USB keyboard does nothing unless the board's firmware goes on emulating PS/2 after the kernel takes over, which is not known for any of them. Plan to type over serial. |
|
|
| A4 | **The only disk driver is virtio.** | `kernel/src/virtio/virtio_blk.c`; `kernel_main.c:493` | On hardware Artemis finds no disk ("Artemis: no virtio-blk disk"). What the fleet then does has not been tried even in QEMU: see step 3.3. |
|
|
| A5 | **Entropy:** RDRAND on amd64 only. aarch64 and riscv64 have virtio-rng alone. | `kernel/src/rng/rng.c` | Pi 5 and Mars print the "no entropy backend available" warning; anything that needs random bytes is refused. Minting needs them. |
|
|
| A6 | **The board images cannot build the v4 node.** `make boot_image` has no `STARFORTH_V4` path. | root `Makefile`, `kernel/Makefile` | Ruled 2026-10-13: both systems, switchable. Not built yet. |
|
|
|
|
### 1.2 SER5
|
|
|
|
| # | What | Where | Effect |
|
|
|---|---|---|---|
|
|
| S1 | HPET address fixed at `0xFED00000`, not read from ACPI. | `FABRIC-3.md` III item 6, finding 1 | Wrong only on a machine that puts it elsewhere. Most do not. |
|
|
| S2 | Local APIC address fixed at `0xFEE00000`; the MADT's override entry is not parsed. | finding 2 | The same. |
|
|
| S3 | The i8042 controller and the legacy PIC are written to with no check that they exist. | finding 3 | Unknown on a machine with neither. |
|
|
| S4 | `BYE` resets through the i8042, not the ACPI reset register. | finding 4 | `BYE` may do nothing. It does not hang. |
|
|
| S5 | Whether the SER5 has a serial header is not known. | `FABRIC-3.md` III | Without one, and with A3, the SER5 can be watched over HDMI and not typed to. |
|
|
|
|
The loader probes COM1 before using it, and since 2026-10-13 so does the kernel's console.
|
|
Before that, on a board with no COM1 the status port read all ones: writes went nowhere, and
|
|
the prompt was told a key was waiting on every poll and read `0xFF` for ever.
|
|
|
|
### 1.3 Raspberry Pi 5
|
|
|
|
| # | What | Where | Effect |
|
|
|---|---|---|---|
|
|
| R1 | **Fixed 2026-10-13.** Every character the console printed was also written to a PL011 at `0x09000000`, QEMU's address, which on a Pi 5 is ordinary RAM. The console now finds its serial line from the devicetree's `/chosen/stdout-path`: on the Pi 5 that is `serial10`, the debug connector, a PL011 at `0x107d001000`. | `kernel/src/hal/console.c`, `kernel/src/hal/fdt_uart.c`; `tools/fdt_uart_test.c` reads the board's real devicetree | Checked off the board only. The first run is the board's. |
|
|
| R2 | Entry is at EL2 with the MMU off. Nothing on this path has ever run. | `boards/raspi/README.md`; `FABRIC-3.md` IV.3 | Unknown. |
|
|
| R3 | Two details of the framebuffer request are unverified: the size field of the allocate tag, and whether the address returned needs its top bits masked. The mode is fixed at 1920x1080x32. | `FABRIC-3.md` IV.3 item 3 | No picture, or a wrong one. With R1 unfixed there is then no channel at all. |
|
|
| R4 | USB, Ethernet and GPIO are behind the RP1 chip on PCIe, which needs a Broadcom-specific driver that is not written. | `FABRIC-3.md` IV.3 item 5 | No USB on the Pi 5 whatever is done about A1. |
|
|
| R5 | No hardware entropy source is known for the BCM2712. | `FABRIC-3.md` IV.2 | A5 stands. |
|
|
|
|
### 1.4 Milk-V Mars
|
|
|
|
| # | What | Where | Effect |
|
|
|---|---|---|---|
|
|
| M1 | **Fixed 2026-10-13.** The console, and the UEFI loader before it, wrote to a 16550 at `0x10000000` with registers one byte apart. The JH7110's UART is at that address with `reg-shift = <2>` and `reg-io-width = <4>` (mainline `jh7110.dtsi`): the loader would have waited for ever on its first character. Both now take the layout from the devicetree. | `kernel/src/hal/console.c`, `kernel/src/boot/uefi_loader.c` | Rehearsed in QEMU through U-Boot, which hands over a devicetree: "serial line is a 16550 at 0x10000000 (named by the devicetree)". QEMU's UART is byte-spaced, so the four-byte layout itself is checked by the host test only. |
|
|
| M2 | The display depends on U-Boot offering a framebuffer to the EFI loader. | `boards/milkv/README.md` | Unknown. With M1 unfixed there is then no channel at all. |
|
|
| M3 | USB is behind the JH7110's PCIe controller; whether that is plain ECAM has not been looked up. | `FABRIC-3.md` V.3 item 5 | No USB until it is. |
|
|
| M4 | `FABRIC-3.md` V describes a native entry at `0x40000000`; the image built today is the UEFI loader run by U-Boot's `bootefi`. The README here is the newer and is what the build does. | `boards/milkv/README.md` | None; noted so the two are not confused on the day. |
|
|
| M5 | Whether the U74 has the entropy instruction is not known. | `FABRIC-3.md` V.2 | A5 stands. |
|
|
|
|
### 1.5 Zynq-7020
|
|
|
|
No image can be built. Needed first, in order: the board chosen (it fixes `BOOT.BIN`); an ARMv7
|
|
port, `kernel/src/arch/armv7` (entry, MMU, GIC, private timer); and the four files that use
|
|
`__int128` or have no ARMv7 branch (`boards/zynq7020/README.md` names them). It is the host for
|
|
the v4 mesh, so it also waits on A6.
|
|
|
|
### 1.6 Found in rehearsal, and fixed, 2026-10-13: the bring-up build flooded its prompt
|
|
|
|
Built with `EMERGENCY_CONSOLE_ENABLED=1` and booted with no thumbdrive, the prompt printed
|
|
`ok> ok` without end: 1.4 million times in 200 seconds. The line reader
|
|
(`kernel/src/repl.c`, `sk_console_readline()`) gave up at once whenever no identity was logged
|
|
in, which the production build answers by going silent; the bring-up build took it as an
|
|
empty line and asked again. It now gives up only in the production build. Rehearsed on
|
|
riscv64 (`logs/20261013-235129`): one prompt, which waits, and three typed lines answered.
|
|
|
|
### 1.7 What I would close before the bench day
|
|
|
|
In this order, each as a design for approval first:
|
|
|
|
1. ~~R1 and M1: a console that finds its UART from the devicetree, and does nothing when
|
|
there is none.~~ Done 2026-10-13, and 1.6, the flood.
|
|
2. A6: the v4 switch in the board images. The v4 node needs only a console to reach a prompt;
|
|
it has no login, no fleet and no disk to wait for, so it is the shorter road to a first
|
|
prompt on each board.
|
|
3. A1: find the USB controller by its class code, not one vendor's number. That gives the SER5
|
|
thumbdrives. The Pi 5 and the Mars need R4 and M3 as well.
|
|
4. A serial cable for every board (section 2).
|
|
|
|
---
|
|
|
|
## 2. Before the day
|
|
|
|
**To have on the bench**
|
|
|
|
- [ ] A USB-to-serial adapter with 3.3 V logic levels, and jumper wires. It is the one channel
|
|
that survives a framebuffer failure, and with A3 it is the one way to type. FABRIC-3
|
|
decided HDMI only for the Pi 5 and the Mars because no adapter was to hand; that
|
|
decision is worth revisiting before the day.
|
|
- [ ] HDMI display and cable (micro-HDMI for the Pi 5).
|
|
- [ ] A USB stick for the SER5; a microSD card each for the Pi 5 and the Mars; a card reader.
|
|
- [ ] A PS/2 keyboard if the SER5 turns out to have a PS/2 port; otherwise serial.
|
|
- [ ] A camera, for the screen: when there is no serial log, photographs are the record.
|
|
- [ ] The identity thumbdrives (`disk/README.md`), once A1 is closed.
|
|
|
|
**To know before starting**
|
|
|
|
- [ ] SER5: Secure Boot is off (`FABRIC-3.md` III says it is on this unit); which key opens
|
|
the firmware's boot menu; whether there is a serial header.
|
|
- [ ] Pi 5: the EEPROM firmware is recent enough to honour `kernel_address` and `os_check`
|
|
(boot Raspberry Pi OS once and note the version).
|
|
- [ ] Mars: the SPI flash holds a U-Boot that scans the SD card for an EFI loader; the boot
|
|
switches select SPI flash. Stop U-Boot at its prompt once and save `printenv`, then
|
|
`fdt addr ${fdtcontroladdr}` and the output of `fdt print /soc/serial@10000000`: that
|
|
settles M1.
|
|
|
|
---
|
|
|
|
## 3. Build, and rehearse in QEMU
|
|
|
|
### 3.1 Build
|
|
|
|
```
|
|
make boot_image TARGET=SER5 EMERGENCY_CONSOLE_ENABLED=1
|
|
make boot_image TARGET=RASPI EMERGENCY_CONSOLE_ENABLED=1
|
|
make boot_image TARGET=MILKV EMERGENCY_CONSOLE_ENABLED=1
|
|
```
|
|
|
|
- [ ] **`make clean TARGET=<board>` first.** The switch is compiled in, and objects built
|
|
without it are not rebuilt when it changes: an image built over old objects boots
|
|
headless (seen 2026-10-13).
|
|
- [ ] Each ends with its image in `build/boards/<board>/`. Record `sha256sum` of each.
|
|
- [ ] Confirm the switch took: the image booted in QEMU (3.2) shows a prompt with no
|
|
thumbdrive attached. After a clean build it does (tried on `MILKV`).
|
|
- [ ] The Pi 5 build fetches the board's DTB once from the pinned firmware release; with no
|
|
network, pass `RPI5_DTB=/path/to/bcm2712-rpi-5-b.dtb`.
|
|
- [ ] Put back `v3/include/version.h` and `capsules/BLOCK_MAP.md` afterwards: the build
|
|
rewrites both.
|
|
|
|
### 3.2 Rehearse each image as its own disk
|
|
|
|
One QEMU at a time. Use a copy of the image: the kernel writes to its disk.
|
|
|
|
- [ ] **SER5:** q35 with OVMF, the image as the only disk, no `-cdrom`, no virtio disk, no
|
|
thumbdrive. This is the machine the README's "booted in QEMU" refers to.
|
|
- [ ] **MILKV:** the command in `boards/milkv/README.md` (OpenSBI, U-Boot, `bootefi`).
|
|
- [ ] **RASPI:** there is no QEMU model of the Pi 5. Nothing can be rehearsed; the first run
|
|
is on the board.
|
|
|
|
### 3.3 What to settle in the rehearsal
|
|
|
|
- [ ] With no virtio disk and no thumbdrive, how far does the v3 system get, and what does it
|
|
print? (A4. Not tried.)
|
|
- [ ] Note the verdict lines of that boot (section 5). They are what the board is compared
|
|
with.
|
|
- [ ] Type a line over the serial port. If it is not taken in QEMU it will not be on the
|
|
board.
|
|
|
|
---
|
|
|
|
## 4. On the bench
|
|
|
|
Do one board at a time, in this order: SER5, then the Mars, then the Pi 5. The SER5's path is
|
|
the one QEMU exercises most closely, and the Pi 5's cannot be rehearsed at all.
|
|
|
|
### 4.1 Writing the media, every board
|
|
|
|
- [ ] `lsblk` before and after inserting the stick or card. Write down the device name and its
|
|
size. **`dd` to the wrong device destroys a disk.**
|
|
- [ ] `sudo dd if=build/boards/<board>/<image> of=/dev/sdX bs=4M conv=fsync status=progress`
|
|
- [ ] Read it back and compare: `sudo cmp -n $(stat -c %s <image>) <image> /dev/sdX`.
|
|
|
|
### 4.2 SER5
|
|
|
|
- [ ] Serial, if there is a header: 115200 8N1, logged to a file from before power-on.
|
|
- [ ] HDMI and keyboard connected. Stick in a rear port.
|
|
- [ ] Power on, open the boot menu, choose the stick.
|
|
- [ ] Watch for, in order: `StarKernel UEFI Loader`; `GOP: linear framebuffer found`;
|
|
`LithosAnanke v...`; `PMM initialized.`; `VMM initialized`; `APIC: init done`;
|
|
`Timer: init done`; `Kernel heap initialized.`; `Stadium: ...`; POST; the verdict lines.
|
|
- [ ] `rng: backend = rdrand`. In QEMU it says `virtio-rng`; this line is new on hardware.
|
|
- [ ] The timer lines differ from QEMU's by design: no hypervisor, so the HPET path runs for
|
|
the first time. S1 is the finding to remember if it stops there.
|
|
|
|
### 4.3 Milk-V Mars
|
|
|
|
- [ ] Serial on the 40-pin header's UART, 115200 8N1, logged from before power-on. U-Boot
|
|
talks on it, so it shows whether the board reached U-Boot even if the kernel prints
|
|
nothing.
|
|
- [ ] Card in, HDMI connected, power on.
|
|
- [ ] U-Boot finds `EFI/BOOT/BOOTRISCV64.EFI` and starts it. If it does not, at its prompt:
|
|
`load mmc 1:1 ${kernel_addr_r} EFI/BOOT/BOOTRISCV64.EFI` then
|
|
`bootefi ${kernel_addr_r} ${fdtcontroladdr}` (the device number may differ: `mmc list`).
|
|
- [ ] The lines of 4.2, with `PLIC:` in place of `APIC:`. For the first time the interrupt
|
|
controller's address and the timer's frequency should come from the devicetree: the
|
|
QEMU lines "no DTB PLIC node" and "FALLBACK, no devicetree" should **not** appear.
|
|
- [ ] `satp.MODE` is printed at entry. Under U-Boot it may be 0 where QEMU shows `0xa`.
|
|
|
|
### 4.4 Raspberry Pi 5
|
|
|
|
- [ ] Serial on the debug connector between the HDMI ports (needs the Pi debug probe or a
|
|
matching cable), 115200 8N1. The firmware prints there before the kernel runs.
|
|
- [ ] Card in, HDMI in the port nearest the USB-C socket, power on.
|
|
- [ ] The firmware loads `kernel_2712.img` at `0x80000`. If the screen stays on the firmware's
|
|
diagnostic page, the firmware did not accept the image: note what it says.
|
|
- [ ] Then the lines of 4.2 from `LithosAnanke v...` on (there is no UEFI loader), with
|
|
`GICv2:` in place of `APIC:`. The line "no DTB GIC node -- using QEMU virt-machine
|
|
defaults" should **not** appear.
|
|
- [ ] Expect `PCI: MCFG parse failed on aarch64 -- no ECAM`: that is R4 and is not a failure
|
|
of the boot.
|
|
|
|
---
|
|
|
|
## 5. What counts as a pass
|
|
|
|
Record which level each board reached. A board is not "booted" on the strength of level 1.
|
|
|
|
| Level | What was seen | Compared with |
|
|
|---|---|---|
|
|
| 1 | The kernel's first line, on any channel | - |
|
|
| 2 | Every milestone line through `Kernel heap initialized.` | The QEMU log of the same build |
|
|
| 3 | `POST: PASSED` and `PARITY:OK` | The same test count as QEMU |
|
|
| 4 | The `PARITY:M7.1a` line's `word_count` and `hash` equal QEMU's for the same ISA | The rehearsal boot of 3.2 |
|
|
| 5 | A prompt, and a typed line answered: `1 2 + .` gives `3` | - |
|
|
| 6 | Entropy from hardware; an identity minted on a thumbdrive and attached again after a power cycle | The gates of `FABRIC-3.md` III, IV, V |
|
|
|
|
Level 4 is the one that says the board runs the same system as QEMU. Levels 5 and 6 wait on
|
|
section 1: today no board can reach 6, and only the SER5 with a serial header can reach 5.
|
|
|
|
For the v4 node, once A6 is built, the lines are `PARITY:V4_POST tests=538 pass=538 fail=0`,
|
|
`PARITY:V4_SYSTEM word_count=... dict_hash=...` equal to the hosted programs', `PARITY:OK`,
|
|
`POST: PASSED`, and the prompt `ok> `.
|
|
|
|
---
|
|
|
|
## 6. If it stops
|
|
|
|
| What is seen | Look at |
|
|
|---|---|
|
|
| Nothing at all, any board | Is the firmware reaching the image? Serial shows the firmware's own output on the Mars and the Pi 5. On the SER5, try the UEFI shell: `startup.nsh` is in the image. |
|
|
| Pi 5: firmware runs, then nothing | R1, then R2, then R3. |
|
|
| Mars: U-Boot starts the loader, then nothing on serial | M1. HDMI may still show the boot if M2 holds. |
|
|
| SER5: stops in the `Timer:` lines | S1. |
|
|
| Stops at `APIC` / `GICv2` / `PLIC` | The controller's address: S2 on the SER5; on the others, whether the devicetree node was found (the line says). |
|
|
| Runs through POST, then silence | A2: the build is headless. Rebuild with `EMERGENCY_CONSOLE_ENABLED=1`. |
|
|
| A prompt that takes no keys | A3. Type over serial. |
|
|
| `Artemis: no virtio-blk disk` | A4. Expected on every board today. |
|
|
| `rng: WARNING -- no entropy backend available` | A5. Expected on the Pi 5 and the Mars today. |
|
|
|
|
Write down the last line shown, exactly, and photograph the screen. Do not change two things
|
|
between attempts.
|
|
|
|
---
|
|
|
|
## 7. What to keep
|
|
|
|
- [ ] The serial transcript of every attempt, passed or failed, under `logs/` with the date,
|
|
the board and the image's `sha256` in its name. Logs are kept and committed, as QEMU's
|
|
are.
|
|
- [ ] Photographs of the screen where there was no serial.
|
|
- [ ] The firmware versions: SER5 BIOS, Pi 5 EEPROM, Mars U-Boot and OpenSBI.
|
|
- [ ] The Mars's `printenv` and devicetree, and the Pi 5's DTB as used.
|
|
- [ ] The results written into `FABRIC-3.md` (each section ends with "update this section with
|
|
results") and each board's `README.md` status line.
|
|
|
|
---
|
|
|
|
## 8. Before the builds are cut
|
|
|
|
The administrative work that is yours to call, listed so it is not found on the day:
|
|
|
|
- [ ] The kernel's release number. `kernel/Makefile` holds a table that gives each hardware
|
|
gate its own number (SER5, then the Pi 5, then the Mars); it is still to be ruled.
|
|
- [ ] The uncommitted change to `kernel/Makefile` that adds the ISA to the version line: it
|
|
needs a three-ISA acceptance run in the v3 configuration before it is committed.
|
|
- [ ] `CHANGELOG.md`: nothing between 2026-08-18 and the uncommitted entry of 2026-10-09.
|
|
- [ ] `sbom.spdx` and `sbom.spdx.json` brought up to date.
|
|
- [ ] The merge of `StarForth-v4.0.0` to `master`, and the tags `LithosAnanke v2.0.0` and
|
|
`StarForth v4.0.0`: only when you say.
|
|
- [ ] `.claude/CLAUDE.md` still describes the build before `boards/` existed.
|