Document interactive and unattended disk installation with fds-flash
+2
-2
@@ -51,8 +51,8 @@ indexing also explicitly sets `XBPS_ARCH=aarch64`.
|
||||
## Generic Linux workstation tools and desktop additions
|
||||
|
||||
`make workstation` builds the Arch `fds-tools` package; `make workstation-install`
|
||||
installs it with pacman. `make workstation-binaries` builds native `fds-cartridge`
|
||||
and `fds-emulator` on generic Linux. Python 3 and Git resolve build versions;
|
||||
installs it with pacman. `make workstation-binaries` builds native `fds-cartridge`,
|
||||
`fds-emulator` and `fds-flash` on generic Linux. Python 3 and Git resolve build versions;
|
||||
Dasung builds install these tools in the project-local Void container as well. Runtime
|
||||
requirements are QEMU, erofs-utils, bubblewrap and native XBPS with a prepared
|
||||
Void source checkout for software creation. `fds-cartridge` invokes xbps-src,
|
||||
|
||||
@@ -14,6 +14,7 @@ the inputs named in those reports; a changed source tree needs fresh checks.
|
||||
|
||||
## Design and build references
|
||||
|
||||
- [Workstation disk flashing](Flashing)
|
||||
- [Editing the Gitea wiki](Gitea-Wiki)
|
||||
- [Clean upstream and writable Void workspace](Developer-Void-Workspace)
|
||||
|
||||
|
||||
@@ -28,11 +28,12 @@ own strict format parsers; they are not process argument parsers.
|
||||
## Workstation software and emulator extension
|
||||
|
||||
Current sources extend the frozen 0.1.0 checkpoint with native Linux
|
||||
`fds-cartridge` and `fds-emulator` tools. The software format uses metadata plus
|
||||
`m` payload partitions containing xz tarballs. Software builds and complete
|
||||
image creation run on the workstation; the guest verifies, extracts and runs
|
||||
selected commands as UID 1000. See [usage](Developer-Workstation),
|
||||
[format](Developer-Software-Format), and [current acceptance](Developer-Workstation-Validation).
|
||||
`fds-cartridge`, `fds-emulator` and `fds-flash` tools. The current software format
|
||||
uses metadata plus `m` EROFS payload partitions containing installed Void package
|
||||
trees. Software builds and image creation run on the workstation; the guest
|
||||
verifies and executes those trees directly as UID 1000. Legacy archive readers
|
||||
remain available. See [usage](Workstation), [format](Software-Format),
|
||||
[disk installation](Flashing), and [cartridge/desktop acceptance](Developer-Current-Revision).
|
||||
Historical M0–M12 and Clap reports describe their recorded artifacts; they do
|
||||
not by themselves validate these new sources.
|
||||
|
||||
|
||||
@@ -54,97 +54,13 @@ empty. The builder accepts ordinary image files, never a host block-device
|
||||
output. Final hardware provisioning and identity checks belong to the physical
|
||||
acceptance procedure; do not confuse a partition payload with the complete disk.
|
||||
|
||||
## Install the internal disk when hardware is available
|
||||
## Install the internal disk
|
||||
|
||||
This is a **deferred physical procedure**. The image and virtual NVMe workflow
|
||||
are software-tested; writing and booting the user's actual NVMe still require
|
||||
the hardware. Installation erases the selected disk, including any existing
|
||||
machine settings. Retain backups before replacing an existing installation.
|
||||
|
||||
Use an NVMe enclosure or another Linux machine that can access the target drive
|
||||
while the Pi is off. First verify a downloaded release using a separately trusted
|
||||
public key as described in [Release signatures](Developer-Releases). Its complete disk
|
||||
is named `fds-internal-0.1.0.img`; a local build uses `out/fds-internal.img`.
|
||||
Use the complete disk image, not the separate BOOT or RECOVERY payload.
|
||||
|
||||
List disks before and after connecting the intended drive:
|
||||
|
||||
```sh
|
||||
lsblk -d -o NAME,PATH,MODEL,SERIAL,SIZE,TRAN,LOG-SEC
|
||||
ls -l /dev/disk/by-id/
|
||||
```
|
||||
|
||||
Match the physical model, serial and capacity. Choose a persistent **whole-disk**
|
||||
`/dev/disk/by-id/` path without a `-partN` suffix; never guess a `/dev/sdX` name.
|
||||
Unmount every target partition and disable any swap on it. Do not select the
|
||||
workstation's system disk. The current images require 512-byte logical sectors
|
||||
and a disk at least as large as the image; 4 KiB logical-sector media is not
|
||||
supported by this layout.
|
||||
|
||||
Open Bash (`bash`), replace both paths below, then run the block. It checks the
|
||||
selected disk again, requires a typed confirmation, writes and reads back the
|
||||
complete image, and relocates the backup GPT when the disk is larger than the
|
||||
image. It does not expand any partition or filesystem.
|
||||
|
||||
```bash
|
||||
(
|
||||
set -euo pipefail
|
||||
fds_image="$PWD/out/fds-internal.img"
|
||||
fds_disk=/dev/disk/by-id/REPLACE_WITH_THE_TARGET_DISK
|
||||
[[ -f "$fds_image" && -s "$fds_image" && -b "$fds_disk" ]]
|
||||
[[ $(lsblk -dnro TYPE "$fds_disk") == disk ]]
|
||||
[[ $(sudo blockdev --getss "$fds_disk") == 512 ]]
|
||||
fds_bytes=$(stat -Lc %s "$fds_image")
|
||||
(( $(sudo blockdev --getsize64 "$fds_disk") >= fds_bytes ))
|
||||
lsblk -p -o NAME,TYPE,MODEL,SERIAL,SIZE,MOUNTPOINTS "$fds_disk"
|
||||
if lsblk -nrpo MOUNTPOINTS "$fds_disk" | grep '[^[:space:]]' >/dev/null; then
|
||||
echo 'Target has mounted filesystems or swap; stop and release them first.' >&2
|
||||
exit 1
|
||||
fi
|
||||
if lsblk -nrpo TYPE "$fds_disk" | grep -Ev '^(disk|part)$' >/dev/null; then
|
||||
echo 'Target has device-mapper or other active descendants; stop.' >&2
|
||||
exit 1
|
||||
fi
|
||||
read -r -p "Type ERASE $fds_disk to erase this disk: " fds_confirmation
|
||||
[[ "$fds_confirmation" == "ERASE $fds_disk" ]]
|
||||
sudo dd if="$fds_image" of="$fds_disk" bs=4M conv=fsync status=progress
|
||||
sudo blockdev --flushbufs "$fds_disk"
|
||||
sudo cmp -n "$fds_bytes" "$fds_image" "$fds_disk"
|
||||
sudo sfdisk --lock=yes --relocate gpt-bak-std "$fds_disk"
|
||||
sudo sfdisk --verify "$fds_disk"
|
||||
sudo blockdev --flushbufs "$fds_disk"
|
||||
)
|
||||
```
|
||||
|
||||
Every command must succeed. The byte comparison occurs before relocating GPT,
|
||||
because relocation intentionally changes disk-table headers. GNU `dd`'s `fsync`
|
||||
flushes output before it returns; `sfdisk`'s `gpt-bak-std` moves the backup header
|
||||
to the end of the target. See the [GNU dd manual](https://www.gnu.org/s/coreutils/manual/html_node/dd-invocation.html)
|
||||
and [sfdisk manual](https://man7.org/linux/man-pages/man8/sfdisk.8.html).
|
||||
These commands use the already documented coreutils, diffutils and util-linux
|
||||
host tools; they do not add a target daemon.
|
||||
|
||||
Confirm that the disk shows `FDS_BOOT`, `FDS_RECOVERY` and `FDS_INTERNAL` in that
|
||||
order using `lsblk -o NAME,PARTLABEL,FSTYPE,MOUNTPOINTS`. Unmount anything the
|
||||
desktop automatically mounted, then safely disconnect the enclosure and install
|
||||
the NVMe in the powered-off Pi. Follow [EEPROM preparation](Developer-EEPROM) for the
|
||||
separately reviewed NVMe boot settings.
|
||||
|
||||
Prepare the **first SYSTEM cartridge on the workstation** using the same guarded
|
||||
write block, with its two path assignments changed to the chosen SYSTEM image
|
||||
and a different, empty USB cartridge disk. For a local build select
|
||||
`out/fds-system-cli.img` or `out/fds-system-development.img`; release files are
|
||||
`fds-system-cli-0.1.0.img` and `fds-system-development-0.1.0.img`. They are
|
||||
alternative complete GPT images, each containing one `FDS_SYSTEM` partition.
|
||||
Readback and backup-GPT relocation apply to this disk too. Check its partition
|
||||
label, safely disconnect it, and insert exactly one SYSTEM cartridge in the Pi
|
||||
before normal boot. Subsequent cartridge creation and updates can use FDS's
|
||||
confirmed [media workflow](Developer-Media-Tools) after bay calibration.
|
||||
|
||||
On the first physical boot, check `fds info`, `fds machine status`, and
|
||||
`fds bays`. The supplied bay map is empty until calibration. Follow
|
||||
[physical acceptance](Developer-Stress-Testing) to measure ports, test the Dasung
|
||||
display, and record actual boot/shutdown behavior before relying on the machine.
|
||||
Current workstation installation uses [fds-flash](Flashing), with guided or
|
||||
unattended operation, image/target validation, readback and backup-GPT relocation.
|
||||
Follow [the installation commands](Internal-Storage#install-the-internal-disk).
|
||||
Historical M12 acceptance describes the artifacts and procedures recorded then;
|
||||
it does not validate this new workstation tool.
|
||||
|
||||
## Configure the machine before building
|
||||
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ checks. `make workstation-test` exercises the installed-tree cartridge creator;
|
||||
`make emulator-test` covers stopping and starting the same directory, preserved
|
||||
logs/overlays/mappings, and rejecting a restart of a live VM.
|
||||
`make workstation-package-test` installs the real Arch package with pacman in a
|
||||
disposable root and executes both installed commands. After building matching
|
||||
disposable root and executes all three installed commands. After building matching
|
||||
images, `python3 tests/integration/version-images.py` reads the identity and
|
||||
metadata directly from the GPT/EROFS image and executes its twelve FDS commands
|
||||
under ARM emulation to compare their versions. Image acceptance
|
||||
|
||||
@@ -5,8 +5,8 @@ include_toc: true
|
||||
# Workstation tooling plan
|
||||
|
||||
The current source of requirements is [the active revision](Developer-Current-Revision).
|
||||
The public tools remain native Linux Clap applications: `fds-cartridge` and
|
||||
`fds-emulator`. Full OS cross builds keep their separate pinned Void environment.
|
||||
The public tools remain native Linux Clap applications: `fds-cartridge`, `fds-emulator` and
|
||||
`fds-flash`. Full OS cross builds keep their separate pinned Void environment.
|
||||
|
||||
New software creation uses Void source templates and `xbps-src`. The image builder
|
||||
installs packages and dependencies on the workstation, verifies installed trees,
|
||||
@@ -31,3 +31,12 @@ The Arch distribution package is `fds-tools`, built by `make workstation` and
|
||||
installed by `make workstation-install`. `make workstation-binaries` preserves
|
||||
the generic Linux build. Stopped emulator directories support a fresh boot while
|
||||
retaining logs, DATA overlays and archived cartridge mappings.
|
||||
|
||||
`fds-flash` installs complete internal and cartridge GPT images. Its interactive
|
||||
mode requires terminal confirmation; unattended mode binds a specific image
|
||||
SHA-256 and target identity. Installation includes exclusive block access,
|
||||
readback, backup-GPT relocation and kernel partition refresh. The tool reuses
|
||||
existing Rust dependencies; it does not invoke shell disk-writing commands.
|
||||
See [flashing](Flashing) and validate with `make flash-test`,
|
||||
`make flash-vm-test`, `make workstation-test`, `make emulator-test` and
|
||||
`make workstation-package-test`. Physical-drive behavior remains a separate gate.
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@ source software to a cartridge disk image, runs that image in FDS, and explains
|
||||
how to write the same complete image to USB. All commands run from the checkout
|
||||
root unless marked as guest commands.
|
||||
|
||||
The two native host tools are `fds-cartridge` and `fds-emulator`. They use typed
|
||||
The original native host tools are `fds-cartridge` and `fds-emulator`. The current
|
||||
workstation package also includes [fds-flash](Flashing) for complete disk installation. All use typed
|
||||
Clap interfaces; append `--help` to any command or subcommand. The target's `fds`
|
||||
command remains a static AArch64 executable. The new host tools are never part
|
||||
of the Pi base image. Dasung support remains in the base boot bundle.
|
||||
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
---
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
# Flash disk images with fds-flash
|
||||
|
||||
[Home](Home) · [Real hardware](Hardware-Setup) · [Workstation tools](Workstation) · [Release verification](Releases)
|
||||
|
||||
`fds-flash` installs a complete FDS disk image from a Linux workstation. It has
|
||||
an interactive guide and an unattended mode for scripts. It validates the image,
|
||||
checks the destination, writes it, flushes it, reads the written bytes back, and
|
||||
relocates the backup GPT automatically when the destination is larger.
|
||||
You no longer need the manual `dd`, `cmp` and `sfdisk` installation sequence.
|
||||
|
||||
## Install the tool
|
||||
|
||||
From the OS checkout on Arch Linux:
|
||||
|
||||
```sh
|
||||
make workstation
|
||||
make workstation-install
|
||||
fds-flash --help
|
||||
```
|
||||
|
||||
The `fds-tools` package includes `fds-flash`, `fds-cartridge` and `fds-emulator`.
|
||||
For another Linux distribution, or to use the checkout without installing:
|
||||
|
||||
```sh
|
||||
make workstation-binaries
|
||||
out/workstation/fds-flash --help
|
||||
```
|
||||
|
||||
Build as an ordinary user. Only physical disk writes require root. The examples
|
||||
below use the checkout binary; substitute `fds-flash` after package installation.
|
||||
The flasher adds no crates or external runtime utilities: it uses the existing
|
||||
Clap, serde/JSON, SHA-256 and libc dependencies plus Linux block-device APIs.
|
||||
The Python commands in the scripting example only read saved JSON; Python is
|
||||
not required by the installed flasher.
|
||||
|
||||
## Choose the correct image
|
||||
|
||||
| Image | Destination |
|
||||
| --- | --- |
|
||||
| `out/fds-internal.img` | Whole NVMe disk, normally connected through an enclosure |
|
||||
| `out/fds-system-cli.img` | Whole USB SYSTEM cartridge |
|
||||
| `out/fds-system-development.img` | Alternative SYSTEM cartridge with development tools |
|
||||
| A complete PROGRAM, DATA or ENVIRONMENT `.img` | Its separate cartridge disk |
|
||||
|
||||
Versioned release filenames are supported too. First verify downloaded releases
|
||||
with a separately trusted key as described in [Release verification](Releases).
|
||||
The flasher's SHA-256 check detects changed input; it does not authenticate a
|
||||
publisher. PROGRAM images should also pass `fds-cartridge inspect` to check
|
||||
software metadata and installed program trees before deployment.
|
||||
|
||||
Use an uncompressed, complete FDS GPT disk image. The raw `fds-boot.img` and
|
||||
`fds-recovery.img` partition payloads, compressed archives, arbitrary operating
|
||||
system images and 4 KiB logical-sector destinations are rejected. A disk must
|
||||
have 512-byte logical sectors and enough space for the complete image.
|
||||
|
||||
## Interactive mode
|
||||
|
||||
Keep the Pi powered off while preparing its NVMe. Connect only the intended
|
||||
installation media, then launch the guide:
|
||||
|
||||
```sh
|
||||
sudo ./out/workstation/fds-flash
|
||||
```
|
||||
|
||||
1. Enter the image's path.
|
||||
2. Select a disk by its model, serial and capacity. Mounted or otherwise occupied
|
||||
disks are marked **BLOCKED**. There is no default disk selection.
|
||||
3. Review the image type, partitions, SHA-256, destination and target ID.
|
||||
4. Type the exact `ERASE /dev/...` phrase shown. Any other response cancels.
|
||||
5. Wait for `VERIFIED`. Errors or interruption return a nonzero exit status.
|
||||
|
||||
You can provide either path in advance. With both supplied, the command still
|
||||
shows the plan and requires terminal confirmation:
|
||||
|
||||
```sh
|
||||
sudo ./out/workstation/fds-flash \
|
||||
--image out/fds-internal.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_NVME_DISK
|
||||
```
|
||||
|
||||
Replace the destination with the verified **whole-disk** path, without a
|
||||
`-partN` suffix. The confirmation uses the resolved kernel path shown in the
|
||||
review. Repeat for SYSTEM with its image and a different disk:
|
||||
|
||||
```sh
|
||||
sudo ./out/workstation/fds-flash \
|
||||
--image out/fds-system-cli.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_SYSTEM_DISK
|
||||
```
|
||||
|
||||
Every confirmed write replaces the destination's partition table and the image
|
||||
region. Reinstalling an internal disk also replaces its saved machine settings.
|
||||
The tool does not automatically unmount filesystems, disable swap or select an
|
||||
alternative disk. Release the intended disk yourself and rerun if it is blocked.
|
||||
|
||||
## Inspect without writing
|
||||
|
||||
List physical disks and reasons they are unavailable:
|
||||
|
||||
```sh
|
||||
out/workstation/fds-flash list
|
||||
out/workstation/fds-flash list --json
|
||||
```
|
||||
|
||||
To inspect an image and destination together, without opening the disk for writing:
|
||||
|
||||
```sh
|
||||
out/workstation/fds-flash \
|
||||
--image out/fds-internal.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_NVME_DISK \
|
||||
--dry-run --json >out/nvme-plan.json
|
||||
```
|
||||
|
||||
Read the saved plan. `plan.target` contains model, serial, capacity, logical-sector
|
||||
size, canonical device path, host boot ID and kernel insertion identity. `plan.target_id`
|
||||
binds those fields together. `plan.sha256` identifies the complete source image.
|
||||
After a host reboot, or if the device is reinserted, replaced, resized or otherwise changes identity,
|
||||
obtain and review a new plan.
|
||||
|
||||
## Unattended mode
|
||||
|
||||
Unattended writes require all of `--image`, `--device`, `--expect-target` and
|
||||
`--sha256`. There is no bare `--yes` that can silently accept a newly discovered
|
||||
disk. Obtain the expected values from a reviewed dry run or from your controlled
|
||||
provisioning inventory, then pass them explicitly:
|
||||
|
||||
```sh
|
||||
sudo -n ./out/workstation/fds-flash \
|
||||
--image out/fds-internal.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_NVME_DISK \
|
||||
--unattended \
|
||||
--expect-target TARGET_ID_FROM_THE_REVIEWED_PLAN \
|
||||
--sha256 EXPECTED_IMAGE_SHA256 \
|
||||
--json >out/nvme-flash.json
|
||||
```
|
||||
|
||||
Replace both hash placeholders with their full 64 hexadecimal characters.
|
||||
`sudo -n` refuses to ask for a password, so privileges must already be available.
|
||||
A script already running as root can invoke the binary directly. The flasher
|
||||
never prompts or invokes sudo in unattended mode.
|
||||
|
||||
For an already reviewed `out/nvme-plan.json`, this complete shell example loads
|
||||
the bindings without adding a JSON utility dependency:
|
||||
|
||||
```sh
|
||||
fds_target_id=$(python3 -c 'import json; print(json.load(open("out/nvme-plan.json"))["plan"]["target_id"])')
|
||||
fds_sha256=$(python3 -c 'import json; print(json.load(open("out/nvme-plan.json"))["plan"]["sha256"])')
|
||||
sudo -n ./out/workstation/fds-flash \
|
||||
--image out/fds-internal.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_NVME_DISK \
|
||||
--unattended --expect-target "$fds_target_id" --sha256 "$fds_sha256" \
|
||||
--json >out/nvme-flash.json
|
||||
```
|
||||
|
||||
A successful JSON response has `status: "verified"`; a dry run has
|
||||
`status: "dry_run"`. Progress and diagnostics go to stderr. Exit status 0 means
|
||||
success for the requested operation; status 2 means an error, rejected input
|
||||
or cancelled confirmation. Treat a killed/interrupted process as a failed flash
|
||||
and reflash before using that disk. Check the process exit status before reading
|
||||
an output file; failures may leave that redirected file empty.
|
||||
|
||||
## What verification covers
|
||||
|
||||
Before writing, the tool checks GPT headers and tables, partition bounds, expected
|
||||
FDS labels/types, basic filesystem signatures, image size/hash and target identity.
|
||||
It rejects partitions, virtual/loop/device-mapper destinations, mounted disks or
|
||||
children, swap, kernel holders, read-only media and unsupported sector sizes.
|
||||
The destination is opened exclusively and checked again through block-device
|
||||
ioctls before the first write. A target replacement or changed source aborts.
|
||||
|
||||
Readback compares the written image region and relocated backup GPT, after
|
||||
flushing and invalidating the kernel block cache. Partition starts, sizes and
|
||||
filesystem contents stay unchanged. Unallocated capacity is not expanded or
|
||||
securely erased. Success also requires the kernel to reload the partition table.
|
||||
|
||||
After an internal installation, check `FDS_BOOT`, `FDS_RECOVERY` and `FDS_INTERNAL`
|
||||
with `lsblk -o NAME,PARTLABEL,FSTYPE,MOUNTPOINTS`. If udev is still processing
|
||||
partition events, run `udevadm settle` before checking labels. SYSTEM should show
|
||||
`FDS_SYSTEM`.
|
||||
Unmount any filesystems the desktop mounted after completion, safely disconnect
|
||||
the media, and continue with [first boot](Hardware-Setup#6-power-on-and-reach-the-console).
|
||||
|
||||
## Disposable tests and hardware acceptance
|
||||
|
||||
`--file-target` is only for existing disposable regular files, as an ordinary user.
|
||||
It is never inferred from a path, and root use of this test mode is rejected.
|
||||
`make flash-test` covers the public CLI, interactive terminal confirmation,
|
||||
unattended bindings, cancellation, changed inputs, corruption, and exact/larger
|
||||
destinations. `make flash-vm-test` also exercises block-device writes and failures
|
||||
on isolated virtual NVMe/USB disks. These tests do not write host block devices.
|
||||
`make clean` recognizes these generated test directories and retains their latest
|
||||
recorded results.
|
||||
|
||||
Physical acceptance remains separate: use a spare drive, record its model,
|
||||
serial and logical-sector size, retain the dry-run and verified JSON plus image
|
||||
hash, safely disconnect/reconnect it, and check its GPT and payloads independently.
|
||||
Then perform the [real-hardware boot procedure](Hardware-Setup). Drive firmware
|
||||
flush behavior, USB enclosure recovery and physical power-loss behavior remain
|
||||
unverified until measured on that hardware.
|
||||
|
||||
## Software validation record
|
||||
|
||||
The 2026-09-24 run passed `make flash-vm-test`, including native CLI and transfer
|
||||
unit tests, real pseudo-terminal interaction, disposable-file writes, inspection
|
||||
of the current internal/SYSTEM build images, and isolated ARM NVMe/USB writes.
|
||||
The VM checks covered the full wizard, unattended operation, kernel partition
|
||||
refresh, reinstallation, mounted/partition/read-only/4 KiB rejection, USB
|
||||
replacement, and injected write, flush and readback errors. These are software
|
||||
and virtual-disk results; they do not establish physical durability.
|
||||
|
||||
The existing workstation software-image tests, twelve-bay emulator lifecycle
|
||||
checks and `make check` also passed. Source and binary hashes, the latest test
|
||||
record paths and package-validation evidence are recorded locally in
|
||||
`out/manifests/fds-flash-validation.json`. Detailed logs are in
|
||||
`out/logs/flash-validation-final.log` and
|
||||
`out/logs/flash-workstation-regression.log`. The existing frozen 0.1.0 release
|
||||
was not modified.
|
||||
|
||||
Linux interface reference: [kernel block-device ABI](https://www.kernel.org/doc/html/latest/admin-guide/abi-stable.html).
|
||||
+20
-14
@@ -184,24 +184,30 @@ boot order until the rescue and normal boot paths have been checked.
|
||||
|
||||
## 5. Write the two disks
|
||||
|
||||
On the **workstation**, follow the complete
|
||||
[guarded disk-writing procedure](Internal-Storage#install-the-internal-disk).
|
||||
It includes disk identification by model/serial, an explicit erase confirmation,
|
||||
readback, and backup-GPT relocation. Run it separately for these assignments:
|
||||
On the **workstation**, build the native tools and run `fds-flash` once per disk:
|
||||
|
||||
| Pass | `fds_image` | `fds_disk` |
|
||||
| --- | --- | --- |
|
||||
| Internal disk | `$PWD/out/fds-internal.img` | The verified NVMe enclosure's whole-disk `/dev/disk/by-id/…` path |
|
||||
| SYSTEM | `$PWD/out/fds-system-cli.img` | A different, verified USB cartridge's whole-disk `/dev/disk/by-id/…` path |
|
||||
```sh
|
||||
make workstation-binaries
|
||||
sudo ./out/workstation/fds-flash --image out/fds-internal.img
|
||||
sudo ./out/workstation/fds-flash --image out/fds-system-cli.img
|
||||
```
|
||||
|
||||
Both writes erase the selected disk. Follow all checks in that procedure; a
|
||||
`-part1` path is not a whole-disk destination. The disks must use 512-byte logical
|
||||
sectors and be at least as large as their respective images.
|
||||
Each invocation lists disks by model, serial and capacity. Select the NVMe
|
||||
enclosure for the internal image and a different USB disk for SYSTEM, review the
|
||||
plan, and enter the displayed erase phrase. Both writes replace the selected
|
||||
media. The tool refuses mounted/occupied disks and non-512-byte logical sectors;
|
||||
it writes, flushes, verifies readback and relocates the backup GPT automatically.
|
||||
Wait for `VERIFIED` before proceeding.
|
||||
|
||||
Use `--device /dev/disk/by-id/...` to preselect a whole disk while retaining
|
||||
interactive confirmation. The [flashing guide](Flashing) covers dry runs and
|
||||
unattended mode with explicit image checksum and target identity.
|
||||
|
||||
Confirm the three internal partition labels and the USB's single `FDS_SYSTEM`
|
||||
label after writing. Safely disconnect the disks, install NVMe on the powered-off
|
||||
Pi, and connect exactly one SYSTEM. Do not leave the NVMe enclosure connected as
|
||||
a duplicate source of FDS partitions.
|
||||
label with `lsblk -o NAME,PARTLABEL,FSTYPE,MOUNTPOINTS`. Unmount any automatic
|
||||
desktop mounts after flashing, safely disconnect the disks, install NVMe on the
|
||||
powered-off Pi, and connect exactly one SYSTEM. Do not leave the NVMe enclosure
|
||||
connected as a duplicate source of FDS partitions.
|
||||
|
||||
## 6. Power on and reach the console
|
||||
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ Use the sidebar or [all pages](Page-Index) to find a guide.
|
||||
| --- | --- |
|
||||
| [Overview](Overview) | How the computer, internal storage and cartridges fit together |
|
||||
| [Run on a Raspberry Pi 5](Hardware-Setup) | Wire HDMI/USB/power, prepare NVMe and SYSTEM, reach the first console, calibrate bays and diagnose hardware |
|
||||
| [Flash disk images](Flashing) | Install NVMe and cartridges interactively or unattended with verification |
|
||||
| [Build and start FDS](Getting-Started) | Prepare the OS build workstation, create images and boot the emulator |
|
||||
| [Software and emulator walkthrough](Workstation) | Build Void source packages, assemble cartridges, insert them and write USB media |
|
||||
| [Using cartridges](Cartridges) | Inspect bays, run applications, resolve command names and eject safely |
|
||||
|
||||
+26
-64
@@ -57,79 +57,41 @@ public key as described in [Release signatures](Releases). Its complete disk
|
||||
is named `fds-internal-0.1.0.img`; a local build uses `out/fds-internal.img`.
|
||||
Use the complete disk image, not the separate BOOT or RECOVERY payload.
|
||||
|
||||
List disks before and after connecting the intended drive:
|
||||
Install the workstation `fds-tools` package or run `make workstation-binaries`,
|
||||
then use [fds-flash](Flashing) for interactive or unattended installation:
|
||||
|
||||
```sh
|
||||
lsblk -d -o NAME,PATH,MODEL,SERIAL,SIZE,TRAN,LOG-SEC
|
||||
ls -l /dev/disk/by-id/
|
||||
sudo ./out/workstation/fds-flash \
|
||||
--image out/fds-internal.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_NVME_DISK
|
||||
```
|
||||
|
||||
Match the physical model, serial and capacity. Choose a persistent **whole-disk**
|
||||
`/dev/disk/by-id/` path without a `-partN` suffix; never guess a `/dev/sdX` name.
|
||||
Unmount every target partition and disable any swap on it. Do not select the
|
||||
workstation's system disk. The current images require 512-byte logical sectors
|
||||
and a disk at least as large as the image; 4 KiB logical-sector media is not
|
||||
supported by this layout.
|
||||
Replace the destination with the verified whole-disk path. The tool shows model,
|
||||
serial, capacity, partitions and image hash, then requires an exact erase phrase.
|
||||
It refuses mounted or occupied disks and handles flushing, readback, backup-GPT
|
||||
relocation and kernel partition-table refresh. Partitions and filesystems retain
|
||||
their image sizes. The [flashing guide](Flashing) covers dry runs, JSON output,
|
||||
unattended identity/checksum bindings and failure handling.
|
||||
|
||||
Open Bash (`bash`), replace both paths below, then run the block. It checks the
|
||||
selected disk again, requires a typed confirmation, writes and reads back the
|
||||
complete image, and relocates the backup GPT when the disk is larger than the
|
||||
image. It does not expand any partition or filesystem.
|
||||
Prepare the first SYSTEM cartridge separately:
|
||||
|
||||
```bash
|
||||
(
|
||||
set -euo pipefail
|
||||
fds_image="$PWD/out/fds-internal.img"
|
||||
fds_disk=/dev/disk/by-id/REPLACE_WITH_THE_TARGET_DISK
|
||||
[[ -f "$fds_image" && -s "$fds_image" && -b "$fds_disk" ]]
|
||||
[[ $(lsblk -dnro TYPE "$fds_disk") == disk ]]
|
||||
[[ $(sudo blockdev --getss "$fds_disk") == 512 ]]
|
||||
fds_bytes=$(stat -Lc %s "$fds_image")
|
||||
(( $(sudo blockdev --getsize64 "$fds_disk") >= fds_bytes ))
|
||||
lsblk -p -o NAME,TYPE,MODEL,SERIAL,SIZE,MOUNTPOINTS "$fds_disk"
|
||||
if lsblk -nrpo MOUNTPOINTS "$fds_disk" | grep '[^[:space:]]' >/dev/null; then
|
||||
echo 'Target has mounted filesystems or swap; stop and release them first.' >&2
|
||||
exit 1
|
||||
fi
|
||||
if lsblk -nrpo TYPE "$fds_disk" | grep -Ev '^(disk|part)$' >/dev/null; then
|
||||
echo 'Target has device-mapper or other active descendants; stop.' >&2
|
||||
exit 1
|
||||
fi
|
||||
read -r -p "Type ERASE $fds_disk to erase this disk: " fds_confirmation
|
||||
[[ "$fds_confirmation" == "ERASE $fds_disk" ]]
|
||||
sudo dd if="$fds_image" of="$fds_disk" bs=4M conv=fsync status=progress
|
||||
sudo blockdev --flushbufs "$fds_disk"
|
||||
sudo cmp -n "$fds_bytes" "$fds_image" "$fds_disk"
|
||||
sudo sfdisk --lock=yes --relocate gpt-bak-std "$fds_disk"
|
||||
sudo sfdisk --verify "$fds_disk"
|
||||
sudo blockdev --flushbufs "$fds_disk"
|
||||
)
|
||||
```sh
|
||||
sudo ./out/workstation/fds-flash \
|
||||
--image out/fds-system-cli.img \
|
||||
--device /dev/disk/by-id/REPLACE_WITH_THE_SYSTEM_DISK
|
||||
```
|
||||
|
||||
Every command must succeed. The byte comparison occurs before relocating GPT,
|
||||
because relocation intentionally changes disk-table headers. GNU `dd`'s `fsync`
|
||||
flushes output before it returns; `sfdisk`'s `gpt-bak-std` moves the backup header
|
||||
to the end of the target. See the [GNU dd manual](https://www.gnu.org/s/coreutils/manual/html_node/dd-invocation.html)
|
||||
and [sfdisk manual](https://man7.org/linux/man-pages/man8/sfdisk.8.html).
|
||||
These commands use the already documented coreutils, diffutils and util-linux
|
||||
host tools; they do not add a target daemon.
|
||||
Use a different disk for SYSTEM. Both confirmed writes replace the selected
|
||||
media's contents; the internal image also replaces stored machine settings.
|
||||
The alternative development image is `out/fds-system-development.img`.
|
||||
Versioned release images use the same commands.
|
||||
|
||||
Confirm that the disk shows `FDS_BOOT`, `FDS_RECOVERY` and `FDS_INTERNAL` in that
|
||||
order using `lsblk -o NAME,PARTLABEL,FSTYPE,MOUNTPOINTS`. Unmount anything the
|
||||
desktop automatically mounted, then safely disconnect the enclosure and install
|
||||
the NVMe in the powered-off Pi. Follow [EEPROM preparation](EEPROM) for the
|
||||
separately reviewed NVMe boot settings.
|
||||
|
||||
Prepare the **first SYSTEM cartridge on the workstation** using the same guarded
|
||||
write block, with its two path assignments changed to the chosen SYSTEM image
|
||||
and a different, empty USB cartridge disk. For a local build select
|
||||
`out/fds-system-cli.img` or `out/fds-system-development.img`; release files are
|
||||
`fds-system-cli-0.1.0.img` and `fds-system-development-0.1.0.img`. They are
|
||||
alternative complete GPT images, each containing one `FDS_SYSTEM` partition.
|
||||
Readback and backup-GPT relocation apply to this disk too. Check its partition
|
||||
label, safely disconnect it, and insert exactly one SYSTEM cartridge in the Pi
|
||||
before normal boot. Subsequent cartridge creation and updates can use FDS's
|
||||
confirmed [media workflow](Developer-Media-Tools) after bay calibration.
|
||||
Confirm `FDS_BOOT`, `FDS_RECOVERY`, `FDS_INTERNAL` on NVMe and `FDS_SYSTEM` on
|
||||
SYSTEM with `lsblk -o NAME,PARTLABEL,FSTYPE,MOUNTPOINTS`. Unmount any automatic
|
||||
desktop mounts after flashing, safely disconnect the media, and install NVMe in
|
||||
the powered-off Pi. Insert exactly one SYSTEM cartridge before normal boot.
|
||||
Continue with [real-hardware setup](Hardware-Setup) and the separately reviewed
|
||||
[EEPROM configuration](EEPROM).
|
||||
|
||||
## Configure the machine before building
|
||||
|
||||
|
||||
+2
-2
@@ -62,7 +62,7 @@ Run these from the repository root:
|
||||
| Command | Result |
|
||||
| --- | --- |
|
||||
| `make wiki-check` | Check the documentation in `fds-os.wiki` |
|
||||
| `make workstation` | Arch `fds-tools` package containing both workstation commands |
|
||||
| `make workstation` | Arch `fds-tools` package containing all three workstation commands |
|
||||
| `make workstation-install` | Install that package using pacman |
|
||||
| `make workstation-binaries` | Native commands for other Linux distributions |
|
||||
| `make bootstrap` | Prepares the complete OS build environment on x86_64 Arch Linux |
|
||||
@@ -78,7 +78,7 @@ programs and dependencies directly. FDS does not extract those programs at launc
|
||||
|
||||
The workstation walkthrough includes prerequisites, complete example commands,
|
||||
expected outputs, emulator lifecycle and the confirmed USB-writing workflow.
|
||||
Append `--help` to either native tool for its command reference; run `make help`
|
||||
Append `--help` to any native tool for its command reference; run `make help`
|
||||
for the complete build target list.
|
||||
|
||||
Build identities come from Git release tags. See [versioning](Developer-Versioning) for release, development and source-export behavior.
|
||||
|
||||
@@ -6,6 +6,7 @@ include_toc: true
|
||||
|
||||
## User manual
|
||||
|
||||
- [Flash disk images with fds-flash](Flashing)
|
||||
- [Build and start FDS](Getting-Started)
|
||||
- [Build software cartridges and use the emulator](Workstation)
|
||||
- [Dasung Paperlike display](Dasung)
|
||||
|
||||
+14
-23
@@ -11,7 +11,7 @@ as guest commands.
|
||||
|
||||
## Prepare the tools
|
||||
|
||||
The native tools are `fds-cartridge` and `fds-emulator`. On Arch Linux, build
|
||||
The native tools are `fds-cartridge`, `fds-emulator` and `fds-flash`. On Arch Linux, build
|
||||
and install their `fds-tools` package from the checkout:
|
||||
|
||||
```sh
|
||||
@@ -21,7 +21,7 @@ make workstation-install
|
||||
```
|
||||
|
||||
`make workstation` produces `out/workstation/fds-tools-VERSION-1-ARCH.pkg.tar.zst`
|
||||
with both commands, documentation, examples and license notices. It does not
|
||||
with all three commands, documentation, examples and license notices. It does not
|
||||
install packages. `make workstation-install` builds that package and invokes
|
||||
`sudo pacman -U` to install it into `/usr/bin`. Pacman tracks upgrades and removal;
|
||||
remove it later with `sudo pacman -R fds-tools`. The exact latest package path is
|
||||
@@ -246,33 +246,24 @@ preserved by `make clean`; keep them under your own names, such as `my-emulator`
|
||||
|
||||
## Write a cartridge to USB
|
||||
|
||||
Identify the intended whole USB drive, unmount its partitions, then preview:
|
||||
Use `fds-flash` to write the complete cartridge image interactively:
|
||||
|
||||
```sh
|
||||
fds-cartridge preview out/demo-tools.img /dev/sdX out/usb-preview.json
|
||||
sudo fds-flash --image out/demo-tools.img
|
||||
```
|
||||
|
||||
Replace `/dev/sdX` with the actual destination. The JSON identifies the drive,
|
||||
capacity, image hash and exact confirmation phrase. Check those values before
|
||||
writing: this replaces the selected drive's contents.
|
||||
Choose the intended whole USB disk, review its model, serial and capacity, and
|
||||
type the displayed erase phrase. The tool writes, flushes and verifies the disk,
|
||||
including backup-GPT relocation on a larger destination. For a checkout build,
|
||||
use `sudo ./out/workstation/fds-flash` instead of the installed command.
|
||||
|
||||
```sh
|
||||
sudo /absolute/path/to/fds-cartridge write out/usb-preview.json \
|
||||
--confirm 'COPY THE EXACT confirmation VALUE FROM THE PREVIEW'
|
||||
```
|
||||
The [flashing guide](Flashing) covers explicit device paths, dry-run JSON,
|
||||
unattended writes and disposable-file testing. It also covers the internal
|
||||
NVMe and first SYSTEM disk; `fds-flash` accepts those complete disk images too.
|
||||
|
||||
The writer rechecks identity, writes the entire disk image, flushes it and verifies
|
||||
readback. On a larger drive it moves the backup GPT to the end. A changed image
|
||||
or reinserted drive requires a fresh preview. Use the image-tool runner for
|
||||
preview and inspection if your EROFS utilities are in the local container.
|
||||
|
||||
To rehearse with a disposable regular file:
|
||||
|
||||
```sh
|
||||
truncate -s "$(stat -c %s out/demo-tools.img)" out/disposable-usb.img
|
||||
fds-cartridge preview out/demo-tools.img out/disposable-usb.img out/file-preview.json --file-target
|
||||
fds-cartridge write out/file-preview.json --confirm 'COPY THE EXACT confirmation VALUE'
|
||||
```
|
||||
The older `fds-cartridge preview` / `write --confirm` interface remains supported
|
||||
for USB cartridge workflows. It performs deeper cartridge content inspection and
|
||||
retains its protection against overwriting internal FDS partitions.
|
||||
|
||||
See [troubleshooting](Troubleshooting) for failed builds, namespace errors,
|
||||
busy consoles, invalid media and blocked ejects.
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
|
||||
**Install and maintain**
|
||||
|
||||
- [Flash disk images](Flashing)
|
||||
- [Internal storage and machine settings](Internal-Storage)
|
||||
- [Pi 5 EEPROM configuration](EEPROM)
|
||||
- [Recovery and rollback](Recovery)
|
||||
|
||||
Reference in New Issue
Block a user