docs(boards): bring-up checklist for the four boards, and what stands between today and a first boot
What to do on the day a board is on the bench: media, cabling, what to watch for, what counts as a pass, what to keep. Written before any board has been booted. Section 1 lists what was found in the code while writing it, none of it fixed: the USB controller driver matches QEMU's controller only; the production build shows no prompt without a thumbdrive login; there is no USB keyboard driver and no disk driver but virtio; on the Pi 5 the console writes every character to QEMU's UART address, which is RAM there; on the Mars the console's UART register layout is probably not the board's; the board images cannot build the v4 node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
010cfc54e6
commit
f4e359859a
@@ -0,0 +1,275 @@
|
||||
# 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. The kernel's own console writes to port `0x3F8`
|
||||
without a probe; on a board with no COM1 the status port reads all ones and the write goes
|
||||
nowhere.
|
||||
|
||||
### 1.3 Raspberry Pi 5
|
||||
|
||||
| # | What | Where | Effect |
|
||||
|---|---|---|---|
|
||||
| R1 | **Blocks first boot.** Every character the console prints is also written to a PL011 UART at `0x09000000`, QEMU's address, after waiting on a flag read from `0x09000018`. On a Pi 5 that is ordinary RAM. | `kernel/src/hal/console.c:84-93`, `:223` | Each character overwrites a word of RAM at 144 MiB; and if the word at `0x09000018` has bit 5 set, the first character waits for ever. `rpi5_uart_base()` finds the real UART and nothing calls it. |
|
||||
| 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 | **Likely blocks first boot; to be confirmed against the board's devicetree.** The console writes to a 16550 UART at `0x10000000` with its registers one byte apart, and waits on the status register at offset 5. The JH7110's UART is at that address, but as I recall its devicetree gives `reg-shift = <2>`: registers four bytes apart, status at offset `0x14`. | `kernel/src/hal/console.c:99-109` | If so, the first character waits for ever on a byte that is not the status register. QEMU's UART is a byte-spaced 16550, so the QEMU boot through U-Boot did not show this. |
|
||||
| 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 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. Without them the Pi 5 and the Mars may show nothing at all.
|
||||
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
|
||||
```
|
||||
|
||||
- [ ] 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. That the root `Makefile` passes the setting down has not been
|
||||
tried.
|
||||
- [ ] 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.
|
||||
Reference in New Issue
Block a user