diff --git a/conf/common.rmk b/conf/common.rmk index 31b62892b..905024a55 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -695,4 +695,9 @@ bin_UTILITIES += grub-mkpasswd-pbkdf2 grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 +# Randomly generated +SUCCESSFUL_BOOT_STRING=3e49994fd5d82b7c9298d672d774080d + +bootcheck: $(BOOTCHECKS) + include $(srcdir)/conf/gcry.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a89203dea..33575a87c 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -368,5 +368,15 @@ pkglib_DATA += efiemu32.o efiemu64.o endif +BOOTTARGET=bios-cd + +bootcheck-linux16-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux.cfg grub-shell + timeout -s KILL 30s ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-i386 --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null + +bootcheck-linux16-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux.cfg grub-shell + timeout -s KILL 30s ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null + +BOOTCHECKS+=bootcheck-linux16-i386 bootcheck-linux16-x86_64 + include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386.rmk b/conf/i386.rmk index 7ef337c61..9305bf09c 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -41,3 +41,24 @@ multiboot2_mod_SOURCES = loader/i386/multiboot.c \ multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) + +linuxinit.x86_64: $(srcdir)/tests/boot/linuxinit-x86_64.S + $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +linuxinit.i386: $(srcdir)/tests/boot/linuxinit-i386.S + $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +linux-initramfs.%: linuxinit.% Makefile + TDIR=`mktemp -d`; (cp $< $$TDIR/init; cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR + +CLEANFILES += linuxinit.i386 linuxinit.x86_64 linux-initramfs.i386 linux-initramfs.x86_64 + +bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux.cfg grub-shell + timeout -s KILL 30s ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-i386 --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null + +bootcheck-linux-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux.cfg grub-shell + timeout -s KILL 30s ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null + +BOOTCHECKS+=bootcheck-linux-i386 bootcheck-linux-x86_64 + +.PHONY: bootcheck-linux-i386 bootcheck-linux-x86_64 diff --git a/tests/boot/linux.cfg b/tests/boot/linux.cfg new file mode 100644 index 000000000..201de99fd --- /dev/null +++ b/tests/boot/linux.cfg @@ -0,0 +1,3 @@ +linux /linux console=ttyS0 root=/dev/ram0 +initrd /initrd +boot diff --git a/tests/boot/linux16.cfg b/tests/boot/linux16.cfg new file mode 100644 index 000000000..ed0a50872 --- /dev/null +++ b/tests/boot/linux16.cfg @@ -0,0 +1,3 @@ +linux16 /linux console=ttyS0 root=/dev/ram0 +initrd16 /initrd +boot diff --git a/tests/boot/linuxinit-i386.S b/tests/boot/linuxinit-i386.S new file mode 100644 index 000000000..a79a5787e --- /dev/null +++ b/tests/boot/linuxinit-i386.S @@ -0,0 +1,55 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define SYSCALL_WRITE 4 +#define SYSCALL_RESET 88 +#define SYSCALL_EXIT 1 +#define SYSCALL_INT 0x80 + +#define STDOUT 1 +#define SHUTDOWN_MAGIC1 0xfee1dead +#define SHUTDOWN_MAGIC2 0x28121969 +#define SHUTDOWN_MAGIC3 0x4321fedc + + .text + .global start, _start +_start: +start: + /* write. */ + movl $SYSCALL_WRITE, %eax + movl $STDOUT, %ebx + leal message, %ecx + movl $(messageend-message), %edx + int $SYSCALL_INT + + /* shutdown. */ + movl $SYSCALL_RESET, %eax + movl $SHUTDOWN_MAGIC1, %ebx + movl $SHUTDOWN_MAGIC2, %ecx + movl $SHUTDOWN_MAGIC3, %edx + int $SYSCALL_INT + + /* exit (1). Shouldn't be reached. */ + movl $SYSCALL_EXIT, %eax + movl $1, %ebx + int $SYSCALL_INT + .data +message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" +messageend: + \ No newline at end of file diff --git a/tests/boot/linuxinit-x86_64.S b/tests/boot/linuxinit-x86_64.S new file mode 100644 index 000000000..17ba8040c --- /dev/null +++ b/tests/boot/linuxinit-x86_64.S @@ -0,0 +1,54 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define SYSCALL_WRITE 1 +#define SYSCALL_RESET 169 +#define SYSCALL_EXIT 60 + +#define STDOUT 1 +#define SHUTDOWN_MAGIC1 0xfee1dead +#define SHUTDOWN_MAGIC2 0x28121969 +#define SHUTDOWN_MAGIC3 0x4321fedc + + .text + .global start, _start +_start: +start: + /* write. */ + movq $SYSCALL_WRITE, %rax + movq $STDOUT, %rdi + leaq message, %rsi + movq $(messageend-message), %rdx + syscall + + /* shutdown. */ + movq $SYSCALL_RESET, %rax + movq $SHUTDOWN_MAGIC1, %rdi + movq $SHUTDOWN_MAGIC2, %rsi + movq $SHUTDOWN_MAGIC3, %rdx + syscall + + /* exit(1). Shouldn't be reached. */ + movq $SYSCALL_EXIT, %rax + movq $1, %rdi + syscall + .data +message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" +messageend: + \ No newline at end of file diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index e6fef8313..ee0cded55 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -44,7 +44,9 @@ Run GRUB script in a Qemu instance. -v, --version print the version information and exit --boot=[fd|hd|cd] boot method for Qemu instance --modules=MODULES pre-load specified modules MODULES + --qemu=FILE Name of qemu binary --qemu-opts=OPTIONS extra options to pass to Qemu instance + --files=FILES add files to the image $0 runs input GRUB script or SOURCE file in a Qemu instance and prints its output. @@ -53,6 +55,9 @@ Report bugs to . EOF } +boot=bios-hd +qemu=qemu-system-i386 + # Check the arguments. for option in "$@"; do case "$option" in @@ -65,14 +70,19 @@ for option in "$@"; do --modules=*) ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'` modules="$modules $ms" ;; + --files=*) + fls=`echo "$option" | sed -e 's/--files=//' -e 's/,/ /g'` + files="$files $fls" ;; + --qemu=*) + qemu=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;; --qemu-opts=*) qs=`echo "$option" | sed -e 's/--qemu-opts=//'` qemuopts="$qemuopts $qs" ;; --boot=*) dev=`echo "$option" | sed -e 's/--boot=//'` - if [ "$dev" = "fd" ] ; then bootdev=a; - elif [ "$dev" = "hd" ] ; then bootdev=c; - elif [ "$dev" = "cd" ] ; then bootdev=d; + if [ "$dev" = "bios-fd" ] ; then boot=bios-fd; + elif [ "$dev" = "bios-hd" ] ; then boot=bios-hd; + elif [ "$dev" = "bios-cd" ] ; then boot=bios-cd; else echo "Unrecognized boot method \`$dev'" 1>&2 usage @@ -100,10 +110,6 @@ if [ "x${source}" = x ] ; then source=${tmpfile} fi -if [ "x${bootdev}" = x ] ; then - bootdev=c # default is boot as disk image -fi - cfgfile=`mktemp` cat <${cfgfile} grubshell=yes @@ -123,23 +129,28 @@ source /boot/grub/testcase.cfg halt EOF -isofile=`mktemp` -grub-mkrescue --output=${isofile} --override-directory=${builddir} \ - /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ - >/dev/null 2>&1 +if [ x$boot = xbios-hd ] || [ x$boot = xbios-fd ] || [ x$boot = xbios-cd ]; then + isofile=`mktemp` + grub-mkrescue --output=${isofile} --override-directory=${builddir} \ + /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ + ${files} >/dev/null 2>&1 + if [ x$boot = xbios-hd ]; then + device=hda + bootdev=c + fi + if [ x$boot = xbios-cd ]; then + device=cdrom + bootdev=d + fi + if [ x$boot = xbios-fd ]; then + device=fda + bootdev=a + fi + ${qemu} ${qemuopts} -nographic -serial file:/dev/stdout -monitor file:/dev/null -${device} ${isofile} -boot ${bootdev} | tr -d "\r" + rm -f ${isofile} +fi -hdafile=`mktemp` -cp ${isofile} ${hdafile} - -fdafile=`mktemp` -cp ${isofile} ${fdafile} - -outfile=`mktemp` -qemu-system-i386 ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} - -cat $outfile - -rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} ${hdafile} ${fdafile} +rm -f ${tmpfile} ${cfgfile} exit 0