root/morphix/trunk/gengrubmenu2/gengrubmenu2

Revision 2, 9.7 kB (checked in by nextime, 2 years ago)

Initial import, branching from morphix svn

Line 
1 #! /bin/sh
2
3 # this is code initally ported by Mantas Kriauciunas <mantas@akl.lt>
4 # for the Morphix project. The code came for a large part from the
5 # grub-installer (taken from debian-installer) postinst script and
6 # update-grub script from the grub debian package.
7 # os-prober tool from debian-installer project is needed for finding
8 # other operating systems.
9
10 set -e
11 #set -x
12
13 newline="
14 "
15
16 if [ -z $5 ]; then
17     echo "$0 GRUBDIR BOOTDEV ROOTDEV KERNELARGUMENTS IMAGE [INITRD]"
18     echo "where: "
19     echo " - GRUBDIR is the /boot/grub directory which"
20     echo "  contains device.map and will contain your new menu.lst"
21     echo " - BOOTDEV is the device grub will boot Morphix from"
22     echo " - ROOTDEV is the root= argument to the kernel"
23     echo " - KERNELARGUMENTS is the line of arguments to the kernel"
24     echo " - IMAGE is the name of the kernel in the BOOTDEV"
25     echo " - INITRD is the name of the initrd in the BOOTDEV"
26     exit
27 fi
28
29 TARGET="$1"
30
31 log=/var/log/messages
32
33 log() {
34         logger -t grub-installer "$@"
35 }
36
37 error() {
38         log "error: $@"
39 }
40
41 info() {
42         log "info: $@"
43 }
44
45 get_serial_console() {
46         local defconsole="$(sed -e 's/.*console=/console=/' /proc/cmdline)"
47         if echo "${defconsole}" | grep -q console=ttyS; then
48                 local PORT="$(echo "${defconsole}" | sed -e 's%^console=ttyS%%' -e 's%,.*%%')"
49                 local SPEED="$(echo "${defconsole}" | sed -e 's%^console=ttyS[0-9]\+,%%' -e 's% .*%%')"
50                 local SERIAL="${PORT},${SPEED}"
51                 echo "console=$SERIAL"
52         fi
53 }
54
55 serial="$(get_serial_console)"
56
57 # This is copied from update-grub. We've requested that it be moved
58 # to a utility or shell library.
59 # Comment by mantas:
60 # device.map should be created before convert function is created
61 # Maybe add check in convert function ?
62 # device.map can be created with this command:
63 #grub --batch --no-floppy --no-config-file --device-map=/mnt/target/boot/grub/device.map
64 # End of comment by mantas
65 device_map=$TARGET/device.map
66 # Usage: convert os_device
67 # Convert an OS device to the corresponding GRUB drive.
68 # This part is OS-specific.
69 convert () {
70 #    # First, check if the device file exists.
71 #    if test -e "$1"; then
72 #               :
73 #    else
74 #               echo "$1: Not found or not a block device." 1>&2
75 #               exit 1
76 #    fi
77
78         host_os=`uname -s | tr '[A-Z]' '[a-z]'`
79
80     # Break the device name into the disk part and the partition part.
81     case "$host_os" in
82     linux*)
83                 tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
84                                   -e 's%\(fd[0-9]*\)$%\1%' \
85                                   -e 's%/part[0-9]*$%/disc%' \
86                                   -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
87                 tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
88                                   -e 's%.*/fd[0-9]*$%%' \
89                                   -e 's%.*/floppy/[0-9]*$%%' \
90                                   -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
91                                   -e 's%.*c[0-7]d[0-9]*p*%%'`
92         ;;
93     gnu*)
94                 tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
95                 tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
96     freebsd*)
97                 tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
98                             | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
99                 tmp_part=`echo "$1" \
100                         | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
101                 | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
102         ;;
103     netbsd*)
104                 tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
105                         | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
106                 tmp_part=`echo "$1" \
107                         | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
108         ;;
109     *)
110                 echo "update-grub does not support your OS yet." 1>&2
111                 exit 1 ;;
112     esac
113
114     # Get the drive name.
115     tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
116                         | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
117
118     # If not found, print an error message and exit.
119     if test "x$tmp_drive" = x; then
120                 echo "$1 does not have any corresponding BIOS drive." 1>&2
121                 exit 1
122     fi
123
124     if test "x$tmp_part" != x; then
125                 # If a partition is specified, we need to translate it into the
126                 # GRUB's syntax.
127                 case "$host_os" in
128                 linux*)
129                 echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
130                 gnu*)
131                 if echo $tmp_part | grep "^s" >/dev/null; then
132                                 tmp_pc_slice=`echo $tmp_part \
133                                 | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
134                                 tmp_drive=`echo "$tmp_drive" \
135                                 | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
136                 fi
137                 if echo $tmp_part | grep "[a-g]$" >/dev/null; then
138                                 tmp_bsd_partition=`echo "$tmp_part" \
139                                 | sed "s%[^a-g]*\([a-g]\)$%\1%"`
140                                 tmp_drive=`echo "$tmp_drive" \
141                                 | sed "s%)%,$tmp_bsd_partition)%"`
142                 fi
143                 echo "$tmp_drive" ;;
144                 freebsd*)
145                 if echo $tmp_part | grep "^s" >/dev/null; then
146                                 tmp_pc_slice=`echo $tmp_part \
147                                 | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
148                                 tmp_drive=`echo "$tmp_drive" \
149                                 | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
150                 fi
151                 if echo $tmp_part | grep "[a-h]$" >/dev/null; then
152                                 tmp_bsd_partition=`echo "$tmp_part" \
153                                 | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
154                                 tmp_drive=`echo "$tmp_drive" \
155                                 | sed "s%)%,$tmp_bsd_partition)%"`
156                 fi
157                 echo "$tmp_drive" ;;
158                 netbsd*)
159                 if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
160                                 tmp_bsd_partition=`echo "$tmp_part" \
161                                 | sed "s%\([a-p]\)$%\1%"`
162                                 tmp_drive=`echo "$tmp_drive" \
163                                 | sed "s%)%,$tmp_bsd_partition)%"`
164                 fi
165                 echo "$tmp_drive" ;;
166                 esac
167     else
168                 # If no partition is specified, just print the drive name.
169                 echo "$tmp_drive"
170     fi
171 }
172
173 # Convert a linux non-devfs disk device name into the hurd's syntax.
174 hurd_convert () {
175         dr_type=$(expr "$1" : '.*\([hs]d\)[a-h][0-9]*')
176         dr_letter=$(expr "$1" : '.*d\([a-h]\)[0-9]*')
177         dr_part=$(expr "$1" : '.*d[a-h]\([0-9]*\)')
178         case "$dr_letter" in
179         a) dr_num=0 ;;
180         b) dr_num=1 ;;
181         c) dr_num=2 ;;
182         d) dr_num=3 ;;
183         e) dr_num=4 ;;
184         f) dr_num=5 ;;
185         g) dr_num=6 ;;
186         h) dr_num=7 ;;
187         esac
188         echo "$dr_type${dr_num}s$dr_part"
189 }
190
191 #The start'
192
193 boot=$(convert "$2")
194 root="$3"
195 user_params="$4"
196 image="$5"
197 initrd="$6"
198
199 if test "x$initrd" != x; then
200     initrd="initrd $initrd"
201 fi
202
203 #If boot is device, then boot=root in menu.lst
204 if echo $boot | grep -v "," >/dev/null; then
205     boot=$(convert "$3")
206 fi
207
208 # Mantas-> I don't know what IFS is, but after this newlines are written ;)
209 IFS="$OLDIFS"
210
211 BC_GRUBTEMPLATE1="# See www.gnu.org/software/grub for details
212 # By default, boot the first entry
213 default 0
214 # Boot automatically after 5 seconds
215 timeout 5
216
217 title Morphix GNU/Linux
218 # kernel path-to-kernel root=rootdevice kernelarguments
219 root $boot
220 kernel $image root=$root $user_params
221 $initrd
222
223 title Morphix GNU/Linux (recovery mode)
224 # kernel path-to-kernel root=rootdevice kernelarguments
225 root $boot
226 kernel $image root=$root $user_params single
227 $initrd
228 "
229
230 #Maybe there should be check if menu.lst already exist ?
231 echo $BC_GRUBTEMPLATE1 > $TARGET/menu.lst
232
233 os-prober > /tmp/os-probed || true
234
235 # Generation menu.lst addition for other OSes.
236 tmpfile=/tmp/menu.lst.extras
237 OLDIFS="$IFS"
238 IFS="$newline"
239 for os in $(cat /tmp/os-probed); do
240         IFS="$OLDIFS"
241         title=$(echo "$os" | cut -d: -f2)
242         type=$(echo "$os" | cut -d: -f4)
243         case "$type" in
244                 chain)
245                         partition=$(echo "$os" | cut -d: -f1)
246                         grubdrive=$(convert "$partition") || true
247                         if [ -n "$grubdrive" ]; then
248                                 cat >> $tmpfile <<EOF
249
250 # This entry automatically added by the Debian installer for a non-linux OS
251 # on $partition
252 title           $title
253 root            $grubdrive
254 savedefault
255 EOF
256                                 # Only set makeactive if grub is installed
257                                 # in the mbr.
258                                 if [ "$bootdev" = "(hd0)" ]; then
259                                         cat >> $tmpfile <<EOF
260 makeactive
261 EOF
262                                 fi
263                                 cat >> $tmpfile <<EOF
264 chainloader     +1
265
266 EOF
267                         fi
268                 ;;
269                 linux)
270                         partition=$(echo "$os" | cut -d: -f1)
271                         mappedpartition=$partition
272                         IFS="$newline"
273                         for entry in $(linux-boot-prober "$partition"); do
274                                 IFS="$OLDIFS"
275                                 bootpart=$(echo "$entry" | cut -d: -f2)
276                                 mappedbootpart=$bootpart || true
277                                 if [ -z "$mappedbootpart" ]; then
278                                         mappedbootpart="$bootpart"
279                                 fi
280                                 label=$(echo "$entry" | cut -d : -f3)
281                                 if [ -z "$label" ]; then
282                                         label="$title"
283                                 fi
284                                 kernel=$(echo "$entry" | cut -d : -f4)
285                                 initrd=$(echo "$entry" | cut -d : -f5)
286                                 if echo "$kernel" | grep -q '^/boot/' && \
287                                    [ "$mappedbootpart" != "$mappedpartition" ]; then
288                                         # separate /boot partition
289                                         kernel=$(echo "$kernel" | sed 's!^/boot!!')
290                                         initrd=$(echo "$initrd" | sed 's!^/boot!!')
291                                         grubdrive=$(convert "$mappedbootpart") || true
292                                 else
293                                         grubdrive=$(convert "$mappedpartition") || true
294                                 fi
295                                 params="$(echo "$entry" | cut -d : -f6-) $serial"
296                                 cat >> $tmpfile <<EOF
297
298 # This entry automatically added by the Debian installer for an existing
299 # linux installation on $mappedpartition.
300 title           $label (on $mappedpartition)
301 root            $grubdrive
302 kernel          $kernel $params
303 EOF
304                                 if [ -n "$initrd" ]; then
305                                         cat >> $tmpfile <<EOF
306 initrd          $initrd
307 EOF
308                                 fi
309                                 cat >> $tmpfile <<EOF
310 savedefault
311 boot
312
313 EOF
314                                 IFS="$newline"
315                         done
316                         IFS="$OLDIFS"
317                 ;;
318                 hurd)
319                         partition=$(echo "$os" | cut -d: -f1)
320                         grubdrive=$(convert "$partition") || true
321                         hurddrive=$(hurd_convert "$partition") || true
322                         # Use the standard hurd boilerplate to boot it.
323                         cat >> $tmpfile <<EOF
324
325 # This entry automatically added by the Debian installer for an existing
326 # hurd installation on $partition.
327 title           $title (on $partition)
328 root            $grubdrive
329 kernel          /boot/gnumach.gz root=device:$hurddrive
330 module          /hurd/ext2fs.static --readonly \\
331                         --multiboot-command-line=\${kernel-command-line} \\
332                         --host-priv-port=\${host-port} \\
333                         --device-master-port=\${device-port} \\
334                         --exec-server-task=\${exec-task} -T typed \${root} \\
335                         \$(task-create) \$(task-resume)
336 module          /lib/ld.so.1 /hurd/exec \$(exec-task=task-create)
337 savedefault
338 boot
339
340 EOF
341                 ;;
342                 *)
343                         info "unhandled: $os"
344                 ;;
345         esac
346         IFS="$newline"
347 done
348 IFS="$OLDIFS"
349 rm -f /tmp/os-probed
350
351 if [ -s $tmpfile ]; then
352         if [ -s $TARGET/menu.lst ]; then
353             cat >> $TARGET/menu.lst << EOF
354
355 # This is a divider, added to separate the menu items below from the Debian
356 # ones.
357 title           Other operating systems:
358 root
359
360 EOF
361         fi
362         cat $tmpfile >> $TARGET/menu.lst
363         rm -f $tmpfile
364 fi
365
Note: See TracBrowser for help on using the browser.