OpenWrt – Blame information for rev 3
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | RAMFS_COPY_BIN='osafeloader oseama' |
2 | |||
3 | PART_NAME=firmware |
||
4 | |||
5 | # $(1): file to read magic from |
||
6 | # $(2): offset in bytes |
||
7 | get_magic_long_at() { |
||
8 | dd if="$1" skip=$2 bs=1 count=4 2>/dev/null | hexdump -v -e '1/1 "%02x"' |
||
9 | } |
||
10 | |||
11 | platform_flash_type() { |
||
12 | # On NAND devices "rootfs" is UBI volume, so won't be find in /proc/mtd |
||
13 | grep -q "\"rootfs\"" /proc/mtd && { |
||
14 | echo "serial" |
||
15 | return |
||
16 | } |
||
17 | |||
18 | echo "nand" |
||
19 | } |
||
20 | |||
21 | platform_expected_image() { |
||
22 | local machine=$(board_name) |
||
23 | |||
24 | case "$machine" in |
||
25 | "dlink,dir-885l") echo "seama wrgac42_dlink.2015_dir885l"; return;; |
||
26 | "netgear,r6250v1") echo "chk U12H245T00_NETGEAR"; return;; |
||
27 | "netgear,r6300v2") echo "chk U12H240T00_NETGEAR"; return;; |
||
28 | "netgear,r7000") echo "chk U12H270T00_NETGEAR"; return;; |
||
29 | "netgear,r7900") echo "chk U12H315T30_NETGEAR"; return;; |
||
30 | "netgear,r8000") echo "chk U12H315T00_NETGEAR"; return;; |
||
31 | "netgear,r8500") echo "chk U12H334T00_NETGEAR"; return;; |
||
32 | "tplink,archer-c9-v1") echo "safeloader"; return;; |
||
33 | esac |
||
34 | } |
||
35 | |||
36 | platform_identify() { |
||
37 | local magic |
||
38 | |||
39 | magic=$(get_magic_long "$1") |
||
40 | case "$magic" in |
||
41 | "48445230") |
||
42 | echo "trx" |
||
43 | return |
||
44 | ;; |
||
45 | "2a23245e") |
||
46 | echo "chk" |
||
47 | return |
||
48 | ;; |
||
49 | "5ea3a417") |
||
50 | echo "seama" |
||
51 | return |
||
52 | ;; |
||
53 | esac |
||
54 | |||
55 | magic=$(get_magic_long_at "$1" 14) |
||
56 | [ "$magic" = "55324e44" ] && { |
||
57 | echo "cybertan" |
||
58 | return |
||
59 | } |
||
60 | |||
61 | if osafeloader info "$1" > /dev/null 2>&1; then |
||
62 | echo "safeloader" |
||
63 | return |
||
64 | fi |
||
65 | |||
66 | echo "unknown" |
||
67 | } |
||
68 | |||
69 | platform_check_image() { |
||
70 | [ "$#" -gt 1 ] && return 1 |
||
71 | |||
72 | local file_type=$(platform_identify "$1") |
||
73 | local magic |
||
74 | local error=0 |
||
75 | |||
76 | case "$file_type" in |
||
77 | "chk") |
||
78 | local header_len=$((0x$(get_magic_long_at "$1" 4))) |
||
79 | local board_id_len=$(($header_len - 40)) |
||
80 | local board_id=$(dd if="$1" skip=40 bs=1 count=$board_id_len 2>/dev/null | hexdump -v -e '1/1 "%c"') |
||
81 | local dev_board_id=$(platform_expected_image) |
||
82 | echo "Found CHK image with device board_id $board_id" |
||
83 | |||
84 | [ -n "$dev_board_id" -a "chk $board_id" != "$dev_board_id" ] && { |
||
85 | echo "Firmware board_id doesn't match device board_id ($dev_board_id)" |
||
86 | error=1 |
||
87 | } |
||
88 | |||
89 | if ! otrx check "$1" -o "$header_len"; then |
||
90 | echo "No valid TRX firmware in the CHK image" |
||
91 | error=1 |
||
92 | fi |
||
93 | ;; |
||
94 | "cybertan") |
||
95 | local pattern=$(dd if="$1" bs=1 count=4 2>/dev/null | hexdump -v -e '1/1 "%c"') |
||
96 | local dev_pattern=$(platform_expected_image) |
||
97 | echo "Found CyberTAN image with device pattern: $pattern" |
||
98 | |||
99 | [ -n "$dev_pattern" -a "cybertan $pattern" != "$dev_pattern" ] && { |
||
100 | echo "Firmware pattern doesn't match device pattern ($dev_pattern)" |
||
101 | error=1 |
||
102 | } |
||
103 | |||
104 | if ! otrx check "$1" -o 32; then |
||
105 | echo "No valid TRX firmware in the CyberTAN image" |
||
106 | error=1 |
||
107 | fi |
||
108 | ;; |
||
109 | "safeloader") |
||
110 | ;; |
||
111 | "seama") |
||
112 | local img_signature=$(oseama info "$1" | grep "Meta entry:.*signature=" | sed "s/.*=//") |
||
113 | local dev_signature=$(platform_expected_image) |
||
114 | echo "Found Seama image with device signature: $img_signature" |
||
115 | |||
116 | [ -n "$dev_signature" -a "seama $img_signature" != "$dev_signature" ] && { |
||
117 | echo "Firmware signature doesn't match device signature ($dev_signature)" |
||
118 | error=1 |
||
119 | } |
||
120 | |||
121 | $(oseama info "$1" -e 0 | grep -q "Meta entry:.*type=firmware") || { |
||
122 | echo "Seama container doesn't have firmware entity" |
||
123 | error=1 |
||
124 | } |
||
125 | ;; |
||
126 | "trx") |
||
127 | local expected=$(platform_expected_image) |
||
128 | |||
129 | [ "$expected" == "safeloader" ] && { |
||
130 | echo "This device expects SafeLoader format and may not work with TRX" |
||
131 | error=1 |
||
132 | } |
||
133 | |||
134 | if ! otrx check "$1"; then |
||
135 | echo "Invalid (corrupted?) TRX firmware" |
||
136 | error=1 |
||
137 | fi |
||
138 | ;; |
||
139 | *) |
||
140 | echo "Invalid image type. Please use only .trx files" |
||
141 | error=1 |
||
142 | ;; |
||
143 | esac |
||
144 | |||
145 | return $error |
||
146 | } |
||
147 | |||
148 | # $(1): image for upgrade (with possible extra header) |
||
149 | # $(2): offset of trx in image |
||
150 | platform_pre_upgrade_trx() { |
||
151 | local dir="/tmp/sysupgrade-bcm53xx" |
||
152 | local trx="$1" |
||
153 | local offset="$2" |
||
154 | |||
155 | # Extract partitions from trx |
||
156 | rm -fR $dir |
||
157 | mkdir -p $dir |
||
158 | otrx extract "$trx" \ |
||
159 | ${offset:+-o $offset} \ |
||
160 | -1 $dir/kernel \ |
||
161 | -2 $dir/root |
||
162 | [ $? -ne 0 ] && { |
||
163 | echo "Failed to extract TRX partitions." |
||
164 | return |
||
165 | } |
||
166 | |||
167 | # Firmwares without UBI image should be flashed "normally" |
||
168 | local root_type=$(identify $dir/root) |
||
169 | [ "$root_type" != "ubi" ] && { |
||
170 | echo "Provided firmware doesn't use UBI for rootfs." |
||
171 | return |
||
172 | } |
||
173 | |||
174 | # Prepare TRX file with just a kernel that will replace current one |
||
175 | local linux_length=$(grep "\"linux\"" /proc/mtd | sed "s/mtd[0-9]*:[ \t]*\([^ \t]*\).*/\1/") |
||
176 | [ -z "$linux_length" ] && { |
||
177 | echo "Unable to find \"linux\" partition size" |
||
178 | exit 1 |
||
179 | } |
||
180 | linux_length=$((0x$linux_length)) |
||
181 | local kernel_length=$(wc -c $dir/kernel | cut -d ' ' -f 1) |
||
182 | [ $kernel_length -gt $linux_length ] && { |
||
183 | echo "New kernel doesn't fit \"linux\" partition." |
||
184 | return |
||
185 | } |
||
186 | rm -f /tmp/null.bin |
||
187 | rm -f /tmp/kernel.trx |
||
188 | touch /tmp/null.bin |
||
189 | otrx create /tmp/kernel.trx \ |
||
190 | -f $dir/kernel -b $(($linux_length + 28)) \ |
||
191 | -f /tmp/null.bin |
||
192 | [ $? -ne 0 ] && { |
||
193 | echo "Failed to create simple TRX with new kernel." |
||
194 | return |
||
195 | } |
||
196 | |||
197 | # Prepare UBI image (drop unwanted extra blocks) |
||
198 | local ubi_length=0 |
||
199 | while [ "$(dd if=$dir/root skip=$ubi_length bs=1 count=4 2>/dev/null)" = "UBI#" ]; do |
||
200 | ubi_length=$(($ubi_length + 131072)) |
||
201 | done |
||
202 | dd if=$dir/root of=/tmp/root.ubi bs=131072 count=$((ubi_length / 131072)) 2>/dev/null |
||
203 | [ $? -ne 0 ] && { |
||
204 | echo "Failed to prepare new UBI image." |
||
205 | return |
||
206 | } |
||
207 | |||
208 | # Flash |
||
3 | office | 209 | mtd write /tmp/kernel.trx firmware |
1 | office | 210 | nand_do_upgrade /tmp/root.ubi |
211 | } |
||
212 | |||
213 | platform_pre_upgrade_seama() { |
||
214 | local dir="/tmp/sysupgrade-bcm53xx" |
||
215 | local seama="$1" |
||
216 | local tmp |
||
217 | |||
218 | # Extract Seama entity from Seama seal |
||
219 | rm -fR $dir |
||
220 | mkdir -p $dir |
||
221 | oseama extract "$seama" \ |
||
222 | -e 0 \ |
||
223 | -o $dir/seama.entity |
||
224 | [ $? -ne 0 ] && { |
||
225 | echo "Failed to extract Seama entity." |
||
226 | return |
||
227 | } |
||
228 | local entity_size=$(wc -c $dir/seama.entity | cut -d ' ' -f 1) |
||
229 | |||
230 | local ubi_offset=0 |
||
231 | tmp=0 |
||
232 | while [ 1 ]; do |
||
233 | [ $tmp -ge $entity_size ] && break |
||
234 | [ "$(dd if=$dir/seama.entity skip=$tmp bs=1 count=4 2>/dev/null)" = "UBI#" ] && { |
||
235 | ubi_offset=$tmp |
||
236 | break |
||
237 | } |
||
238 | tmp=$(($tmp + 131072)) |
||
239 | done |
||
240 | [ $ubi_offset -eq 0 ] && { |
||
241 | echo "Failed to find UBI in Seama entity." |
||
242 | return |
||
243 | } |
||
244 | |||
245 | local ubi_length=0 |
||
246 | while [ "$(dd if=$dir/seama.entity skip=$(($ubi_offset + $ubi_length)) bs=1 count=4 2>/dev/null)" = "UBI#" ]; do |
||
247 | ubi_length=$(($ubi_length + 131072)) |
||
248 | done |
||
249 | |||
250 | dd if=$dir/seama.entity of=$dir/kernel.seama bs=131072 count=$(($ubi_offset / 131072)) 2>/dev/null |
||
251 | dd if=$dir/seama.entity of=$dir/root.ubi bs=131072 skip=$(($ubi_offset / 131072)) count=$(($ubi_length / 131072)) 2>/dev/null |
||
252 | |||
253 | # Flash |
||
254 | local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"\(kernel\|linux\)".*/\1/p' /proc/mtd) |
||
3 | office | 255 | mtd write $dir/kernel.seama firmware |
1 | office | 256 | mtd ${kernel_size:+-c 0x$kernel_size} fixseama firmware |
257 | nand_do_upgrade $dir/root.ubi |
||
258 | } |
||
259 | |||
260 | platform_pre_upgrade() { |
||
261 | local file_type=$(platform_identify "$1") |
||
262 | |||
263 | [ "$(platform_flash_type)" != "nand" ] && return |
||
264 | |||
265 | # Find trx offset |
||
266 | case "$file_type" in |
||
267 | "chk") platform_pre_upgrade_trx "$1" $((0x$(get_magic_long_at "$1" 4)));; |
||
268 | "cybertan") platform_pre_upgrade_trx "$1" 32;; |
||
269 | "seama") platform_pre_upgrade_seama "$1";; |
||
270 | "trx") platform_pre_upgrade_trx "$1";; |
||
271 | esac |
||
272 | } |
||
273 | |||
274 | platform_trx_from_chk_cmd() { |
||
275 | local header_len=$((0x$(get_magic_long_at "$1" 4))) |
||
276 | |||
277 | echo -n dd skip=$header_len iflag=skip_bytes |
||
278 | } |
||
279 | |||
280 | platform_trx_from_cybertan_cmd() { |
||
281 | echo -n dd skip=32 iflag=skip_bytes |
||
282 | } |
||
283 | |||
284 | platform_img_from_safeloader() { |
||
285 | local dir="/tmp/sysupgrade-bcm53xx" |
||
286 | |||
287 | # Extract partitions from SafeLoader |
||
288 | rm -fR $dir |
||
289 | mkdir -p $dir |
||
290 | osafeloader extract "$1" \ |
||
291 | -p "os-image" \ |
||
292 | -o $dir/os-image |
||
293 | osafeloader extract "$1" \ |
||
294 | -p "file-system" \ |
||
295 | -o $dir/file-system |
||
296 | |||
297 | mtd write $dir/file-system rootfs |
||
298 | |||
299 | echo -n $dir/os-image |
||
300 | } |
||
301 | |||
302 | platform_img_from_seama() { |
||
303 | local dir="/tmp/sysupgrade-bcm53xx" |
||
304 | local offset=$(oseama info "$1" -e 0 | grep "Entity offset:" | sed "s/.*:\s*//") |
||
305 | local size=$(oseama info "$1" -e 0 | grep "Entity size:" | sed "s/.*:\s*//") |
||
306 | |||
307 | # Busybox doesn't support required iflag-s |
||
308 | # echo -n dd iflag=skip_bytes,count_bytes skip=$offset count=$size |
||
309 | |||
310 | rm -fR $dir |
||
311 | mkdir -p $dir |
||
312 | dd if="$1" of=$dir/image-noheader.bin bs=$offset skip=1 |
||
313 | dd if=$dir/image-noheader.bin of=$dir/image-entity.bin bs=$size count=1 |
||
314 | |||
315 | echo -n $dir/image-entity.bin |
||
316 | } |
||
317 | |||
318 | platform_do_upgrade() { |
||
319 | local file_type=$(platform_identify "$1") |
||
320 | local trx="$1" |
||
321 | local cmd= |
||
322 | |||
323 | [ "$(platform_flash_type)" == "nand" ] && { |
||
324 | echo "Writing whole image to NAND flash. All erase counters will be lost." |
||
325 | } |
||
326 | |||
327 | case "$file_type" in |
||
328 | "chk") cmd=$(platform_trx_from_chk_cmd "$trx");; |
||
329 | "cybertan") cmd=$(platform_trx_from_cybertan_cmd "$trx");; |
||
330 | "safeloader") trx=$(platform_img_from_safeloader "$trx"); PART_NAME=os-image;; |
||
331 | "seama") trx=$(platform_img_from_seama "$trx");; |
||
332 | esac |
||
333 | |||
334 | default_do_upgrade "$trx" "$cmd" |
||
335 | } |