Skip to content

Commit d02de1d

Browse files
georgemoussalemrobimarko
authored andcommitted
qualcommax: ipq50xx: functions for bootconfig partition
The BOOTCONFIG partition is used by Qualcomm's boot chain to store metadata about the device's startup configuration. It contains info such as versioning, configuration flags, primary boot partition, and more. Newer devices with dual boot partitions not only store the active boot partition in a U-boot variable but also in partition info in the BOOTCONFIG partition. As such, add library functions to set and toggle the active boot partition. Signed-off-by: George Moussalem <[email protected]> Link: openwrt/openwrt#21038 Signed-off-by: Robert Marko <[email protected]>
1 parent 606a87e commit d02de1d

File tree

1 file changed

+177
-0
lines changed
  • target/linux/qualcommax/ipq50xx/base-files/lib/functions

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
. /lib/functions.sh
2+
3+
PART_SIZE=20
4+
NAME_SIZE=16
5+
MAX_NUM_PARTS=16
6+
7+
MAGIC_START_HEX="a0 a1 a2 a3"
8+
MAGIC_START_TRY_HEX="a1 a1 a2 a3"
9+
MAGIC_END_HEX="b0 b1 b2 b3"
10+
11+
validate_bootconfig_magic() {
12+
local file=$1
13+
magic_start=$(hexdump -v -n 4 -e '4/1 "%02x "' "$file")
14+
magic_end=$(hexdump -v -s 332 -n 4 -e '4/1 "%02x "' "$file")
15+
16+
if [ "$magic_start" != "$MAGIC_START_HEX" ] && \
17+
[ "$magic_start" != "$MAGIC_START_TRY_HEX" ]; then
18+
echo "Not a valid bootconfig file, start magic does not match" >&2
19+
return 1
20+
fi
21+
22+
if [ "$magic_end" != "$MAGIC_END_HEX" ]; then
23+
echo "Not a valid bootconfig file, end magic does not match" >&2
24+
return 1
25+
fi
26+
return 0
27+
}
28+
29+
get_bootconfig_numparts() {
30+
local file=$1
31+
numpartshex=$(hexdump -v -s 8 -n 4 -e '4/1 "%02x "' "$file")
32+
numparts=$(( 0x$(echo $numpartshex | awk '{print $4$3$2$1}') ))
33+
echo ${numparts}
34+
}
35+
36+
get_bootconfig_partidx() {
37+
local file=$1
38+
local partname=$2
39+
local numparts=$(get_bootconfig_numparts "$file")
40+
41+
if [ -z "$numparts" ]; then
42+
echo "Could not get number of partitions" >&2
43+
return
44+
fi
45+
46+
if [ $numparts -gt $MAX_NUM_PARTS ]; then
47+
numparts=$MAX_NUM_PARTS
48+
fi
49+
50+
for i in $(seq 0 $((numparts -1))); do
51+
nameoffset=$((12 + i * $PART_SIZE))
52+
nameraw=$(dd if="$file" bs=1 skip="$nameoffset" count=12 2>/dev/null)
53+
name=${nameraw//S'\x00'/}
54+
if [ "$partname" = "$name" ]; then
55+
echo $i
56+
fi
57+
done
58+
}
59+
60+
get_bootconfig_primaryboot() {
61+
local file=$1
62+
local partname=$2
63+
64+
local partidx=$(get_bootconfig_partidx "$file" "$partname")
65+
if ! echo "$partidx" | grep -Eq '^[0-9]+$'; then
66+
echo "Could not get partition index for $partname in $file" >&2
67+
return
68+
fi
69+
70+
if [ "$partidx" -ge 0 ] && [ "$partidx" -lt $MAX_NUM_PARTS ]; then
71+
offset=$((12 + $partidx * $PART_SIZE + $NAME_SIZE))
72+
primaryboothex=$(hexdump -v -s "$offset" -n 4 -e '4/1 "%02x "' $file)
73+
primaryboot=$(( 0x$(echo $primaryboothex | awk '{print $4$3$2$1}') ))
74+
echo $primaryboot
75+
fi
76+
}
77+
78+
_set_bootconfig_primaryboot() {
79+
local file=$1
80+
local partname=$2
81+
local primaryboot=$3
82+
local primaryboothex
83+
local partidx
84+
local primarybootoffset
85+
86+
partidx=$(get_bootconfig_partidx "$file" "$partname")
87+
if ! echo "$partidx" | grep -Eq '^[0-9]+$'; then
88+
echo "Could not get partition index for $2" >&2
89+
return 1
90+
fi
91+
primarybootoffset=$((12 + $partidx * $PART_SIZE + $NAME_SIZE))
92+
93+
case "$primaryboot" in
94+
0)
95+
printf "\x00\x00\x00\x00" | dd of="$file" seek="$primarybootoffset" bs=1 count=4 conv=notrunc 2>/dev/null
96+
;;
97+
1)
98+
printf "\x01\x00\x00\x00" | dd of="$file" seek="$primarybootoffset" bs=1 count=4 conv=notrunc 2>/dev/null
99+
;;
100+
*)
101+
echo "invalid argument: primaryboot must be 0 or 1" >&2
102+
return 1
103+
;;
104+
esac
105+
}
106+
107+
set_bootconfig_primaryboot() {
108+
local file=$1
109+
local partname=$2
110+
local primaryboot=$3
111+
112+
[ -z "$file" ] || [ -z "$partname" ] || [ -z "$primaryboot" ] && {
113+
echo "usage: $0 <file> <partition name> <0|1>"
114+
return 1
115+
}
116+
117+
[ ! -e "$file" ] && {
118+
echo "file $file not found" >&2
119+
return 1
120+
}
121+
122+
[ ! -w $file ] && {
123+
echo "file $file not writable" >&2
124+
return 1
125+
}
126+
127+
validate_bootconfig_magic "$file"
128+
[ $? -ne 0 ] && return 1
129+
130+
_set_bootconfig_primaryboot $file $partname $primaryboot
131+
[ $? -ne 0 ] && return 1
132+
133+
return 0
134+
}
135+
136+
toggle_bootconfig_primaryboot() {
137+
local file=$1
138+
local partname=$2
139+
local primaryboot
140+
141+
[ -z "$file" ] || [ -z "$partname" ] && {
142+
echo "usage: $0 <file> <partition name>"
143+
return 1
144+
}
145+
146+
[ ! -e "$file" ] && {
147+
echo "file $file not found" >&2
148+
return 1
149+
}
150+
151+
[ ! -w $file ] && {
152+
echo "file $file not writable" >&2
153+
return 1
154+
}
155+
156+
validate_bootconfig_magic "$file"
157+
[ $? -ne 0 ] && return 1
158+
159+
primaryboot=$(get_bootconfig_primaryboot "$1" "$2")
160+
161+
case "$primaryboot" in
162+
0)
163+
_set_bootconfig_primaryboot "$1" "$2" 1
164+
;;
165+
1)
166+
_set_bootconfig_primaryboot "$1" "$2" 0
167+
;;
168+
*)
169+
echo "invalid value: primaryboot must be 0 or 1" >&2
170+
return 1
171+
;;
172+
esac
173+
174+
[ $? -ne 0 ] && return 1
175+
176+
return 0
177+
}

0 commit comments

Comments
 (0)