Skip to content

Instantly share code, notes, and snippets.

@qwertychouskie
Created August 6, 2025 03:59
Show Gist options
  • Save qwertychouskie/e80f8de3b80c84746aad91ec36f7ee94 to your computer and use it in GitHub Desktop.
Save qwertychouskie/e80f8de3b80c84746aad91ec36f7ee94 to your computer and use it in GitHub Desktop.
#!/bin/bash
TARGET=$1
NEW_FREQUENCY=$2
function print_usage() {
APP=$(basename $0)
echo -e "Usage:"
echo -e "$APP <target> <frequency>"
echo
echo -e "<target>\tthe target file or the block device where ddrbin is contained"
echo -e "<frequency>\tchosen frequency, in MHz, to set"
echo
echo -e "Examples:"
echo
echo -e "./$APP block.bin 660"
echo -e "./$APP /dev/mmcblk0 660"
echo
}
echo -e "Rockchip rk3318/rk3328 ddrbin frequency switcher"
echo
echo -e "DISCLAIMER!!! Use this script at your own risk, proper or improper use may"
echo -e "prevent existing systems to boot and could require hardware manipulation"
echo -e "to restore functionalty. Do not use it if you are not prepared for consequences"
echo
if [[ -z "$TARGET" ]]; then
print_usage
exit 0
fi
if [[ -z "$NEW_FREQUENCY" ]]; then
print_usage
exit 0
fi
if [[ "$NEW_FREQUENCY" -lt 330 || "$NEW_FREQUENCY" -gt 800 ]]; then
echo "Invalid frequency value, valid range is 330 - 800"
exit 0
fi
# Create a tempfile that we will use for our operations
TEMPFILE=$(mktemp)
ERROR=$(dd if="$TARGET" of="$TEMPFILE" bs=64k count=1 2>&1 1>/dev/null)
if [[ $? -ne 0 ]]; then
echo "error when accessing $TARGET: $ERROR"
exit 1
fi
# Find the offset for the given signature
OFFSET=$(od --endian=big -A o -w4 -tx4 "$TEMPFILE" | grep "60e31621" | cut -d " " -f 1)
if [[ -z "$OFFSET" ]]; then
echo "could not proceed: unable to find signature in the target file/device"
exit 1
fi
# Our target values are 12 bytes before the signature
OFFSET=$(($OFFSET - 12))
# Extract the frequency numbers from the target, we should get 6 strings all of
# them with the identical frequency value
FREQ_VALUES=$(od -s -A n -j $OFFSET -N 12 $TEMPFILE | tr -s " ")
if [[ -z "FREQ_VALUES" ]]; then
echo "could not proceed: unable to find valid frequency values in target"
exit 1
fi
# Use read to convert the frequency values string into an array, we will
# also check if all the items in the array have the same values
read -a FREQ_ARRAY <<< $FREQ_VALUES
if [[ ${#FREQ_ARRAY[@]} -ne 6 ]]; then
echo "could not proceed: the frequency array does not contains the expected 6 elements"
exit 1
fi
CHECK_REF_VALUE=${FREQ_ARRAY[0]}
for CHECK_VALUE in ${FREQ_ARRAY}; do
if [[ "$CHECK_REF_VALUE" -ne "$CHECK_VALUE" ]]; then
echo "could not proceed: the frequency values in the array do not match"
exit 1
fi
done
echo "Current frequency in $TARGET: $CHECK_REF_VALUE MHz"
echo "Changing with $NEW_FREQUENCY MHz"
# All checks are ok, now proceed to write the values to the temporary file and then
# copy the temporary file over the target
LOW=$(($NEW_FREQUENCY % 256))
HIGH=$(($NEW_FREQUENCY / 256))
for idx in {1..6}; do
# First write low byte (double printf is necessary, sigh :( )
printf \\$(printf '%03o' $LOW) | dd of="$TEMPFILE" bs=1 seek=$OFFSET count=1 conv=notrunc 2>/dev/null
OFFSET=$(($OFFSET + 1))
# Then write high byte
printf \\$(printf '%03o' $HIGH) | dd of="$TEMPFILE" bs=1 seek=$OFFSET count=1 conv=notrunc 2>/dev/null
OFFSET=$(($OFFSET + 1))
done
if [[ $? -ne 0 ]]; then
echo "an error occurred writing new frequency to temporary file"
exit 1
fi
# Finally substitute the binary part into the target with the temporary file
ERROR=$(dd if="$TEMPFILE" of="$TARGET" bs=64k count=1 conv=notrunc 2>&1 1>/dev/null)
if [[ $? -ne 0 ]]; then
echo "an error occurred committing the new frequency to target file: $ERROR"
exit 1
fi
# Remove the temporary file
rm "$TEMPFILE"
echo "done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment