From 242f0731c7805a94d79eade8cb0cf928a526839c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 20 Nov 2009 09:41:20 +0100 Subject: [PATCH 01/31] reimported savedefault by cjwatson and myself Also-By: Vladimir 'phcoder' Serbinenko --- ChangeLog.savedefault | 29 +++++++ conf/common.rmk | 14 ++++ normal/menu.c | 2 + normal/menu_text.c | 26 ++++++- util/grub-install.in | 5 ++ util/grub-mkconfig_lib.in | 8 ++ util/grub-reboot.in | 104 ++++++++++++++++++++++++++ util/grub-set-default.in | 99 ++++++++++++++++++++++++ util/grub.d/00_header.in | 8 ++ util/grub.d/10_hurd.in | 1 + util/grub.d/10_kfreebsd.in | 1 + util/grub.d/10_linux.in | 1 + util/grub.d/10_windows.in | 1 + util/grub.d/30_os-prober.in | 3 + util/i386/efi/grub-install.in | 5 ++ util/ieee1275/grub-install.in | 5 ++ util/sparc64/ieee1275/grub-install.in | 5 ++ 17 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.savedefault create mode 100644 util/grub-reboot.in create mode 100644 util/grub-set-default.in diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault new file mode 100644 index 000000000..c18106bd5 --- /dev/null +++ b/ChangeLog.savedefault @@ -0,0 +1,29 @@ +2009-10-25 Vladimir Serbinenko +2009-10-25 Colin Watson + + * normal/menu.c (grub_menu_execute_entry): Save selected entry title + in `chosen' environment variable. + * normal/menu_text.c (get_entry_number): Check if the variable + matches the title of a menu entry. + (run_menu): Pass menu to get_entry_number. + + * util/grub-reboot.in: New file. + * util/grub-set-default.in: New file. + * conf/common.rmk (grub-reboot): New utility. + (grub-set-default): New utility. + + * util/grub-mkconfig_lib.in (save_default_entry): New function. + * util/grub.d/00_header.in: If GRUB_DEFAULT is `saved', set + default to `${saved_entry}'. If `${prev_saved_entry}' is non-empty, + move it to `saved_entry' for the next boot. Load environment on + initialisation. + * util/grub.d/10_kfreebsd.in: Call save_default_entry. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in (linux_entry): Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + + * util/grub-install.in: Create environment block. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + * util/sparc64/ieee1275/grub-install.in: Likewise. diff --git a/conf/common.rmk b/conf/common.rmk index 173f24b62..881c72795 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -175,6 +175,20 @@ CLEANFILES += $(grub-mkconfig_SCRIPTS) grub-mkconfig_DATA += util/grub.d/README +# For grub-set-default. +grub-set-default: util/grub-set-default.in config.status + ./config.status --file=$@:$< + chmod +x $@ +sbin_SCRIPTS += grub-set-default +CLEANFILES += grub-set-default + +# For grub-reboot. +grub-reboot: util/grub-reboot.in config.status + ./config.status --file=$@:$< + chmod +x $@ +sbin_SCRIPTS += grub-reboot +CLEANFILES += grub-reboot + # Filing systems. pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \ ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod \ diff --git a/normal/menu.c b/normal/menu.c index 8ee7d1c22..b9f74b7d7 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -137,6 +137,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry) return; } + grub_env_set ("chosen", entry->title); + grub_parser_execute ((char *) entry->sourcecode); if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) diff --git a/normal/menu_text.c b/normal/menu_text.c index e0d96c47f..19f9cf756 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -237,7 +237,7 @@ grub_menu_init_page (int nested, int edit) /* Get the entry number from the variable NAME. */ static int -get_entry_number (const char *name) +get_entry_number (grub_menu_t menu, const char *name) { char *val; int entry; @@ -250,6 +250,28 @@ get_entry_number (const char *name) entry = (int) grub_strtoul (val, 0, 0); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + /* See if the variable matches the title of a menu entry. */ + grub_menu_entry_t e = menu->entry_list; + int i; + + grub_errno = GRUB_ERR_NONE; + + for (i = 0; e; i++) + { + if (grub_strcmp (e->title, val) == 0) + { + entry = i; + break; + } + e = e->next; + } + + if (! e) + entry = -1; + } + if (grub_errno != GRUB_ERR_NONE) { grub_errno = GRUB_ERR_NONE; @@ -291,7 +313,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) first = 0; - default_entry = get_entry_number ("default"); + default_entry = get_entry_number (menu, "default"); /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ diff --git a/util/grub-install.in b/util/grub-install.in index 356e161e7..1cf7135fd 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -39,6 +39,7 @@ else fi grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= grub_prefix=`echo /boot/grub | sed ${transform}` modules= @@ -250,6 +251,10 @@ fi # Write device to a variable so we don't have to traverse /dev every time. grub_device=`$grub_probe --target=device ${grubdir}` +if ! test -f ${grubdir}/grubenv; then + $grub_editenv ${grubdir}/grubenv create +fi + # Create the core image. First, auto-detect the filesystem module. fs_module=`$grub_probe --target=fs --device ${grub_device}` if test "x$fs_module" = x -a "x$modules" = x; then diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index bb30cc475..8cdd1d470 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -130,6 +130,14 @@ convert_system_path_to_grub_path () echo ${drive}${relative_path} } +save_default_entry () +{ + if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then + echo 'saved_entry=${chosen}' + echo 'save_env saved_entry' + fi +} + prepare_grub_to_access_device () { device=$1 diff --git a/util/grub-reboot.in b/util/grub-reboot.in new file mode 100644 index 000000000..886d61770 --- /dev/null +++ b/util/grub-reboot.in @@ -0,0 +1,104 @@ +#! /bin/sh +# +# Set a default boot entry for GRUB, for the next boot only. +# Copyright (C) 2004,2009 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 . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ + +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` +rootdir= + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$entry" != x; then + echo "More than one entry?" 1>&2 + usage + exit 1 + fi + entry="${option}" ;; + esac +done + +if test "x$entry" = x; then + echo "entry not specified." 1>&2 + usage + exit 1 +fi + +# Initialize these directories here, since ROOTDIR was initialized. +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + bootdir=${rootdir} + ;; +*) + # Use /boot/grub by default. + bootdir=${rootdir}/boot + ;; +esac + +grubdir=${bootdir}/`echo grub | sed ${transform}` + +prev_saved_entry=`$grub_editenv ${grubdir}/grubenv list | sed -n 's/^saved_entry=//p'` +if [ "$prev_saved_entry" ]; then + $grub_editenv ${grubdir}/grubenv set prev_saved_entry="$prev_saved_entry" +else + $grub_editenv ${grubdir}/grubenv unset prev_saved_entry +fi +$grub_editenv ${grubdir}/grubenv set saved_entry="$entry" + +# Bye. +exit 0 diff --git a/util/grub-set-default.in b/util/grub-set-default.in new file mode 100644 index 000000000..6663d3fbd --- /dev/null +++ b/util/grub-set-default.in @@ -0,0 +1,99 @@ +#! /bin/sh +# +# Set a default boot entry for GRUB. +# Copyright (C) 2004,2009 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 . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ + +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` +rootdir= + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$entry" != x; then + echo "More than one entry?" 1>&2 + usage + exit 1 + fi + entry="${option}" ;; + esac +done + +if test "x$entry" = x; then + echo "entry not specified." 1>&2 + usage + exit 1 +fi + +# Initialize these directories here, since ROOTDIR was initialized. +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + bootdir=${rootdir} + ;; +*) + # Use /boot/grub by default. + bootdir=${rootdir}/boot + ;; +esac + +grubdir=${bootdir}/`echo grub | sed ${transform}` + +$grub_editenv ${grubdir}/grubenv unset prev_saved_entry +$grub_editenv ${grubdir}/grubenv set saved_entry="$entry" + +# Bye. +exit 0 diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 9f421dc1c..7279469b7 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -32,11 +32,19 @@ for i in ${GRUB_PRELOAD_MODULES} ; do done if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi +if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi cat << EOF +load_env set default=${GRUB_DEFAULT} +if [ \${prev_saved_entry} ]; then + saved_entry=\${prev_saved_entry} + save_env saved_entry + prev_saved_entry= + save_env prev_saved_entry +fi EOF case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index e693c7dfa..c1871e07a 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -75,6 +75,7 @@ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF +save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index c6712e32f..026f1d7ac 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -39,6 +39,7 @@ kfreebsd_entry () args="$4" # not used yet title="$(gettext "%s, with kFreeBSD %s")" printf "menuentry \"${title}\" {" ${os} ${version} + save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 8803055cf..dc9696ec8 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -59,6 +59,7 @@ linux_entry () title="$(gettext "%s, with Linux %s")" fi printf "menuentry \"${title}\" {" ${os} ${version} + save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 055258e29..35dd4a4cc 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -73,6 +73,7 @@ for dir in $dirlist ; do menuentry "$OS" { EOF + save_default_entry | sed -e 's,^,\t,' prepare_grub_to_access_device "$dev" | sed 's,^,\t,' cat << EOF diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index c5728866c..103785ed9 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -55,6 +55,7 @@ for OS in ${OSPROBED} ; do cat << EOF menuentry "${LONGNAME} (on ${DEVICE})" { EOF + save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" case ${LONGNAME} in @@ -113,6 +114,8 @@ EOF cat << EOF menuentry "${LONGNAME} (on ${DEVICE})" { EOF + save_default_entry | sed -e "s/^/\t/" + save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" cat << EOF insmod vbe diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index a5f97e346..e597c4eee 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -34,6 +34,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= grub_prefix=`echo /boot/grub | sed ${transform}` modules= @@ -178,6 +179,10 @@ for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do cp -f $file ${grubdir} || exit 1 done +if ! test -f ${grubdir}/grubenv; then + $grub_editenv ${grubdir}/grubenv create +fi + # Create the core image. First, auto-detect the filesystem module. fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}` if test "x$fs_module" = xfat; then :; else diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 710ed125b..9a26b0dca 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -37,6 +37,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= grub_prefix=`echo /boot/grub | sed ${transform}` modules= @@ -163,6 +164,10 @@ for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst ; do cp -f $file ${grubdir} || exit 1 done +if ! test -f ${grubdir}/grubenv; then + $grub_editenv ${grubdir}/grubenv create +fi + # Create the core image. First, auto-detect the filesystem module. fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}` if test "x$fs_module" = x -a "x$modules" = x; then diff --git a/util/sparc64/ieee1275/grub-install.in b/util/sparc64/ieee1275/grub-install.in index a03869cb3..f49157acd 100644 --- a/util/sparc64/ieee1275/grub-install.in +++ b/util/sparc64/ieee1275/grub-install.in @@ -38,6 +38,7 @@ grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= grub_prefix=`echo /boot/grub | sed ${transform}` modules= @@ -206,6 +207,10 @@ for file in ${pkglibdir}/*.img; do cp -f $file ${grubdir} || exit 1 done +if ! test -f ${grubdir}/grubenv; then + $grub_editenv ${grubdir}/grubenv create +fi + # Write device to a variable so we don't have to traverse /dev every time. grub_device=`$grub_probe --target=device ${grubdir}` From b824145a8f2f6435a62b6d127536078f6d3e136c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 00:56:39 +0000 Subject: [PATCH 02/31] 2009-12-08 Colin Watson * util/grub.d/30_os-prober.in: Fix merge error that moved a `save_default_entry' call from the macosx case to the linux case. --- ChangeLog.savedefault | 5 +++++ util/grub.d/30_os-prober.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index c18106bd5..0810274a3 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,8 @@ +2009-12-08 Colin Watson + + * util/grub.d/30_os-prober.in: Fix merge error that moved a + `save_default_entry' call from the macosx case to the linux case. + 2009-10-25 Vladimir Serbinenko 2009-10-25 Colin Watson diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 0e71096d1..f4a37d5f5 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -97,6 +97,7 @@ EOF cat << EOF menuentry "${LLABEL} (on ${DEVICE})" { EOF + save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | sed -e "s/^/\t/")" fi @@ -119,7 +120,6 @@ EOF cat << EOF menuentry "${LONGNAME} (on ${DEVICE})" { EOF - save_default_entry | sed -e "s/^/\t/" save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" cat << EOF From 36cd6dd151db7b033fb3d0fd055f8c7d83feb928 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 00:57:46 +0000 Subject: [PATCH 03/31] 2009-12-08 Colin Watson * util/grub.d/00_header.in: Quote the value assigned to `default', in case it contains spaces. --- ChangeLog.savedefault | 5 +++++ util/grub.d/00_header.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 0810274a3..6f885a73f 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,8 @@ +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Quote the value assigned to `default', + in case it contains spaces. + 2009-12-08 Colin Watson * util/grub.d/30_os-prober.in: Fix merge error that moved a diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 577a12722..e8c3a14c4 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -40,7 +40,7 @@ if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi cat << EOF load_env -set default=${GRUB_DEFAULT} +set default="${GRUB_DEFAULT}" if [ \${prev_saved_entry} ]; then saved_entry=\${prev_saved_entry} save_env saved_entry From 42356b4d5e1ee06d9189b4b4001215585c62dc8a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 00:59:26 +0000 Subject: [PATCH 04/31] 2009-12-08 Colin Watson * util/grub.d/00_header.in: Silently ignore zero-sized environment blocks. --- ChangeLog.savedefault | 5 +++++ util/grub.d/00_header.in | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 6f885a73f..cdeb05a87 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,8 @@ +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Silently ignore zero-sized environment + blocks. + 2009-12-08 Colin Watson * util/grub.d/00_header.in: Quote the value assigned to `default', diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index e8c3a14c4..2bcfe1d25 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -39,7 +39,9 @@ if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi cat << EOF -load_env +if [ -s \$prefix/grubenv ]; then + load_env +fi set default="${GRUB_DEFAULT}" if [ \${prev_saved_entry} ]; then saved_entry=\${prev_saved_entry} From 47075ea3c749f0d4ed082f7748387abc7f8a0717 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 01:00:26 +0000 Subject: [PATCH 05/31] 2009-12-08 Colin Watson * util/grub-reboot.in: Fix --version output. * util/grub-set-default.in: Likewise. --- ChangeLog.savedefault | 5 +++++ util/grub-reboot.in | 2 +- util/grub-set-default.in | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index cdeb05a87..55500a67c 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,8 @@ +2009-12-08 Colin Watson + + * util/grub-reboot.in: Fix --version output. + * util/grub-set-default.in: Likewise. + 2009-12-08 Colin Watson * util/grub.d/00_header.in: Silently ignore zero-sized environment diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 886d61770..16abdf6f4 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -51,7 +51,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "grub-reboot (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; diff --git a/util/grub-set-default.in b/util/grub-set-default.in index 6663d3fbd..4d7c10e8e 100644 --- a/util/grub-set-default.in +++ b/util/grub-set-default.in @@ -51,7 +51,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "grub-set-default (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; From b967a04d5b398fcbe5e3a157432f8559ca41b087 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 01:01:21 +0000 Subject: [PATCH 06/31] 2009-12-08 Colin Watson * util/grub.d/00_header.in: Use `set var=val' rather than plain `var=val'. * util/grub-mkconfig_lib.in (save_default_entry): Likewise. --- ChangeLog.savedefault | 6 ++++++ util/grub-mkconfig_lib.in | 2 +- util/grub.d/00_header.in | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 55500a67c..25811c79b 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,9 @@ +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Use `set var=val' rather than plain + `var=val'. + * util/grub-mkconfig_lib.in (save_default_entry): Likewise. + 2009-12-08 Colin Watson * util/grub-reboot.in: Fix --version output. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index d18002ce4..95fd02ad9 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -93,7 +93,7 @@ convert_system_path_to_grub_path () save_default_entry () { if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then - echo 'saved_entry=${chosen}' + echo 'set saved_entry=${chosen}' echo 'save_env saved_entry' fi } diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 2bcfe1d25..4cd8fd30c 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -44,9 +44,9 @@ if [ -s \$prefix/grubenv ]; then fi set default="${GRUB_DEFAULT}" if [ \${prev_saved_entry} ]; then - saved_entry=\${prev_saved_entry} + set saved_entry=\${prev_saved_entry} save_env saved_entry - prev_saved_entry= + set prev_saved_entry= save_env prev_saved_entry fi EOF From 6c1f8c1215b57cf404d103003d0becc74dbeed10 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Dec 2009 01:02:08 +0000 Subject: [PATCH 07/31] 2009-12-08 Colin Watson * util/grub.d/30_os-prober.in: Call save_default_entry for hurd. --- ChangeLog.savedefault | 4 ++++ util/grub.d/30_os-prober.in | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 25811c79b..7457c3f71 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,7 @@ +2009-12-08 Colin Watson + + * util/grub.d/30_os-prober.in: Call save_default_entry for hurd. + 2009-12-08 Colin Watson * util/grub.d/00_header.in: Use `set var=val' rather than plain diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index f4a37d5f5..b91838782 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -170,6 +170,7 @@ EOF cat << EOF menuentry "${LONGNAME} (on ${DEVICE})" { EOF + save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" grub_device="`${grub_probe} --device ${DEVICE} --target=drive`" mach_device="`echo "${grub_device}" | tr -d '()' | tr , s`" From b445cfaa4dadc0ce15d9dddd9764e8db295feffb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 5 Jan 2010 10:30:14 +0000 Subject: [PATCH 08/31] 2010-10-05 Jordan Uggla 2010-10-05 Colin Watson * util/grub-mkconfig_lib.in (save_default_entry): Only set saved_entry if boot_once is unset. * util/grub.d/00_header.in: Set boot_once to "true" if there was a previous saved entry (i.e. grub-reboot). --- ChangeLog.savedefault | 8 ++++++++ util/grub-mkconfig_lib.in | 8 ++++++-- util/grub.d/00_header.in | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 7457c3f71..f07bd6beb 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,11 @@ +2010-10-05 Jordan Uggla +2010-10-05 Colin Watson + + * util/grub-mkconfig_lib.in (save_default_entry): Only set + saved_entry if boot_once is unset. + * util/grub.d/00_header.in: Set boot_once to "true" if there was a + previous saved entry (i.e. grub-reboot). + 2009-12-08 Colin Watson * util/grub.d/30_os-prober.in: Call save_default_entry for hurd. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 95fd02ad9..acfc9f6ea 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -93,8 +93,12 @@ convert_system_path_to_grub_path () save_default_entry () { if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then - echo 'set saved_entry=${chosen}' - echo 'save_env saved_entry' + cat << EOF +if [ -z \${boot_once} ]; then + set saved_entry=${chosen} + save_env saved_entry +fi +EOF fi } diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 4cd8fd30c..85ce0d4a0 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -48,6 +48,7 @@ if [ \${prev_saved_entry} ]; then save_env saved_entry set prev_saved_entry= save_env prev_saved_entry + set boot_once=true fi EOF From fcab4f04e5e32cd2d3247e25d2c629085fcb23bf Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 5 Jan 2010 10:39:30 +0000 Subject: [PATCH 09/31] missing backslash --- util/grub-mkconfig_lib.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index acfc9f6ea..72e0e38f9 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -95,7 +95,7 @@ save_default_entry () if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then cat << EOF if [ -z \${boot_once} ]; then - set saved_entry=${chosen} + set saved_entry=\${chosen} save_env saved_entry fi EOF From 5c23bb0f529f6b3d1577dbfa405338e3ec81fbf3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 5 Jan 2010 10:41:51 +0000 Subject: [PATCH 10/31] 2010-10-05 Jordan Uggla 2010-10-05 Colin Watson * util/grub.d/00_header.in: Define a "savedefault" function for use in menu entries. * util/grub-mkconfig_lib.in (save_default_entry): Use it. --- ChangeLog.savedefault | 7 +++++++ util/grub-mkconfig_lib.in | 5 +---- util/grub.d/00_header.in | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index f07bd6beb..90875588e 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,10 @@ +2010-10-05 Jordan Uggla +2010-10-05 Colin Watson + + * util/grub.d/00_header.in: Define a "savedefault" function for use + in menu entries. + * util/grub-mkconfig_lib.in (save_default_entry): Use it. + 2010-10-05 Jordan Uggla 2010-10-05 Colin Watson diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 72e0e38f9..380ba1a48 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -94,10 +94,7 @@ save_default_entry () { if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then cat << EOF -if [ -z \${boot_once} ]; then - set saved_entry=\${chosen} - save_env saved_entry -fi +savedefault EOF fi } diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 85ce0d4a0..cfb8648ca 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -50,6 +50,13 @@ if [ \${prev_saved_entry} ]; then save_env prev_saved_entry set boot_once=true fi + +function savedefault { + if [ -z \${boot_once} ]; then + saved_entry=\${chosen} + save_env saved_entry + fi +} EOF case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in From cf2fd2a6d1a58ad0c47cf8b968ff695d0073b57a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 5 Jan 2010 11:16:42 +0000 Subject: [PATCH 11/31] 2010-10-05 Jordan Uggla 2010-10-05 Colin Watson * util/grub-reboot.in: Make sure prev_saved_entry always gets a non-empty value. --- ChangeLog.savedefault | 6 ++++++ util/grub-reboot.in | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 90875588e..722769776 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,3 +1,9 @@ +2010-10-05 Jordan Uggla +2010-10-05 Colin Watson + + * util/grub-reboot.in: Make sure prev_saved_entry always gets a + non-empty value. + 2010-10-05 Jordan Uggla 2010-10-05 Colin Watson diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 16abdf6f4..20f2b10bc 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -96,7 +96,11 @@ prev_saved_entry=`$grub_editenv ${grubdir}/grubenv list | sed -n 's/^saved_entry if [ "$prev_saved_entry" ]; then $grub_editenv ${grubdir}/grubenv set prev_saved_entry="$prev_saved_entry" else - $grub_editenv ${grubdir}/grubenv unset prev_saved_entry + # We need some non-empty value for prev_saved_entry so that GRUB will + # recognise that grub-reboot has been used and restore the previous + # saved entry. "0" is the same as an empty value, i.e. the first menu + # entry. + $grub_editenv ${grubdir}/grubenv set prev_saved_entry=0 fi $grub_editenv ${grubdir}/grubenv set saved_entry="$entry" From 6fc804ffbb7d0163a3f6a73dbd2b6f7c5f954fff Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 8 Jan 2010 15:19:10 +0530 Subject: [PATCH 12/31] unit testing framework --- Makefile.in | 19 +++- conf/tests.rmk | 41 ++++++++ genmk.rb | 6 +- include/grub/test.h | 88 ++++++++++++++++++ tests/example_functional_test.c | 17 ++++ tests/example_grub_script_test.in | 3 + tests/example_scripted_test.in | 3 + tests/example_unit_test.c | 20 ++++ tests/lib/functional_test.c | 75 +++++++++++++++ tests/lib/test.c | 150 ++++++++++++++++++++++++++++++ tests/lib/unit_test.c | 122 ++++++++++++++++++++++++ tests/util/grub-shell-tester.in | 109 ++++++++++++++++++++++ tests/util/grub-shell.in | 125 +++++++++++++++++++++++++ 13 files changed, 774 insertions(+), 4 deletions(-) create mode 100644 conf/tests.rmk create mode 100644 include/grub/test.h create mode 100644 tests/example_functional_test.c create mode 100644 tests/example_grub_script_test.in create mode 100644 tests/example_scripted_test.in create mode 100644 tests/example_unit_test.c create mode 100644 tests/lib/functional_test.c create mode 100644 tests/lib/test.c create mode 100644 tests/lib/unit_test.c create mode 100644 tests/util/grub-shell-tester.in create mode 100644 tests/util/grub-shell.in diff --git a/Makefile.in b/Makefile.in index ffa8716ed..2358060f2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -141,6 +141,7 @@ PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES) SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) \ $(lib_SCRIPTS) INFOS = $(info_INFOS) +TESTS = $(check_UNITTESTS) $(check_FUNCTIONALTESTS) $(check_SCRIPTEDTESTS) CLEANFILES = MOSTLYCLEANFILES = @@ -167,6 +168,8 @@ ifeq ($(platform), emu) include $(srcdir)/conf/any-emu.mk else include $(srcdir)/conf/$(target_cpu)-$(platform).mk +# For tests. +include $(srcdir)/conf/tests.mk # For external modules. -include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk) endif @@ -458,7 +461,21 @@ distcheck: dist @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' -check: +$(TESTS): $(check_SCRIPTS) $(check_MODULES) $(check_PROGRAMS) +check: all $(TESTS) + @list="$(check_UNITTESTS) $(check_SCRIPTEDTESTS)"; \ + for file in $$list; do \ + if $(builddir)/$$file; then \ + echo "$$file: PASS"; \ + else \ + echo "$$file: FAIL"; \ + fi; \ + done + @list="$(check_FUNCTIONALTESTS)"; \ + for test in $$list; do \ + echo "insmod functional_test; insmod $test; functional_test" \ + | $(builddir)/grub-shell; \ + done .SUFFIX: .SUFFIX: .c .o .S .d diff --git a/conf/tests.rmk b/conf/tests.rmk new file mode 100644 index 000000000..03d6acbd1 --- /dev/null +++ b/conf/tests.rmk @@ -0,0 +1,41 @@ +# -*- makefile -*- + +# For grub-shell +grub-shell: tests/util/grub-shell.in config.status + ./config.status --file=$@:$< + chmod +x $@ +check_SCRIPTS += grub-shell +CLEANFILES += grub-shell + +# For grub-shell-tester +grub-shell-tester: tests/util/grub-shell-tester.in config.status + ./config.status --file=$@:$< + chmod +x $@ +check_SCRIPTS += grub-shell-tester +CLEANFILES += grub-shell-tester + +check_MODULES += functional_test.mod +functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c +functional_test_mod_CFLAGS = $(COMMON_CFLAGS) +functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Unit tests + +check_UNITTESTS += example_unit_test +example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c +example_unit_test_CFLAGS = -Wno-format + +# Functional tests + +check_FUNCTIONALTESTS += example_functional_test.mod +example_functional_test_mod_SOURCES = tests/example_functional_test.c +example_functional_test_mod_CFLAGS = -Wno-format $(COMMON_CFLAGS) +example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Scripted tests + +check_SCRIPTEDTESTS += example_scripted_test +example_scripted_test_SOURCES = tests/example_scripted_test.in + +check_SCRIPTEDTESTS += example_grub_script_test +example_grub_script_test_SOURCES = tests/example_grub_script_test.in diff --git a/genmk.rb b/genmk.rb index b1cce3831..006fc3d29 100644 --- a/genmk.rb +++ b/genmk.rb @@ -407,12 +407,12 @@ while l = gets Image.new(prefix, img) end - when 'MODULES' + when 'MODULES', 'FUNCTIONALTESTS' pmodules += args.split(/\s+/).collect do |pmod| PModule.new(prefix, pmod) end - when 'UTILITIES' + when 'UTILITIES', 'UNITTESTS' utils += args.split(/\s+/).collect do |util| Utility.new(prefix, util) end @@ -422,7 +422,7 @@ while l = gets Program.new(prefix, prog) end - when 'SCRIPTS' + when 'SCRIPTS', 'SCRIPTEDTESTS' scripts += args.split(/\s+/).collect do |script| Script.new(prefix, script) end diff --git a/include/grub/test.h b/include/grub/test.h new file mode 100644 index 000000000..fbc2bff8c --- /dev/null +++ b/include/grub/test.h @@ -0,0 +1,88 @@ +#ifndef GRUB_TEST_HEADER +#define GRUB_TEST_HEADER + +#include +#include +#include +#include +#include + +struct grub_test +{ + /* The next test. */ + struct grub_test *next; + + /* The test name. */ + char *name; + + /* The test main function. */ + void (*main) (void); +}; +typedef struct grub_test *grub_test_t; + +extern grub_test_t EXPORT_VAR (grub_test_list); + +void EXPORT_FUNC (grub_test_register) (const char *name, void (*test) (void)); + +void EXPORT_FUNC (grub_test_unregister) (const char *name); + +/* Execute a test and print results. */ +int grub_test_run (const char *name); + +/* Test `cond' for nonzero; log failure otherwise. */ +void grub_test_nonzero (int cond, const char *file, + const char *func, grub_uint32_t line, + const char *fmt, ...) + __attribute__ ((format (printf, 5, 6))); + +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ < 199901L +# if __GNUC__ >= 2 +# define __func__ __FUNCTION__ +# else +# define __func__ "" +# endif +#endif +#else +#define __func__ "" +#endif + +/* Macro to fill in location details and an optional error message. */ +#define grub_test_assert(cond, ...) \ + grub_test_nonzero(cond, __FILE__, __func__, __LINE__, \ + ## __VA_ARGS__, \ + "assert failed: %s", #cond) + +/* Macro to define a unit test. */ +#define GRUB_UNIT_TEST(name, funp) \ + void grub_unit_test_init (void) \ + { \ + grub_test_register (name, funp); \ + } \ + \ + void grub_unit_test_fini (void) \ + { \ + grub_test_unregister (name); \ + } + +/* Macro to define a functional test. */ +#define GRUB_FUNCTIONAL_TEST(name, funp) \ + GRUB_MOD_INIT(functional_test_##funp) \ + { \ + grub_test_register (name, funp); \ + } \ + \ + GRUB_MOD_FINI(functional_test_##funp) \ + { \ + grub_test_unregister (name); \ + } + +/* Functions that are defined differently for unit and functional tests. */ +void *grub_test_malloc (grub_size_t size); +void grub_test_free (void *ptr); +char *grub_test_strdup (const char *str); +int grub_test_vsprintf (char *str, const char *fmt, va_list args); +int grub_test_printf (const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + +#endif /* ! GRUB_TEST_HEADER */ diff --git a/tests/example_functional_test.c b/tests/example_functional_test.c new file mode 100644 index 000000000..475d1c7f0 --- /dev/null +++ b/tests/example_functional_test.c @@ -0,0 +1,17 @@ +/* All tests need to include test.h for GRUB testing framework. */ +#include + +/* Functional test main method. */ +static void +example_test (void) +{ + /* Check if 1st argument is true and report with default error message. */ + grub_test_assert (1 == 1); + + /* Check if 1st argument is true and report with custom error message. */ + grub_test_assert (2 == 2, "2 equal 2 expected"); + grub_test_assert (2 == 3, "2 is not equal to %d", 3); +} + +/* Register example_test method as a functional test. */ +GRUB_FUNCTIONAL_TEST ("example_functional_test", example_test); diff --git a/tests/example_grub_script_test.in b/tests/example_grub_script_test.in new file mode 100644 index 000000000..93a90a18e --- /dev/null +++ b/tests/example_grub_script_test.in @@ -0,0 +1,3 @@ +#! @builddir@/grub-shell-tester --modules=echo + +echo "hello world" diff --git a/tests/example_scripted_test.in b/tests/example_scripted_test.in new file mode 100644 index 000000000..9ac0424c0 --- /dev/null +++ b/tests/example_scripted_test.in @@ -0,0 +1,3 @@ +#!/bin/sh -e + +true diff --git a/tests/example_unit_test.c b/tests/example_unit_test.c new file mode 100644 index 000000000..e2fad06ff --- /dev/null +++ b/tests/example_unit_test.c @@ -0,0 +1,20 @@ +/* Unit tests are normal programs, so they can include C library. */ +#include + +/* All tests need to include test.h for GRUB testing framework. */ +#include + +/* Unit test main method. */ +static void +example_test (void) +{ + /* Check if 1st argument is true and report with default error message. */ + grub_test_assert (1 == 1); + + /* Check if 1st argument is true and report with custom error message. */ + grub_test_assert (2 == 2, "2 equal 2 expected"); + grub_test_assert (2 == 3, "2 is not equal to %d", 3); +} + +/* Register example_test method as a unit test. */ +GRUB_UNIT_TEST ("example_unit_test", example_test); diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c new file mode 100644 index 000000000..24e82932e --- /dev/null +++ b/tests/lib/functional_test.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +void * +grub_test_malloc (grub_size_t size) +{ + return grub_malloc (size); +} + +void +grub_test_free (void *ptr) +{ + grub_free (ptr); +} + +int +grub_test_vsprintf (char *str, const char *fmt, va_list args) +{ + return grub_vsprintf (str, fmt, args); +} + +char * +grub_test_strdup (const char *str) +{ + return grub_strdup (str); +} + +int +grub_test_printf (const char *fmt, ...) +{ + int r; + va_list ap; + + va_start (ap, fmt); + r = grub_vprintf (fmt, ap); + va_end (ap); + + return r; +} + +static grub_err_t +grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + int i; + int status; + grub_test_t test; + + status = 0; + for (i = 0; i < argc; i++) + { + test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list), + args[i]); + status = grub_test_run (test->name) ? : status; + } + + return status; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT (functional_test) +{ + cmd = grub_register_extcmd ("functional_test", grub_functional_test, + GRUB_COMMAND_FLAG_CMDLINE, 0, + "Run all functional tests.", 0); +} + +GRUB_MOD_FINI (functional_test) +{ + grub_unregister_extcmd (cmd); +} diff --git a/tests/lib/test.c b/tests/lib/test.c new file mode 100644 index 000000000..37f8fff72 --- /dev/null +++ b/tests/lib/test.c @@ -0,0 +1,150 @@ +#include +#include + +struct grub_test_failure +{ + /* The next failure. */ + struct grub_test_failure *next; + + /* The test source file name. */ + char *file; + + /* The test function name. */ + char *funp; + + /* The test call line number. */ + grub_uint32_t line; + + /* The test failure message. */ + char *message; +}; +typedef struct grub_test_failure *grub_test_failure_t; + +grub_test_t grub_test_list; +static grub_test_failure_t failure_list; + +static void +add_failure (const char *file, + const char *funp, + grub_uint32_t line, const char *fmt, va_list args) +{ + char buf[1024]; + grub_test_failure_t failure; + + failure = (grub_test_failure_t) grub_test_malloc (sizeof (*failure)); + if (!failure) + return; + + grub_test_vsprintf (buf, fmt, args); + + failure->file = grub_test_strdup (file ? : ""); + failure->funp = grub_test_strdup (funp ? : ""); + failure->line = line; + failure->message = grub_test_strdup (buf); + + grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure)); +} + +static void +free_failures (void) +{ + grub_test_failure_t item; + + while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0) + { + if (item->message) + grub_test_free (item->message); + + if (item->funp) + grub_test_free (item->funp); + + if (item->file) + grub_test_free (item->file); + + grub_test_free (item); + } + failure_list = 0; +} + +void +grub_test_nonzero (int cond, + const char *file, + const char *funp, grub_uint32_t line, const char *fmt, ...) +{ + va_list ap; + + if (cond) + return; + + va_start (ap, fmt); + add_failure (file, funp, line, fmt, ap); + va_end (ap); +} + +void +grub_test_register (const char *name, void (*test_main) (void)) +{ + grub_test_t test; + + test = (grub_test_t) grub_test_malloc (sizeof (*test)); + if (!test) + return; + + test->name = grub_test_strdup (name); + test->main = test_main; + + grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test)); +} + +void +grub_test_unregister (const char *name) +{ + grub_test_t test; + + test = (grub_test_t) grub_named_list_find + (GRUB_AS_NAMED_LIST (grub_test_list), name); + + if (test) + { + grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), + GRUB_AS_LIST (test)); + + if (test->name) + grub_test_free (test->name); + + grub_test_free (test); + } +} + +int +grub_test_run (const char *name) +{ + grub_test_t test; + + auto int print_failure (grub_test_failure_t item); + int print_failure (grub_test_failure_t item) + { + grub_test_failure_t failure = (grub_test_failure_t) item; + + grub_test_printf (" %s:%s:%u: %s\n", + (failure->file ? : ""), + (failure->funp ? : ""), + failure->line, (failure->message ? : "")); + return 0; + } + + test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list), name); + if (!test) + return GRUB_ERR_FILE_NOT_FOUND; + + test->main (); + + if (!failure_list) + return GRUB_ERR_NONE; + + grub_test_printf ("%s:\n", test->name); + grub_list_iterate (GRUB_AS_LIST (failure_list), + (grub_list_hook_t) print_failure); + free_failures (); + return GRUB_ERR_TEST_FAILURE; +} diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c new file mode 100644 index 000000000..15bb0da5d --- /dev/null +++ b/tests/lib/unit_test.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include + +#include +#include +#include + +void * +grub_test_malloc (grub_size_t size) +{ + return malloc (size); +} + +void +grub_test_free (void *ptr) +{ + free (ptr); +} + +int +grub_test_vsprintf (char *str, const char *fmt, va_list args) +{ + return vsprintf (str, fmt, args); +} + +char * +grub_test_strdup (const char *str) +{ + return strdup (str); +} + +int +grub_test_printf (const char *fmt, ...) +{ + int r; + va_list ap; + + va_start (ap, fmt); + r = vprintf (fmt, ap); + va_end (ap); + + return r; +} + +int +main (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + int status = 0; + + extern void grub_unit_test_init (void); + extern void grub_unit_test_fini (void); + + auto int run_test (grub_test_t test); + int run_test (grub_test_t test) + { + status = grub_test_run (test->name) ? : status; + return 0; + } + + grub_unit_test_init (); + grub_list_iterate (GRUB_AS_LIST (grub_test_list), + (grub_list_hook_t) run_test); + grub_unit_test_fini (); + + exit (status); +} + +/* Other misc. functions necessary for successful linking. */ + +char * +grub_env_get (const char *name __attribute__ ((unused))) +{ + return NULL; +} + +grub_err_t +grub_error (grub_err_t n, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + + return n; +} + +void * +grub_malloc (grub_size_t size) +{ + return malloc (size); +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_exit (void) +{ + exit (1); +} + +struct grub_handler_class grub_term_input_class; +struct grub_handler_class grub_term_output_class; diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in new file mode 100644 index 000000000..18f5e79b7 --- /dev/null +++ b/tests/util/grub-shell-tester.in @@ -0,0 +1,109 @@ +#! /bin/bash -e + +# Compares GRUB script output with BASH output. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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 . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +builddir=@builddir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ + +# Force build directory components +PATH=${builddir}:$PATH +export PATH + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + ms=`echo "$option" | sed -e 's/--modules=//'` + modules="$modules,$ms" ;; + --qemu-opts=*) + qs=`echo "$option" | sed -e 's/--qemu-opts=//'` + qemuopts="$qemuopts $qs" ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if [ "x${source}" != x ] ; then + echo "too many parameters at the end" 1>&2 + usage + exit 1 + fi + source="${option}" ;; + esac +done + +if [ "x${source}" = x ] ; then + tmpfile=`mktemp` + while read; do + echo $REPLY >> ${tmpfile} + done + source=${tmpfile} +fi + +outfile1=`mktemp` +@builddir@/grub-shell --qemu-opts="${qemuopts}" --modules=${modules} ${source} >${outfile1} + +outfile2=`mktemp` +bash ${source} >${outfile2} + +if ! diff -q ${outfile1} ${outfile2} >/dev/null +then + echo "$1: GRUB and BASH outputs (${outfile1}, ${outfile2}) did not match" + status=1 +else + rm -f ${outfile1} ${outfile2} +fi + +exit $status + + diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in new file mode 100644 index 000000000..c1b2ef258 --- /dev/null +++ b/tests/util/grub-shell.in @@ -0,0 +1,125 @@ +#! /bin/bash -e + +# Run GRUB script in a Qemu instance +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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 . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +builddir=@builddir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ + +# Force build directory components +PATH=${builddir}:$PATH +export PATH + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'` + modules="$modules $ms" ;; + --qemu-opts=*) + qs=`echo "$option" | sed -e 's/--qemu-opts=//'` + qemuopts="$qemuopts $qs" ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if [ "x${source}" != x ] ; then + echo "too many parameters at the end" 1>&2 + usage + exit 1 + fi + source="${option}" ;; + esac +done + +if [ "x${source}" = x ] ; then + tmpfile=`mktemp` + while read; do + echo $REPLY >> ${tmpfile} + done + source=${tmpfile} +fi + +cfgfile=`mktemp` +cat <${cfgfile} +grubshell=yes +insmod serial +serial +terminal_input serial +terminal_output serial +EOF + +for mod in ${modules} +do + echo "insmod ${mod}" >> ${cfgfile} +done + +cat <>${cfgfile} +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 + +outfile=`mktemp` +qemu ${qemuopts} -nographic -serial stdio -cdrom ${isofile} -boot d | tr -d "\r" >${outfile} + +cat $outfile + +rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} +exit 0 + + From 169b1cd2d87102670dfdb1717aef8723143d8c4b Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 8 Jan 2010 16:35:32 +0530 Subject: [PATCH 13/31] added functional tests to make-check --- Makefile.in | 19 +++++++++++++------ conf/tests.rmk | 14 +++++++------- genmk.rb | 6 +++--- include/grub/test.h | 2 +- tests/lib/functional_test.c | 21 +++++++++------------ tests/lib/test.c | 18 +++++++----------- tests/lib/unit_test.c | 2 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2358060f2..567571897 100644 --- a/Makefile.in +++ b/Makefile.in @@ -141,7 +141,6 @@ PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES) SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) \ $(lib_SCRIPTS) INFOS = $(info_INFOS) -TESTS = $(check_UNITTESTS) $(check_FUNCTIONALTESTS) $(check_SCRIPTEDTESTS) CLEANFILES = MOSTLYCLEANFILES = @@ -461,19 +460,27 @@ distcheck: dist @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' -$(TESTS): $(check_SCRIPTS) $(check_MODULES) $(check_PROGRAMS) +TESTS = $(check_UTILITIES) $(check_SCRIPTS) $(check_MODULES) +$(TESTS): $(test_framework_SCRIPTS) $(test_framework_MODULES) + check: all $(TESTS) - @list="$(check_UNITTESTS) $(check_SCRIPTEDTESTS)"; \ + @list="$(check_UTILITIES)"; \ for file in $$list; do \ + $(builddir)/$$file; \ + done + @list="$(check_SCRIPTS)"; \ + for file in $$list; do \ + echo "$$file:"; \ if $(builddir)/$$file; then \ echo "$$file: PASS"; \ else \ echo "$$file: FAIL"; \ fi; \ done - @list="$(check_FUNCTIONALTESTS)"; \ - for test in $$list; do \ - echo "insmod functional_test; insmod $test; functional_test" \ + @list="$(check_MODULES)"; \ + for file in $$list; do \ + mod=`basename $$file .mod`; \ + echo "insmod functional_test; insmod $$mod; functional_test" \ | $(builddir)/grub-shell; \ done diff --git a/conf/tests.rmk b/conf/tests.rmk index 03d6acbd1..c35ea0baa 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -4,38 +4,38 @@ grub-shell: tests/util/grub-shell.in config.status ./config.status --file=$@:$< chmod +x $@ -check_SCRIPTS += grub-shell +test_framework_SCRIPTS += grub-shell CLEANFILES += grub-shell # For grub-shell-tester grub-shell-tester: tests/util/grub-shell-tester.in config.status ./config.status --file=$@:$< chmod +x $@ -check_SCRIPTS += grub-shell-tester +test_framework_SCRIPTS += grub-shell-tester CLEANFILES += grub-shell-tester -check_MODULES += functional_test.mod +test_framework_MODULES += functional_test.mod functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c functional_test_mod_CFLAGS = $(COMMON_CFLAGS) functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) # Unit tests -check_UNITTESTS += example_unit_test +check_UTILITIES += example_unit_test example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c example_unit_test_CFLAGS = -Wno-format # Functional tests -check_FUNCTIONALTESTS += example_functional_test.mod +check_MODULES += example_functional_test.mod example_functional_test_mod_SOURCES = tests/example_functional_test.c example_functional_test_mod_CFLAGS = -Wno-format $(COMMON_CFLAGS) example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) # Scripted tests -check_SCRIPTEDTESTS += example_scripted_test +check_SCRIPTS += example_scripted_test example_scripted_test_SOURCES = tests/example_scripted_test.in -check_SCRIPTEDTESTS += example_grub_script_test +check_SCRIPTS += example_grub_script_test example_grub_script_test_SOURCES = tests/example_grub_script_test.in diff --git a/genmk.rb b/genmk.rb index 006fc3d29..b1cce3831 100644 --- a/genmk.rb +++ b/genmk.rb @@ -407,12 +407,12 @@ while l = gets Image.new(prefix, img) end - when 'MODULES', 'FUNCTIONALTESTS' + when 'MODULES' pmodules += args.split(/\s+/).collect do |pmod| PModule.new(prefix, pmod) end - when 'UTILITIES', 'UNITTESTS' + when 'UTILITIES' utils += args.split(/\s+/).collect do |util| Utility.new(prefix, util) end @@ -422,7 +422,7 @@ while l = gets Program.new(prefix, prog) end - when 'SCRIPTS', 'SCRIPTEDTESTS' + when 'SCRIPTS' scripts += args.split(/\s+/).collect do |script| Script.new(prefix, script) end diff --git a/include/grub/test.h b/include/grub/test.h index fbc2bff8c..4b028371b 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -27,7 +27,7 @@ void EXPORT_FUNC (grub_test_register) (const char *name, void (*test) (void)); void EXPORT_FUNC (grub_test_unregister) (const char *name); /* Execute a test and print results. */ -int grub_test_run (const char *name); +int grub_test_run (grub_test_t test); /* Test `cond' for nonzero; log failure otherwise. */ void grub_test_nonzero (int cond, const char *file, diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 24e82932e..2e03dabc4 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -45,19 +45,16 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - int i; - int status; - grub_test_t test; + auto int run_test (grub_test_t test); + int run_test (grub_test_t test) + { + grub_test_run (test); + return 0; + } - status = 0; - for (i = 0; i < argc; i++) - { - test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list), - args[i]); - status = grub_test_run (test->name) ? : status; - } - - return status; + grub_list_iterate (GRUB_AS_LIST (grub_test_list), + (grub_list_hook_t) run_test); + return GRUB_ERR_NONE; } static grub_extcmd_t cmd; diff --git a/tests/lib/test.c b/tests/lib/test.c index 37f8fff72..562c2f6e4 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -117,10 +117,8 @@ grub_test_unregister (const char *name) } int -grub_test_run (const char *name) +grub_test_run (grub_test_t test) { - grub_test_t test; - auto int print_failure (grub_test_failure_t item); int print_failure (grub_test_failure_t item) { @@ -133,18 +131,16 @@ grub_test_run (const char *name) return 0; } - test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list), name); - if (!test) - return GRUB_ERR_FILE_NOT_FOUND; - test->main (); - if (!failure_list) - return GRUB_ERR_NONE; - grub_test_printf ("%s:\n", test->name); grub_list_iterate (GRUB_AS_LIST (failure_list), (grub_list_hook_t) print_failure); + if (!failure_list) + grub_test_printf ("%s: PASS\n", test->name); + else + grub_test_printf ("%s: FAIL\n", test->name); + free_failures (); - return GRUB_ERR_TEST_FAILURE; + return GRUB_ERR_NONE; } diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index 15bb0da5d..59931898a 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -56,7 +56,7 @@ main (int argc __attribute__ ((unused)), auto int run_test (grub_test_t test); int run_test (grub_test_t test) { - status = grub_test_run (test->name) ? : status; + status = grub_test_run (test) ? : status; return 0; } From 1afc27d06b9030b83f3398edd13344d8fbe81c24 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 8 Jan 2010 21:28:57 +0530 Subject: [PATCH 14/31] added changelog file --- ChangeLog.unit-testing-framework | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ChangeLog.unit-testing-framework diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework new file mode 100644 index 000000000..a451108c4 --- /dev/null +++ b/ChangeLog.unit-testing-framework @@ -0,0 +1,26 @@ +2010-01-08 BVK Chaitanya + + Unit testing framework for GRUB. + + * Makefile.in: Test framework build rules for 'make check'. + * conf/tests.rmk: Build rules for individual tests and framework. + + * include/grub/test.h: Header file for whitebox tests. + * tests/lib/functional_test.c: Framework support for whitebox + functional tests. + * tests/lib/test.c: Common whitebox testing code for unit and + functional tests. + * tests/lib/unit_test.c: Framework support for whitebox unit + tests. + + * tests/util/grub-shell-tester.in: Support utility for grub-script + tests. + * tests/util/grub-shell.in: Utility to execute grub-script + commands in a Qemu instance. + + * tests/example_functional_test.c: Example whitebox functional + test. + * tests/example_grub_script_test.in: Example grub-script test. + * tests/example_scripted_test.in: Example scripted test. + * tests/example_unit_test.c: Example whitebox unit test. + From 5cc318eb3532f333dc324627dc977fe2f5bef40a Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 8 Jan 2010 22:06:46 +0530 Subject: [PATCH 15/31] replaced __func__ with simpler __FUNCTION__ macro --- include/grub/test.h | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/include/grub/test.h b/include/grub/test.h index 4b028371b..b4851bbf6 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -35,22 +35,10 @@ void grub_test_nonzero (int cond, const char *file, const char *fmt, ...) __attribute__ ((format (printf, 5, 6))); -#ifdef __STDC_VERSION__ -#if __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 -# define __func__ __FUNCTION__ -# else -# define __func__ "" -# endif -#endif -#else -#define __func__ "" -#endif - /* Macro to fill in location details and an optional error message. */ -#define grub_test_assert(cond, ...) \ - grub_test_nonzero(cond, __FILE__, __func__, __LINE__, \ - ## __VA_ARGS__, \ +#define grub_test_assert(cond, ...) \ + grub_test_nonzero(cond, __FILE__, __FUNCTION__, __LINE__, \ + ## __VA_ARGS__, \ "assert failed: %s", #cond) /* Macro to define a unit test. */ From afdc9ad0065bfa84b2d9a981c038a89aaba67f14 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 12 Jan 2010 09:00:55 +0530 Subject: [PATCH 16/31] fixed an error message --- ChangeLog.unit-testing-framework | 4 ++++ tests/util/grub-shell-tester.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index a451108c4..5fd7a2f28 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,3 +1,7 @@ +2010-01-12 BVK Chaitanya + + * tests/util/grub-shell-tester.in: Fix error message. + 2010-01-08 BVK Chaitanya Unit testing framework for GRUB. diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in index 18f5e79b7..6ed4ebcac 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -98,7 +98,7 @@ bash ${source} >${outfile2} if ! diff -q ${outfile1} ${outfile2} >/dev/null then - echo "$1: GRUB and BASH outputs (${outfile1}, ${outfile2}) did not match" + echo "${source}: GRUB and BASH outputs did not match (see diff -u ${outfile1} ${outfile2})" status=1 else rm -f ${outfile1} ${outfile2} From 350285caaefc8384ca73263fe42f89f66ec28779 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 12 Jan 2010 09:23:24 +0530 Subject: [PATCH 17/31] removed unnecessary EXPORT_* macro usage --- ChangeLog.unit-testing-framework | 2 ++ include/grub/test.h | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index 5fd7a2f28..973a7c756 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,5 +1,7 @@ 2010-01-12 BVK Chaitanya + * include/grub/test.h: Removed EXPORT_* usage. + * tests/util/grub-shell-tester.in: Fix error message. 2010-01-08 BVK Chaitanya diff --git a/include/grub/test.h b/include/grub/test.h index b4851bbf6..bd5b7d806 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -20,11 +20,10 @@ struct grub_test }; typedef struct grub_test *grub_test_t; -extern grub_test_t EXPORT_VAR (grub_test_list); +extern grub_test_t grub_test_list; -void EXPORT_FUNC (grub_test_register) (const char *name, void (*test) (void)); - -void EXPORT_FUNC (grub_test_unregister) (const char *name); +void grub_test_register (const char *name, void (*test) (void)); +void grub_test_unregister (const char *name); /* Execute a test and print results. */ int grub_test_run (grub_test_t test); From c5431d4029cfe61dcdd3f28a3bd6d9f22a0b80ea Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 12 Jan 2010 10:16:17 +0530 Subject: [PATCH 18/31] build tests on make, but run on make check --- ChangeLog.unit-testing-framework | 5 ++++- Makefile.in | 21 +++++++++------------ conf/tests.rmk | 31 ++++++++++++++++++------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index 973a7c756..620ac80cf 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,6 +1,9 @@ 2010-01-12 BVK Chaitanya - * include/grub/test.h: Removed EXPORT_* usage. + * conf/tests.rmk: Build tests on make. + * Makefile.in (check): Use new variables. + + * include/grub/test.h: Remove EXPORT_* usage. * tests/util/grub-shell-tester.in: Fix error message. diff --git a/Makefile.in b/Makefile.in index 567571897..45c6f3e45 100644 --- a/Makefile.in +++ b/Makefile.in @@ -460,15 +460,18 @@ distcheck: dist @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' -TESTS = $(check_UTILITIES) $(check_SCRIPTS) $(check_MODULES) -$(TESTS): $(test_framework_SCRIPTS) $(test_framework_MODULES) - -check: all $(TESTS) - @list="$(check_UTILITIES)"; \ +check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS) + @list="$(UNIT_TESTS)"; \ for file in $$list; do \ $(builddir)/$$file; \ done - @list="$(check_SCRIPTS)"; \ + @list="$(FUNCTIONAL_TESTS)"; \ + for file in $$list; do \ + mod=`basename $$file .mod`; \ + echo "insmod functional_test; insmod $$mod; functional_test" \ + | $(builddir)/grub-shell; \ + done + @list="$(SCRIPTED_TESTS)"; \ for file in $$list; do \ echo "$$file:"; \ if $(builddir)/$$file; then \ @@ -477,12 +480,6 @@ check: all $(TESTS) echo "$$file: FAIL"; \ fi; \ done - @list="$(check_MODULES)"; \ - for file in $$list; do \ - mod=`basename $$file .mod`; \ - echo "insmod functional_test; insmod $$mod; functional_test" \ - | $(builddir)/grub-shell; \ - done .SUFFIX: .SUFFIX: .c .o .S .d diff --git a/conf/tests.rmk b/conf/tests.rmk index c35ea0baa..e894323ae 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -4,38 +4,43 @@ grub-shell: tests/util/grub-shell.in config.status ./config.status --file=$@:$< chmod +x $@ -test_framework_SCRIPTS += grub-shell +bin_SCRIPTS += grub-shell CLEANFILES += grub-shell # For grub-shell-tester grub-shell-tester: tests/util/grub-shell-tester.in config.status ./config.status --file=$@:$< chmod +x $@ -test_framework_SCRIPTS += grub-shell-tester +bin_SCRIPTS += grub-shell-tester CLEANFILES += grub-shell-tester -test_framework_MODULES += functional_test.mod +pkglib_MODULES += functional_test.mod functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c functional_test_mod_CFLAGS = $(COMMON_CFLAGS) functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) -# Unit tests - -check_UTILITIES += example_unit_test +# Rules for unit tests +bin_UTILITIES += example_unit_test example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c example_unit_test_CFLAGS = -Wno-format -# Functional tests - -check_MODULES += example_functional_test.mod +# Rules for functional tests +pkglib_MODULES += example_functional_test.mod example_functional_test_mod_SOURCES = tests/example_functional_test.c example_functional_test_mod_CFLAGS = -Wno-format $(COMMON_CFLAGS) example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) -# Scripted tests - -check_SCRIPTS += example_scripted_test +# Rules for scripted tests +bin_SCRIPTS += example_scripted_test example_scripted_test_SOURCES = tests/example_scripted_test.in -check_SCRIPTS += example_grub_script_test +bin_SCRIPTS += example_grub_script_test example_grub_script_test_SOURCES = tests/example_grub_script_test.in + + +# List of tests to execute on "make check" + +SCRIPTED_TESTS = example_scripted_test +SCRIPTED_TESTS += example_grub_script_test +UNIT_TESTS = example_unit_test +FUNCTIONAL_TESTS = example_functional_test.mod From afafb37e9b56158454aeacc6072b368b8198e55f Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 12 Jan 2010 10:54:37 +0530 Subject: [PATCH 19/31] added boot device selection to grub-shell --- ChangeLog.unit-testing-framework | 2 ++ tests/util/grub-shell.in | 40 ++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index 620ac80cf..8641d09ee 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,5 +1,7 @@ 2010-01-12 BVK Chaitanya + * tests/util/grub-shell.in: New --boot option. + * conf/tests.rmk: Build tests on make. * Makefile.in (check): Use new variables. diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index c1b2ef258..b103872ba 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -42,6 +42,7 @@ Run GRUB script in a Qemu instance. -h, --help print this message and exit -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-opts=OPTIONS extra options to pass to Qemu instance @@ -67,11 +68,20 @@ for option in "$@"; do --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; + else + echo "Unrecognized boot method \`$dev'" 1>&2 + usage + exit 1 + fi ;; -*) echo "Unrecognized option \`$option'" 1>&2 usage - exit 1 - ;; + exit 1 ;; *) if [ "x${source}" != x ] ; then echo "too many parameters at the end" 1>&2 @@ -83,11 +93,15 @@ for option in "$@"; do done if [ "x${source}" = x ] ; then - tmpfile=`mktemp` - while read; do - echo $REPLY >> ${tmpfile} - done - source=${tmpfile} + tmpfile=`mktemp` + while read; do + echo $REPLY >> ${tmpfile} + done + source=${tmpfile} +fi + +if [ "x${bootdev}" = x ] ; then + bootdev=c # default is boot as disk image fi cfgfile=`mktemp` @@ -101,7 +115,7 @@ EOF for mod in ${modules} do - echo "insmod ${mod}" >> ${cfgfile} + echo "insmod ${mod}" >> ${cfgfile} done cat <>${cfgfile} @@ -114,12 +128,18 @@ grub-mkrescue --output=${isofile} --override-directory=${builddir} \ /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ >/dev/null 2>&1 +hdafile=`mktemp` +cp ${isofile} ${hdafile} + +fdafile=`mktemp` +cp ${isofile} ${fdafile} + outfile=`mktemp` -qemu ${qemuopts} -nographic -serial stdio -cdrom ${isofile} -boot d | tr -d "\r" >${outfile} +qemu ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} cat $outfile -rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} +rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} ${hdafile} ${fdafile} exit 0 From 4d362fde5883655a9a0d5a56068e16d0e81bf9be Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 12 Jan 2010 15:49:40 +0530 Subject: [PATCH 20/31] build only functional tests on make --- ChangeLog.unit-testing-framework | 2 +- conf/tests.rmk | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index 8641d09ee..aa4d4fd03 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -2,7 +2,7 @@ * tests/util/grub-shell.in: New --boot option. - * conf/tests.rmk: Build tests on make. + * conf/tests.rmk: Build functional tests on make. * Makefile.in (check): Use new variables. * include/grub/test.h: Remove EXPORT_* usage. diff --git a/conf/tests.rmk b/conf/tests.rmk index e894323ae..18b23ff5a 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -4,14 +4,14 @@ grub-shell: tests/util/grub-shell.in config.status ./config.status --file=$@:$< chmod +x $@ -bin_SCRIPTS += grub-shell +check_SCRIPTS += grub-shell CLEANFILES += grub-shell # For grub-shell-tester grub-shell-tester: tests/util/grub-shell-tester.in config.status ./config.status --file=$@:$< chmod +x $@ -bin_SCRIPTS += grub-shell-tester +check_SCRIPTS += grub-shell-tester CLEANFILES += grub-shell-tester pkglib_MODULES += functional_test.mod @@ -20,7 +20,7 @@ functional_test_mod_CFLAGS = $(COMMON_CFLAGS) functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) # Rules for unit tests -bin_UTILITIES += example_unit_test +check_UTILITIES += example_unit_test example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c example_unit_test_CFLAGS = -Wno-format @@ -31,16 +31,20 @@ example_functional_test_mod_CFLAGS = -Wno-format $(COMMON_CFLAGS) example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS) # Rules for scripted tests -bin_SCRIPTS += example_scripted_test +check_SCRIPTS += example_scripted_test example_scripted_test_SOURCES = tests/example_scripted_test.in -bin_SCRIPTS += example_grub_script_test +check_SCRIPTS += example_grub_script_test example_grub_script_test_SOURCES = tests/example_grub_script_test.in # List of tests to execute on "make check" - SCRIPTED_TESTS = example_scripted_test SCRIPTED_TESTS += example_grub_script_test UNIT_TESTS = example_unit_test FUNCTIONAL_TESTS = example_functional_test.mod + +# dependencies between tests and testing-tools +$(SCRIPTED_TESTS): grub-shell grub-shell-tester +$(FUNCTIONAL_TESTS): functional_test.mod + From 0b8891c276ae3b1f3d93ff881a13a405d6471269 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 14 Jan 2010 17:17:51 +0530 Subject: [PATCH 21/31] removed unnecessary grub_test_* wrappers --- ChangeLog.unit-testing-framework | 20 +++++++++++++++ include/grub/test.h | 8 ------ tests/lib/functional_test.c | 37 --------------------------- tests/lib/test.c | 44 ++++++++++++++++---------------- tests/lib/unit_test.c | 43 +++++-------------------------- 5 files changed, 48 insertions(+), 104 deletions(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index aa4d4fd03..6643e9989 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,3 +1,23 @@ +2010-01-14 BVK Chaitanya + + Removed unnecessary grub_test_* wrappers. + + * tests/lib/unit_test.c (grub_test_malloc): Removed. + (grub_test_vsprintf): Removed. + (grub_test_strdup): Removed. + (grub_test_printf): Removed. + (grub_test_free): Replaced with.... + (grub_free): ...new wrapper. + * tests/lib/functional_test.c (grub_test_malloc): Removed. + (grub_test_free): Removed. + (grub_test_vsprintf): Removed. + (grub_test_strdup): Removed. + (grub_test_printf): Removed. + * tests/lib/test.c: Replaced + grub_test_{malloc,free,strdup,printf,vsprintf} methods with + grub_{malloc,free,strdup,printf,vsprintf} methods. + * include/grub/test.h: Removed prototypes for the above. + 2010-01-12 BVK Chaitanya * tests/util/grub-shell.in: New --boot option. diff --git a/include/grub/test.h b/include/grub/test.h index bd5b7d806..544e1c817 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -64,12 +64,4 @@ void grub_test_nonzero (int cond, const char *file, grub_test_unregister (name); \ } -/* Functions that are defined differently for unit and functional tests. */ -void *grub_test_malloc (grub_size_t size); -void grub_test_free (void *ptr); -char *grub_test_strdup (const char *str); -int grub_test_vsprintf (char *str, const char *fmt, va_list args); -int grub_test_printf (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); - #endif /* ! GRUB_TEST_HEADER */ diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 2e03dabc4..8ad034503 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -3,43 +3,6 @@ #include #include -void * -grub_test_malloc (grub_size_t size) -{ - return grub_malloc (size); -} - -void -grub_test_free (void *ptr) -{ - grub_free (ptr); -} - -int -grub_test_vsprintf (char *str, const char *fmt, va_list args) -{ - return grub_vsprintf (str, fmt, args); -} - -char * -grub_test_strdup (const char *str) -{ - return grub_strdup (str); -} - -int -grub_test_printf (const char *fmt, ...) -{ - int r; - va_list ap; - - va_start (ap, fmt); - r = grub_vprintf (fmt, ap); - va_end (ap); - - return r; -} - static grub_err_t grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/tests/lib/test.c b/tests/lib/test.c index 562c2f6e4..aba2f4415 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -1,3 +1,4 @@ +#include #include #include @@ -31,16 +32,16 @@ add_failure (const char *file, char buf[1024]; grub_test_failure_t failure; - failure = (grub_test_failure_t) grub_test_malloc (sizeof (*failure)); + failure = (grub_test_failure_t) grub_malloc (sizeof (*failure)); if (!failure) return; - grub_test_vsprintf (buf, fmt, args); + grub_vsprintf (buf, fmt, args); - failure->file = grub_test_strdup (file ? : ""); - failure->funp = grub_test_strdup (funp ? : ""); + failure->file = grub_strdup (file ? : ""); + failure->funp = grub_strdup (funp ? : ""); failure->line = line; - failure->message = grub_test_strdup (buf); + failure->message = grub_strdup (buf); grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure)); } @@ -53,15 +54,15 @@ free_failures (void) while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0) { if (item->message) - grub_test_free (item->message); + grub_free (item->message); if (item->funp) - grub_test_free (item->funp); + grub_free (item->funp); if (item->file) - grub_test_free (item->file); + grub_free (item->file); - grub_test_free (item); + grub_free (item); } failure_list = 0; } @@ -86,11 +87,11 @@ grub_test_register (const char *name, void (*test_main) (void)) { grub_test_t test; - test = (grub_test_t) grub_test_malloc (sizeof (*test)); + test = (grub_test_t) grub_malloc (sizeof (*test)); if (!test) return; - test->name = grub_test_strdup (name); + test->name = grub_strdup (name); test->main = test_main; grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test)); @@ -106,13 +107,12 @@ grub_test_unregister (const char *name) if (test) { - grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), - GRUB_AS_LIST (test)); + grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test)); if (test->name) - grub_test_free (test->name); + grub_free (test->name); - grub_test_free (test); + grub_free (test); } } @@ -124,22 +124,22 @@ grub_test_run (grub_test_t test) { grub_test_failure_t failure = (grub_test_failure_t) item; - grub_test_printf (" %s:%s:%u: %s\n", - (failure->file ? : ""), - (failure->funp ? : ""), - failure->line, (failure->message ? : "")); + grub_printf (" %s:%s:%u: %s\n", + (failure->file ? : ""), + (failure->funp ? : ""), + failure->line, (failure->message ? : "")); return 0; } test->main (); - grub_test_printf ("%s:\n", test->name); + grub_printf ("%s:\n", test->name); grub_list_iterate (GRUB_AS_LIST (failure_list), (grub_list_hook_t) print_failure); if (!failure_list) - grub_test_printf ("%s: PASS\n", test->name); + grub_printf ("%s: PASS\n", test->name); else - grub_test_printf ("%s: FAIL\n", test->name); + grub_printf ("%s: FAIL\n", test->name); free_failures (); return GRUB_ERR_NONE; diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index 59931898a..2ca011433 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -7,43 +7,6 @@ #include #include -void * -grub_test_malloc (grub_size_t size) -{ - return malloc (size); -} - -void -grub_test_free (void *ptr) -{ - free (ptr); -} - -int -grub_test_vsprintf (char *str, const char *fmt, va_list args) -{ - return vsprintf (str, fmt, args); -} - -char * -grub_test_strdup (const char *str) -{ - return strdup (str); -} - -int -grub_test_printf (const char *fmt, ...) -{ - int r; - va_list ap; - - va_start (ap, fmt); - r = vprintf (fmt, ap); - va_end (ap); - - return r; -} - int main (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) @@ -70,6 +33,12 @@ main (int argc __attribute__ ((unused)), /* Other misc. functions necessary for successful linking. */ +void +grub_free (void *ptr) +{ + free (ptr); +} + char * grub_env_get (const char *name __attribute__ ((unused))) { From 2285d4642a6a6177d6c9d9daa2658b347ba183c2 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 14 Jan 2010 18:39:12 +0530 Subject: [PATCH 22/31] use qemu-system-i386 instead of qemu --- ChangeLog.unit-testing-framework | 4 ++++ tests/util/grub-shell.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.unit-testing-framework b/ChangeLog.unit-testing-framework index 6643e9989..ba5ba8cc5 100644 --- a/ChangeLog.unit-testing-framework +++ b/ChangeLog.unit-testing-framework @@ -1,5 +1,9 @@ 2010-01-14 BVK Chaitanya + Use qemu-system-i386 instead of qemu. + + * tests/util/grub-shell.in (outfile): Use qemu-system-i386. + Removed unnecessary grub_test_* wrappers. * tests/lib/unit_test.c (grub_test_malloc): Removed. diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index b103872ba..e6fef8313 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -135,7 +135,7 @@ fdafile=`mktemp` cp ${isofile} ${fdafile} outfile=`mktemp` -qemu ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} +qemu-system-i386 ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} cat $outfile From 6d1e76899b216af8e83516a93231bafc9570edf7 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 14 Jan 2010 14:06:36 +0000 Subject: [PATCH 23/31] fix changelog dates --- ChangeLog.savedefault | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog.savedefault b/ChangeLog.savedefault index 722769776..d68d75eab 100644 --- a/ChangeLog.savedefault +++ b/ChangeLog.savedefault @@ -1,18 +1,18 @@ -2010-10-05 Jordan Uggla -2010-10-05 Colin Watson +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson * util/grub-reboot.in: Make sure prev_saved_entry always gets a non-empty value. -2010-10-05 Jordan Uggla -2010-10-05 Colin Watson +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson * util/grub.d/00_header.in: Define a "savedefault" function for use in menu entries. * util/grub-mkconfig_lib.in (save_default_entry): Use it. -2010-10-05 Jordan Uggla -2010-10-05 Colin Watson +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson * util/grub-mkconfig_lib.in (save_default_entry): Only set saved_entry if boot_once is unset. From 0a46429a55ee7701dfb450ac648b1d1a07e6287c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 14 Jan 2010 21:08:31 +0000 Subject: [PATCH 24/31] 2010-01-14 Robert Millan * include/grub/i386/loader.h (grub_linux16_boot): Renamed to ... (grub_linux16_real_boot): ... this. * kern/i386/loader.S: Likewise. * loader/i386/pc/linux.c: Include `' and `'. (grub_linux16_boot): New function. Switches to text mode and calls grub_linux16_real_boot(). * loader/i386/bsd.c: Include `'. (grub_freebsd_boot, grub_openbsd_boot, grub_netbsd_boot): Switch to text mode before calling grub_unix_real_boot(). * loader/i386/multiboot.c: Include `'. (grub_multiboot_boot): Switch to text mode before calling grub_relocator32_boot(). * loader/i386/pc/chainloader.c: Include `'. (grub_chainloader_boot): Switch to text mode before calling grub_chainloader_real_boot(). --- ChangeLog | 21 +++++++++++++++++++++ include/grub/i386/loader.h | 4 ++-- kern/i386/loader.S | 2 +- loader/i386/bsd.c | 10 ++++++++-- loader/i386/multiboot.c | 5 ++++- loader/i386/pc/chainloader.c | 4 +++- loader/i386/pc/linux.c | 14 +++++++++++++- 7 files changed, 52 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0fa70ecf6..652cc145a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-01-14 Robert Millan + + * include/grub/i386/loader.h (grub_linux16_boot): Renamed to ... + (grub_linux16_real_boot): ... this. + * kern/i386/loader.S: Likewise. + * loader/i386/pc/linux.c: Include `' and `'. + (grub_linux16_boot): New function. Switches to text mode and calls + grub_linux16_real_boot(). + + * loader/i386/bsd.c: Include `'. + (grub_freebsd_boot, grub_openbsd_boot, grub_netbsd_boot): Switch to + text mode before calling grub_unix_real_boot(). + + * loader/i386/multiboot.c: Include `'. + (grub_multiboot_boot): Switch to text mode before calling + grub_relocator32_boot(). + + * loader/i386/pc/chainloader.c: Include `'. + (grub_chainloader_boot): Switch to text mode before calling + grub_chainloader_real_boot(). + 2010-01-05 Jordan Uggla 2010-01-05 Colin Watson diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h index 0df5f757f..05954b6db 100644 --- a/include/grub/i386/loader.h +++ b/include/grub/i386/loader.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004,2007,2008,2009,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 @@ -31,7 +31,7 @@ extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size); extern char *EXPORT_VAR(grub_linux_tmp_addr); extern char *EXPORT_VAR(grub_linux_real_addr); extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage); -grub_err_t EXPORT_FUNC(grub_linux16_boot) (void); +grub_err_t EXPORT_FUNC(grub_linux16_real_boot) (void); #endif #endif /* ! GRUB_LOADER_CPU_HEADER */ diff --git a/kern/i386/loader.S b/kern/i386/loader.S index 3e9c71327..ed57c43ca 100644 --- a/kern/i386/loader.S +++ b/kern/i386/loader.S @@ -59,7 +59,7 @@ VARIABLE(grub_linux_real_addr) VARIABLE(grub_linux_is_bzimage) .long 0 -FUNCTION(grub_linux16_boot) +FUNCTION(grub_linux16_real_boot) /* Must be done before zImage copy. */ call EXT_C(grub_dl_unload_all) diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 0785a3fc1..49be758c6 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Copyright (C) 2008,2009,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 @@ -35,7 +35,7 @@ #include #include #include - +#include #ifdef GRUB_MACHINE_PCBIOS #include #endif @@ -509,6 +509,8 @@ grub_freebsd_boot (void) bi.bi_kernend = kern_end; + grub_video_set_mode ("text", NULL); + if (is_64bit) { grub_uint32_t *gdt; @@ -617,6 +619,8 @@ grub_openbsd_boot (void) pa->ba_type = OPENBSD_BOOTARG_END; pa++; + grub_video_set_mode ("text", NULL); + grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER, 0, (grub_uint32_t) (grub_mmap_get_upper () >> 10), (grub_uint32_t) (grub_mmap_get_lower () >> 10), @@ -713,6 +717,8 @@ grub_netbsd_boot (void) bootinfo->bi_data[0] = mmap; } + grub_video_set_mode ("text", NULL); + grub_unix_real_boot (entry, bootflags, 0, bootinfo, 0, (grub_uint32_t) (grub_mmap_get_upper () >> 10), (grub_uint32_t) (grub_mmap_get_lower () >> 10)); diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 5dc304117..4360e8a2c 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -1,7 +1,7 @@ /* multiboot.c - boot a multiboot OS image. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,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 @@ -46,6 +46,7 @@ #include #include #include +#include extern grub_dl_t my_mod; static grub_size_t code_size, alloc_mbi; @@ -89,6 +90,8 @@ grub_multiboot_boot (void) if (err) return err; + grub_video_set_mode ("text", NULL); + grub_relocator32_boot (grub_multiboot_payload_orig, grub_multiboot_payload_dest, state); diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c index 81cfddac1..e28a4e7f9 100644 --- a/loader/i386/pc/chainloader.c +++ b/loader/i386/pc/chainloader.c @@ -1,7 +1,7 @@ /* chainloader.c - boot another boot loader */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2004,2007,2009 Free Software Foundation, Inc. + * Copyright (C) 2002,2004,2007,2009,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 @@ -33,6 +33,7 @@ #include #include #include +#include static grub_dl_t my_mod; static int boot_drive; @@ -41,6 +42,7 @@ static void *boot_part_addr; static grub_err_t grub_chainloader_boot (void) { + grub_video_set_mode ("text", NULL); grub_chainloader_real_boot (boot_drive, boot_part_addr); /* Never reach here. */ diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c index 24bb39555..96973adb9 100644 --- a/loader/i386/pc/linux.c +++ b/loader/i386/pc/linux.c @@ -1,7 +1,7 @@ /* linux.c - boot Linux zImage or bzImage */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,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 @@ -31,6 +31,8 @@ #include #include #include +#include +#include #define GRUB_LINUX_CL_OFFSET 0x9000 #define GRUB_LINUX_CL_END_OFFSET 0x90FF @@ -48,6 +50,16 @@ grub_linux_unload (void) return GRUB_ERR_NONE; } +static grub_err_t +grub_linux16_boot (void) +{ + grub_video_set_mode ("text", NULL); + grub_linux16_real_boot (); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + static grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) From ba2f6848e06aa654bf8d6df02d5737aca73035b9 Mon Sep 17 00:00:00 2001 From: carles Date: Thu, 14 Jan 2010 22:31:06 +0000 Subject: [PATCH 25/31] 2010-01-14 Carles Pina i Estany * gettext/gettext.c (grub_gettext_translate): Push and pop grub_errno. (grub_gettext_delete_list): Change comment style. * kern/err.c (grub_error): Gettextizze. (grub_fatal): Gettextizze. --- ChangeLog | 8 ++++++++ gettext/gettext.c | 17 ++++++++++++++--- kern/err.c | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 652cc145a..17083d1b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-01-14 Carles Pina i Estany + + * gettext/gettext.c (grub_gettext_translate): Push and pop + grub_errno. + (grub_gettext_delete_list): Change comment style. + * kern/err.c (grub_error): Gettextizze. + (grub_fatal): Gettextizze. + 2010-01-14 Robert Millan * include/grub/i386/loader.h (grub_linux16_boot): Renamed to ... diff --git a/gettext/gettext.c b/gettext/gettext.c index 6fa6271f2..83497b7f6 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -148,14 +148,24 @@ grub_gettext_translate (const char *orig) struct grub_gettext_msg *cur; + /* Make sure we can use grub_gettext_translate for error messages. Push + active error message to error stack and reset error message. */ + grub_error_push (); + cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list), orig); if (cur) - return cur->translated; + { + grub_error_pop (); + return cur->translated; + } if (fd_mo == 0) - return orig; + { + grub_error_pop (); + return orig; + } min = 0; max = grub_gettext_max; @@ -205,6 +215,7 @@ grub_gettext_translate (const char *orig) grub_errno = GRUB_ERR_NONE; } + grub_error_pop (); return ret; } @@ -308,7 +319,7 @@ grub_gettext_delete_list (void) char *original = (char *) ((struct grub_gettext_msg *) item)->name; grub_free (original); - // Don't delete the translated message because could be in use. + /* Don't delete the translated message because could be in use. */ } } diff --git a/kern/err.c b/kern/err.c index 02d7d879f..1a881db25 100644 --- a/kern/err.c +++ b/kern/err.c @@ -45,7 +45,7 @@ grub_error (grub_err_t n, const char *fmt, ...) grub_errno = n; va_start (ap, fmt); - grub_vsprintf (grub_errmsg, fmt, ap); + grub_vsprintf (grub_errmsg, _(fmt), ap); va_end (ap); return n; @@ -57,7 +57,7 @@ grub_fatal (const char *fmt, ...) va_list ap; va_start (ap, fmt); - grub_vprintf (fmt, ap); + grub_vprintf (_(fmt), ap); va_end (ap); grub_abort (); From c586fbb2064081efec63333dee9d73999e2c6f42 Mon Sep 17 00:00:00 2001 From: carles Date: Thu, 14 Jan 2010 23:04:49 +0000 Subject: [PATCH 26/31] 2001-01-14 Carles Pina i Estany * loader/i386/pc/chainloader.c: Include `'. --- ChangeLog | 4 ++++ loader/i386/pc/chainloader.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 17083d1b1..fe54d5c3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2001-01-14 Carles Pina i Estany + + * loader/i386/pc/chainloader.c: Include `'. + 2010-01-14 Carles Pina i Estany * gettext/gettext.c (grub_gettext_translate): Push and pop diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c index e28a4e7f9..1d6de1de7 100644 --- a/loader/i386/pc/chainloader.c +++ b/loader/i386/pc/chainloader.c @@ -34,6 +34,7 @@ #include #include #include +#include static grub_dl_t my_mod; static int boot_drive; From cca15b52c11e5f469f2fce8ce61ff1ded3b20137 Mon Sep 17 00:00:00 2001 From: carles Date: Thu, 14 Jan 2010 23:07:44 +0000 Subject: [PATCH 27/31] 2010-01-14 Carles Pina i Estany * normal/cmdline.c (print_completion): Gettextizze. --- ChangeLog | 4 ++++ normal/cmdline.c | 19 +++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe54d5c3a..0478d6cb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-14 Carles Pina i Estany + + * normal/cmdline.c (print_completion): Gettextizze. + 2001-01-14 Carles Pina i Estany * loader/i386/pc/chainloader.c: Include `'. diff --git a/normal/cmdline.c b/normal/cmdline.c index 429c84be7..bcffffeab 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -166,31 +166,30 @@ print_completion (const char *item, grub_completion_type_t type, int count) if (count == 0) { /* If this is the first time, print a label. */ - const char *what; - + + grub_puts (""); switch (type) { case GRUB_COMPLETION_TYPE_COMMAND: - what = "commands"; + grub_puts_ (N_("Possible commands are:")); break; case GRUB_COMPLETION_TYPE_DEVICE: - what = "devices"; + grub_puts_ (N_("Possible devices are:")); break; case GRUB_COMPLETION_TYPE_FILE: - what = "files"; + grub_puts_ (N_("Possible files are:")); break; case GRUB_COMPLETION_TYPE_PARTITION: - what = "partitions"; + grub_puts_ (N_("Possible partitions are:")); break; case GRUB_COMPLETION_TYPE_ARGUMENT: - what = "arguments"; + grub_puts_ (N_("Possible arguments are:")); break; default: - what = "things"; + grub_puts_ (N_("Possible things are:")); break; } - - grub_printf ("\nPossible %s are:\n", what); + grub_puts (""); } if (type == GRUB_COMPLETION_TYPE_PARTITION) From 5c71db1b9ba1aee67cdee92cb2b7a71c9aadbf46 Mon Sep 17 00:00:00 2001 From: carles Date: Thu, 14 Jan 2010 23:20:13 +0000 Subject: [PATCH 28/31] 2010-01-14 Carles Pina i Estany * util/grub.d/30_os-prober.in: Use `set var=val' rather than plain `var=val'. --- ChangeLog | 5 +++++ util/grub.d/30_os-prober.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0478d6cb1..e2d8a81f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-14 Carles Pina i Estany + + * util/grub.d/30_os-prober.in: Use `set var=val' rather than plain + `var=val'. + 2010-01-14 Carles Pina i Estany * normal/cmdline.c (print_completion): Gettextizze. diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index da6eea6b6..edef37e66 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -45,10 +45,10 @@ EOF prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" cat << EOF insmod ${GRUB_VIDEO_BACKEND} - do_resume=0 + set do_resume=0 if [ /var/vm/sleepimage -nt10 / ]; then if xnu_resume /var/vm/sleepimage; then - do_resume=1 + set do_resume=1 fi fi if [ \$do_resume == 0 ]; then From 0d90e8a6fb31c9d6b9200b3a34fa3b2ffa38214d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Jan 2010 16:11:18 +0100 Subject: [PATCH 29/31] 2010-01-15 Vladimir Serbinenko Video driver ids. * include/grub/video.h (grub_video_driver_id): New type. (grub_video_adapter): New member 'id'. All users updated. (grub_video_get_driver_id): New proto. * video/video.c (grub_video_get_driver_id): New function. --- ChangeLog | 9 +++++++++ include/grub/video.h | 12 ++++++++++++ video/efi_gop.c | 1 + video/efi_uga.c | 1 + video/i386/pc/vbe.c | 1 + video/video.c | 8 ++++++++ 6 files changed, 32 insertions(+) diff --git a/ChangeLog b/ChangeLog index e2d8a81f5..dc123888b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-01-15 Vladimir Serbinenko + + Video driver ids. + + * include/grub/video.h (grub_video_driver_id): New type. + (grub_video_adapter): New member 'id'. All users updated. + (grub_video_get_driver_id): New proto. + * video/video.c (grub_video_get_driver_id): New function. + 2010-01-14 Carles Pina i Estany * util/grub.d/30_os-prober.in: Use `set var=val' rather than plain diff --git a/include/grub/video.h b/include/grub/video.h index 4145db465..437c98eb9 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -159,10 +159,19 @@ struct grub_video_palette_data grub_uint8_t a; /* Reserved bits value (0-255). */ }; +typedef enum grub_video_driver_id + { + GRUB_VIDEO_DRIVER_NONE, + GRUB_VIDEO_DRIVER_VBE, + GRUB_VIDEO_DRIVER_EFI_UGA, + GRUB_VIDEO_DRIVER_EFI_GOP + } grub_video_driver_id_t; + struct grub_video_adapter { /* The video adapter name. */ const char *name; + grub_video_driver_id_t id; /* Initialize the video adapter. */ grub_err_t (*init) (void); @@ -310,4 +319,7 @@ grub_err_t grub_video_set_mode (const char *modestring, int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p, struct grub_video_mode_info *mode_info)); +grub_video_driver_id_t +grub_video_get_driver_id (void); + #endif /* ! GRUB_VIDEO_HEADER */ diff --git a/video/efi_gop.c b/video/efi_gop.c index 30863c1ed..13ef0ddae 100644 --- a/video/efi_gop.c +++ b/video/efi_gop.c @@ -353,6 +353,7 @@ grub_video_gop_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_gop_adapter = { .name = "EFI GOP driver", + .id = GRUB_VIDEO_DRIVER_EFI_GOP, .init = grub_video_gop_init, .fini = grub_video_gop_fini, diff --git a/video/efi_uga.c b/video/efi_uga.c index 12ca35cde..7ef7594cc 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -300,6 +300,7 @@ grub_video_uga_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_uga_adapter = { .name = "EFI UGA driver", + .id = GRUB_VIDEO_DRIVER_EFI_UGA, .init = grub_video_uga_init, .fini = grub_video_uga_fini, diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 17d9b3282..918bab0b0 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -557,6 +557,7 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_vbe_adapter = { .name = "VESA BIOS Extension Video Driver", + .id = GRUB_VIDEO_DRIVER_VBE, .init = grub_video_vbe_init, .fini = grub_video_vbe_fini, diff --git a/video/video.c b/video/video.c index 682bebcbf..e678c2982 100644 --- a/video/video.c +++ b/video/video.c @@ -93,6 +93,14 @@ grub_video_get_info (struct grub_video_mode_info *mode_info) return grub_video_adapter_active->get_info (mode_info); } +grub_video_driver_id_t +grub_video_get_driver_id (void) +{ + if (! grub_video_adapter_active) + return GRUB_VIDEO_DRIVER_NONE; + return grub_video_adapter_active->id; +} + /* Get information about active video mode. */ grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info, From 884ade56545bc515a13307e24a9694b0ef357a8a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Jan 2010 16:30:57 +0100 Subject: [PATCH 30/31] 2010-01-15 Vladimir Serbinenko Video multiboot support. * include/grub/multiboot.h (grub_multiboot_set_accepts_video): New prototype. * include/multiboot.h: Resynced with multiboot specification. * include/multiboot2.h: Likewise. * loader/i386/multiboot.c (UNSUPPORTED_FLAGS): Support video flags. (grub_multiboot): Parse MULTIBOOT_VIDEO_MODE fields. * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): New constant. (HAS_VGA_TEXT): Likewise. (accepts_video): New variable. (grub_multiboot_set_accepts_video): New function. (grub_multiboot_get_mbi_size): Account for video structures. (set_video_mode): New function. (retrieve_video_parameters): Likewise. (grub_multiboot_make_mbi): Fill video fields. --- ChangeLog | 19 ++++++ include/grub/multiboot.h | 2 + include/multiboot.h | 38 ++++++++++- include/multiboot2.h | 38 ++++++++++- loader/i386/multiboot.c | 34 ++++++++-- loader/i386/multiboot_mbi.c | 129 +++++++++++++++++++++++++++++++++++- 6 files changed, 252 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc123888b..8d3245ea3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-01-15 Vladimir Serbinenko + + Video multiboot support. + + * include/grub/multiboot.h (grub_multiboot_set_accepts_video): + New prototype. + * include/multiboot.h: Resynced with multiboot specification. + * include/multiboot2.h: Likewise. + * loader/i386/multiboot.c (UNSUPPORTED_FLAGS): Support video flags. + (grub_multiboot): Parse MULTIBOOT_VIDEO_MODE fields. + * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): New constant. + (HAS_VGA_TEXT): Likewise. + (accepts_video): New variable. + (grub_multiboot_set_accepts_video): New function. + (grub_multiboot_get_mbi_size): Account for video structures. + (set_video_mode): New function. + (retrieve_video_parameters): Likewise. + (grub_multiboot_make_mbi): Fill video fields. + 2010-01-15 Vladimir Serbinenko Video driver ids. diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index f9edb0c59..665292e33 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -35,6 +35,8 @@ void grub_multiboot (int argc, char *argv[]); void grub_module (int argc, char *argv[]); +void grub_multiboot_set_accepts_video (int val); + grub_size_t grub_multiboot_get_mbi_size (void); grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize); diff --git a/include/multiboot.h b/include/multiboot.h index da7afd9b3..57c154c98 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -85,10 +85,12 @@ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ -#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #ifndef ASM_FILE +typedef unsigned char multiboot_uint8_t; typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; @@ -187,9 +189,43 @@ struct multiboot_info multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; }; typedef struct multiboot_info multiboot_info_t; +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/include/multiboot2.h b/include/multiboot2.h index 0488849d7..a241a70ad 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -85,10 +85,12 @@ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ -#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #ifndef ASM_FILE +typedef unsigned char multiboot_uint8_t; typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; @@ -187,9 +189,43 @@ struct multiboot_info multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; }; typedef struct multiboot_info multiboot_info_t; +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 4360e8a2c..637bc5d49 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -28,13 +28,11 @@ */ /* The bits in the required part of flags field we don't support. */ -#define UNSUPPORTED_FLAGS 0x0000fffc +#define UNSUPPORTED_FLAGS 0x0000fff8 #include #include #include -#include -#include #include #include #include @@ -90,8 +88,6 @@ grub_multiboot_boot (void) if (err) return err; - grub_video_set_mode ("text", NULL); - grub_relocator32_boot (grub_multiboot_payload_orig, grub_multiboot_payload_dest, state); @@ -235,6 +231,34 @@ grub_multiboot (int argc, char *argv[]) else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) goto fail; + if (header->flags & MULTIBOOT_VIDEO_MODE) + { + switch (header->mode_type) + { + case 1: + grub_env_set ("gfxpayload", "text"); + break; + + case 0: + { + char buf[sizeof ("XXXXXXXXXXxXXXXXXXXXXxXXXXXXXXXX,XXXXXXXXXXxXXXXXXXXXX,auto")]; + if (header->depth && header->width && header->height) + grub_sprintf (buf, "%dx%dx%d,%dx%d,auto", header->width, + header->height, header->depth, header->width, + header->height); + else if (header->width && header->height) + grub_sprintf (buf, "%dx%d,auto", header->width, header->height); + else + grub_sprintf (buf, "auto"); + + grub_env_set ("gfxpayload", buf); + break; + } + } + } + + grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE)); + grub_multiboot_set_bootdev (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 58802d44c..5f33a7314 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -29,6 +29,16 @@ #include #include #include +#include + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#include +#define DEFAULT_VIDEO_MODE "text" +#define HAS_VGA_TEXT 1 +#else +#define DEFAULT_VIDEO_MODE "auto" +#define HAS_VGA_TEXT 0 +#endif struct module { @@ -46,6 +56,13 @@ static unsigned modcnt; static char *cmdline = NULL; static grub_uint32_t bootdev; static int bootdev_set; +static int accepts_video; + +void +grub_multiboot_set_accepts_video (int val) +{ + accepts_video = val; +} /* Return the length of the Multiboot mmap that will be needed to allocate our platform's map. */ @@ -73,7 +90,8 @@ grub_multiboot_get_mbi_size (void) { return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len (); + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len () + + 256 * sizeof (struct multiboot_color); } /* Fill previously allocated Multiboot mmap. */ @@ -106,6 +124,107 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) grub_mmap_iterate (hook); } +static grub_err_t +set_video_mode (void) +{ + grub_err_t err; + const char *modevar; + + if (accepts_video || !HAS_VGA_TEXT) + { + modevar = grub_env_get ("gfxpayload"); + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); + else + { + char *tmp; + tmp = grub_malloc (grub_strlen (modevar) + + sizeof (DEFAULT_VIDEO_MODE) + 1); + if (! tmp) + return grub_errno; + grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, 0); + grub_free (tmp); + } + } + else + err = grub_video_set_mode ("text", 0); + + return err; +} + +static grub_err_t +retrieve_video_parameters (struct multiboot_info *mbi, + grub_uint8_t *ptrorig, grub_uint32_t ptrdest) +{ + grub_err_t err; + struct grub_video_mode_info mode_info; + void *framebuffer; + grub_video_driver_id_t driv_id; + struct grub_video_palette_data palette[256]; + + err = set_video_mode (); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_video_get_palette (0, ARRAY_SIZE (palette), palette); + + driv_id = grub_video_get_driver_id (); + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return GRUB_ERR_NONE; + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + if (err) + return err; + + mbi->framebuffer_addr = (grub_addr_t) framebuffer; + mbi->framebuffer_pitch = mode_info.pitch; + + mbi->framebuffer_width = mode_info.width; + mbi->framebuffer_height = mode_info.height; + + mbi->framebuffer_bpp = mode_info.bpp; + + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + struct multiboot_color *mb_palette; + unsigned i; + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED; + mbi->framebuffer_palette_addr = ptrdest; + mbi->framebuffer_palette_num_colors = mode_info.number_of_colors; + if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette)) + mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette); + mb_palette = (struct multiboot_color *) ptrorig; + for (i = 0; i < mbi->framebuffer_palette_num_colors; i++) + { + mb_palette[i].red = palette[i].r; + mb_palette[i].green = palette[i].g; + mb_palette[i].blue = palette[i].b; + } + ptrorig += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + ptrdest += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + } + else + { + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; + mbi->framebuffer_red_field_position = mode_info.green_field_pos; + mbi->framebuffer_red_mask_size = mode_info.green_mask_size; + mbi->framebuffer_green_field_position = mode_info.green_field_pos; + mbi->framebuffer_green_mask_size = mode_info.green_mask_size; + mbi->framebuffer_blue_field_position = mode_info.blue_field_pos; + mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size; + } + + mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; + + return GRUB_ERR_NONE; +} + grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize) @@ -117,6 +236,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, unsigned i; struct module *cur; grub_size_t mmap_size; + grub_err_t err; if (bufsize < grub_multiboot_get_mbi_size ()) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"); @@ -182,6 +302,13 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, mbi->flags |= MULTIBOOT_INFO_BOOTDEV; } + err = retrieve_video_parameters (mbi, ptrorig, ptrdest); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; } From a0b766fc9b50388d12eb5ed08756f5c5ab0ad480 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Jan 2010 21:11:51 +0100 Subject: [PATCH 31/31] 2010-01-15 Vladimir Serbinenko Enable multiboot on non-pc. * conf/i386-coreboot.rmk, conf/i386-pc.rmk (pkglib_MODULES): Move multiboot.mod and multiboot2.mod to ... * conf/i386.rmk (pkglib_MODULES): ... here. * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_SOURCES): Moved to ... * conf/i386.rmk (multiboot_mod_SOURCES): .. here. * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_CFLAGS): Moved to ... * conf/i386.rmk (multiboot_mod_CFLAGS): .. here. * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_ASFLAGS): Moved to ... * conf/i386.rmk (multiboot_mod_ASFLAGS): .. here. * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_LDFLAGS): Moved to ... * conf/i386.rmk (multiboot_mod_LDFLAGS): .. here. * conf/x86_64-efi.rmk (pkglib_MODULES): Remove ata.mod and relocator.mod. (ata_mod_SOURCES): Removed. (ata_mod_CFLAGS): Likewise. (ata_mod_LDFLAGS): Likewise. (relocator_mod_SOURCES): Removed. (relocator_mod_CFLAGS): Likewise. (relocator_mod_ASFLAGS): Likewise. (relocator_mod_LDFLAGS): Likewise. Include i386.mk. * include/grub/x86_64/multiboot.h: New file. * loader/i386/multiboot.c (grub_multiboot_boot) [GRUB_MACHINE_EFI]: Terminate EFI. --- ChangeLog | 33 +++++++++++++++++++++++++++++++++ conf/i386-coreboot.rmk | 16 ---------------- conf/i386-pc.rmk | 16 ---------------- conf/i386.rmk | 16 ++++++++++++++++ conf/x86_64-efi.rmk | 14 ++------------ include/grub/x86_64/multiboot.h | 1 + loader/i386/multiboot.c | 9 +++++++++ 7 files changed, 61 insertions(+), 44 deletions(-) create mode 100644 include/grub/x86_64/multiboot.h diff --git a/ChangeLog b/ChangeLog index 8d3245ea3..3acc543d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2010-01-15 Vladimir Serbinenko + + Enable multiboot on non-pc. + + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (pkglib_MODULES): Move + multiboot.mod and multiboot2.mod to ... + * conf/i386.rmk (pkglib_MODULES): ... here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_SOURCES): + Moved to ... + * conf/i386.rmk (multiboot_mod_SOURCES): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_CFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_CFLAGS): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_ASFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_ASFLAGS): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_LDFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_LDFLAGS): .. here. + * conf/x86_64-efi.rmk (pkglib_MODULES): Remove ata.mod and + relocator.mod. + (ata_mod_SOURCES): Removed. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + (relocator_mod_SOURCES): Removed. + (relocator_mod_CFLAGS): Likewise. + (relocator_mod_ASFLAGS): Likewise. + (relocator_mod_LDFLAGS): Likewise. + Include i386.mk. + * include/grub/x86_64/multiboot.h: New file. + * loader/i386/multiboot.c (grub_multiboot_boot) [GRUB_MACHINE_EFI]: + Terminate EFI. + 2010-01-15 Vladimir Serbinenko Video multiboot support. diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index d73c9f0e2..57fb3350c 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -140,22 +140,6 @@ serial_mod_SOURCES = term/i386/pc/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) -pkglib_MODULES += multiboot.mod -multiboot_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c \ - loader/multiboot_loader.c -multiboot_mod_CFLAGS = $(COMMON_CFLAGS) -multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) -multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) - -pkglib_MODULES += multiboot2.mod -multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/multiboot_loader.c \ - loader/i386/multiboot_mbi.c -multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 -multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) -multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) - # For aout.mod. aout_mod_SOURCES = loader/aout.c aout_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2a69571aa..a89203dea 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -201,22 +201,6 @@ serial_mod_SOURCES = term/i386/pc/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) -pkglib_MODULES += multiboot.mod -multiboot_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c \ - loader/multiboot_loader.c -multiboot_mod_CFLAGS = $(COMMON_CFLAGS) -multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) -multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) - -pkglib_MODULES += multiboot2.mod -multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c \ - loader/multiboot_loader.c -multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 -multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) -multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) - # For vbe.mod. vbe_mod_SOURCES = video/i386/pc/vbe.c vbe_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386.rmk b/conf/i386.rmk index c3f036d0f..7ef337c61 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -25,3 +25,19 @@ pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += multiboot.mod +multiboot_mod_SOURCES = loader/i386/multiboot.c \ + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) +multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) + +pkglib_MODULES += multiboot2.mod +multiboot2_mod_SOURCES = loader/i386/multiboot.c \ + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c +multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 +multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) +multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 4f6ace057..122700711 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -32,7 +32,7 @@ grub_install_SOURCES = util/i386/efi/grub-install.in pkglib_MODULES = kernel.img chain.mod appleldr.mod \ halt.mod reboot.mod linux.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ - fixvideo.mod mmap.mod acpi.mod ata.mod + fixvideo.mod mmap.mod acpi.mod # For kernel.img. kernel_img_EXPORTS = no @@ -77,11 +77,6 @@ acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c acpi_mod_CFLAGS = $(COMMON_CFLAGS) acpi_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For ata.mod -ata_mod_SOURCES = disk/ata.c -ata_mod_CFLAGS = $(COMMON_CFLAGS) -ata_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For mmap.mod. mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \ mmap/efi/mmap.c @@ -166,10 +161,5 @@ xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) -pkglib_MODULES += relocator.mod -relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S -relocator_mod_CFLAGS = $(COMMON_CFLAGS) -relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) -relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) - +include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/include/grub/x86_64/multiboot.h b/include/grub/x86_64/multiboot.h new file mode 100644 index 000000000..957c7a5ad --- /dev/null +++ b/include/grub/x86_64/multiboot.h @@ -0,0 +1 @@ +#include diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 637bc5d49..d06f18692 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -46,6 +46,10 @@ #include #include +#ifdef GRUB_MACHINE_EFI +#include +#endif + extern grub_dl_t my_mod; static grub_size_t code_size, alloc_mbi; @@ -88,6 +92,11 @@ grub_multiboot_boot (void) if (err) return err; +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + grub_relocator32_boot (grub_multiboot_payload_orig, grub_multiboot_payload_dest, state);