wok-current view syslinux/stuff/tools/isohybrid.sh @ rev 8974
[q-z]*: use veriable
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Mar 02 11:06:20 2011 +0100 (2011-03-02) |
parents | f25f2e389934 |
children | 2188bfc43e67 |
line source
1 #!/bin/sh
3 if [ "$1" == "--build" ]; then
4 cat >> $0 <<EOM
5 $(for i in fx fx_f fx_c px px_f px_c ; do
6 cat mbr/isohdp$i.bin /dev/zero | dd bs=1 count=512 2> /dev/null
7 done | gzip -9 | uuencode -m -)
8 EOT
9 EOM
10 sed -i '/--build/,/^fi/d' $0
11 exit
12 fi
13 iso=
14 heads=64 # zipdrive-style geometry
15 sectors=32
16 partype=23 # "Windows hidden IFS"
17 entry=1
18 id=$(( ($RANDOM <<16) + $RANDOM))
19 offset=0
20 partok=0
21 hd0=0
22 always=0
24 while [ -n "$1" ]; do
25 case "${1/--/-}" in
26 -a*) always=1;;
27 -ct*) hd0=2;;
28 -e*) entry=$2; shift;;
29 -f*) hd0=1;;
30 -h) heads=$2; shift;;
31 -i*) id=$(($2)); shift;;
32 -noh*) hd0=0;;
33 -nop*) partok=0;;
34 -o*) offset=$(($2)); shift;;
35 -p*) partok=1;;
36 -s) sectors=$2; shift;;
37 -t*) partype=$(($2 & 255)); shift;;
38 *) iso=$1;;
39 esac
40 shift
41 done
43 if [ ! -f "$iso" ]; then
44 cat << EOT
45 usage: $0 [options] isoimage
46 options:
47 -h <X> Number of default geometry heads
48 -s <X> Number of default geometry sectors
49 -e --entry Specify partition entry number (1-4)
50 -o --offset Specify partition offset (default 0)
51 -t --type Specify partition type (default 0x17)
52 -i --id Specify MBR ID (default random)
53 --forcehd0 Assume we are loaded as disk ID 0
54 --ctrlhd0 Assume disk ID 0 if the Ctrl key is pressed
55 --partok Allow booting from within a partition
56 --always Do not abort on errors
57 EOT
58 exit 1
59 fi
61 ddq()
62 {
63 dd "$@" 2> /dev/null
64 }
66 readiso()
67 {
68 ddq bs=2k skip=$1 count=1 if=$iso | ddq bs=1 skip=$2 count=$3
69 }
71 # read a 32 bits data
72 read32()
73 {
74 readiso $1 $2 4 | hexdump -e '"" 1/4 "%d" "\n"'
75 }
77 # write a 32 bits data
78 store32()
79 {
80 n=$2; for i in 1 2 3 4; do
81 printf '\\\\x%02X' $(($n & 255))
82 n=$(($n >> 8))
83 done | xargs echo -en | ddq bs=1 conv=notrunc of=$iso seek=$(($1))
84 }
86 main()
87 {
88 uudecode | gunzip | ddq bs=512 count=1 of=$iso conv=notrunc \
89 skip=$(( (3*$partok) + $hd0))
90 store32 432 $(($lba * 4))
91 store32 440 $id
92 store32 508 0xAA550000
93 e=$(( (($entry -1) % 4) *16 +446))
94 store32 $e 0x10080
95 esect=$(( ($sectors + ((($cylinders -1) & 0x300) >>2)) <<16))
96 ecyl=$(( (($cylinders -1) & 0xff) <<24))
97 store32 $(($e + 4)) $(($partype + (($heads - 1) <<8) +$esect +$ecyl))
98 store32 $(($e + 8)) $offset
99 store32 $(($e + 12)) $(($cylinders * $heads * $sectors))
100 }
102 abort()
103 {
104 echo "$iso: $1"
105 [ $always -eq 0 ] && exit 1
106 }
108 [ "$(readiso 17 7 23)" == "EL TORITO SPECIFICATION" ] ||
109 abort "no boot record found."
110 cat=$(read32 17 71)
111 [ $(read32 $cat 0) -eq 1 -a $(read32 $cat 30) -eq $(( 0x88AA55 )) ] ||
112 abort "invalid boot catalog."
113 lba=$(read32 $cat 40)
114 [ $(read32 $lba 64) -eq 1886961915 ] ||
115 abort "no isolinux.bin hybrid signature in bootloader."
116 size=$(stat -c "%s" $iso)
117 trksz=$(( 512 * $heads * $sectors ))
118 cylinders=$(( ($size + $trksz - 1) / $trksz ))
119 pad=$(( (($cylinders * $trksz) - $size) / 512 ))
120 [ $pad -eq 0 ] || ddq bs=512 count=$pad if=/dev/zero >> $iso
121 if [ $cylinders -gt 1024 ]; then
122 cat 1>&2 <<EOT
123 Warning: more than 1024 cylinders ($cylinders).
124 Not all BIOSes will be able to boot this device.
125 EOT
126 cylinders=1024
127 fi
129 main <<EOT