diff --git a/boards/BRINGUP.md b/boards/BRINGUP.md new file mode 100644 index 00000000..d8dbfebd --- /dev/null +++ b/boards/BRINGUP.md @@ -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//`. 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// of=/dev/sdX bs=4M conv=fsync status=progress` +- [ ] Read it back and compare: `sudo cmp -n $(stat -c %s ) /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.