Last active
July 7, 2024 20:59
-
-
Save loopyd/284fd6ad5f8325bc293895396a6a126f to your computer and use it in GitHub Desktop.
[bash] EzRkFlash - Easy Rockchip flashing tool (rkdevtool) wrapper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
shopt -s extglob dotglob | |
IMAGE_PATH=${IMAGE_PATH:-} | |
LOADER_PATH=${LOADER_PATH:-} | |
FLASH_OFFSET=${FLASH_OFFSET:-0} | |
ERASE_EMMC_SIZE=${ERASE_EMMC_SIZE:-0} | |
WAIT_DEVICE=${WAIT_DEVICE:-false} | |
WAIT_DEVICE_TIMEOUT=${WAIT_DEVICE_TIMEOUT:-30} | |
AUTO_REBOOT=${AUTO_REBOOT:-false} | |
CARGS=("$@") | |
ACTION="" | |
# block non-root execution | |
if [ "$(id -u)" -ne 0 ]; then | |
echo "This script must be run as root" 1>&2 | |
exit 1 | |
fi | |
# trap exit signals with function | |
function error_trap() { | |
local LASTEXITCODE=$? | |
if [ $LASTEXITCODE -ne 0 ]; then | |
echo "Script exited with status code: $LASTEXITCODE" 1>&2 | |
exit $LASTEXITCODE | |
fi | |
exit 0 | |
} | |
trap error_trap ERR SIGINT SIGTERM SIGHUP SIGQUIT SIGTSTP EXIT | |
# check if shell command exists | |
function shell_cmd_exists() { | |
local cmd=$1 | |
if [ -z "$cmd" ]; then | |
echo "E: Command not provided" 1>&2 | |
return 2 | |
fi | |
command -v $cmd >/dev/null 2>&1 || { | |
return 1 | |
} | |
return 0 | |
} | |
# check if the device is connected | |
function is_device_connected() { | |
if ! rkdeveloptool ld 2>&1 | grep -q "Maskrom"; then | |
return 1 | |
fi | |
return 0 | |
} | |
# test if the device is connected | |
function test_device() { | |
printf "Testing device..." | |
if rkdeveloptool td 2>&1 | grep -q "failed"; then | |
printf "Failed\n" | |
return 1 | |
fi | |
printf "OK\n" | |
return 0 | |
} | |
function check_chip() { | |
printf "Checking chip info..." | |
if rkdeveloptool rci 2>&1 | grep -q "failed"; then | |
printf "Failed\n" | |
return 1 | |
fi | |
printf "OK\n" | |
return 0 | |
} | |
function read_flash_info() { | |
printf "Reading flash info..." | |
if rkdeveloptool rfi | grep -q "failed"; then | |
printf "Failed\n" | |
return 1 | |
fi | |
printf "OK\n" | |
return 0 | |
} | |
# Sideload loader bin | |
function sideload_loader() { | |
local loader=$1 | |
if [ ! -f "$loader" ]; then | |
echo "Loader file not found" >&2 | |
return 1 | |
fi | |
printf "Sideload bootloader..." | |
eval "rkdeveloptool db ${loader} >/dev/null 2>&1 " || { | |
printf "Failed\n" | |
return 1 | |
} | |
printf "OK\n" | |
test_device || return $? | |
check_chip || return $? | |
read_flash_info || return $? | |
return 0 | |
} | |
# Clear the emmc with zero image | |
function erase_emmc() { | |
local size | |
size=$1 | |
tmpfile=$(mktemp -f /tmp/zero.img.XXXXXX) | |
printf "Creating zero image..." | |
eval "dd if=/dev/zero of=${tmpfile} bs=1M count=${size} >/dev/null 2>&1 " || { | |
printf "Failed\n" | |
return 1 | |
} | |
printf "OK\n" | |
printf "Erasing emmc..." | |
eval "rkdeveloptool wl 0 ${tmpfile} >/dev/null 2>&1" || { | |
printf "Failed\n" | |
return 1 | |
} | |
rm -f $tmpfile || { | |
printf "Failed\n" | |
return 1 | |
} | |
printf "OK\n" | |
return 0 | |
} | |
# Reboot the device | |
function reboot_device() { | |
printf "Rebooting device..." | |
eval "rkdeveloptool rd >/dev/null 2>&1" || { | |
printf "Failed\n" | |
return 1 | |
} | |
printf "OK\n" | |
return 0 | |
} | |
# Flash the image | |
function flash_image() { | |
local image=$1 | |
if [ ! -f "$image" ]; then | |
echo "Image file not found" 1>&2 | |
return 1 | |
fi | |
shift 1 | |
local offset | |
offset=$1 | |
if [ -z "$offset" ]; then | |
echo "W: Offset not provided, using 0" 1>&2 | |
offset=0 | |
fi | |
eval "rkdeveloptool wl 0 $image" || { | |
echo "Failed to write image" 1>&2 | |
return 1 | |
} | |
return 0 | |
} | |
# Wait for device to connect | |
function wait_connect() { | |
local timeout | |
timeout=$1 | |
if [ -z "$timeout" ]; then | |
echo "W: Timeout not provided, using 30 seconds" 1>&2 | |
timeout=30 | |
fi | |
while [ $timeout -gt 0 ]; do | |
printf "Waiting for device to connect (%d seconds) \r" $timeout | |
if is_device_connected; then | |
return 0 | |
fi | |
sleep 1 | |
timeout=$((timeout - 1)) | |
done | |
return 1 | |
} | |
# Print program usage information | |
function usage() { | |
case $1 in | |
flash) | |
echo "EzRkFlash - Rockchip Flashing Tool (v1.0)" | |
echo "by: loopyd <[email protected]> (GPL3.0 permassive - 2024)" | |
echo "" | |
echo "Usage: $0 flash [OPTIONS]" | |
echo "" | |
echo "Flash Options:" | |
echo " -i, --image <path> Path to the image file" | |
echo " -l, --loader <path> Path to the loader file" | |
echo " -o, --offset <offset> Offset to write the image" | |
echo "" | |
echo "Device Options:" | |
echo " -w, --wait-device Wait for device to connect" | |
echo " -t, --timeout <time> Timeout to wait for device" | |
echo " -r, --reboot Reboot device after flashing" | |
;; | |
erase) | |
echo "Usage: $0 erase [OPTIONS]" | |
echo "" | |
echo "Erase Options:" | |
echo " -e, --erase-emmc-size <size> Size in MB to erase" | |
echo "" | |
echo "Device Options:" | |
echo " -w, --wait-device Wait for device to connect" | |
echo " -t, --timeout <time> Timeout to wait for device" | |
echo " -r, --reboot Reboot device after erasing" | |
;; | |
*) | |
echo "Usage: $0 <action> [OPTIONS]" 1>&2 | |
echo "" | |
echo "Tool Actions:" | |
echo " flash Flash the image" | |
echo " erase Erase the emmc" | |
;; | |
esac | |
exit 1 | |
} | |
# Parse command line arguments | |
function parse_args() { | |
local ARGS=($*) | |
if [ ${#ARGS} -lt 2 ]; then | |
echo "E: No arguments provided" 1>&2 | |
usage | |
fi | |
ACTION=${ARGS[0]} | |
if [ -z "$ACTION" ]; then | |
echo "E: No action provided" 1>&2 | |
usage | |
fi | |
ARGS=(${ARGS[@]:1}) | |
case "$ACTION" in | |
flash) | |
while [ ${#ARGS[@]} -gt 0 ]; do | |
case ${ARGS[0]} in | |
-h | --help) | |
usage $ACTION | |
;; | |
-i | --image) | |
IMAGE_PATH=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-l | --loader) | |
LOADER_PATH=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-o | --offset) | |
FLASH_OFFSET=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-w | --wait-device) | |
WAIT_DEVICE=true | |
ARGS=(${ARGS[@]:1}) | |
;; | |
-t | --timeout) | |
WAIT_DEVICE_TIMEOUT=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-r | --reboot) | |
AUTO_REBOOT=true | |
ARGS=(${ARGS[@]:1}) | |
;; | |
*) | |
echo "E: Unknown argument: ${ARGS[0]}" 1>&2 | |
usage $ACTION | |
;; | |
esac | |
done | |
;; | |
erase) | |
while [ ${#ARGS[@]} -gt 0 ]; do | |
case ${ARGS[0]} in | |
-h | --help) | |
usage $ACTION | |
;; | |
-e | --erase-emmc-size) | |
ERASE_EMMC_SIZE=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-w | --wait-device) | |
WAIT_DEVICE=true | |
ARGS=(${ARGS[@]:1}) | |
;; | |
-t | --timeout) | |
WAIT_DEVICE_TIMEOUT=${ARGS[1]} | |
ARGS=(${ARGS[@]:2}) | |
;; | |
-r | --reboot) | |
AUTO_REBOOT=true | |
ARGS=(${ARGS[@]:1}) | |
;; | |
*) | |
echo "E: Unknown argument: ${ARGS[0]}" 1>&2 | |
usage $ACTION | |
;; | |
esac | |
done | |
;; | |
*) | |
echo "E: Unknown action: $ACTION" 1>&2 | |
usage | |
;; | |
esac | |
} | |
### Main | |
parse_args ${CARGS[*]} | |
case "$ACTION" in | |
flash) | |
if [ -z "$IMAGE_PATH" ]; then | |
echo "E: Image path not provided" 1>&2 | |
usage $ACTION | |
fi | |
if [ -z "$LOADER_PATH" ]; then | |
echo "E: Loader path not provided" 1>&2 | |
usage $ACTION | |
fi | |
if ! shell_cmd_exists rkdeveloptool; then | |
echo "E: rkdeveloptool not found on PATH, please compile/install it." 1>&2 | |
exit 1 | |
fi | |
echo "Flash Parameters:" | |
echo " Sideload loader: $LOADER_PATH" | |
echo " Image: $IMAGE_PATH" | |
echo " Byte Offset: $FLASH_OFFSET" | |
if [ "$WAIT_DEVICE" = true ]; then | |
wait_connect $WAIT_DEVICE_TIMEOUT || { | |
echo "E: Maskrom Device not connected" 1>&2 | |
exit 1 | |
} | |
else | |
if ! is_device_connected; then | |
echo "E: Maskrom Device not connected" 1>&2 | |
exit 1 | |
fi | |
fi | |
sideload_loader $LOADER_PATH || exit $? | |
flash_image $IMAGE_PATH || exit $? | |
if [ "$AUTO_REBOOT" = true ]; then | |
reboot_device || exit $? | |
fi | |
;; | |
erase) | |
if [ $ERASE_EMMC_SIZE -eq 0 ]; then | |
echo "Erase size not provided" 1>&2 | |
usage $ACTION | |
fi | |
if ! shell_cmd_exists rkdeveloptool; then | |
echo "E: rkdeveloptool not found on PATH, please compile/install it." 1>&2 | |
exit 1 | |
fi | |
echo "Erase Parameters:" | |
echo " Erase size: $ERASE_EMMC_SIZE" | |
if [ "$WAIT_DEVICE" = true ]; then | |
wait_connect $WAIT_DEVICE_TIMEOUT || { | |
echo "E: Maskrom Device did not connect within the specified timeframe." 1>&2 | |
exit 1 | |
} | |
else | |
if ! is_device_connected; then | |
echo "E: Maskrom Device not connected" 1>&2 | |
exit 1 | |
fi | |
fi | |
erase_emmc $ERASE_EMMC_SIZE || exit $? | |
if [ "$AUTO_REBOOT" = true ]; then | |
reboot_device || exit $? | |
fi | |
;; | |
*) | |
usage | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
EzRkFlash
Version 1.0.0
This tool allows you to flash custom ROM to Rockchip devices using rkdevtool in linux.
It was written to offer easier solution in Linux over RkDevtool in Windows.
This post reserved for future updates