4 # Run GRUB script in a Qemu instance
5 # Copyright (C) 2009,2010 Free Software Foundation, Inc.
7 # GRUB is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # GRUB is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 # Initialize some variables.
22 exec_prefix
="@exec_prefix@"
23 datarootdir
="@datarootdir@"
26 PACKAGE_NAME
=@PACKAGE_NAME@
27 PACKAGE_TARNAME
=@PACKAGE_TARNAME@
28 PACKAGE_VERSION
=@PACKAGE_VERSION@
30 # Force build directory components
31 PATH
="${builddir}:$PATH"
40 Usage: $0 [OPTION] [SOURCE]
41 Run GRUB script in a Qemu instance.
43 -h, --help print this message and exit
44 -v, --version print the version information and exit
45 --boot=[fd|hd|cd|net] boot method for Qemu instance
46 --modules=MODULES pre-load specified modules MODULES
47 --qemu=FILE Name of qemu binary
48 --disk=FILE Attach FILE as a disk
49 --qemu-opts=OPTIONS extra options to pass to Qemu instance
50 --files=FILES add files to the image
51 --mkrescue-arg=ARGS additional arguments to grub-mkrescue
52 --timeout=SECONDS set timeout
53 --trim trim firmware output
55 $0 runs input GRUB script or SOURCE file in a Qemu instance and prints
58 Report bugs to <bug-grub@gnu.org>.
62 .
"${builddir}/grub-core/modinfo.sh"
63 qemuopts
="${GRUB_QEMU_OPTS}"
69 case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
71 device_map
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
75 # To skip "Welcome to GRUB" and color setttings
83 serial_null
="-serial null"
89 qemu
=qemu-system-sparc64
91 serial_port
=ieee1275
/ttya
93 qemuopts
="$qemuopts -no-reboot"
100 qemuopts
="$qemuopts -M mips"
105 qemu
=qemu-system-mips64
106 qemuopts
="$qemuopts -M indy"
107 serial_port
=arc
/serial
0/line0
113 qemu
=qemu-system-mips64el
114 qemuopts
="$qemuopts -M magnum -no-reboot"
115 serial_port
=arc
/multi
0/serial0
122 qemu
=qemu-system-mipsel
123 qemuopts
="$qemuopts -M mips"
128 qemu
=qemu-system-mips64el
129 qemuopts
="$qemuopts -M fulong2e"
135 qemu
=qemu-system-i386
140 qemu
=qemu-system-i386
145 qemu
=qemu-system-i386
152 qemu
=qemu-system-i386
157 qemu
=qemu-system-i386
163 qemu
=qemu-system-i386
169 qemu
=qemu-system-x86_64
176 qemu
=qemu-system-i386
183 # Check the arguments.
184 for option
in "$@"; do
190 echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
198 ms
=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'`
199 modules
="$modules $ms" ;;
201 fls
=`echo "$option" | sed -e 's/--files=//' -e 's/,/ /g'`
202 files
="$files $fls" ;;
204 mkr
=`echo "$option" | sed -e 's/--mkrescue-arg=//' -e 's/,/ /g'`
205 mkrescue_args
="$mkrescue_args $mkr" ;;
207 qemu
=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;;
209 qemu
=qemu-system-ppc64
210 serial_port
=ieee1275
/hvterm
212 qemuopts
="$qemuopts -M pseries -no-reboot"
217 qs
=`echo "$option" | sed -e 's/--qemu-opts=//'`
218 qemuopts
="$qemuopts $qs" ;;
220 dsk
=`echo "$option" | sed -e 's/--disk=//'`
221 if [ ${grub_modinfo_platform} = emu
]; then
222 echo "(hd$disk) $dsk" >> "$device_map"
225 if [ $disk = error
]; then
226 echo "Too many disks" 1>&2
229 qemuopts
="$qemuopts -$disk $dsk"
230 if [ "$disk" = hda
]; then
232 elif [ "$disk" = hdb
]; then
235 elif [ "$disk" = hdd
]; then
242 timeout
=`echo "$option" | sed -e 's/--timeout=//'`
245 # Intentionally undocumented
246 --grub-mkimage-extra)
247 mkimage_extra_arg
="$mkimage_extra_arg `argument $option "$@
"`"; shift ;;
248 --grub-mkimage-extra=*)
249 mkimage_extra_arg
="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
252 dev
=`echo "$option" | sed -e 's/--boot=//'`
253 if [ "$dev" = "fd" ] ; then boot
=fd
;
254 elif [ "$dev" = "hd" ] ; then boot
=hd
;
255 elif [ "$dev" = "cd" ] ; then boot
=cd;
256 elif [ "$dev" = "net" ] ; then boot
=net
;
257 elif [ "$dev" = "qemu" ] ; then boot
=qemu
;
258 elif [ "$dev" = "coreboot" ] ; then boot
=coreboot
;
259 elif [ "$dev" = "mips_qemu" ] ; then boot
=mips_qemu
;
260 elif [ "$dev" = "mipsel_qemu" ] ; then boot
=mipsel_qemu
;
261 elif [ "$dev" = "mipsel_fulong2e" ] ; then boot
=mipsel_fulong2e
;
263 echo "Unrecognized boot method \`$dev'" 1>&2
268 echo "Unrecognized option \`$option'" 1>&2
272 if [ "x${source}" != x
] ; then
273 echo "too many parameters at the end" 1>&2
277 source="${option}" ;;
281 if [ "x${source}" = x
] ; then
282 tmpfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
284 echo "$REPLY" >> ${tmpfile}
289 cfgfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
290 cat <<EOF >${cfgfile}
295 if [ "${grub_modinfo_platform}" != emu
]; then
296 echo insmod serial
>>${cfgfile}
299 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275
]; then
300 echo insmod escc
>>${cfgfile}
302 if [ "${grub_modinfo_platform}" != emu
]; then
303 echo "serial ${serial_port}" >>${cfgfile}
304 term
="serial_${serial_port}"
309 cat <<EOF >>${cfgfile}
310 terminfo -g 1024x1024 ${term} dumb
311 terminal_input ${term}
312 terminal_output ${term}
315 trim_head
=664cbea8-132f-4770-8aa4-1696d59ac35c
317 if [ $trim = 1 ]; then
318 echo "echo $trim_head" >>${cfgfile}
321 rom_directory
=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
323 for mod
in ${modules}
325 echo "insmod ${mod}" >> ${cfgfile}
328 cat <<EOF >>${cfgfile}
329 source "\$prefix/testcase.cfg"
330 # Stop serial output to suppress "ACPI shutdown failed" error.
332 if [ x
$console != x
]; then
333 echo "terminal_output $console" >>${cfgfile}
335 echo "${halt_cmd}" >>${cfgfile}
337 test -z "$debug" ||
echo "GRUB script: ${cfgfile}" >&2
338 test -z "$debug" ||
echo "GRUB testcase script: ${tmpfile}" >&2
339 test -z "$debug" ||
echo "Boot device: ${boot}" >&2
341 isofile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
342 test -z "$debug" ||
echo "GRUB ISO file: ${isofile}" >&2
343 test -z "$debug" ||
echo "GRUB ROM directory: ${rom_directory}" >&2
345 if test -z "$debug"; then
346 qemuopts
="${qemuopts} -nographic -monitor file:/dev/null"
349 if [ x
$boot != xnet
] && [ x
$boot != xemu
]; then
350 pkgdatadir
="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
351 --rom-directory="${rom_directory}" \
352 --themes-directory="@srcdir@/themes" \
353 $mkimage_extra_arg ${mkrescue_args} \
354 "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
355 ${files} >/dev
/null
2>&1
357 if [ x
$boot = xhd
]; then
358 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc
]; then
365 if [ x
$boot = xcd
]; then
366 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275
] && [ x
$pseries != xy
] ; then
367 device
="-drive if=ide,media=cdrom,file="
373 if [ x
$boot = xfd
]; then
378 if [ x
$boot = xqemu
]; then
379 bootdev
="-bios ${rom_directory}/qemu.img"
383 if [ x
$boot = xmipsel_qemu
]; then
384 bootdev
="-kernel ${rom_directory}/mipsel-qemu_mips.elf"
388 if [ x
$boot = xmipsel_fulong2e
]; then
389 bootdev
="-kernel ${rom_directory}/mipsel-loongson.elf -append machtype=lemote-fuloong-2e"
393 if [ x
$boot = xmips_qemu
]; then
394 bootdev
="-kernel ${rom_directory}/mips-qemu_mips.elf"
398 if [ x
$boot = xcoreboot
]; then
399 imgfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
400 cp "${GRUB_COREBOOT_ROM}" "${imgfile}"
401 "${GRUB_CBFSTOOL}" "${imgfile}" add-payload "${rom_directory}/coreboot.elf" fallback
/payload
402 bootdev
="-bios ${imgfile}"
404 test -z "$debug" ||
echo "Coreboot image: ${imgfile}" >&2
407 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mipsel-arc
]; then
410 bootdev
="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/disk" ;;
412 bootdev
="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/cdrom";;
418 if [ $trim = 1 ]; then
419 awk '{ if (have_head == 1) print $0; } /664cbea8-132f-4770-8aa4-1696d59ac35c/ { have_head=1; }'
429 # FIXME support '=' in file names
430 for _file
in "$@"; do
431 _target
="${_file%=*}"
432 _source
="${_file#*=}"
433 [ -n "$_source" ] || _source
="$_target"
434 _target
="$_destdir/$_target"
435 _targetdir
="$(dirname "$_target")"
436 [ -d "$_targetdir" ] || mkdir
-p "$_targetdir"
437 cp "$_source" "$_target"
441 if [ x
$boot = xnet
]; then
442 netdir
=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
443 pkgdatadir
="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
444 cp "${cfgfile}" "$netdir/boot
/grub
/grub.cfg
"
445 cp "${source}" "$netdir/boot
/grub
/testcase.cfg
"
446 [ -z "$files" ] || copy_extra_files "$netdir" $files
447 timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.
$netbootext" -net nic | cat | tr -d "\r" | do_trim
448 elif [ x$boot = xemu ]; then
449 grubdir="$
(mktemp
-d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")"
450 mkdir -p "$grubdir/fonts
"
451 mkdir -p "$grubdir/themes
"
452 mkdir -p "$grubdir/locale
"
453 cp "@builddir@
/"unicode.pf2 "$grubdir/fonts
/unicode.pf2
"
454 cp -R "@srcdir@
/themes
/starfield
" "$grubdir/themes
/starfield
"
455 for file in "@srcdir@
/po
/"*.gmo; do
456 if [ -f "$file" ]; then
457 cp "$file" "$grubdir/locale
/"
460 cp "${cfgfile}" "$grubdir/grub.cfg
"
461 cp "${source}" "$grubdir/testcase.cfg
"
462 @builddir@/grub-core/grub-emu -m "$device_map" -d "$grubdir" | tr -d "\r" | do_trim
465 timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} |
cat |
tr -d "\r" | do_trim
467 if [ x
$boot = xcoreboot
]; then
468 test -n "$debug" ||
rm -f "${imgfile}"
470 test -n "$debug" ||
rm -f "${isofile}"
471 test -n "$debug" ||
rm -rf "${rom_directory}"
472 test -n "$debug" ||
rm -f "${tmpfile}" "${cfgfile}"