1
0
Fork 0

Rewrite README to reflect tart LineageOS ATV port

This commit is contained in:
Brendan Szymanski 2026-07-12 00:05:59 -04:00
parent 9a659abcf3
commit 9063cf7f8e
3 changed files with 181 additions and 254 deletions

View file

@ -1,16 +1,41 @@
AOSP 16 device configuration for Orangepi 5 Pro. # android_device_rockchip_tart
Ported from KonstaKang's raspberry vanilla aosp 16 project. Device tree for building [LineageOS 23.2](https://lineageos.org/) (Android 16, Android TV variant) for the **Orange Pi 5 Ultra**, codename **`tart`**.
Not working - ## Hardware
Camera - **SoC:** Rockchip RK3588 (4x Cortex-A76 @ 2.4GHz + 4x Cortex-A55 @ 1.8GHz)
3.5 mm audio - **GPU:** ARM Mali-G610 MP4 "Odin" (Valhall, OpenGL ES 3.2 / Vulkan 1.2 / OpenCL 2.2)
- **Ethernet:** 2.5GbE via Realtek RTL8125BG (PCIe)
- **WiFi/BT:** WiFi 6E + Bluetooth 5.3 via Ampak AP6611S module (Synaptics SYN43711 chipset)
- **Audio:** Everest ES8388 codec (3.5mm jack, mic, HDMI eARC)
- **Display:** HDMI 2.1 out (8K60), 4-lane MIPI DSI out, HDMI 2.0 capture in
Working - ## Status
everything else including vulkan. This is an active bring-up port, not a finished build. Working/not-working status changes frequently — the authoritative, currently-maintained list lives in [`AGENTS.md`](../../AGENTS.md) and [`CLAUDE.md`](../../CLAUDE.md) at the root of the parent project repo, not here. As of the last update to this README:
This project can be ported to any device which utilises Rockchip SoC with minor changes. **Working:**
- Boots to Android on real hardware (kernel, all 8 CPUs, GPU/USB/PCIe detected)
- `breakfast tart` + plain `mka` build system/vendor/boot/ramdisk images
- GPT image creation (`mkimg.sh`) and flashing via U-Boot/extlinux
any doubts, feel free to mail me at vdarbha0473@gmail.com **Not working / deferred:**
- GPU acceleration — stock AOSP mesa3d only, no Panfrost yet
- SELinux enforcing (currently permissive)
- Camera, HDMI capture input, RTL8125BG Ethernet firmware, and WiFi/BT driver support are all unverified/in progress
This device has **no Android recovery** (`TARGET_NO_RECOVERY := true`) — it boots via U-Boot + `extlinux.conf`, not a recovery/OTA-zip flow. Use plain `mka`, not `mka bacon` (see [`BoardConfig.mk`](BoardConfig.mk) and the parent project's build docs for why `bacon` fails on this device).
## Building and flashing
Full setup, sync, and build instructions live in the [`android_local_manifest`](https://git.bscubed.dev/lineage-rockchip/android_local_manifest) README — this repo is just one of several projects (device tree, kernel, vendor blobs) that manifest pulls in.
Two scripts in this repo are used post-build:
- [`mkimg.sh`](mkimg.sh) — assembles a flashable GPT image (U-Boot + FAT32 boot partition with `extlinux.conf`/kernel/DTB/ramdisk, plus system/vendor/metadata/userdata partitions) from the build output. Run from the source tree root after `mka`, in the same shell used to build (needs `TARGET_PRODUCT`/`ANDROID_PRODUCT_OUT` from `lunch`/`breakfast`). Do not run with `sudo` — it escalates internally per-command only where needed.
- [`wrimg.sh`](wrimg.sh) — writes individual partition images (`boot`/`system`/`vendor`) directly to an already-flashed physical device for fast dev-iteration re-flashes, without rebuilding the whole GPT image. Also supports `wipe` (reformat userdata) and `wipe-metadata`. Auto-detects the target block device by matching partition labels/sizes against `mkimg.sh`'s 5-partition layout.
## License
Apache-2.0. Originally forked from KonstaKang's Orange Pi 5 Pro AOSP device tree and dvab-sarma's port; substantially modified for the Orange Pi 5 Ultra / LineageOS ATV port.

201
mkimg.sh
View file

@ -1,98 +1,191 @@
#!/bin/bash
# #
# Copyright (C) 2025 Venkata Atchuta Bheemeswara Sarma Darbha # Copyright (C) 2025 Venkata Atchuta Bheemeswara Sarma Darbha
#
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
#!/bin/bash # Create an RK3588 GPT AOSP image (no changes to original sector/start/size values).
# - Writes U-Boot at sector 64
# - Creates GPT with named partitions so Android creates /dev/block/by-name/*
# - Copies boot/system/vendor images (dd)
# - Creates metadata/userdata ext4 and sets proper GPT & fs labels
# - Uses kpartx to map partitions and cleans up reliably
#
set -euo pipefail
IFS=$'\n\t'
DEVICE_PATH=device/rockchip/tart
KERNEL_PATH=device/rockchip/tart-kernel
# Helper: print error and cleanup
exit_with_error() { exit_with_error() {
echo $@ echo "ERROR: $*" >&2
cleanup || true
exit 1 exit 1
} }
# Check required env vars cleanup() {
if [ -z ${TARGET_PRODUCT} ]; then
exit_with_error "TARGET_PRODUCT environment variable is not set. Run lunch first."
fi
if [ -z ${ANDROID_PRODUCT_OUT} ]; then if [ -n "${LOOPDEV:-}" ]; then
exit_with_error "ANDROID_PRODUCT_OUT environment variable is not set. Run lunch first." if sudo kpartx -l "${IMAGE_PATH}" >/dev/null 2>&1; then
fi sudo kpartx -d "${IMAGE_PATH}" || true
fi
fi
}
# Check required images trap cleanup EXIT
for PARTITION in "boot" "system" "vendor"; do
if [ ! -f ${ANDROID_PRODUCT_OUT}/${PARTITION}.img ]; then
exit_with_error "Partition image not found: ${PARTITION}.img. Run 'make ${PARTITION}image' first." : "${TARGET_PRODUCT:?TARGET_PRODUCT environment variable is not set. Run lunch first.}"
: "${ANDROID_PRODUCT_OUT:?ANDROID_PRODUCT_OUT environment variable is not set. Run lunch first.}"
for PART in boot system vendor; do
if [ ! -f "${ANDROID_PRODUCT_OUT}/${PART}.img" ]; then
exit_with_error "Missing partition image: ${ANDROID_PRODUCT_OUT}/${PART}.img — run 'make ${PART}image' first."
fi fi
done done
UBOOT_BIN=device/rockchip/tart-kernel/u-boot-rockchip.bin UBOOT_BIN=${KERNEL_PATH}/u-boot-rockchip.bin
if [ ! -f "${UBOOT_BIN}" ]; then
if [ ! -f ${UBOOT_BIN} ]; then exit_with_error "Missing U-Boot: ${UBOOT_BIN}"
exit_with_error "Missing u-boot-rockchip.bin! Make sure it's built and placed at ${UBOOT_BIN}"
fi fi
VERSION=OrangePi_5Pro_aosp LINEAGE_VERSION=$(build/soong/bin/get_build_var LINEAGE_VERSION)
DATE=$(date +%Y%m%d) if [ -z "${LINEAGE_VERSION}" ]; then
TARGET=$(echo ${TARGET_PRODUCT} | sed 's/^aosp_//') exit_with_error "LINEAGE_VERSION is empty. Run 'lunch' first and ensure the build environment is configured."
IMGNAME=${VERSION}-${DATE}-${TARGET}.img fi
IMGSIZE=19456MiB IMGSIZE=19456MiB
IMAGE_PATH="${ANDROID_PRODUCT_OUT}/lineage-${LINEAGE_VERSION}.img"
if [ -f ${ANDROID_PRODUCT_OUT}/${IMGNAME} ]; then if [ -f "${IMAGE_PATH}" ]; then
exit_with_error "${ANDROID_PRODUCT_OUT}/${IMGNAME} already exists!" echo "Overwriting existing image: ${IMAGE_PATH}"
sudo rm -f "${IMAGE_PATH}"
fi fi
echo "Creating image file ${ANDROID_PRODUCT_OUT}/${IMGNAME}..." echo "Creating image file ${IMAGE_PATH} (${IMGSIZE})..."
sudo fallocate -l ${IMGSIZE} ${ANDROID_PRODUCT_OUT}/${IMGNAME} sudo fallocate -l "${IMGSIZE}" "${IMAGE_PATH}"
sync sync
echo "Writing U-Boot to sector 64..." echo "Writing U-Boot to sector 64..."
sudo dd if=${UBOOT_BIN} of=${ANDROID_PRODUCT_OUT}/${IMGNAME} seek=64 bs=512 conv=notrunc # write u-boot binary to offset 64*512 = sector 64
sudo dd if="${UBOOT_BIN}" of="${IMAGE_PATH}" seek=64 bs=512 conv=notrunc status=progress
sync sync
echo "Partitioning image using sfdisk..." echo "Partitioning image using sfdisk (GPT) with explicit partition NAMES..."
PART_TABLE=$(cat <<EOF PART_TABLE=$(cat <<EOF
label: dos label: gpt
unit: sectors unit: sectors
${ANDROID_PRODUCT_OUT}/${IMGNAME}1 : start=32768, size=262144, type=c, bootable # Partition 1: boot (FAT32)
${ANDROID_PRODUCT_OUT}/${IMGNAME}2 : start=294912, size=7122944, type=5 ${IMAGE_PATH}1 : start=32768, size=262144, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="boot"
${ANDROID_PRODUCT_OUT}/${IMGNAME}3 : start=7417856, type=83
${ANDROID_PRODUCT_OUT}/${IMGNAME}5 : start=303104, size=6291456, type=83
${ANDROID_PRODUCT_OUT}/${IMGNAME}6 : start=6596608, size=786432, type=83
${ANDROID_PRODUCT_OUT}/${IMGNAME}7 : start=7385088, size=32768, type=83
# Partition 2: system (EXT4)
${IMAGE_PATH}2 : start=303104, size=6291456, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="system"
# Partition 3: vendor (EXT4)
${IMAGE_PATH}3 : start=6596608, size=786432, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="vendor"
# Partition 4: metadata (EXT4)
${IMAGE_PATH}4 : start=7385088, size=32768, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="metadata"
# Partition 5: userdata (EXT4)
${IMAGE_PATH}5 : start=7417856, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="userdata"
EOF EOF
) )
echo "$PART_TABLE" | sudo sfdisk ${ANDROID_PRODUCT_OUT}/${IMGNAME} # Use a temporary file for sfdisk input so variable interpolation is safe
echo "${PART_TABLE}" | sudo sfdisk "${IMAGE_PATH}"
sync sync
LOOPDEV=$(sudo kpartx -av ${ANDROID_PRODUCT_OUT}/${IMGNAME} | awk 'NR==1{ sub(/p[0-9]$/, "", $3); print $3 }') echo "Mapping partitions using kpartx..."
if [ -z ${LOOPDEV} ]; then
exit_with_error "Unable to find loop device!" KPARTX_OUT=$(sudo kpartx -av "${IMAGE_PATH}")
echo "${KPARTX_OUT}"
LOOPDEV=$(echo "${KPARTX_OUT}" | awk '/add map/ {dev=$3} END { sub(/p[0-9]+$/, "", dev); print dev }')
if [ -z "${LOOPDEV}" ]; then
exit_with_error "kpartx failed to map partitions or to return a loop device name."
fi fi
echo "Image mounted as /dev/${LOOPDEV}" echo "Mapped image as /dev/mapper/${LOOPDEV}p* (base loop: ${LOOPDEV})"
# Wait for device nodes to appear
sleep 1 sleep 1
if [ ! -b "/dev/mapper/${LOOPDEV}p1" ]; then
echo "Waiting a bit longer for /dev/mapper/${LOOPDEV}p1 to appear..."
sleep 1
fi
if [ ! -b "/dev/mapper/${LOOPDEV}p1" ]; then
exit_with_error "Device mapper nodes not found (e.g. /dev/mapper/${LOOPDEV}p1). Check kpartx output."
fi
echo "Copying boot..." # --- Copy images into partitions ---
sudo dd if=${ANDROID_PRODUCT_OUT}/boot.img of=/dev/mapper/${LOOPDEV}p1 bs=1M echo "Creating FAT32 filesystem on p1 (boot partition)..."
echo "Copying system..." sudo mkfs.vfat -F 32 -n "boot" "/dev/mapper/${LOOPDEV}p1"
sudo dd if=${ANDROID_PRODUCT_OUT}/system.img of=/dev/mapper/${LOOPDEV}p5 bs=1M
echo "Copying vendor..."
sudo dd if=${ANDROID_PRODUCT_OUT}/vendor.img of=/dev/mapper/${LOOPDEV}p6 bs=1M
# Mount the boot partition and copy kernel/boot files
BOOT_MOUNT=$(mktemp -d)
sudo mount "/dev/mapper/${LOOPDEV}p1" "${BOOT_MOUNT}"
sudo cp ${KERNEL_PATH}/Image "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/rk3588-orangepi-5-ultra.dtb "${BOOT_MOUNT}/"
sudo mkdir -p "${BOOT_MOUNT}/extlinux"
sudo tee "${BOOT_MOUNT}/extlinux/extlinux.conf" > /dev/null << 'EXTLINUX_EOF'
label LineageOS Android TV
kernel /Image
fdt /rk3588-orangepi-5-ultra.dtb
initrd /ramdisk.img
append console=ttyS2,1500000 no_console_suspend root=/dev/ram0 rootwait androidboot.hardware=tart androidboot.selinux=permissive androidboot.boot_devices=fe2c0000.mmc
EXTLINUX_EOF
sudo cp ${KERNEL_PATH}/boot.scr "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/android-sdcard.dtbo "${BOOT_MOUNT}/"
sudo cp "${ANDROID_PRODUCT_OUT}/ramdisk.img" "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/config.txt "${BOOT_MOUNT}/"
sudo umount "${BOOT_MOUNT}"
rmdir "${BOOT_MOUNT}"
echo "Creating metadata..." echo "Writing system image to p2 (raw dd)."
sudo mkfs.ext4 /dev/mapper/${LOOPDEV}p7 -I 512 -L metadata # Use conv=notrunc so we don't shrink partition image area; status=progress for visibility
sudo dd if="${ANDROID_PRODUCT_OUT}/system.img" of="/dev/mapper/${LOOPDEV}p2" bs=1M conv=notrunc status=progress
echo "Writing vendor image to p3 (raw dd)."
sudo dd if="${ANDROID_PRODUCT_OUT}/vendor.img" of="/dev/mapper/${LOOPDEV}p3" bs=1M conv=notrunc status=progress
echo "Creating userdata..."
sudo mkfs.ext4 /dev/mapper/${LOOPDEV}p3 -I 512 -L userdata
sync sync
sudo kpartx -d "/dev/${LOOPDEV}" # --- Ensure filesystem labels and types are correct ---
sudo chown ${USER}:${USER} ${ANDROID_PRODUCT_OUT}/${IMGNAME} # Note: dd'ing system/vendor may already contain an internal FS label; we force the GPT
# partition name above and set the filesystem label to match as a guard.
echo "Setting filesystem labels on p2 (system) and p3 (vendor) and creating metadata/userdata..."
echo "✅ Done! Created ${ANDROID_PRODUCT_OUT}/${IMGNAME} with U-Boot and properly aligned partitions." # Try to set ext4 label on system; if it isn't an ext4, warn but continue.
set +e
sudo e2label "/dev/mapper/${LOOPDEV}p2" system 2>/dev/null
E2_RC=$?
if [ "${E2_RC}" -ne 0 ]; then
echo "Warning: /dev/mapper/${LOOPDEV}p2 does not appear to be ext4 or e2label failed. Continuing."
fi
sudo e2label "/dev/mapper/${LOOPDEV}p3" vendor 2>/dev/null || echo "Warning: e2label on vendor failed (maybe not ext4)."
set -e
# Create/format metadata and userdata partitions and set filesystem labels
sudo mkfs.ext4 -F -L metadata "/dev/mapper/${LOOPDEV}p4"
sudo mkfs.ext4 -F -L userdata "/dev/mapper/${LOOPDEV}p5"
sync
# Final sanity: list by-name symlinks
echo "Partition mapping summary (kpartx):"
sudo ls -l /dev/mapper/"${LOOPDEV}"* || true
# Unmap now that we have set labels
sudo kpartx -d "${IMAGE_PATH}" || true
# fix ownership
sudo chown "${USER}:${USER}" "${IMAGE_PATH}"
echo "✅ Created ${IMAGE_PATH} with GPT partition names and filesystem labels."
echo "You should now be able to write this image to your SD/NVMe and boot RK3588. "
sudo sgdisk -p "${IMAGE_PATH}"
exit 0 exit 0

View file

@ -1,191 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2025 Venkata Atchuta Bheemeswara Sarma Darbha
# SPDX-License-Identifier: Apache-2.0
#
# Create an RK3588 GPT AOSP image (no changes to original sector/start/size values).
# - Writes U-Boot at sector 64
# - Creates GPT with named partitions so Android creates /dev/block/by-name/*
# - Copies boot/system/vendor images (dd)
# - Creates metadata/userdata ext4 and sets proper GPT & fs labels
# - Uses kpartx to map partitions and cleans up reliably
#
set -euo pipefail
IFS=$'\n\t'
DEVICE_PATH=device/rockchip/tart
KERNEL_PATH=device/rockchip/tart-kernel
# Helper: print error and cleanup
exit_with_error() {
echo "ERROR: $*" >&2
cleanup || true
exit 1
}
cleanup() {
if [ -n "${LOOPDEV:-}" ]; then
if sudo kpartx -l "${IMAGE_PATH}" >/dev/null 2>&1; then
sudo kpartx -d "${IMAGE_PATH}" || true
fi
fi
}
trap cleanup EXIT
: "${TARGET_PRODUCT:?TARGET_PRODUCT environment variable is not set. Run lunch first.}"
: "${ANDROID_PRODUCT_OUT:?ANDROID_PRODUCT_OUT environment variable is not set. Run lunch first.}"
for PART in boot system vendor; do
if [ ! -f "${ANDROID_PRODUCT_OUT}/${PART}.img" ]; then
exit_with_error "Missing partition image: ${ANDROID_PRODUCT_OUT}/${PART}.img — run 'make ${PART}image' first."
fi
done
UBOOT_BIN=${KERNEL_PATH}/u-boot-rockchip.bin
if [ ! -f "${UBOOT_BIN}" ]; then
exit_with_error "Missing U-Boot: ${UBOOT_BIN}"
fi
LINEAGE_VERSION=$(build/soong/bin/get_build_var LINEAGE_VERSION)
if [ -z "${LINEAGE_VERSION}" ]; then
exit_with_error "LINEAGE_VERSION is empty. Run 'lunch' first and ensure the build environment is configured."
fi
IMGSIZE=19456MiB
IMAGE_PATH="${ANDROID_PRODUCT_OUT}/lineage-${LINEAGE_VERSION}.img"
if [ -f "${IMAGE_PATH}" ]; then
echo "Overwriting existing image: ${IMAGE_PATH}"
sudo rm -f "${IMAGE_PATH}"
fi
echo "Creating image file ${IMAGE_PATH} (${IMGSIZE})..."
sudo fallocate -l "${IMGSIZE}" "${IMAGE_PATH}"
sync
echo "Writing U-Boot to sector 64..."
# write u-boot binary to offset 64*512 = sector 64
sudo dd if="${UBOOT_BIN}" of="${IMAGE_PATH}" seek=64 bs=512 conv=notrunc status=progress
sync
echo "Partitioning image using sfdisk (GPT) with explicit partition NAMES..."
PART_TABLE=$(cat <<EOF
label: gpt
unit: sectors
# Partition 1: boot (FAT32)
${IMAGE_PATH}1 : start=32768, size=262144, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="boot"
# Partition 2: system (EXT4)
${IMAGE_PATH}2 : start=303104, size=6291456, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="system"
# Partition 3: vendor (EXT4)
${IMAGE_PATH}3 : start=6596608, size=786432, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="vendor"
# Partition 4: metadata (EXT4)
${IMAGE_PATH}4 : start=7385088, size=32768, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="metadata"
# Partition 5: userdata (EXT4)
${IMAGE_PATH}5 : start=7417856, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="userdata"
EOF
)
# Use a temporary file for sfdisk input so variable interpolation is safe
echo "${PART_TABLE}" | sudo sfdisk "${IMAGE_PATH}"
sync
echo "Mapping partitions using kpartx..."
KPARTX_OUT=$(sudo kpartx -av "${IMAGE_PATH}")
echo "${KPARTX_OUT}"
LOOPDEV=$(echo "${KPARTX_OUT}" | awk '/add map/ {dev=$3} END { sub(/p[0-9]+$/, "", dev); print dev }')
if [ -z "${LOOPDEV}" ]; then
exit_with_error "kpartx failed to map partitions or to return a loop device name."
fi
echo "Mapped image as /dev/mapper/${LOOPDEV}p* (base loop: ${LOOPDEV})"
# Wait for device nodes to appear
sleep 1
if [ ! -b "/dev/mapper/${LOOPDEV}p1" ]; then
echo "Waiting a bit longer for /dev/mapper/${LOOPDEV}p1 to appear..."
sleep 1
fi
if [ ! -b "/dev/mapper/${LOOPDEV}p1" ]; then
exit_with_error "Device mapper nodes not found (e.g. /dev/mapper/${LOOPDEV}p1). Check kpartx output."
fi
# --- Copy images into partitions ---
echo "Creating FAT32 filesystem on p1 (boot partition)..."
sudo mkfs.vfat -F 32 -n "boot" "/dev/mapper/${LOOPDEV}p1"
# Mount the boot partition and copy kernel/boot files
BOOT_MOUNT=$(mktemp -d)
sudo mount "/dev/mapper/${LOOPDEV}p1" "${BOOT_MOUNT}"
sudo cp ${KERNEL_PATH}/Image "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/rk3588-orangepi-5-ultra.dtb "${BOOT_MOUNT}/"
sudo mkdir -p "${BOOT_MOUNT}/extlinux"
sudo tee "${BOOT_MOUNT}/extlinux/extlinux.conf" > /dev/null << 'EXTLINUX_EOF'
label LineageOS Android TV
kernel /Image
fdt /rk3588-orangepi-5-ultra.dtb
initrd /ramdisk.img
append console=ttyS2,1500000 no_console_suspend root=/dev/ram0 rootwait androidboot.hardware=tart androidboot.selinux=permissive androidboot.boot_devices=fe2c0000.mmc
EXTLINUX_EOF
sudo cp ${KERNEL_PATH}/boot.scr "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/android-sdcard.dtbo "${BOOT_MOUNT}/"
sudo cp "${ANDROID_PRODUCT_OUT}/ramdisk.img" "${BOOT_MOUNT}/"
sudo cp ${KERNEL_PATH}/config.txt "${BOOT_MOUNT}/"
sudo umount "${BOOT_MOUNT}"
rmdir "${BOOT_MOUNT}"
echo "Writing system image to p2 (raw dd)."
# Use conv=notrunc so we don't shrink partition image area; status=progress for visibility
sudo dd if="${ANDROID_PRODUCT_OUT}/system.img" of="/dev/mapper/${LOOPDEV}p2" bs=1M conv=notrunc status=progress
echo "Writing vendor image to p3 (raw dd)."
sudo dd if="${ANDROID_PRODUCT_OUT}/vendor.img" of="/dev/mapper/${LOOPDEV}p3" bs=1M conv=notrunc status=progress
sync
# --- Ensure filesystem labels and types are correct ---
# Note: dd'ing system/vendor may already contain an internal FS label; we force the GPT
# partition name above and set the filesystem label to match as a guard.
echo "Setting filesystem labels on p2 (system) and p3 (vendor) and creating metadata/userdata..."
# Try to set ext4 label on system; if it isn't an ext4, warn but continue.
set +e
sudo e2label "/dev/mapper/${LOOPDEV}p2" system 2>/dev/null
E2_RC=$?
if [ "${E2_RC}" -ne 0 ]; then
echo "Warning: /dev/mapper/${LOOPDEV}p2 does not appear to be ext4 or e2label failed. Continuing."
fi
sudo e2label "/dev/mapper/${LOOPDEV}p3" vendor 2>/dev/null || echo "Warning: e2label on vendor failed (maybe not ext4)."
set -e
# Create/format metadata and userdata partitions and set filesystem labels
sudo mkfs.ext4 -F -L metadata "/dev/mapper/${LOOPDEV}p4"
sudo mkfs.ext4 -F -L userdata "/dev/mapper/${LOOPDEV}p5"
sync
# Final sanity: list by-name symlinks
echo "Partition mapping summary (kpartx):"
sudo ls -l /dev/mapper/"${LOOPDEV}"* || true
# Unmap now that we have set labels
sudo kpartx -d "${IMAGE_PATH}" || true
# fix ownership
sudo chown "${USER}:${USER}" "${IMAGE_PATH}"
echo "✅ Created ${IMAGE_PATH} with GPT partition names and filesystem labels."
echo "You should now be able to write this image to your SD/NVMe and boot RK3588. "
sudo sgdisk -p "${IMAGE_PATH}"
exit 0