diff --git a/ci/firmware/Dockerfile b/ci/firmware/Dockerfile index ea7791e..6e4456b 100644 --- a/ci/firmware/Dockerfile +++ b/ci/firmware/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update \ libnl-3-dev libssl-dev llvm-dev lz4 openssl parted patch \ pkg-config python-is-python3 python3 python3-dev python3-pip python3-pyelftools \ rsync sudo texinfo \ - u-boot-tools udev unzip uuid-dev wget xz-utils zstd \ + u-boot-tools udev unzip uuid-dev wget xxd xz-utils zstd \ && rm -rf /var/lib/apt/lists/* # Google's `repo` launcher (v2.69), pinned by content hash. diff --git a/docs/firmware-release.md b/docs/firmware-release.md index 5ac166a..57523ed 100644 --- a/docs/firmware-release.md +++ b/docs/firmware-release.md @@ -80,6 +80,7 @@ What a freshly flashed unit looks like, and what "factory reset" must restore: | Item | Factory state | | --- | --- | +| `/userdata` | empty partition; first boot copies the factory binary from `/usr/lib/rustkvm/` | | `/userdata/rustkvm/config.toml` | absent → setup wizard on first login (device password or no-password mode) | | TLS certificate | self-signed, generated at start | | SSH (dropbear) | off; enabled only by `/userdata/rustkvm/devmode.enable` | diff --git a/os/rk3588/README.md b/os/rk3588/README.md index 7c4f728..6a4c055 100644 --- a/os/rk3588/README.md +++ b/os/rk3588/README.md @@ -10,9 +10,11 @@ checks it out at the commits pinned here and applies the rest. | `patches//NNNN-*.patch` | Changes to SDK projects, applied in order with `git apply` | | `rootfs-overlay/` | Files copied into the root filesystem (init script, network config) | -The build also adds two things that are not in the tree: the `rustkvm_app` binary -(installed to `/userdata/rustkvm/bin/`) and `/etc/rustkvm-release` with the firmware -version. +The build also adds two things that are not in the tree: the `rustkvm_app` binary and +`/etc/rustkvm-release` with the firmware version. The binary ships in the rootfs as +`/usr/lib/rustkvm/rustkvm_app`, because `/userdata` is a separate partition that starts +empty and is mounted over the rootfs directory; `S99rustkvm` copies it to +`/userdata/rustkvm/bin/` on first boot and whenever userdata has been wiped. ## What the patches do @@ -20,6 +22,7 @@ version. | --- | --- | | `buildroot` | dhcpcd privsep seccomp allows `dup3` (SIGSYS at boot); chrony drift file ownership | | `buildroot` | RustKVM defconfig (GStreamer Opus, RGA, uvc-gadget, dropbear client, update engine); uvc-gadget builds with `-Dwerror=false` and accepts CONTINUOUS frame intervals | +| `buildroot` | rkupdate's license points at its real `LICENSE` file, so `make legal-info` completes | | `kernel` | `nanopi6_linux_defconfig`: NBD built in (virtual media), USB UAC2 gadget | | `scripts/sd-fuse` | builds the `v4l2loopback` module (operator-camera passthrough) | | `external` | rockit links `librkAlgoDis.so` | diff --git a/os/rk3588/manifest.xml b/os/rk3588/manifest.xml index 1c8bf3c..a771c3b 100644 --- a/os/rk3588/manifest.xml +++ b/os/rk3588/manifest.xml @@ -11,7 +11,8 @@ - + + diff --git a/os/rk3588/patches/buildroot/0003-rkupdate-point-license-at-the-existing-LICENSE-file.patch b/os/rk3588/patches/buildroot/0003-rkupdate-point-license-at-the-existing-LICENSE-file.patch new file mode 100644 index 0000000..15cf07d --- /dev/null +++ b/os/rk3588/patches/buildroot/0003-rkupdate-point-license-at-the-existing-LICENSE-file.patch @@ -0,0 +1,13 @@ +diff --git a/package/rockchip/rkupdate/rkupdate.mk b/package/rockchip/rkupdate/rkupdate.mk +index 2ac99eb6..dfb1d658 100644 +--- a/package/rockchip/rkupdate/rkupdate.mk ++++ b/package/rockchip/rkupdate/rkupdate.mk +@@ -9,7 +9,7 @@ RKUPDATE_SITE = $(TOPDIR)/../external/rkupdate + RKUPDATE_SITE_METHOD = local + + RKUPDATE_LICENSE = Apache V2.0 +-RKUPDATE_LICENSE_FILES = NOTICE ++RKUPDATE_LICENSE_FILES = LICENSE + + RKUPDATE_DEPENDENCIES = \ + libpthread-stubs util-linux diff --git a/os/rk3588/rootfs-overlay/etc/init.d/S99rustkvm b/os/rk3588/rootfs-overlay/etc/init.d/S99rustkvm index 207dfba..7f90409 100755 --- a/os/rk3588/rootfs-overlay/etc/init.d/S99rustkvm +++ b/os/rk3588/rootfs-overlay/etc/init.d/S99rustkvm @@ -4,6 +4,7 @@ # exit, so it is always stopped with SIGTERM. SIGKILL reboots the device. APP=/userdata/rustkvm/bin/rustkvm_app +FACTORY_APP=/usr/lib/rustkvm/rustkvm_app LOG_DIR=/userdata/rustkvm/log stop_app() { @@ -43,6 +44,12 @@ start) mkdir -p $LOG_DIR + # First boot or wiped userdata: install the binary shipped in the image. + if [ ! -f "$APP" ] && [ -f "$FACTORY_APP" ]; then + mkdir -p "$(dirname "$APP")" + cp "$FACTORY_APP" "$APP.tmp" && mv "$APP.tmp" "$APP" + fi + if [ ! -f "$APP" ]; then echo "rustkvm_app not found!" >>$LOG_DIR/rustkvm_app.log exit 1 diff --git a/scripts/build-firmware.sh b/scripts/build-firmware.sh index 32aea16..7edacef 100755 --- a/scripts/build-firmware.sh +++ b/scripts/build-firmware.sh @@ -119,17 +119,32 @@ BOARD=${BOARD_MK%.mk} EOF [ -f "$APP" ] || die "application binary not found: $APP (run scripts/build-app.sh first)" + # /userdata is its own (initially empty) partition mounted over the rootfs + # directory, so the factory binary lives in the rootfs and S99rustkvm copies + # it to /userdata/rustkvm/bin on first boot (and after a userdata wipe). log "install application $(basename "$APP")" - local bin=$SDK/device/rockchip/common/images/userdata/normal/rustkvm/bin - mkdir -p "$bin" - install -m 0755 "$APP" "$bin/rustkvm_app" + rm -rf "$SDK/device/rockchip/common/images/userdata/normal/rustkvm" + install -D -m 0755 "$APP" "$files/usr/lib/rustkvm/rustkvm_app" } step_build() { cd "$SDK" - log "build kernel, u-boot, Buildroot and SD image ($BOARD_MK)" - ./build.sh "$BOARD_MK" - log "build eMMC flasher image" + # `./build.sh .mk` builds everything twice, the second time as root, + # which leaves root-owned objects that break the next unprivileged build. + # Select the board ourselves and build each part as the current user; only + # image packing needs root (build.sh sudoes for those targets itself). + if [ -n "$(find u-boot kernel buildroot/output -maxdepth 3 -user root -print -quit 2>/dev/null)" ]; then + log "reclaim root-owned build files" + sudo chown -R "$(id -u):$(id -g)" u-boot kernel buildroot/output scripts/sd-fuse/out + fi + ln -sfn "$(readlink -f .current)/$BOARD_MK" .current_config.mk + for part in uboot kernel buildroot; do + log "build $part ($BOARD_MK)" + ./build.sh "$part" + done + log "pack SD image" + ./build.sh sd-img + log "pack eMMC flasher image" ./build.sh emmc-img } @@ -140,10 +155,14 @@ step_collect() { sd=$(ls -t "$SDK"/out/*_sd.img 2>/dev/null | head -n1) || true eflasher=$(ls -t "$SDK"/out/*_eflasher.img 2>/dev/null | head -n1) || true [ -n "$sd" ] || die "no SD image under $SDK/out" - local name=rustkvm-rk3588-$FW_VERSION + # Name the files after the version baked into the image, not the current HEAD. + local release=$SDK/device/friendlyelec/rustkvm-files/etc/rustkvm-release + local built + built=$(sed -n 's/^FIRMWARE_VERSION=//p' "$release") + local name=rustkvm-rk3588-$built gzip -c "$sd" >"$OUT/$name-sd.img.gz" [ -n "$eflasher" ] && gzip -c "$eflasher" >"$OUT/$name-eflasher.img.gz" - cp "$SDK/device/friendlyelec/rustkvm-files/etc/rustkvm-release" "$OUT/$name.release" + cp "$release" "$OUT/$name.release" (cd "$OUT" && sha256sum "$name"-* "$name.release" >"$name.SHA256SUMS") ls -lh "$OUT"/"$name"* } diff --git a/scripts/devkit.sh b/scripts/devkit.sh index 62248b4..c77a599 100755 --- a/scripts/devkit.sh +++ b/scripts/devkit.sh @@ -97,8 +97,9 @@ cmd_firmware_image() { cmd_firmware() { have_image "$FIRMWARE_IMAGE" || cmd_firmware_image mkdir -p "$SDK" "$CACHE/dl" "$CACHE/ccache" - # --privileged: the SDK packs SD/eMMC images through loop devices. - docker run --rm "${TTY[@]}" --privileged \ + # --privileged and the host /dev: the SDK packs SD/eMMC images through loop + # devices, and only the host creates the loopNpM partition nodes. + docker run --rm "${TTY[@]}" --privileged -v /dev:/dev \ -e RUSTKVM_SDK_DIR=/sdk -e BR2_DL_DIR=/cache/dl \ -e RUSTKVM_ROOT_PASSWORD -e FW_VERSION -e BOARD_MK -e REPO_DEPTH \ -v "$ROOT:/work" -v "$SDK:/sdk" -v "$CACHE:/cache" \ diff --git a/scripts/gpl-source-bundle.sh b/scripts/gpl-source-bundle.sh index a35c51f..f0df4bb 100755 --- a/scripts/gpl-source-bundle.sh +++ b/scripts/gpl-source-bundle.sh @@ -50,6 +50,8 @@ if [ "${LEGAL_INFO:-0}" = 1 ]; then out_dir=$SDK/buildroot/output/rockchip_rk3588 [ -f "$out_dir/.config" ] || { echo "error: no built Buildroot tree in $out_dir" >&2; exit 1; } make -C "$SDK/buildroot" O="$out_dir" legal-info - tar -C "$out_dir" -czf "$OUT/rustkvm-$version-legal-info.tar.gz" legal-info + # Host tools are not distributed, so their sources stay out of the bundle. + tar -C "$out_dir" --exclude=legal-info/host-sources \ + -czf "$OUT/rustkvm-$version-legal-info.tar.gz" legal-info echo "==> $OUT/rustkvm-$version-legal-info.tar.gz" fi