From 86d60f4743f6a092471b088a396138d2553080fc Mon Sep 17 00:00:00 2001 From: foxxcn Date: Sat, 24 Oct 2026 17:55:35 +0800 Subject: [PATCH] docs: make the from-scratch path work for an outside developer A clean-room run (anonymous clone, public ghcr images, no local toolchain or credentials) built the app and the firmware, but several documented steps assumed the reference workbench: - dev_deploy.sh only built with the self-built stage2 toolchain; it now falls back to the Docker devkit and deploys out/app/. - getting-started.md described the old buildkit artifact / update.img flow and root SSH; it now flashes the RustKVM image and turns on SSH through Settings (SSH access + developer mode). - README and README.zh-CN put dev_deploy.sh first and required stage2; they now lead with the devkit, note that no login is needed, and show how to use the pinned nightly and the published buildkit without stage2. - building.md: measured disk and time, WSL2 disk lives on C:, the firmware builder image is built locally from Docker Hub ubuntu:22.04. - New docs/customizing.md: hostname, UI name, USB descriptors, firmware version, root password and own build images. - build-firmware.sh removes the previous dated raw images before packing (two ~8 GB files per build day were never cleaned up). - MQTT discovery release_url pointed at the old foxxcn repository. Co-Authored-By: Claude Opus 5.5 --- README.md | 52 ++++++++++++++++--------- README.zh-CN.md | 22 ++++++++--- app/src/mqtt/discovery.rs | 2 +- dev_deploy.sh | 12 ++++-- docs/README.md | 1 + docs/building.md | 34 +++++++++++++--- docs/customizing.md | 81 +++++++++++++++++++++++++++++++++++++++ docs/getting-started.md | 62 +++++++++++++++++++++--------- scripts/build-firmware.sh | 3 ++ 9 files changed, 217 insertions(+), 52 deletions(-) create mode 100644 docs/customizing.md diff --git a/README.md b/README.md index 27c5535..ca8452a 100644 --- a/README.md +++ b/README.md @@ -219,17 +219,18 @@ What RustKVM focuses on: The full walkthrough, including flashing and wiring, is in [docs/getting-started.md](docs/getting-started.md). -1. **Build** the frontend and the device binary (next section), or use `dev_deploy.sh`. -2. **Deploy** to the device: +1. **Flash** a firmware image to a microSD card ([docs/quickstart.md](docs/quickstart.md)), + from a release or built yourself (next section). It already runs RustKVM. +2. **Open** `https:///` (or `https://rustkvm.local/`) and accept the + self-signed certificate. +3. **Finish the setup wizard**, then click the video view to take control. +4. **Deploy your own build** (optional): enable SSH under Settings → Security → SSH access + and Settings → System → Developer mode, then ```bash - ./dev_deploy.sh -r -u root + ./dev_deploy.sh -r # builds in the devkit unless you have stage2 ``` -3. **Open** `https:///` (or `https://rustkvm.local/`) and accept the - self-signed certificate. -4. **Finish the setup wizard**, then click the video view to take control. - Useful runtime flags (all also settable via `RUSTKVM_*` environment variables, see `rustkvm_app --help`): @@ -251,9 +252,11 @@ scripts/devkit.sh run scripts/build-app.sh # → out/app/rustkvm_app-aarch64-u scripts/devkit.sh firmware # → out/firmware/ SD and eMMC images ``` -Pinned versions, caches, proxies and the firmware build are covered in -[`docs/building.md`](docs/building.md). The manual setup below is what the containers -automate. +Only Docker and git are needed; the images are public and pulled without a login. +Pinned versions, disk space, caches, proxies and the firmware build are covered in +[`docs/building.md`](docs/building.md); renaming and rebranding your build in +[`docs/customizing.md`](docs/customizing.md). The manual setup below is what the +containers automate, and you only need it to work without Docker. ### 1. Frontend (any host) @@ -279,8 +282,10 @@ cargo +nightly test --workspace ### 3. Device build (aarch64 / RK3588) -The production binary uses the Buildroot RK3588 host toolchain and a self-built Rust -`stage2` toolchain with `-Z build-std`. +Without Docker, the binary needs the Buildroot RK3588 host toolchain and a nightly Rust +with `rust-src` (`-Z build-std`). The reference workbench uses a self-built `stage2` +toolchain, which `rust-toolchain.toml` names; with the pinned nightly instead, set +`RUSTUP_TOOLCHAIN=nightly-2026-06-14` (this is what the devkit does).
Step-by-step cross-compilation setup @@ -302,21 +307,25 @@ sudo apt install pkg-config gcc-arm-linux-gnueabihf clang llvm-dev libclang-dev python-is-python3 texinfo kmod cmake ``` -**Buildroot host toolchain.** Extract the RK3588 Buildroot SDK on a Linux filesystem -(extracting on Windows breaks its symlinks) and build it: +**Buildroot host toolchain.** Build the firmware once (`scripts/build-firmware.sh`, on a +Linux filesystem; a Windows drive breaks the SDK's symlinks) and copy its host dir: ```bash -mkdir -p buildroot-rk3588-20250527 && tar -xf buildroot-rk3588-20250527.tar -C buildroot-rk3588-20250527 -cd buildroot-rk3588-20250527 -./build.sh rk3588.mk sudo mkdir -p /opt/rk3588-buildkit -sudo cp -r "$PWD"/buildroot/output/rockchip_rk3588/host/* /opt/rk3588-buildkit/ +sudo cp -r ~/rustkvm-sdk/rk3588/buildroot/output/rockchip_rk3588/host/* /opt/rk3588-buildkit/ +``` + +Or copy it out of the published image: + +```bash +docker create --name bk ghcr.io/rust-kvm/rk3588-buildkit:20250527 +sudo docker cp bk:/opt/rk3588-buildkit /opt/ && docker rm bk ``` The [`buildkit`](.github/workflows/buildkit.yml) workflow can also build this toolchain and publish it as the `ghcr.io//rk3588-buildkit` container image. -**Rust stage2 toolchain.** In the `rust/` submodule, create `bootstrap.toml`: +**Rust stage2 toolchain** (optional; skip it to use the pinned nightly). In the `rust/` submodule, create `bootstrap.toml`: ```toml [build] @@ -344,6 +353,8 @@ profile sets `panic = "abort"`): cargo +stage2 build -Z build-std=std,panic_abort \ --target aarch64-unknown-linux-gnu -p rustkvm --bin rustkvm_app --release # → target/aarch64-unknown-linux-gnu/release/rustkvm_app +# without stage2: rustup toolchain install nightly-2026-06-14 --component rust-src \ +# --target aarch64-unknown-linux-gnu, then replace +stage2 with +nightly-2026-06-14 ``` ## API overview @@ -379,7 +390,10 @@ claude mcp add --transport http rustkvm https://rustkvm.local/mcp \ ## Documentation +- [`docs/quickstart.md`](docs/quickstart.md): flash a release image and log in - [`docs/getting-started.md`](docs/getting-started.md): flash, deploy, wire up and log in on an RK3588 board +- [`docs/building.md`](docs/building.md): Docker devkit, application and firmware builds +- [`docs/customizing.md`](docs/customizing.md): your own hostname, name, USB IDs and firmware version - [`docs/api.md`](docs/api.md): HTTP, JSON-RPC, MCP, HID-RPC and metrics reference - [`AGENTS.md`](AGENTS.md): architecture, module tree, coding conventions and gotchas - [`CONTRIBUTING.md`](CONTRIBUTING.md): development workflow and quality gates diff --git a/README.zh-CN.md b/README.zh-CN.md index cbc1cd5..990c476 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -79,13 +79,25 @@ RustKVM 的侧重点:RK3588 的 8 核算力与 H.264 / H.265 硬件编码; 完整步骤(刷机、接线、首次登录)见 [docs/getting-started.md](docs/getting-started.md)。 -1. 构建前端与设备程序(见下节),或直接使用 `dev_deploy.sh` -2. 部署到设备:`./dev_deploy.sh -r <设备IP> -u root` -3. 浏览器打开 `https://<设备IP>/` 或 `https://rustkvm.local/`,接受自签名证书 -4. 完成设置向导,点击画面即可开始控制 +1. 把固件镜像写入 microSD 卡([docs/quickstart.md](docs/quickstart.md)),可用 Release 下载的,也可自己构建(见下节);固件已自带 RustKVM +2. 浏览器打开 `https://<设备IP>/` 或 `https://rustkvm.local/`,接受自签名证书 +3. 完成设置向导,点击画面即可开始控制 +4. 部署自己构建的程序(可选):在 设置 → 安全 → SSH 访问 填入公钥,在 设置 → 系统 → 开发者 打开开发者模式,然后执行 `./dev_deploy.sh -r <设备IP>`(没有 stage2 工具链时自动在 devkit 容器里编译) ## 从源码构建 +**最快路径:任意装了 Docker 的 Linux 主机(含 WSL2)**,无需登录 GitHub 或 `docker login`,镜像都是公开的: + +```bash +git clone https://github.com/Rust-KVM/rustkvm && cd rustkvm +scripts/devkit.sh run scripts/build-app.sh # → out/app/rustkvm_app-aarch64-unknown-linux-gnu,约 7 分钟 +scripts/devkit.sh firmware # → out/firmware/ SD 卡与 eMMC 镜像,首次需约 50 GB 空闲磁盘 +``` + +版本固定、磁盘占用、代理与固件构建见 [docs/building.md](docs/building.md);改主机名、界面名称、USB 标识和固件版本见 [docs/customizing.md](docs/customizing.md)。WSL2 下 Docker 和 Linux 文件都在 C 盘的虚拟磁盘里,可用空间以 C 盘为准。 + +不用 Docker 时的手动步骤: + ```bash # 1. 前端(任意主机,stable Rust) rustup target add wasm32-unknown-unknown && cargo install trunk @@ -95,7 +107,7 @@ cd crates/rkvm-web && trunk build --release && cd - sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev cargo +nightly test --workspace -# 3. aarch64 设备构建(需 Buildroot RK3588 工具链 + 自建 stage2 Rust 工具链) +# 3. aarch64 设备构建(需 /opt/rk3588-buildkit 工具链;stage2 是参考工作站自建的,也可换成 +nightly-2026-06-14) cargo +stage2 build -Z build-std=std,panic_abort \ --target aarch64-unknown-linux-gnu -p rustkvm --bin rustkvm_app --release ``` diff --git a/app/src/mqtt/discovery.rs b/app/src/mqtt/discovery.rs index 73526fd..cbef952 100644 --- a/app/src/mqtt/discovery.rs +++ b/app/src/mqtt/discovery.rs @@ -520,7 +520,7 @@ impl MqttManager { state_topic: Some(self.topic(&["update", "state"])), device_class: Some("firmware".to_string()), entity_category: Some("config".to_string()), - release_url: Some("https://github.com/foxxcn/rustkvm/releases".to_string()), + release_url: Some("https://github.com/Rust-KVM/rustkvm/releases".to_string()), availability_topic: avail_topic.clone(), availability_template: avail_template.to_string(), device: Some(device.clone()), diff --git a/dev_deploy.sh b/dev_deploy.sh index 6485da6..f65b8f4 100755 --- a/dev_deploy.sh +++ b/dev_deploy.sh @@ -36,9 +36,15 @@ if [ -z "${REMOTE_HOST}" ]; then exit 1 fi -# 1. Build application +# 1. Build application: the self-built stage2 toolchain if installed, else the Docker devkit echo "🔨 Building application..." -cargo +stage2 build -Z build-std=std,panic_abort --target aarch64-unknown-linux-gnu -p rustkvm --bin rustkvm_app --release +if rustup toolchain list 2>/dev/null | grep -q '^stage2'; then + cargo +stage2 build -Z build-std=std,panic_abort --target aarch64-unknown-linux-gnu -p rustkvm --bin rustkvm_app --release + APP_BIN=target/aarch64-unknown-linux-gnu/release/rustkvm_app +else + "$(dirname "$0")/scripts/devkit.sh" run scripts/build-app.sh + APP_BIN=out/app/rustkvm_app-aarch64-unknown-linux-gnu +fi # 2. Stop existing process gracefully, then clean up. # rustkvm_app arms the hardware watchdog and only disarms it during graceful @@ -62,7 +68,7 @@ ssh "${REMOTE_USER}@${REMOTE_HOST}" ' echo "📦 Deploying to device..." ssh "${REMOTE_USER}@${REMOTE_HOST}" 'mkdir -p /userdata/rustkvm/bin' ssh "${REMOTE_USER}@${REMOTE_HOST}" 'mkdir -p /userdata/rustkvm/log' -ssh "${REMOTE_USER}@${REMOTE_HOST}" "cat > /userdata/rustkvm/bin/rustkvm_app" < target/aarch64-unknown-linux-gnu/release/rustkvm_app +ssh "${REMOTE_USER}@${REMOTE_HOST}" "cat > /userdata/rustkvm/bin/rustkvm_app" < "${APP_BIN}" ssh "${REMOTE_USER}@${REMOTE_HOST}" 'chmod +x /userdata/rustkvm/bin/rustkvm_app' # # 4. Start application diff --git a/docs/README.md b/docs/README.md index f5649d9..aafddf7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,7 @@ | [Getting started on RK3588](getting-started.md) | Flashing, deploying, wiring and first login | | [API reference](api.md) | HTTP routes, JSON-RPC, MCP tools, HID-RPC, MQTT, Prometheus metrics | | [Building](building.md) | Docker devkit, application package and firmware image, pinned versions | +| [Customizing your build](customizing.md) | Your own hostname, UI name, USB IDs, firmware version and build images | | [Releasing and shipping firmware](firmware-release.md) | Versioning, release checklist, flashing, factory state, acceptance test | | [Building from source manually](../README.md#building-from-source) | Frontend, x86_64 host build and the aarch64 cross toolchain without containers | | [Architecture and conventions](../AGENTS.md) | Module tree, coding rules, gotchas | diff --git a/docs/building.md b/docs/building.md index 9c4b43a..96cb93e 100644 --- a/docs/building.md +++ b/docs/building.md @@ -11,6 +11,22 @@ only Docker installed: The scripts also run directly on a host that has the tools installed; the containers just pin those tools. +Getting started from nothing: + +```bash +git clone https://github.com/Rust-KVM/rustkvm && cd rustkvm +scripts/devkit.sh run scripts/build-app.sh +``` + +No GitHub account or `docker login` is needed: the repository and the `ghcr.io/rust-kvm` +images are public. Your user must be able to run `docker` (member of the `docker` +group, or Docker Desktop's WSL integration). + +> [!NOTE] +> **WSL2:** Docker and the Linux filesystem live in a virtual disk on the Windows system +> drive, so free space on `C:` is the real limit, whatever `df /` says. Clone and build +> on the Linux filesystem (`~/...`), not under `/mnt/c`. + ## Pinned versions | What | Version | Where it is pinned | @@ -33,8 +49,9 @@ scripts/devkit.sh run scripts/build-app.sh ``` The first run pulls the published devkit image, -`ghcr.io/rust-kvm/rustkvm-devkit:nightly-2026-06-14` (about 3 GB unpacked). `out/app/` then -holds `rustkvm_app-aarch64-unknown-linux-gnu`, its `.sha256` (the same pair the OTA +`ghcr.io/rust-kvm/rustkvm-devkit:nightly-2026-06-14` (about 3 GB unpacked) and takes +about 7 minutes on 16 threads; it needs about 5 GB of disk in all (image, `target/` and +the cargo cache in `~/.cache/rustkvm`). `out/app/` then holds `rustkvm_app-aarch64-unknown-linux-gnu`, its `.sha256` (the same pair the OTA updater installs) and `BUILD_INFO`. The devkit image sits on `ghcr.io/rust-kvm/rk3588-buildkit:20250527`, the cross gcc and @@ -66,11 +83,11 @@ Deploy to a board on the network as before: `./dev_deploy.sh -r `. ## 2. Firmware image -Costs of the first build (the disk figure is the reference workbench's SDK tree; network and time are estimates): +Costs of the first build (the disk figure is measured on the reference workbench; network and time are estimates): | | | | --- | --- | -| Disk | about 60 GB for the SDK checkout and build tree, plus about 10 GB of download and ccache under `~/.cache/rustkvm` | +| Disk | about 40 GB for the SDK checkout and build tree (38 GB measured with the headless defconfig), plus about 2 GB of downloads and ccache under `~/.cache/rustkvm` and 2 GB for the builder image; keep 50 GB free | | Network | about 15 GB on the first sync (shallow clones plus Buildroot package sources) | | Time | several hours on 16 threads; later builds reuse the tree and ccache | @@ -79,6 +96,11 @@ scripts/devkit.sh run scripts/build-app.sh # the image embeds out/app/ scripts/devkit.sh firmware # sync, patch, build, collect ``` +The builder image (`rustkvm/firmware-builder:local`, Ubuntu 22.04 with the SDK's host +packages) is not published; the first `firmware` run builds it from +`ci/firmware/Dockerfile`, pulling `ubuntu:22.04` from Docker Hub. Every pinned SDK +commit is fetched anonymously from `github.com/friendlyarm`. + Steps can be run separately: `scripts/devkit.sh firmware patch build collect` skips the sync. The SDK checkout lives in `RUSTKVM_SDK_DIR` (default `~/rustkvm-sdk/rk3588`) and belongs to the script: the patch step resets every patched project to its pinned commit. @@ -96,7 +118,9 @@ belongs to the script: the patch step resets every patched project to its pinned set `FW_VERSION` to override it for a release. The firmware container runs `--privileged` because the SDK packs images through loop -devices. What the SDK changes are and how to edit them: [`os/rk3588/README.md`](../os/rk3588/README.md). +devices. An incremental rebuild after an application or overlay change +(`scripts/devkit.sh firmware patch build collect`) takes 7 to 40 minutes, depending on what changed. What the SDK changes are and how to edit them: [`os/rk3588/README.md`](../os/rk3588/README.md). +Your own hostname, name and version label: [customizing.md](customizing.md). ## Networks behind a proxy diff --git a/docs/customizing.md b/docs/customizing.md new file mode 100644 index 0000000..77fcec2 --- /dev/null +++ b/docs/customizing.md @@ -0,0 +1,81 @@ +# Customizing your build + +How to ship RustKVM under your own name: device hostname, the name in the web UI, USB +descriptors, the firmware version label and your own build images. Build everything with +the devkit first ([building.md](building.md)); each change below is followed by the same +two commands: + +```bash +scripts/devkit.sh run scripts/build-app.sh +FW_VERSION= scripts/devkit.sh firmware # only if you ship firmware +``` + +## Per device, no rebuild + +`/userdata/rustkvm/config.toml` on the device overrides the built-in defaults. Edit it +over SSH (developer mode, see [getting-started.md](getting-started.md#3-deploy-rustkvm)) +and restart with `/etc/init.d/S99rustkvm restart`. + +```toml +[network_config] +hostname = "mykvm" # system hostname; mDNS keeps the --mdns-hostname name + +[usb_config] # all five keys are required in this table +vendor_id = "0x1d6b" +product_id = "0x0104" +serial_number = "" +manufacturer = "MyKVM" +product = "MyKVM USB Emulation Device" +``` + +`rustkvm_app --help` lists every runtime flag; each also reads a `RUSTKVM_*` environment +variable (for example `--mdns-hostname` / `RUSTKVM_MDNS_HOSTNAME`). The firmware starts +the app from `/etc/init.d/S99rustkvm` without flags, so to change a flag for every unit +change the default in the source instead. + +## Built-in defaults (rebuild the app) + +| What | Where | +| --- | --- | +| mDNS name (`rustkvm.local`) and fallback hostname | `default_value` of `mdns_hostname` in `app/src/cli.rs` | +| Browser tab title | `` in `crates/rkvm-web/index.html` | +| Name in the sidebar, login card and page header | `"rustkvm"` strings in `crates/rkvm-web/src/shell/sidebar.rs` and `crates/rkvm-web/src/app.rs` | +| USB manufacturer, product, VID/PID | `impl Default for UsbConfig` in `app/src/config/types.rs` | +| Virtual media SCSI inquiry string | `inquiry_string` in `app/src/hardware/usb/gadget.rs` | +| MQTT base topic and Home Assistant device | `app/src/mqtt/types.rs`, `app/src/mqtt/discovery.rs` | + +Use a USB vendor and product ID you are entitled to before shipping hardware; the default +`0x1d6b:0x0104` is the Linux Foundation multifunction gadget ID. + +The MCP `serverInfo.name` (`app/src/mcp.rs`) is asserted by `app/tests/mcp.rs`; change +both together if you rename it. + +## Firmware + +| What | How | +| --- | --- | +| Version label (`/etc/rustkvm-release`, Settings → About, image file names) | `FW_VERSION=...` on the `firmware` command | +| Root password on the serial console | `RUSTKVM_ROOT_PASSWORD='<crypt hash>'` (`mkpasswd -m sha-512`); unset disables root password login. Keep it out of the repository. | +| Files in the root filesystem | `os/rk3588/rootfs-overlay/` | +| Kernel, Buildroot or board changes | patches under `os/rk3588/patches/`, see [`os/rk3588/README.md`](../os/rk3588/README.md) | + +The image files are always named `rustkvm-rk3588-<FW_VERSION>-*.img.gz`; rename them +after `collect` if you need another prefix. + +## Your own build images + +The devkit pulls `ghcr.io/rust-kvm/*` images anonymously. To build and host your own +(after changing `ci/devkit/Dockerfile` or the toolchain), point the scripts at your +registry and push: + +```bash +export RUSTKVM_BUILDKIT_IMAGE=ghcr.io/<you>/rk3588-buildkit:<tag> +export RUSTKVM_DEVKIT_IMAGE=ghcr.io/<you>/rustkvm-devkit:<tag> +scripts/devkit.sh image # builds the devkit on top of the buildkit image +docker login ghcr.io # with your own token, never committed +scripts/devkit.sh push +``` + +In a fork, `buildkit.yml` already publishes under your own owner; `release.yml` names +`ghcr.io/rust-kvm/rustkvm-devkit` directly, so change it there if releases should use +your devkit. diff --git a/docs/getting-started.md b/docs/getting-started.md index 1c440cd..0607875 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,50 +1,71 @@ # Getting started on an RK3588 board This guide takes you from a bare RK3588 board to controlling a target computer in the -browser. It assumes you have already built `rustkvm_app` as described in the -[README](../README.md#building-from-source). +browser, with an application you built yourself. It assumes you have built the +application (and, if you want your own image, the firmware) with the Docker devkit as +described in [building.md](building.md): + +```bash +scripts/devkit.sh run scripts/build-app.sh # out/app/ +scripts/devkit.sh firmware # out/firmware/ (optional) +``` ## 1. What you need | Item | Notes | | --- | --- | | RK3588 board | With an **HDMI input** (HDMI-RX) and a USB port that supports **device / OTG mode** | -| Buildroot system image | Built from the RK3588 Buildroot SDK; the [`buildkit`](../.github/workflows/buildkit.yml) workflow uploads the images as an artifact | +| RustKVM firmware image | `rustkvm-rk3588-<version>-sd.img.gz` or `-eflasher.img.gz`, from a release or your own `out/firmware/` | +| microSD card | 8 GB or larger | | HDMI cable | Target's video output → board's HDMI input | | USB cable | Board's OTG port → a USB port on the target (keyboard, mouse and virtual media) | | Network | Ethernet or Wi-Fi on the same network as your browser | | Optional | ATX extension wired to the target's front-panel header, DC power extension | -## 2. Flash the system image +## 2. Flash the firmware -Flash the Buildroot image (the `update.img` or partition images under `rockdev/`) -with the usual Rockchip tools, for example `rkdeveloptool` on Linux or RKDevTool on -Windows, with the board in Maskrom or Loader mode. Your board vendor's flashing guide -applies unchanged. +Write the image to a microSD card exactly as in [quickstart.md](quickstart.md#1-write-the-installer-card): +the `-eflasher` image installs to eMMC, the `-sd` image runs from the card. Boot the +board, find its IP address in your router's DHCP list, open `https://<device_ip>/` and +finish the setup wizard. -After the first boot, find the board's IP address (router DHCP list, serial console, -or `ip addr` on the board) and make sure you can `ssh root@<device_ip>`. +The firmware already runs RustKVM, so you can stop here. The next section replaces the +application with one you are working on. ## 3. Deploy RustKVM -From the repository, with the frontend already built: +SSH is off in the factory image and root password login is disabled, so turn on key +login from the web UI first: + +1. Settings → Security → **SSH access**: paste your public key (`~/.ssh/id_ed25519.pub`) + and save. +2. Settings → System → Developer: tick **Developer mode**. The device starts the SSH + server; `ssh root@<device_ip>` now works with that key. + +Then, from the repository: ```bash -./dev_deploy.sh -r <device_ip> -u root +./dev_deploy.sh -r <device_ip> ``` -The script cross-builds `rustkvm_app`, stops a running instance gracefully, copies the -binary to `/userdata/rustkvm/bin/` and opens an SSH session on the board. Start the -service from that session: +The script builds `rustkvm_app` (with the self-built `stage2` toolchain if you have one, +otherwise in the devkit), stops the running instance gracefully, copies the binary to +`/userdata/rustkvm/bin/` and opens an SSH session on the board. Start the service from +that session: ```bash -nohup setsid /userdata/rustkvm/bin/rustkvm_app </dev/null >>/userdata/rustkvm/log/rustkvm_app.log 2>&1 & +/etc/init.d/S99rustkvm restart tail -f /userdata/rustkvm/log/rustkvm_app.log ``` > [!WARNING] -> `rustkvm_app` arms the hardware watchdog. Stop it with `killall rustkvm_app` -> (SIGTERM). `killall -9` or `fuser -k` while it runs makes the watchdog reboot the board. +> `rustkvm_app` arms the hardware watchdog. Stop it with `/etc/init.d/S99rustkvm stop` +> or `killall rustkvm_app` (SIGTERM). `killall -9` or `fuser -k` while it runs makes the +> watchdog reboot the board. + +To go back to the application shipped in the image, delete +`/userdata/rustkvm/bin/rustkvm_app` and restart the service; it copies the factory copy +from `/usr/lib/rustkvm/` again. ## 4. Connect the target @@ -78,7 +99,9 @@ tail -f /userdata/rustkvm/log/rustkvm_app.log | --- | --- | | `/userdata/rustkvm/bin/rustkvm_app` | The binary | | `/userdata/rustkvm/config.toml` | Configuration (a legacy `config.json` is migrated automatically) | -| `/userdata/rustkvm/log/rustkvm_app.log` | Log, when started as above | +| `/usr/lib/rustkvm/rustkvm_app` | Factory copy in the image, installed when the one above is missing | +| `/userdata/rustkvm/log/rustkvm_app.log` | Log | +| `/userdata/rustkvm/devmode.enable` | Present while developer mode (SSH) is on | | `/userdata/rustkvm/.enablefailsafe` | Create this file to force failsafe mode on the next start | | `/tmp/rustkvm/` | TLS certificate and key (not persisted) | @@ -90,6 +113,7 @@ tail -f /userdata/rustkvm/log/rustkvm_app.log | Keyboard or mouse does nothing | The OTG cable must go to a data-capable port; `getUSBState` should report `configured`. | | `Text file busy` on redeploy | Run `killall rustkvm_app` and wait before copying. Only if that fails: `killall -9 rustkvm_app; sleep 2`. | | Browser cannot reach `rustkvm.local` | mDNS may be blocked on your network; use the IP address. | +| `ssh: connect ... refused` | Developer mode is off, or the key was not saved (step 3) | | Locked out after failed logins | Login is rate-limited with exponential backoff (up to 2 hours); wait or restart the service. | Still stuck? Open a [bug report](https://github.com/Rust-KVM/rustkvm/issues/new/choose) diff --git a/scripts/build-firmware.sh b/scripts/build-firmware.sh index 163c7a2..e152b45 100755 --- a/scripts/build-firmware.sh +++ b/scripts/build-firmware.sh @@ -154,6 +154,9 @@ step_build() { ./build.sh "$part" done echo "$stamp" >"$br_out/.rustkvm-defconfig" + # The packers name images by date and never remove older ones (two ~8 GB raw + # images per build day); keep only the ones this build writes. + sudo rm -f out/*_sd.img out/*_sd.img.gz out/*_eflasher.img log "pack SD image" ./build.sh sd-img log "pack eMMC flasher image"