#!/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 KERNEL_BUILD_OUT=${ANDROID_PRODUCT_OUT}/obj/KERNEL_OBJ # 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 </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 androidboot.console=ttyS2 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 sfdisk -l "${IMAGE_PATH}" exit 0