Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 282 lines (262 sloc) 10.34 kb
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
1 #!/usr/bin/env mksh
2 # $Id$
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
3 # $miros: src/sys/arch/i386/stand/bootxx/mkbxinst.sh,v 1.28 2010/11/12 21:20:35 tg Exp $
4 # $miros: src/sys/arch/i386/stand/bootxx/bootxx.S,v 1.26 2010/12/01 19:56:58 tg Exp $ +t:GRUB +s:MBR
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
5 #-
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
6 # Copyright (c) 2007, 2008, 2009, 2010
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
7 # Thorsten Glaser <tg@mirbsd.org>
8 #
9 # Provided that these terms and disclaimer and all copyright notices
10 # are retained or reproduced in an accompanying document, permission
11 # is granted to deal in this work without restriction, including un‐
12 # limited rights to use, publicly perform, distribute, sell, modify,
13 # merge, give away, or sublicence.
14 #
15 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
16 # the utmost extent permitted by applicable law, neither express nor
17 # implied; without malicious intent or gross negligence. In no event
18 # may a licensor, author or contributor be held liable for indirect,
19 # direct, other damage, loss, or other issues arising in any way out
20 # of dealing in the work, even if advised of the possibility of such
21 # damage or existence of a defect, except proven that it results out
22 # of said person’s immediate fault when using the work as intended.
23 #-
24 # Self-installing 32-bit x86 boot blocks for GNU GRUB2 on i386-pc
25 # Reads a list of extents (firstblock lastblock) from standard input
26 # and writes bootxx to standard output, which can subsequentially be
27 # stored as partition boot record (or floppy boot sector) on disc.
28
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
29 set -A thecode 0x66 0x31 0xC9 0x8E 0xD1 0xBC 0xFC 0x7B 0x66 0x51 0x66 0x9D 0x8E 0xC1 0xBE 0x00 0x7C 0x8E 0xD9 0xBB 0x00 0x08 0x53 0x53 0x8E 0xC3 0xBF 0x00 0xFE 0xB5 0x02 0xF3 0xA4 0x1F 0x68 0x6B 0xFE 0xCB 0x30 0x41 0x41 0x44 0x20 0x4C 0x6F 0x61 0x64 0x69 0x6E 0x67 0x20 0x00 0x20 0x65 0x72 0x72 0x6F 0x72 0x0D 0x0A 0x00 0x96 0x02 0x00 0x12 0x00 0x00 0x80 0x65 0xFF 0xB4 0x0E 0xBB 0x07 0x00 0xCD 0x10 0xAC 0x08 0xC0 0x75 0xF4 0xC3 0xE8 0xF7 0xFF 0xB8 0x41 0xFF 0x87 0x06 0x44 0xFE 0x3D 0x41 0xFF 0x75 0x19 0x31 0xC0 0xCD 0x16 0xEA 0xF0 0xFF 0x00 0xF0 0xFB 0x88 0x16 0x43 0xFE 0xBE 0x26 0xFE 0x80 0xFA 0x80 0x72 0xDB 0xE8 0xD2 0xFF 0x31 0xDB 0xBE 0x68 0xFF 0x0F 0xB6 0x2E 0x3D 0xFE 0xAC 0x0F 0xB6 0xC8 0xC0 0xE9 0x05 0x83 0xE0 0x1F 0x40 0x41 0x50 0xBF 0x10 0xFE 0xB8 0x10 0x00 0xAB 0xB0 0x01 0xAB 0x89 0xD8 0xAB 0x8C 0xC8 0xAB 0xF3 0xA4 0x31 0xC0 0xAB 0xAB 0xAB 0xAB 0x5F 0x55 0x56 0xBE 0x10 0xFE 0xFF 0x16 0x44 0xFE 0xBD 0x04 0x00 0x8A 0x16 0x43 0xFE 0x60 0xF9 0xCD 0x13 0x9C 0xB8 0x2E 0x0E 0xBB 0x07 0x00 0xCD 0x10 0x9D 0xFB 0x61 0x73 0x1C 0x4D 0x60 0x9C 0x31 0xC0 0xCD 0x13 0x9D 0xBE 0x34 0xFE 0x0F 0x84 0x77 0xFF 0xB8 0x30 0x0E 0x01 0xE8 0xBB 0x07 0x00 0xCD 0x10 0x61 0xEB 0xD2 0xB4 0x02 0x00 0xE7 0x89 0x5C 0x04 0x00 0xFC 0x72 0x14 0x66 0x83 0x44 0x08 0x01 0x66 0x83 0x54 0x0C 0x00 0x4F 0x75 0xAC 0x5E 0x5D 0x4D 0x0F 0x85 0x7D 0xFF 0xBE 0x3A 0xFE 0xE8 0x3F 0xFF 0x66 0x31 0xD2 0x52 0x66 0x4A 0x8A 0x16 0x43 0xFE 0xB8 0x00 0x82 0x50 0xFA 0xCB 0x60 0x06 0xB4 0x08 0x8A 0x16 0x43 0xFE 0xF9 0xCD 0x13 0xFB 0x07 0xBE 0x34 0xFE 0x0F 0x82 0x21 0xFF 0x80 0xE1 0x3F 0x88 0x0E 0x40 0xFE 0x0F 0xB6 0xC6 0x40 0xA3 0x3E 0xFE 0x61 0x8B 0x0E 0x40 0xFE 0xE3 0xD7 0x8B 0x44 0x08 0x8B 0x54 0x0A 0xF7 0xF1 0x42 0x31 0xC9 0x87 0xD1 0xF7 0x36 0x3E 0xFE 0xC0 0xE4 0x06 0x86 0xC4 0x09 0xC1 0x88 0xD6 0xB8 0x01 0x02 0xC3 0xB4 0x42 0xC3
af6290f @mirabilos experimental diff for issue757
mirabilos authored
30 typeset -i ofs_bkcnt=61
31 typeset -i ofs_geomh=62
32 typeset -i ofs_geoms=64
33 typeset -i ofs_partp=66
34 typeset -i ofs_secsz=234
35 typeset -i begptr=360
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
36 typeset -Uui8 thecode
37
38 typeset -Uui16 curptr=begptr
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
39 typeset -i wnum=0 wofs=0 wrec=0 bkend=0x1FE
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
40
41 function do_record {
af6290f @mirabilos experimental diff for issue757
mirabilos authored
42 typeset -Ui blk=$1 cnt=$2 n
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
43 typeset -Uui16 x=blk y
44
45 (( blk && cnt )) || return
46
47 print -u2 "$wrec @0x${curptr#16#}: $cnt @$blk (0x${x#16#})"
48
49 while (( cnt )); do
50 let wrec++
51 (( n = blk < 0x00000100 ? 0 :
52 blk < 0x00010000 ? 1 :
53 blk < 0x01000000 ? 2 : 3 ))
54 (( x = cnt < 33 ? cnt : 32 ))
55 (( y = blk ))
56 print -u2 " - 0x${curptr#16#}: $((x)) (0x${x#16#}) @ $blk" \
57 "(0x${y#16#})"
58 (( thecode[curptr++] = (n++ << 5) | (x - 1) ))
59 (( blk += x ))
60 (( cnt -= x ))
61 while (( n-- )); do
62 (( thecode[curptr++] = y & 0xFF ))
63 (( y >>= 8 ))
64 done
65 done
66 }
67
68 function record_block {
af6290f @mirabilos experimental diff for issue757
mirabilos authored
69 typeset -Ui blk=$1
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
70
71 if (( !blk || (wofs && blk != (wofs + wnum)) )); then
72 # flush the blocks from the cache
73 (( wnum )) && do_record $wofs $wnum
74 wofs=0
75 wnum=0
76 fi
77 if (( blk )); then
78 # record some new block into the cache
79 (( wofs )) || let wofs=blk
80 (( wnum += 1 << sscale ))
81 fi
82 }
83
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
84 typeset -i partp=0 numheads=0 numsecs=0 sscale=0 bsh=9 mbrpno=0 mbrptp=0 pofs=0
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
85 set -A g_code 0 0 0
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
86
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
87 while getopts ":0:1AB:g:h:M:O:p:S:s:" ch; do
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
88 case $ch {
89 (0) ;;
90 (1) ;;
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
91 (A) numheads=0
92 numsecs=99
93 ;;
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
94 (B) if (( (bsh = OPTARG) < 9 || OPTARG > 15 )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
95 print -u2 Error: invalid block size "2^'$OPTARG'"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
96 exit 1
97 fi
98 ;;
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
99 (g) if [[ $OPTARG != +([0-9]):+([0-9]):+([0-9]) ]]; then
100 print -u2 Error: invalid geometry code "'$OPTARG'"
101 exit 1
102 fi
103 saveIFS=$IFS
104 IFS=:
105 set -A g_code -- $OPTARG
106 IFS=$saveIFS ;;
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
107 (h) if (( (numheads = OPTARG) < 1 || OPTARG > 256 )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
108 print -u2 Warning: invalid head count "'$OPTARG'"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
109 numheads=0
110 fi ;;
af6290f @mirabilos experimental diff for issue757
mirabilos authored
111 (M) if [[ $OPTARG != +([0-9])?(:?(0[Xx])+([0-9])) ]]; then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
112 print -u2 Warning: invalid partition info "'$OPTARG'"
af6290f @mirabilos experimental diff for issue757
mirabilos authored
113 mbrpno=0
114 mbrptp=0
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
115 else
116 saveIFS=$IFS
117 IFS=:
118 set -A mbr_code -- $OPTARG
119 IFS=$saveIFS
120 (( mbrpno = mbr_code[0] ))
121 (( mbrptp = mbr_code[1] ))
122 if (( mbrpno < 1 || mbrpno > 4 )); then
123 print -u2 Warning: invalid partition \
124 number "'$OPTARG'"
125 mbrpno=0
126 fi
127 if (( mbrptp < 1 || mbrptp > 255 )); then
128 print -u2 Warning: invalid partition \
129 type "'$OPTARG'"
130 mbrptp=0
131 fi
132 fi ;;
133 (O) if [[ $OPTARG != +([0-9]) ]]; then
134 print -u2 Warning: invalid partition offset "'$OPTARG'"
135 else
136 pofs=$OPTARG
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
137 fi ;;
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
138 (p) if (( (partp = OPTARG) < 1 || OPTARG > 255 )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
139 print -u2 Warning: invalid partition type "'$OPTARG'"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
140 partp=0
141 fi ;;
142 (S) if (( (sscale = OPTARG) < 0 || OPTARG > 24 )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
143 print -u2 Error: invalid input scale "'$OPTARG'"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
144 exit 1
145 fi ;;
146 (s) if (( (numsecs = OPTARG) < 1 || OPTARG > 63 )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
147 print -u2 Warning: invalid sector count "'$OPTARG'"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
148 numsecs=0
149 fi ;;
150 (*) print -u2 'Syntax:
af6290f @mirabilos experimental diff for issue757
mirabilos authored
151 bxinst [-1A] [-B blocksize] [-g C:H:S] [-h heads] [-M pno(1..4)[:typ]]
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
152 [-O partitionofs] [-p type] [-S scale] [-s secs] <sectorlist | \\
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
153 dd of=image conv=notrunc
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
154 Default values: blocksize=9 heads=16 sectors=63 part.ofs=0 type=0x27 scale=0
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
155 partno=4 if -g (create MBR partition) is given; -A = auto boot geometry'
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
156 exit 1 ;;
157 }
158 done
159 shift $((OPTIND - 1))
160
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
161 typeset -Ui psz=0 # must be unsigned
162 if (( g_code[0] )); then
163 # bounds check partition table values, calculate total sectors
164 if (( g_code[0] < 1 || g_code[1] < 1 || g_code[1] > 256 ||
165 g_code[2] < 1 || g_code[2] > 63 )); then
166 print -u2 Invalid geometry, values out of bounds.
9eb39cc @mirabilos Change bootgrub.mksh invocation to use the new features.
mirabilos authored
167 elif [[ $(print "(${g_code[0]} * ${g_code[1]} * ${g_code[2]})" \
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
168 "> 4294967295" | bc) = 1 ]]; then
169 print -u2 Invalid geometry, more than 2 TiB of data.
170 else
171 # we know it's <= 2^32-1
172 (( psz = g_code[0] * g_code[1] * g_code[2] ))
173 fi
174 fi
175 if (( psz )); then
176 print -u2 geometry is $psz sectors \($(print \
177 "$psz * $((1 << bsh))" | bc) bytes\) in ${g_code[0]} cylinders, \
178 ${g_code[1]} heads, ${g_code[2]} sectors per track
179 if (( numsecs == 0 || (numsecs != 99 && numheads == 0) )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
180 print -u2 Warning: using these values for C/H/S boot
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
181 numheads=${g_code[1]}
182 numsecs=${g_code[2]}
183 fi
184 (( mbrpno )) || mbrpno=4 # default partition number
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
185 fi
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
186 if (( mbrpno )); then
187 bkend=0x1BE
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
188 (( psz )) || print -u2 Warning: no geometry given, will not \
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
189 create an MBR partition table entry
190 fi
191
192 if (( numsecs == 99 )); then
193 numheads=0
194 numsecs=0
195 else
196 if (( !numheads )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
197 print -u2 Warning: using default value of 16 heads
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
198 numheads=16
199 fi
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
200
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
201 if (( !numsecs )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
202 print -u2 Warning: using default value of 63 sectors
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
203 numsecs=63
204 fi
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
205 fi
206
207 # read in the extents
208 while read firstblock lastblock junk; do
209 while (( firstblock <= lastblock )); do
210 record_block $((firstblock++ << sscale))
211 done
212 done
213 record_block 0 # just flush
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
214 print -u2 "using $wrec blocks, $((curptr-begptr)) bytes ($((bkend-curptr)) free)"
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
215
216 # fill the block table
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
217 if (( curptr-- > bkend )); then
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
218 print -u2 Error: too many blocks
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
219 exit 1
220 fi
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
221 while (( ++curptr < bkend )); do
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
222 (( thecode[curptr] = (curptr & 0xFCF) == 0x1C2 ? 0 : RANDOM & 0xFF ))
223 # ensure the “active” flag is never set to 0x00 or 0x80
224 if (( ((curptr + 2) & 0xFCF) == 0x01C0 )); then
225 (( thecode[curptr] & 0x7F )) || let --curptr
226 fi
227 done
228 thecode[510]=0x55
229 thecode[511]=0xAA
230
231 # fill in other data
232 (( thecode[ofs_bkcnt] = wrec ))
233 (( thecode[ofs_geomh] = numheads & 0xFF ))
234 (( thecode[ofs_geomh + 1] = numheads >> 8 ))
235 (( thecode[ofs_geoms] = numsecs ))
236 (( thecode[ofs_partp] = partp ))
237 print -u2 "using sectors of 2^$bsh = $((1 << bsh)) bytes"
238 (( thecode[ofs_secsz] = (1 << (bsh - 8)) ))
239
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
240 # create an MBR partition if desired
241 if (( psz )); then
242 (( mbrpno = 0x1BE + ((mbrpno - 1) * 16) ))
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
243 set -A o_code # g_code equivalent for partition offset
244 (( o_code[2] = pofs % g_code[2] + 1 ))
245 (( o_code[1] = pofs / g_code[2] ))
246 (( o_code[0] = o_code[1] / g_code[1] + 1 ))
247 (( o_code[1] = o_code[1] % g_code[1] + 1 ))
248 # boot flag; C/H/S offset
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
249 thecode[mbrpno++]=0x80
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
250 (( thecode[mbrpno++] = o_code[1] - 1 ))
251 (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
252 (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
253 (( thecode[mbrpno++] = cylno & 0x00FF ))
254 # partition type; C/H/S end
af6290f @mirabilos experimental diff for issue757
mirabilos authored
255 (( thecode[mbrpno++] = (mbrptp ? mbrptp : partp ? partp : 0x27) ))
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
256 (( thecode[mbrpno++] = g_code[1] - 1 ))
2099cea @mirabilos fix the partition table (end cylinder off-by-one)
mirabilos authored
257 (( cylno = g_code[0] > 1024 ? 1023 : g_code[0] - 1 ))
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
258 (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
259 (( thecode[mbrpno++] = cylno & 0x00FF ))
7ed3014 @mirabilos manifold supporting and using ISOLINUX now
mirabilos authored
260 # partition offset, size (LBA)
261 (( thecode[mbrpno++] = pofs & 0xFF ))
262 (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
263 (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
264 (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
265 (( pssz = psz - pofs ))
266 (( thecode[mbrpno++] = pssz & 0xFF ))
267 (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
268 (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
269 (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
aefb34f @mirabilos Update bootgrub.mksh from MirBSD
mirabilos authored
270 fi
271
e9c7fea @mika Integrate grub2 for hybrid boot
mika authored
272 # create the output string
273 ostr=
274 curptr=0
275 while (( curptr < 512 )); do
276 ostr=$ostr\\0${thecode[curptr++]#8#}
277 done
278
279 # over and out
280 print -n "$ostr"
281 exit 0
Something went wrong with that request. Please try again.