wok view syslinux/stuff/iso2exe/iso2exe.sh @ rev 19358

syslinux/iso2exe: fix partition scan (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jul 31 11:28:07 2016 +0200 (2016-07-31)
parents 8e396fd3bc8c
children 31e215a4b9bb
line source
1 #!/bin/sh
3 ddq()
4 {
5 dd $@ 2> /dev/null
6 }
8 store()
9 {
10 n=$2; for i in $(seq 8 8 ${4:-16}); do
11 printf '\\\\x%02X' $(($n & 255))
12 n=$(($n >> 8))
13 done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
14 }
16 get()
17 {
18 echo $(od -j $(($1)) -N ${3:-2} -t u${3:-2} -An "$2")
19 }
21 compress()
22 {
23 if [ "$1" ]; then
24 [ "$(which zopfli 2> /dev/null)" ] &&
25 zopfli --i100 -c /dev/stdin > $1 ||
26 gzip -9 > $1
27 [ "$(which advdef 2> /dev/null)" ] &&
28 advdef -z4 $1 > /dev/null
29 elif [ "$(which xz 2> /dev/null)" ]; then
30 xz -z -e --format=lzma --lzma1=mode=normal --stdout
31 else
32 lzma e -si -so
33 fi 2> /dev/null
34 }
36 add_rootfs()
37 {
38 TMP=/tmp/iso2exe$$
39 mkdir -p $TMP/dev
40 cp -a /dev/tty /dev/tty0 $TMP/dev
41 $0 --get init > $TMP/init.exe
42 # mount -o loop,ro $1 $TMP
43 # oldslitaz="$(ls $TMP/boot/isolinux/splash.lss 2> /dev/null)"
44 # umount -d $TMP
45 # [ "$oldslitaz" ] && # for SliTaz <= 3.0 only...
46 # grep -q mount.posixovl.iso2exe $TMP/init.exe && mkdir $TMP/bin &&
47 # cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe \
48 # 2> /dev/null && echo "Store mount.posixovl ($(wc -c \
49 # < /usr/sbin/mount.posixovl) bytes) ..."
50 find $TMP -type f -print0 | xargs -0 chmod +x
51 find $TMP -print0 | xargs -0 touch -t 197001010100.00
52 ( cd $TMP ; find * | grep -v rootfs.gz | cpio -o -H newc ) | \
53 compress $TMP/rootfs.gz
54 SIZE=$(wc -c < $TMP/rootfs.gz)
55 store 24 $SIZE $1
56 OFS=$(( $OFS - $SIZE ))
57 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
58 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
59 rm -rf $TMP
60 }
62 add_dosexe()
63 {
64 TMP=/tmp/bootiso$$
65 $0 --get bootiso.bin > $TMP 2> /dev/null
66 OFS=$(($(get 20 $TMP) - 0xC0))
67 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x8000 - $OFS))
68 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
69 rm -f $TMP
70 }
72 add_doscom()
73 {
74 SIZE=$($0 --get boot.com | wc -c)
75 OFS=$(( $OFS - $SIZE ))
76 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
77 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
78 store 64 $(($OFS+0xC0)) $1
79 }
81 add_tazlito_info()
82 {
83 HOLE=$OFS
84 [ $(get 0 $2) -eq 35615 ] || return
85 zcat $2 | compress /tmp/rezipped$$.gz
86 n=$(stat -c %s /tmp/rezipped$$.gz)
87 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
88 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
89 HOLE=$(($HOLE+$n))
90 rm -f /tmp/rezipped$$.gz
91 }
93 add_win32exe()
94 {
95 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
96 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
97 ddq if=/tmp/exe$$ of=$1 conv=notrunc
98 printf "Adding bootiso head at %04X...\n" 0
99 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
100 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
101 store $((0x94)) $((0xE0 - 12*8)) $1
102 store $((0xF4)) $((16 - 12)) $1
103 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
104 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
105 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
106 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
107 store 417 $(($SIZE/512)) $1 8
108 store 510 $((0xAA55)) $1
109 rm -f /tmp/exe$$ /tmp/coff$$
110 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $SIZE
111 ddq if=$2 bs=1 count=512 of=$1 seek=$SIZE conv=notrunc
112 OFS=$(($SIZE+512))
113 }
115 add_fdbootstrap()
116 {
117 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
118 if [ $SIZE -ne 0 ]; then
119 SIZE=$(( $SIZE - 512 )) # sector 2 is data
120 OFS=$(( $OFS - $SIZE ))
121 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
122 $0 --get bootfd.bin | \
123 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
124 $0 --get bootfd.bin | \
125 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
126 store 26 $(($SIZE/512)) $1 8
127 fi
128 }
130 gzsize()
131 {
132 echo $(($(hexdump -C | awk ' {
133 for (i = 2; i < 18; i++) if ($i != "00") break;
134 if (i == 18) {
135 for (i = 17; i > 1; i--) if ($i != "00") break;
136 print "0x" $1 " + 7 - " (16 - i)
137 exit
138 }
139 }')))
140 }
142 fileofs()
143 {
144 [ $(get 1024 "$ISO") -eq 35615 ] && i=1024 ||
145 i=$((512*(1+$(get 417 "$ISO" 1))))
146 stub=$(($(get 20 "$ISO") - 0xC0))
147 c=$(custom_config_sector "$ISO")
148 SIZE=0; OFFSET=0
149 case "$1" in
150 win32.exe) [ $i -eq 1024 ] || SIZE=$(($i - 512));;
151 syslinux.mbr) [ $i -eq 1024 ] || OFFSET=$(($i - 512)); SIZE=512;;
152 flavor.info) OFFSET=$i
153 SIZE=$(ddq bs=512 skip=$(($i/512)) if="$ISO" | gzsize);;
154 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
155 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
156 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
157 tazboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
158 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
159 dosstub) OFFSET=$stub; SIZE=$((0x8000 - $OFFSET));;
160 boot.md5) OFFSET=$((0x7FF0)); SIZE=16;;
161 fs.iso) OFFSET=$((0x8000))
162 SIZE=$((2048*$c - $OFFSET));;
163 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
164 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
165 SIZE=39 ;;
166 custom.append) OFFSET=$((2048*$c+47)) &&
167 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
168 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
169 custom.initrd) i=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
170 sed '/^append=\|^initrd:/!d' | wc -c)
171 OFFSET=$((2048*$c+$i+40))
172 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
173 sed '/^initrd:/!d;s/.*://') + 0));;
174 esac
175 }
177 list()
178 {
179 HEAP=0
180 for f in win32.exe syslinux.mbr flavor.info floppy.boot tazboot.com \
181 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
182 custom.initrd; do
183 fileofs $f
184 [ $SIZE -le 0 ] && continue
185 [ "${OFFSET:8}" ] && continue
186 [ $OFFSET -lt 0 ] && continue
187 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
188 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
189 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
190 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
191 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
192 done
193 OFFSET=$(stat -c %s "$ISO")
194 [ $OFFSET -gt $HEAP ] &&
195 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
196 }
198 extract()
199 {
200 for f in $@; do
201 fileofs $f
202 [ $SIZE -eq 0 ] ||
203 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
204 done
205 }
207 custom_config_sector()
208 {
209 get 32848 "$1" 4
210 }
212 clear_custom_config()
213 {
214 start=$(custom_config_sector $1)
215 cnt=$((512 - ($start % 512)))
216 [ $cnt -ne 512 ] &&
217 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
218 }
219 case "$1" in
220 --build)
221 shift
222 ls -l $@
223 cat >> $0 <<EOM
224 $(tar cf - $@ | compress | uuencode -m -)
225 EOT
226 EOM
227 sed -i '/^case/,/^esac/d' $0
228 exit ;;
229 --get)
230 cat $2
231 exit ;;
232 --array)
233 DATA=/tmp/dataiso$$
234 ddq if=/dev/zero bs=32k count=1 of=$DATA
235 add_win32exe $DATA $2 > /dev/null
236 HSZ=$OFS
237 add_dosexe $DATA > /dev/null
238 add_rootfs $DATA > /dev/null
239 add_doscom $DATA > /dev/null
240 add_fdbootstrap $DATA > /dev/null
241 name=${3:-bootiso}
242 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
243 cat <<EOT
245 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
247 #ifndef __MSDOS__
248 static char $name[] = {
249 /* head */
250 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
251 /* tail */
252 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
254 /* These strange constants are defined in RFC 1321 as
255 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
256 */
257 /* static const uint32_t C_array[64] */
258 EOT
259 while read a b c d; do
260 for i in $a $b $c $d; do
261 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
262 done
263 done <<EOT
264 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
265 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
266 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
267 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
268 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
269 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
270 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
271 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
272 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
273 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
274 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
275 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
276 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
277 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
278 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
279 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
280 EOT
281 cat <<EOT
282 /* static const char P_array[64] */
283 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
284 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
285 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
286 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
287 /* static const char S_array[16] */
288 7, 12, 17, 22,
289 5, 9, 14, 20,
290 4, 11, 16, 23,
291 6, 10, 15, 21,
292 EOT
294 for mode in data offset ; do
295 ofs=0
296 while read tag str; do
297 if [ "$mode" == "data" ]; then
298 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
299 -e '" /* %04.4_ax */ \n"' | \
300 sed 's/ 0x ,/ /g'
301 else
302 if [ $ofs -eq 0 ]; then
303 cat <<EOT
304 };
305 #endif
307 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
308 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
309 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
310 #define ELTORITOOFS 3
311 EOT
312 fi
313 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
314 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
315 fi
316 done <<EOT
317 READSECTORERR Read sector failure.
318 USAGE Usage: isohybrid.exe [--list|--read] [--append cmdline] [--initrd file] file.iso [--forced|--undo|--quick|filename...]
319 OPENERR Can't open the iso file.
320 ELTORITOERR No EL TORITO SPECIFICATION signature.
321 CATALOGERR Invalid boot catalog.
322 HYBRIDERR No isolinux.bin hybrid signature.
323 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
324 FORCEMSG You can add --forced to proceed anyway.
325 MD5MSG Computing md5sum...
326 UNINSTALLMSG Uninstall done.
327 OPENINITRDERR Can't open the initrd file.
328 ALREADYEXEERR Already an EXE file.
329 WIN32_EXE win32.exe
330 SYSLINUX_MBR syslinux.mbr
331 FLAVOR_INFO flavor.info
332 FLOPPY_BOOT floppy.boot
333 TAZBOOT_COM tazboot.com
334 ROOTFS_GZ rootfs.gz
335 DOSSTUB dosstub
336 BOOT_MD5 boot.md5
337 FS_ISO fs.iso
338 CUSTOM_MAGIC custom.magic
339 CUSTOM_APPEND custom.append
340 CUSTOM_INITRD custom.initrd
341 CUSTOM_HEADER #!boot 00000000000000000000000000000000\\\\n
342 FREE_FORMAT %ld free bytes in %04lX..%04lX\\\\n
343 USED_FORMAT %s at %04lX (%ld bytes).\\\\n
344 CMDLINE_TAG append=
345 INITRD_TAG initrd:
346 EOT
347 done
348 cat <<EOT
349 #ifdef __MSDOS__
350 #define BOOTISOFULLSIZE $(($BOOTISOSZ+(64*4)+64+16+$ofs))
351 static char bootiso[BOOTISOFULLSIZE];
352 static data_fixup(void)
353 {
354 #asm
355 push ds
356 push ds
357 pop es
358 mov ax,ds
359 sub ax,#0x1000
360 mov ds,ax
361 xor si,si
362 scanlp:
363 dec si
364 jz copydone
365 cmp byte ptr [si+2],#0xEB
366 jne scanlp
367 cmp word ptr [si],#0x5A4D
368 jne scanlp
369 mov cx,#BOOTISOFULLSIZE
370 mov di,#_bootiso
371 cld
372 rep
373 movsb
374 copydone:
375 pop ds
376 #endasm
377 if (!bootiso[0]) {
378 puts("No bootiso data");
379 exit(-1);
380 }
381 }
382 #else
383 #define data_fixup()
384 #endif
385 EOT
386 rm -rf $DATA
387 exit ;;
388 --exe)
389 # --exe mvcom.bin x.com y.exe > xy.exe
390 cat $4 $3 > /tmp/exe$$
391 S=$(stat -c %s /tmp/exe$$)
392 store 2 $(($S%512)) /tmp/exe$$
393 store 4 $((($S+511)/512)) /tmp/exe$$
394 store 14 -16 /tmp/exe$$
395 store 16 -2 /tmp/exe$$
396 store 20 256 /tmp/exe$$
397 store 22 -16 /tmp/exe$$
398 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
399 store 65 $(stat -c %s $3) /tmp/exe$$
400 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
401 cat /tmp/exe$$
402 rm -f /tmp/exe$$
403 exit ;;
404 esac
406 main()
407 {
408 [ $(id -u) -ne 0 ] && cmd="$0 $@" && exec su -c "$cmd" < /dev/tty
409 append=
410 initrd=
411 while [ "$1" ]; do
412 case "${1/--/-}" in
413 -get) shift
414 uudecode | unlzma | tar xOf - $@
415 exit ;;
416 -a*) append="$2" ; shift 2 ;;
417 -i*) initrd="$2" ; shift 2 ;;
418 -r*|-l*)
419 ISO="$2" ; shift 2
420 [ -z "$1" ] && list || extract $@
421 exit ;;
422 *) cat > /dev/null
423 break
424 esac
425 done
427 [ ! -s "$1" ] && cat 1>&2 <<EOT && exit 1
428 usage: $0 [--list|--read] [--append custom_cmdline ] [ --initrd custom_initrd ] image.iso [--force|--undo|"DOS help message"|filename...]
429 EOT
430 case "${2/--/-}" in
431 -u*|-r*|-w*|-f*)
432 case "$(get 0 $1)" in
433 23117)
434 b=$(get 417 $1 1)
435 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
436 ddq if=$1 bs=512 count=1 skip=$b of=$1 conv=notrunc
437 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
438 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
439 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc ;;
440 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
441 esac
442 case "${2/--/-}" in
443 -f*)
444 [ "$append$initrd" ] && clear_custom_config $1
445 set -- "$1" "$3" ;;
446 *)
447 clear_custom_config $1
448 exit 0 ;;
449 esac
450 esac
451 case "$(get 0 $1)" in
452 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
453 0) [ -x /usr/bin/isohybrid ] && isohybrid $1;;
454 esac
456 echo "Read hybrid & tazlito data..."
457 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
458 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
459 add_win32exe $1 /tmp/hybrid$$
460 add_tazlito_info $1 /tmp/tazlito$$
461 rm -f /tmp/tazlito$$ /tmp/hybrid$$
463 # keep the largest room for the tazlito info file
464 add_dosexe $1
465 add_rootfs $1
466 add_doscom $1
467 add_fdbootstrap $1
468 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
469 store 440 $(date +%s) $1 32
470 [ "$2" ] && echo "$2 " | \
471 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
472 if [ $(stat -c %s $1) -gt 34816 ]; then
473 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
474 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(($(get 32848 "$1" 4)-16)) | \
475 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
476 ddq bs=16 seek=2047 conv=notrunc of=$1
477 fi
478 if [ "$append$initrd" ]; then
479 echo -n "Adding custom config... "
480 DATA=/tmp/$(basename $0)$$
481 rm -f $DATA > /dev/null
482 isosz=$(stat -c %s $1)
483 [ "$append" ] && echo "append=$append" >> $DATA
484 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
485 cat $initrd >> $DATA
486 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
487 ddq bs=2k seek=$(custom_config_sector $1) of=$1 conv=notrunc
488 newsz=$(stat -c %s $1)
489 for i in 0 1 2 3 ; do
490 [ $(get $((0x1BE+16*i)) $1 4) == $((0x00010080)) ] || continue
491 mb=$(((($newsz -1)/1024/1024)+1))
492 h=$((512*$(get 417 "$1" 1)))
493 store $((0x1C5+16*i)) $(($mb-1)) $1 8
494 store $(($h+0x1C5+16*i)) $(($mb-1)) $1 8
495 store $((0x1CA+16*i)) $(($mb*2048)) $1 32
496 store $(($h+0x1CA+16*i)) $(($mb*2048)) $1 32
497 done
498 if [ $newsz -gt $isosz ]; then
499 echo "$(($newsz - $isosz)) extra bytes."
500 else
501 echo "$(($isosz - 2048*$(get 32848 $1 4)
502 - $(stat -c %s $DATA) - 24)) bytes free."
503 fi
504 rm -f $DATA > /dev/null
505 fi
506 echo -n "Adding boot checksum..."
507 if [ $(stat -c %s $1) -gt 32768 ]; then
508 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
509 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
510 awk '{ i+= $0 } END { print (i % 65536) }') \
511 + $(get $(($n+1)) $1 1)))
512 store 18 $(( (-$n -1) % 65536 )) $1
513 fi
514 echo " done."
515 }
517 main "$@" <<EOT