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"
90 qemu
=qemu-system-sparc64
92 serial_port
=ieee1275
/ttya
94 qemuopts
="$qemuopts -no-reboot"
100 qemu
=qemu-system-mips
101 qemuopts
="-M mips $qemuopts"
106 qemu
=qemu-system-mips64
107 qemuopts
="-M indy $qemuopts"
108 serial_port
=arc
/serial
0/line0
114 qemu
=qemu-system-mips64el
115 qemuopts
="-M magnum $qemuopts -no-reboot"
116 serial_port
=arc
/multi
0/serial0
123 qemu
=qemu-system-mipsel
124 qemuopts
="-M mips $qemuopts"
129 qemu
=qemu-system-mips64el
130 qemuopts
="-M fulong2e $qemuopts"
136 qemu
=qemu-system-i386
141 qemu
=qemu-system-i386
146 qemu
=qemu-system-i386
153 qemu
=qemu-system-i386
158 qemu
=qemu-system-i386
164 qemu
=qemu-system-i386
168 qemuopts
="-bios OVMF32.fd $qemuopts"
171 qemu
=qemu-system-x86_64
175 qemuopts
="-bios OVMF.fd $qemuopts"
178 qemu
=qemu-system-aarch64
182 qemuopts
="-machine virt -cpu cortex-a57 -bios /usr/share/qemu-efi/QEMU_EFI.fd $qemuopts"
183 disk
="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
191 qemuopts
="-machine virt -bios /usr/share/ovmf-arm/QEMU_EFI.fd $qemuopts"
192 disk
="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file="
197 qemu
=qemu-system-i386
204 # Check the arguments.
205 for option
in "$@"; do
211 echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
219 ms
=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'`
220 modules
="$modules $ms" ;;
222 fls
=`echo "$option" | sed -e 's/--files=//' -e 's/,/ /g'`
223 files
="$files $fls" ;;
225 mkr
=`echo "$option" | sed -e 's/--mkrescue-arg=//' -e 's/,/ /g'`
226 mkrescue_args
="$mkrescue_args $mkr" ;;
228 qemu
=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;;
230 qemu
=qemu-system-ppc64
231 serial_port
=ieee1275
/hvterm
233 qemuopts
="$qemuopts -M pseries -no-reboot"
238 qs
=`echo "$option" | sed -e 's/--qemu-opts=//'`
239 qemuopts
="$qemuopts $qs" ;;
241 dsk
=`echo "$option" | sed -e 's/--disk=//'`
242 if [ ${grub_modinfo_platform} = emu
]; then
243 echo "(hd$disk) $dsk" >> "$device_map"
246 if [ "$disk" = error
]; then
247 echo "Too many disks" 1>&2
250 qemuopts
="$qemuopts -$disk$dsk"
251 if [ "$disk" = "hda " ]; then
253 elif [ "$disk" = "hdb " ]; then
256 elif [ "$disk" = "hdd " ]; then
263 timeout
=`echo "$option" | sed -e 's/--timeout=//'`
266 # Intentionally undocumented
267 --grub-mkimage-extra)
268 mkimage_extra_arg
="$mkimage_extra_arg `argument $option "$@
"`"; shift ;;
269 --grub-mkimage-extra=*)
270 mkimage_extra_arg
="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
273 dev
=`echo "$option" | sed -e 's/--boot=//'`
274 if [ "$dev" = "fd" ] ; then boot
=fd
;
275 elif [ "$dev" = "hd" ] ; then boot
=hd
;
276 elif [ "$dev" = "cd" ] ; then boot
=cd;
277 elif [ "$dev" = "net" ] ; then boot
=net
;
278 elif [ "$dev" = "qemu" ] ; then boot
=qemu
;
279 elif [ "$dev" = "coreboot" ] ; then boot
=coreboot
;
280 elif [ "$dev" = "mips_qemu" ] ; then boot
=mips_qemu
;
281 elif [ "$dev" = "mipsel_qemu" ] ; then boot
=mipsel_qemu
;
282 elif [ "$dev" = "mipsel_fulong2e" ] ; then boot
=mipsel_fulong2e
;
284 echo "Unrecognized boot method \`$dev'" 1>&2
289 echo "Unrecognized option \`$option'" 1>&2
293 if [ "x${source}" != x
] ; then
294 echo "too many parameters at the end" 1>&2
298 source="${option}" ;;
302 if [ "x${source}" = x
] ; then
303 tmpfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
305 echo "$REPLY" >> ${tmpfile}
310 cfgfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
311 cat <<EOF >${cfgfile}
313 enable_progress_indicator=0
314 export enable_progress_indicator
318 if [ "${grub_modinfo_platform}" != emu
]; then
319 echo insmod serial
>>${cfgfile}
322 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275
]; then
323 echo insmod escc
>>${cfgfile}
325 if [ "${grub_modinfo_platform}" != emu
]; then
326 echo "serial ${serial_port}" >>${cfgfile}
327 term
="serial_${serial_port}"
332 cat <<EOF >>${cfgfile}
333 terminfo -g 1024x1024 ${term} dumb
334 terminal_input ${term}
335 terminal_output ${term}
338 trim_head
=664cbea8-132f-4770-8aa4-1696d59ac35c
340 if [ $trim = 1 ]; then
341 echo "echo $trim_head" >>${cfgfile}
344 rom_directory
=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
346 for mod
in ${modules}
348 echo "insmod ${mod}" >> ${cfgfile}
351 cat <<EOF >>${cfgfile}
352 source "\$prefix/testcase.cfg"
353 # Stop serial output to suppress "ACPI shutdown failed" error.
355 # Attempt to switch to console on i386-ieee1275 causes "screen not found" message
356 if [ x
$console != x
] && [ x
"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != xi386-ieee1275
]; then
357 echo "terminal_output $console" >>${cfgfile}
359 echo "${halt_cmd}" >>${cfgfile}
361 test -z "$debug" ||
echo "GRUB script: ${cfgfile}" >&2
362 test -z "$debug" ||
echo "GRUB testcase script: ${tmpfile}" >&2
363 test -z "$debug" ||
echo "Boot device: ${boot}" >&2
365 isofile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
366 test -z "$debug" ||
echo "GRUB ISO file: ${isofile}" >&2
367 test -z "$debug" ||
echo "GRUB ROM directory: ${rom_directory}" >&2
369 if test -z "$debug"; then
370 qemuopts
="${qemuopts} -nographic -monitor file:/dev/null"
373 if [ x
$boot != xnet
] && [ x
$boot != xemu
]; then
374 pkgdatadir
="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
375 --rom-directory="${rom_directory}" \
376 --locale-directory="@srcdir@/po" \
377 --themes-directory="@srcdir@/themes" \
378 $mkimage_extra_arg ${mkrescue_args} \
379 "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
380 ${files} >/dev
/null
2>&1
382 if [ x
$boot = xhd
]; then
383 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi
]; then
384 device
="device virtio-blk-device,drive=hd0 -drive if=none,id=hd0,file="
385 elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc
]; then
392 if [ x
$boot = xcd
]; then
393 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi
]; then
394 device
="device virtio-blk-device,drive=cd0 -drive if=none,id=cd0,media=cdrom,file="
395 elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275
] && [ x
$pseries != xy
] ; then
396 device
="-drive if=ide,media=cdrom,file="
402 if [ x
$boot = xfd
]; then
407 if [ x
$boot = xqemu
]; then
408 bootdev
="-bios ${rom_directory}/qemu.img"
412 if [ x
$boot = xmipsel_qemu
]; then
413 bootdev
="-kernel ${rom_directory}/mipsel-qemu_mips.elf"
417 if [ x
$boot = xmipsel_fulong2e
]; then
418 bootdev
="-kernel ${rom_directory}/mipsel-loongson.elf -append machtype=lemote-fuloong-2e"
422 if [ x
$boot = xmips_qemu
]; then
423 bootdev
="-kernel ${rom_directory}/mips-qemu_mips.elf"
427 if [ x
$boot = xcoreboot
]; then
428 imgfile
=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
429 cp "${GRUB_COREBOOT_ROM}" "${imgfile}"
430 "${GRUB_CBFSTOOL}" "${imgfile}" add-payload -f "${rom_directory}/coreboot.elf" -n fallback
/payload
431 bootdev
="-bios ${imgfile}"
433 test -z "$debug" ||
echo "Coreboot image: ${imgfile}" >&2
436 if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mipsel-arc
]; then
439 bootdev
="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/disk" ;;
441 bootdev
="-global ds1225y.filename=$GRUB_QEMU_MAGNUM_NVRAM_DIR/cdrom";;
447 if [ $trim = 1 ]; then
448 awk '{ if (have_head == 1) print $0; } /664cbea8-132f-4770-8aa4-1696d59ac35c/ { have_head=1; }'
458 # FIXME support '=' in file names
459 for _file
in "$@"; do
460 _target
="${_file%=*}"
461 _source
="${_file#*=}"
462 [ -n "$_source" ] || _source
="$_target"
463 _target
="$_destdir/$_target"
464 _targetdir
="$(dirname "$_target")"
465 [ -d "$_targetdir" ] || mkdir
-p "$_targetdir"
466 cp "$_source" "$_target"
470 if [ x
$boot = xnet
]; then
471 netdir
=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` ||
exit 1
472 pkgdatadir
="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
473 cp "${cfgfile}" "$netdir/boot
/grub
/grub.cfg
"
474 cp "${source}" "$netdir/boot
/grub
/testcase.cfg
"
475 [ -z "$files" ] || copy_extra_files "$netdir" $files
476 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
477 elif [ x$boot = xemu ]; then
478 rootdir="$
(mktemp
-d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")"
479 grubdir="$rootdir/boot
/grub
"
480 mkdir -p "$grubdir/fonts
"
481 mkdir -p "$grubdir/themes
"
482 mkdir -p "$grubdir/locale
"
483 cp "@builddir@
/"unicode.pf2 "$grubdir/fonts
/unicode.pf2
"
484 cp -R "@srcdir@
/themes
/starfield
" "$grubdir/themes
/starfield
"
485 for file in "@srcdir@
/po
/"*.gmo; do
486 if [ -f "$file" ]; then
487 cp "$file" "$grubdir/locale
/"
490 cp "${cfgfile}" "$grubdir/grub.cfg
"
491 cp "${source}" "$grubdir/testcase.cfg
"
492 [ -z "$files" ] || copy_extra_files "$rootdir" $files
493 roottar="$
(mktemp
"${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")"
494 (cd "$rootdir"; tar cf "$roottar" .)
495 @builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot
/grub
" | tr -d "\r" | do_trim
496 test -n "$debug" || rm -rf "$rootdir"
497 test -n "$debug" || rm -f "$roottar"
499 timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} |
cat |
tr -d "\r" | do_trim
501 if [ x
$boot = xcoreboot
]; then
502 test -n "$debug" ||
rm -f "${imgfile}"
504 test -n "$debug" ||
rm -f "${isofile}"
505 test -n "$debug" ||
rm -rf "${rom_directory}"
506 test -n "$debug" ||
rm -f "${tmpfile}" "${cfgfile}"