mirror of
https://github.com/jetkvm/rv1106-system.git
synced 2026-06-20 05:24:41 +00:00
* feat: support dual storage variants (eMMC + SDMMC/TF card) and upgrade jetkvm_app to 0.5.6 Introduce two separate build configurations for JetKVM V2 hardware variants that differ only in storage medium: BoardConfig-EMMC-NONE-RV1106_JETKVM_V2.mk → boots from eMMC (mmcblk0, 13640M userdata) BoardConfig-SDMMC-NONE-RV1106_JETKVM_V2.mk → boots from TF card (mmcblk1, dynamic userdata) DTS refactor: - Extract all shared board peripherals (backlight, gmac, i2c1/AT24C02, i2c3/FT5x06, spi0/ST7789V, uart3, rtc, wdt, pwm5, sfc=disabled) into rv1106-jetkvm-v2.dtsi as a common base - rv1106g-jetkvm-v2.dts becomes a thin file with only the eMMC node - New rv1106g-jetkvm-v2-sdmmc.dts thin file with only the sdmmc node - Verified: both DTBs compile correctly; eMMC DTB is binary-identical to upstream Build system: - Add sdmmc as a new RK_BOOT_MEDIUM type throughout project/build.sh: sd_parts device, parse_partition_file, rootfs bootarg, build_recovery, build_factory, build_uboot INI selection, and mount_part script - sysdrv/Makefile: add sdmmc block for KERNEL_CMDLINE_FRAGMENT and env target using mmcblk1; restore emmc back to mmcblk0 - project/scripts/mk-tftp_sd_update.sh: recognize sdmmc alongside emmc - tools/linux/Linux_Pack_Firmware/mk-update_pack.sh: add mmcblk0 to the boot medium list so eMMC update packages are correctly generated U-Boot: - android_ab.c: replace hardcoded mmcblk1 with dev_desc->devnum so the A/B root device path is correct for both eMMC (devnum=0) and SDMMC (devnum=1), matching the DTS alias assignments jetkvm_app: - Upgrade from 0.4.8 to 0.5.6 (SHA256 verified) - Note: 0.5.6 switches from static to dynamic linking (ld-uClibc.so.0) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: switch to ubuntu-22.04 runner and build both EMMC and SDMMC variants - Replace buildjet-16vcpu-ubuntu-2204 with standard ubuntu-22.04 runner - Use matrix strategy (fail-fast: false) to build EMMC and SDMMC in parallel - Artifact names include board variant: OTA-Image-EMMC, Full-Image-EMMC, etc. - buildkit upload remains EMMC-only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: bake SKU identifier into system image for OTA targeting Each build variant writes /etc/jetkvm-sku to the system partition so the jetkvm_app can report the correct SKU when querying the OTA service: BoardConfig-EMMC → RK_SKU=jetkvm-emmc BoardConfig-SDMMC → RK_SKU=jetkvm-sdmmc Matches the SKU routing introduced in jetkvm/cloud-api#49, where the OTA API serves variant-specific binaries under {prefix}/{version}/skus/{sku}/ and defaults to legacy path for unrecognised SKUs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: align OTA SKU names with cloud-api DEFAULT_SKU convention jetkvm-emmc → jetkvm-v2 (matches cloud-api DEFAULT_SKU) jetkvm-sdmmc → jetkvm-v2-sdmmc Ref: jetkvm/cloud-api@1958830 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dts): remove contradictory cap-mmc-highspeed from sdmmc node no-mmc prevents MMC protocol probing entirely, making cap-mmc-highspeed dead and misleading. Only cap-sd-highspeed is relevant for TF card use. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: handle IGNORE mountpoint for sdmmc in mount_part script Line 1601's guard only matched emmc, so SDMMC partitions with IGNORE mountpoint (e.g. inactive A/B slot) would fall through to return 1 instead of return 0, causing boot-time mount errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: add sdmmc to block-device filesystem tool checks in build_mkimg erofs and squashfs paths were missing sdmmc, causing them to fall through to ubifs (NAND-only tool). Latent with current ext4-only config but would silently produce a corrupt image if fs type changed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(sdmmc): build dd-able SD card image for direct flashing Adds build_sd_dd_image() that assembles a flat raw image from the fixed-size partitions (env, idblock, uboot_a/b, boot_a/b, system_a/b) plus a 256 MiB seed userdata.img containing install_to_userdata content (jetkvm_app etc.). Layout follows the cmdline blkdevparts — no MBR/GPT, since the kernel reads partitioning from u-boot env. Why a seed userdata: the SDMMC partition spec terminates with '-(userdata)' which build_mkimg skips, so jetkvm_app never landed in update.img on SDMMC. The mount_part init script (project/build.sh mount_part) calls resize2fs on first boot, which grows the 256 MiB ext4 to the end of the SD card automatically. Workflow: SDMMC artifact is now update_sd.img.zip (zip -9 of a sparse ~1.4 GiB image, ~45 MiB compressed). update.img remains the EMMC artifact since RKDevTool still uses it for production flashing. * fix(sdmmc): chown userdata seed root:root before mkfs.ext4 build_mkimg userdata is a no-op on SDMMC (partition size '-' → 0), so the __RELEASE_FILESYSTEM_FILES chown that build_mkimg normally runs never fires. Without it, mkfs.ext4 -d preserves the builder's uid/gid into the image, so /userdata/jetkvm on the SD card depended on whoever ran the build. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(sdmmc): tune userdata mkfs.ext4 so first-boot resize2fs scales to 1 TiB The previous flags (mkfs default 1K block size, -O ^64bit,^huge_file) made the first-boot resize hang on large cards: - 1K blocks × 8K-blocks-per-group → 128K block groups for 1 TiB. resize2fs has to write GD/bitmap entries for every new group; on slow SD random writes this stretches to many minutes. - Default inode_ratio at 1K = 2048 inodes/group → ~256M inodes after resize. ext4lazyinit kthread then zeroes ~32 GiB of inode tables in the background, saturating SD I/O long after mount returns. - resize_inode reserve = 256 GDT blocks × 32 entries = 8192 group descriptors, capping resize_inode-style growth at 64 GiB. Beyond that, resize2fs falls back to meta_bg, but ^64bit blocks the cleaner path. Switch to: 4K blocks, -T largefile (1 inode/MiB), -O 64bit, and an explicit -E resize= reservation covering 2 TiB. Measured on a 1 TiB sparse loop (host mkfs.ext4 1.47.2): online resize drops from 40 s to 0.4 s, and the post-mount lazy-itable workload drops from ~32 GiB to ~256 MiB of writes. 32 GiB minimum supported card capacity. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(sdmmc): include sdmmc in sysdrv build-medium switches Three places in sysdrv/ branched on the boot medium but left sdmmc out: - Makefile.tools.board.mk: e2fsprogs was gated on BOOT_MEDIUM=emmc, so the SDMMC rootfs shipped without resize2fs/e2fsck/mke2fs. mount_part's first-boot resize2fs call then silently failed and userdata stayed locked at the 256 MiB seed size, never growing to fill the card. - Makefile.param: the RK_BOOT_MEDIUM whitelist that propagates BOOT_MEDIUM omitted sdmmc, so any sub-tool Makefile included Makefile.param standalone (dropbear, eudev, etc.) saw BOOT_MEDIUM unset for sdmmc. Currently benign because no sub-tool branches on BOOT_MEDIUM, but a latent footgun. - tools/pc/toolkits/get_part_info.sh: PARTITION_FIRST_NO=0 was applied only for emmc. mmcblk1pN is also 1-indexed, so sdmmc would produce off-by-one root=/dev/mmcblk1pN values via `make env -C sysdrv`. The project's build.sh path computes part_num itself and isn't affected, but the sysdrv path was wrong. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
249 lines
5.1 KiB
Bash
Executable File
249 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
cmd=`realpath $0`
|
|
cwd=`dirname $cmd`
|
|
CMD_VERSION=1.0.1
|
|
|
|
C_BLACK="\e[30;1m"
|
|
C_RED="\e[31;1m"
|
|
C_GREEN="\e[32;1m"
|
|
C_YELLOW="\e[33;1m"
|
|
C_BLUE="\e[34;1m"
|
|
C_PURPLE="\e[35;1m"
|
|
C_CYAN="\e[36;1m"
|
|
C_WHITE="\e[37;1m"
|
|
C_NORMAL="\033[0m"
|
|
|
|
function msg_info()
|
|
{
|
|
echo -e "${C_GREEN}[$(basename $0):info] $1${C_NORMAL}"
|
|
}
|
|
|
|
function msg_warn()
|
|
{
|
|
echo -e "${C_YELLOW}[$(basename $0):warn] $1${C_NORMAL}"
|
|
}
|
|
|
|
function msg_error()
|
|
{
|
|
echo -e "${C_RED}[$(basename $0):error] $1${C_NORMAL}"
|
|
}
|
|
|
|
function pause()
|
|
{
|
|
msg_error "package update.img fail..."
|
|
msg_error "Press any key to quit:"
|
|
read -n1 -t10 -s key
|
|
exit -1
|
|
}
|
|
|
|
function msg_help()
|
|
{
|
|
echo "command format:"
|
|
echo " `basename $cmd` -v -h -i -id -p -t"
|
|
echo " -v|--version (Optional) view this version."
|
|
echo " -h|--help (Optional) view this help message."
|
|
echo " -id|--chip-id (Essential) input chip id."
|
|
echo " -i|--image (Essential) input firmware image path."
|
|
echo " -p|--parameter (Optional) the partition file path (Not added by default)."
|
|
}
|
|
|
|
function chk_param()
|
|
{
|
|
local cnt
|
|
cnt=0
|
|
while [ $# -ne 0 ]
|
|
do
|
|
case $1 in
|
|
-v|--version)
|
|
msg_info "V$CMD_VERSION"
|
|
exit 0
|
|
;;
|
|
-h|--help)
|
|
msg_help
|
|
exit 0
|
|
;;
|
|
-i|--image)
|
|
IMAGE_PATH=$2
|
|
cnt=$(( cnt + 1 ))
|
|
;;
|
|
-id|--chip-id)
|
|
CHIP_ID=$2
|
|
case $CHIP_ID in
|
|
rv1126|rv1109|RV1126|RV1109)
|
|
CHIP_ID=-RK1126
|
|
;;
|
|
rk3588|RK3588)
|
|
CHIP_ID=-RK3588
|
|
;;
|
|
rv1106|rv1103|RV1106|RV1103)
|
|
CHIP_ID=-RK1106
|
|
;;
|
|
*)
|
|
msg_error "Invalid paramter: -id $CHIP_ID"
|
|
exit -1
|
|
;;
|
|
esac
|
|
cnt=$(( cnt + 1 ))
|
|
;;
|
|
-p|--parameter)
|
|
partition_file=$2
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ $cnt -ne 2 -o -z "$IMAGE_PATH" -o -z "$CHIP_ID" ]; then
|
|
msg_error "Invalid parameter..."
|
|
msg_help
|
|
exit -1
|
|
fi
|
|
msg_info "image input dir: $IMAGE_PATH"
|
|
|
|
if [ -f "$partition_file" ]; then
|
|
PARTITION_FILE=`basename $partition_file`
|
|
return
|
|
fi
|
|
|
|
PARTITION_FILE=$partition_file
|
|
if [ -f "$IMAGE_PATH/$PARTITION_FILE" ]; then
|
|
return
|
|
fi
|
|
|
|
if [ -f "$IMAGE_PATH/env.img" ]; then
|
|
PARTITION_FILE=env.img
|
|
return
|
|
else
|
|
msg_error "Not found file named $PARTITION_FILE in the dir $IMAGE_PATH"
|
|
exit -1
|
|
fi
|
|
}
|
|
|
|
function get_partition_names()
|
|
{
|
|
local part_name part_size
|
|
local part_file part_lines boot_mediums
|
|
local env_all_flag env_final env_final_offset
|
|
|
|
env_all_flag=0
|
|
part_file=$IMAGE_PATH/$PARTITION_FILE
|
|
boot_mediums="blkdevparts=mmcblk0,blkdevparts=mmcblk1,mtdparts=sfc_nor,mtdparts=spi-nand0,mtdparts=rk-nand"
|
|
|
|
IFS=,
|
|
for medium in $boot_mediums;
|
|
do
|
|
part_lines=$(strings $part_file | grep -i $medium)
|
|
[ ! -z "$part_lines" ] && part_lines=${part_lines##*${medium}:} && break
|
|
done
|
|
IFS=
|
|
|
|
[ -z "$part_lines" ] && msg_error "Not found partition line in $part_file" && msg_help && exit -1
|
|
|
|
IFS=,
|
|
read -ra env_arr <<< "$part_lines"
|
|
env_final=${env_arr[-1]}
|
|
if [[ $env_final =~ "@" ]]; then
|
|
env_final_offset=`echo $env_final | cut -s -d '(' -f1|cut -s -d '@' -f2`
|
|
if [[ $((env_final_offset)) == 0 ]]; then
|
|
env_all_flag=1
|
|
fi
|
|
fi
|
|
|
|
for part in $part_lines;
|
|
do
|
|
part_size=`echo $part | cut -d '@' -f1`
|
|
part_name=`echo $part | cut -d '(' -f2|cut -d ')' -f1`
|
|
|
|
[[ $part_size =~ "-" ]] && continue
|
|
[[ "$part" == "$env_final" && "$env_all_flag" == 1 ]] && continue
|
|
PARTITIONS="$part_name,$PARTITIONS"
|
|
done
|
|
IFS=
|
|
|
|
if [ -z "$PARTITIONS" ];then
|
|
msg_error "Invalid partition..."
|
|
exit -1
|
|
fi
|
|
|
|
if [[ "$env_all_flag" == 1 ]]; then
|
|
ENV_ALL_OPTS="-no-overlap-check"
|
|
fi
|
|
# msg_info "partitions:\n$PARTITIONS"
|
|
}
|
|
|
|
function __package_file()
|
|
{
|
|
if [ -f "$IMAGE_PATH/$1" ];then
|
|
PACKAGE_CFG="$part $1\n$PACKAGE_CFG"
|
|
elif [ -f "$IMAGE_PATH/${1}.img" ];then
|
|
PACKAGE_CFG="$part ${1}.img\n$PACKAGE_CFG"
|
|
elif [ -f "$IMAGE_PATH/${1%_[ab]}.img" ];then
|
|
PACKAGE_CFG="$part ${1%_[ab]}.img\n$PACKAGE_CFG"
|
|
else
|
|
msg_error "Not found image file: $IMAGE_PATH/$1"
|
|
[ "$2" = "Essential" ] && exit -1
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function create_package_file()
|
|
{
|
|
IFS=,
|
|
for part in $SPECIAL_PARTITIONS $PARTITIONS;
|
|
do
|
|
case $part in
|
|
package-file)
|
|
PACKAGE_CFG="$part package-file\n$PACKAGE_CFG"
|
|
;;
|
|
bootloader)
|
|
__package_file download.bin Essential
|
|
;;
|
|
parameter)
|
|
__package_file $PARTITION_FILE Essential
|
|
;;
|
|
rootfs)
|
|
__package_file $part
|
|
[ $? -eq 1 ] && __package_file rootfs_base.img
|
|
;;
|
|
*)
|
|
__package_file $part
|
|
;;
|
|
esac
|
|
done
|
|
IFS=
|
|
|
|
msg_info "partitions:\n$PACKAGE_CFG"
|
|
echo -e $PACKAGE_CFG > $IMAGE_PATH/package-file
|
|
}
|
|
|
|
CHIP_ID=""
|
|
IMAGE_PATH=""
|
|
PARTITION_FILE=""
|
|
SPECIAL_PARTITIONS="bootloader,package-file"
|
|
PARTITIONS=""
|
|
PACKAGE_CFG=""
|
|
ENV_ALL_OPTS=""
|
|
|
|
chk_param $@
|
|
|
|
msg_info "partition file name: $PARTITION_FILE"
|
|
msg_info "start to package update.img..."
|
|
|
|
get_partition_names
|
|
|
|
create_package_file
|
|
|
|
echo "TOOL_PATH=$cwd"
|
|
|
|
$cwd/afptool -pack $IMAGE_PATH $IMAGE_PATH/update_tmp.img $ENV_ALL_OPTS || pause
|
|
|
|
$cwd/rkImageMaker $CHIP_ID $IMAGE_PATH/download.bin $IMAGE_PATH/update_tmp.img $IMAGE_PATH/update.img -os_type:androidos || pause
|
|
|
|
msg_info "Making $CHIP_ID update.img OK."
|
|
|
|
# remove temporay image
|
|
rm -f $IMAGE_PATH/update_tmp.img
|
|
rm -f $IMAGE_PATH/package-file
|
|
exit $? |