forked from ghidraninja/game-and-watch-flashloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flash_multi.sh
executable file
·136 lines (113 loc) · 3.34 KB
/
flash_multi.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
function echo_green() {
echo -e "${GREEN}${@}${NC}"
}
function echo_red() {
echo -e "${RED}${@}${NC}"
}
if [[ "$VERBOSE" == "1" ]]; then
set -ex
else
set -e
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ELF=${DIR}/build/gw_base.elf
if [[ $# -lt 1 ]]; then
echo "Usage: flash_multi.sh <binary to flash> [address=0] [chip_erase=0]"
echo ""
echo "address: The address to start writing to in the flash. Default is 0."
echo "chip_erase: Forces the use of chip erase. Will erase the whole chip,"
echo " but may be faster for large flash chips."
echo ""
echo "Note! This will cut the binary in 1M chunks and flash them to address and onwards"
exit
fi
IMAGE="$1"
ADDRESS=0
if [[ $# -gt 1 ]]; then
ADDRESS=$2
fi
CHIP_ERASE=0
if [[ $# -gt 2 ]]; then
CHIP_ERASE=$3
fi
# stat on macOS has different flags
if [[ "$(uname -s)" == "Darwin" ]]; then
FILESIZE=$(stat -f%z "${IMAGE}")
else
FILESIZE=$(stat -c%s "${IMAGE}")
fi
CHUNKS=$(( (FILESIZE + 1024 * 1024 - 1) / (1024 * 1024) ))
SIZE=$((FILESIZE))
SECTOR_SIZE=$(( 4 * 1024 ))
ERASE_BYTES=0
ERASE=1
i=0
while [[ $SIZE -gt 0 ]]; do
ADDRESS_HEX=$(printf "0x%08x" $(( ADDRESS + i * 1024 * 1024 )))
if [[ $SIZE -gt $((1024*1024)) ]]; then
CHUNK_SIZE=$((1024*1024))
else
CHUNK_SIZE=${SIZE}
fi
SIZE_HEX=$(printf "0x%08x" ${CHUNK_SIZE})
TMPFILE=$(mktemp /tmp/flash_chunk.XXXXXX)
if [[ ! -e $TMPFILE ]]; then
echo "Can't create tempfile!"
exit 1
fi
echo_green "Preparing chunk $((i + 1)) / ${CHUNKS} in file ${TMPFILE}"
dd if="${IMAGE}" of="${TMPFILE}" bs=1024 count=$(( (CHUNK_SIZE + 1023) / 1024 )) skip=$(( i * 1024 )) 2> /dev/null
if [[ $CHUNK_SIZE -le 8 ]]; then
echo "Chunk size <= 8 bytes, padding with zeros"
dd if=/dev/zero of=${TMPFILE} bs=1 count=$(( 9 - CHUNK_SIZE )) seek=${CHUNK_SIZE} 2> /dev/null
fi
echo_green "Flashing!"
if [[ $CHIP_ERASE == 1 ]]; then
ERASE_BYTES=0
else
ERASE_BYTES=$(( (( SIZE + SECTOR_SIZE - 1 ) / SECTOR_SIZE) * SECTOR_SIZE ))
fi
# Try to flash 3 times, give up after that.
COUNT=3
for RETRY_COUNT in $(seq $COUNT); do
if [[ $RETRY_COUNT -gt 1 ]]; then
echo_red "Flashing chunk $i failed... power cycle unit and retry? (y/n)"
read -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 1
fi
echo ""
echo "Retry count $RETRY_COUNT/3"
fi
${DIR}/flash.sh ${TMPFILE} ${ADDRESS_HEX} ${SIZE_HEX} ${ERASE} ${ERASE_BYTES} && break
done
if [[ $RETRY_COUNT -eq 3 ]]; then
echo ""
echo ""
echo_red "Programming of the external flash FAILED after 3 tries."
echo_red "Please check your debugger and wires connecting to the target."
echo ""
echo ""
exit 1
else
echo ""
echo ""
echo_green "Programming of chunk $((i + 1)) / ${CHUNKS} succeeded."
echo ""
echo ""
fi
# Skip erase the following iterations
ERASE=0
ERASE_BYTES=0
rm -f ${TMPFILE}
SIZE=$(( SIZE - 1024*1024 ))
i=$(( i + 1 ))
done
echo_green "Programming of the external flash succeeded."
echo ""
echo ""