merge mainline into newreloc

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-16 00:05:33 +01:00
commit 262355247f
44 changed files with 1520 additions and 62 deletions

210
ChangeLog
View file

@ -1,3 +1,213 @@
2010-01-15 Vladimir Serbinenko <phcoder@gmail.com>
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 <phcoder@gmail.com>
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 <phcoder@gmail.com>
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 <carles@pina.cat>
* util/grub.d/30_os-prober.in: Use `set var=val' rather than plain
`var=val'.
2010-01-14 Carles Pina i Estany <carles@pina.cat>
* normal/cmdline.c (print_completion): Gettextizze.
2001-01-14 Carles Pina i Estany <carles@pina.cat>
* loader/i386/pc/chainloader.c: Include `<grub/mm.h>'.
2010-01-14 Carles Pina i Estany <carles@pina.cat>
* 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 <rmh.grub@aybabtu.com>
* 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 `<grub/video.h>' and `<grub/mm.h>'.
(grub_linux16_boot): New function. Switches to text mode and calls
grub_linux16_real_boot().
* loader/i386/bsd.c: Include `<grub/video.h>'.
(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/video.h>'.
(grub_multiboot_boot): Switch to text mode before calling
grub_relocator32_boot().
* loader/i386/pc/chainloader.c: Include `<grub/video.h>'.
(grub_chainloader_boot): Switch to text mode before calling
grub_chainloader_real_boot().
2010-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* util/grub-reboot.in: Make sure prev_saved_entry always gets a
non-empty value.
2010-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* 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-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* 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 <cjwatson@ubuntu.com>
* util/grub.d/30_os-prober.in: Call save_default_entry for hurd.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* 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 <cjwatson@ubuntu.com>
* util/grub-reboot.in: Fix --version output.
* util/grub-set-default.in: Likewise.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Silently ignore zero-sized environment
blocks.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Quote the value assigned to `default',
in case it contains spaces.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* 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 <phcoder@gmail.com>
2009-10-25 Colin Watson <cjwatson@ubuntu.com>
* 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.
2010-01-14 BVK Chaitanya <bvk.groups@gmail.com>
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.
2010-01-14 Vladimir Serbinenko <phcoder@gmail.com>
* conf/i386-coreboot.rmk (multiboot_mod_SOURCES):

View file

@ -167,6 +167,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
@ -461,7 +463,26 @@ distcheck: dist
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
check:
check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS)
@list="$(UNIT_TESTS)"; \
for file in $$list; do \
$(builddir)/$$file; \
done
@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 \
echo "$$file: PASS"; \
else \
echo "$$file: FAIL"; \
fi; \
done
.SUFFIX:
.SUFFIX: .c .o .S .d

View file

@ -185,6 +185,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 \

View file

@ -134,21 +134,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 play.mod.
play_mod_SOURCES = commands/i386/pc/play.c

View file

@ -196,23 +196,6 @@ serial_mod_SOURCES = term/i386/pc/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For multiboot.mod.
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)

View file

@ -46,3 +46,19 @@ bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c
bsd_mod_CFLAGS = $(COMMON_CFLAGS)
bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
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)

50
conf/tests.rmk Normal file
View file

@ -0,0 +1,50 @@
# -*- 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
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)
# Rules for unit tests
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
# 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)
# Rules for scripted tests
check_SCRIPTS += example_scripted_test
example_scripted_test_SOURCES = tests/example_scripted_test.in
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

View file

@ -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 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

View file

@ -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. */
}
}

View file

@ -37,6 +37,7 @@ extern struct grub_relocator *grub_multiboot_relocator;
void grub_multiboot (int argc, char *argv[]);
void grub_module (int argc, char *argv[]);
void grub_multiboot_set_accepts_video (int val);
grub_err_t grub_multiboot_make_mbi (grub_uint32_t *target);
void grub_multiboot_free_mbi (void);
grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);

67
include/grub/test.h Normal file
View file

@ -0,0 +1,67 @@
#ifndef GRUB_TEST_HEADER
#define GRUB_TEST_HEADER
#include <grub/dl.h>
#include <grub/list.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/symbol.h>
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 grub_test_list;
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);
/* 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)));
/* Macro to fill in location details and an optional error message. */
#define grub_test_assert(cond, ...) \
grub_test_nonzero(cond, __FILE__, __FUNCTION__, __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); \
}
#endif /* ! GRUB_TEST_HEADER */

View file

@ -329,4 +329,7 @@ grub_video_check_mode_flag (unsigned int flags, unsigned int mask,
grub_video_driver_id_t
grub_video_get_driver_id (void);
grub_video_driver_id_t
grub_video_get_driver_id (void);
#endif /* ! GRUB_VIDEO_HEADER */

View file

@ -0,0 +1 @@
#include <grub/i386/multiboot.h>

View file

@ -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;

View file

@ -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;

View file

@ -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 ();

View file

@ -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,6 +35,7 @@
#include <grub/i18n.h>
#include <grub/i386/pc/serial.h>
#include <grub/video.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/biosnum.h>
#endif
@ -599,6 +600,8 @@ grub_freebsd_boot (void)
bi.bi_kernend = kern_end;
grub_video_set_mode ("text", 0, 0);
if (is_64bit)
{
struct grub_relocator64_state state;
@ -773,6 +776,8 @@ grub_openbsd_boot (void)
stack[7] = argbuf_target_end - argbuf_target_start;
stack[8] = argbuf_target_start;
grub_video_set_mode ("text", 0, 0);
return grub_relocator32_boot (relocator, state);
}

View file

@ -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
@ -28,7 +28,7 @@
*/
/* The bits in the required part of flags field we don't support. */
#define UNSUPPORTED_FLAGS 0x0000fff0
#define UNSUPPORTED_FLAGS 0x0000fff8
#include <grub/loader.h>
#include <grub/multiboot.h>
@ -43,6 +43,11 @@
#include <grub/gzio.h>
#include <grub/env.h>
#include <grub/i386/relocator.h>
#include <grub/video.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#endif
extern grub_dl_t my_mod;
struct grub_relocator *grub_multiboot_relocator = NULL;
@ -67,6 +72,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_relocator, state);
/* Not reached. */
@ -211,6 +221,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);

View file

@ -29,6 +29,16 @@
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/relocator.h>
#include <grub/video.h>
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
#include <grub/i386/pc/vbe.h>
#define DEFAULT_VIDEO_MODE "text"
#define HAS_VGA_TEXT 1
#else
#define DEFAULT_VIDEO_MODE "auto"
#define HAS_VGA_TEXT 0
#endif
struct module
{
@ -49,6 +59,13 @@ static int bootdev_set;
static grub_size_t elf_sec_num, elf_sec_entsize;
static unsigned elf_sec_shstrndx;
static void *elf_sections;
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. */
@ -77,7 +94,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 ()
+ elf_sec_entsize * elf_sec_num;
+ elf_sec_entsize * elf_sec_num
+ 256 * sizeof (struct multiboot_color);
}
/* Fill previously allocated Multiboot mmap. */
@ -110,6 +128,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, 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, 0);
grub_free (tmp);
}
}
else
err = grub_video_set_mode ("text", 0, 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 (grub_uint32_t *target)
{
@ -207,6 +326,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;
}
err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
if (err)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
return GRUB_ERR_NONE;
}

View file

@ -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,8 @@
#include <grub/command.h>
#include <grub/machine/biosnum.h>
#include <grub/i18n.h>
#include <grub/video.h>
#include <grub/mm.h>
static grub_dl_t my_mod;
static int boot_drive;
@ -41,6 +43,7 @@ static void *boot_part_addr;
static grub_err_t
grub_chainloader_boot (void)
{
grub_video_set_mode ("text", 0, 0);
grub_chainloader_real_boot (boot_drive, boot_part_addr);
/* Never reach here. */

View file

@ -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
@ -33,6 +33,7 @@
#include <grub/i18n.h>
#include <grub/mm.h>
#include <grub/cpu/relocator.h>
#include <grub/video.h>
#define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
@ -57,6 +58,8 @@ grub_linux16_boot (void)
state.sp = GRUB_LINUX_SETUP_STACK;
state.cs = segment + 0x20;
state.ip = 0;
grub_video_set_mode ("text", 0, 0);
return grub_relocator16_boot (relocator, state);
}

View file

@ -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)

View file

@ -157,6 +157,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 ())
@ -273,7 +275,7 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
/* 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;
@ -286,6 +288,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;
@ -312,7 +336,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
int default_entry, current_entry;
int timeout;
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. */

View file

@ -0,0 +1,17 @@
/* All tests need to include test.h for GRUB testing framework. */
#include <grub/test.h>
/* 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);

View file

@ -0,0 +1,3 @@
#! @builddir@/grub-shell-tester --modules=echo
echo "hello world"

View file

@ -0,0 +1,3 @@
#!/bin/sh -e
true

20
tests/example_unit_test.c Normal file
View file

@ -0,0 +1,20 @@
/* Unit tests are normal programs, so they can include C library. */
#include <string.h>
/* All tests need to include test.h for GRUB testing framework. */
#include <grub/test.h>
/* 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);

View file

@ -0,0 +1,35 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/test.h>
static grub_err_t
grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
auto int run_test (grub_test_t test);
int run_test (grub_test_t test)
{
grub_test_run (test);
return 0;
}
grub_list_iterate (GRUB_AS_LIST (grub_test_list),
(grub_list_hook_t) run_test);
return GRUB_ERR_NONE;
}
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);
}

146
tests/lib/test.c Normal file
View file

@ -0,0 +1,146 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/test.h>
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_malloc (sizeof (*failure));
if (!failure)
return;
grub_vsprintf (buf, fmt, args);
failure->file = grub_strdup (file ? : "<unknown_file>");
failure->funp = grub_strdup (funp ? : "<unknown_function>");
failure->line = line;
failure->message = grub_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_free (item->message);
if (item->funp)
grub_free (item->funp);
if (item->file)
grub_free (item->file);
grub_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_malloc (sizeof (*test));
if (!test)
return;
test->name = grub_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_free (test->name);
grub_free (test);
}
}
int
grub_test_run (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_printf (" %s:%s:%u: %s\n",
(failure->file ? : "<unknown_file>"),
(failure->funp ? : "<unknown_function>"),
failure->line, (failure->message ? : "<no message>"));
return 0;
}
test->main ();
grub_printf ("%s:\n", test->name);
grub_list_iterate (GRUB_AS_LIST (failure_list),
(grub_list_hook_t) print_failure);
if (!failure_list)
grub_printf ("%s: PASS\n", test->name);
else
grub_printf ("%s: FAIL\n", test->name);
free_failures ();
return GRUB_ERR_NONE;
}

91
tests/lib/unit_test.c Normal file
View file

@ -0,0 +1,91 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <grub/list.h>
#include <grub/test.h>
#include <grub/handler.h>
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) ? : 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. */
void
grub_free (void *ptr)
{
free (ptr);
}
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;

View file

@ -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 <http://www.gnu.org/licenses/>.
# 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
Usage: $0 [OPTION] [SOURCE]
Compares GRUB script output with BASH shell output.
-h, --help print this message and exit
-v, --version print the version information and exit
--modules=MODULES pre-load specified modules MODULES
--qemu-opts=OPTIONS extra options to pass to Qemu instance
$0 compares GRUB script output with BASH shell output and prints their
differences.
Report bugs to <bug-grub@gnu.org>.
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 "${source}: GRUB and BASH outputs did not match (see diff -u ${outfile1} ${outfile2})"
status=1
else
rm -f ${outfile1} ${outfile2}
fi
exit $status

145
tests/util/grub-shell.in Normal file
View file

@ -0,0 +1,145 @@
#! /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 <http://www.gnu.org/licenses/>.
# 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
Usage: $0 [OPTION] [SOURCE]
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
$0 runs input GRUB script or SOURCE file in a Qemu instance and prints
its output.
Report bugs to <bug-grub@gnu.org>.
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" ;;
--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 ;;
*)
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
if [ "x${bootdev}" = x ] ; then
bootdev=c # default is boot as disk image
fi
cfgfile=`mktemp`
cat <<EOF >${cfgfile}
grubshell=yes
insmod serial
serial
terminal_input serial
terminal_output serial
EOF
for mod in ${modules}
do
echo "insmod ${mod}" >> ${cfgfile}
done
cat <<EOF >>${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
hdafile=`mktemp`
cp ${isofile} ${hdafile}
fdafile=`mktemp`
cp ${isofile} ${fdafile}
outfile=`mktemp`
qemu-system-i386 ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile}
cat $outfile
rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} ${hdafile} ${fdafile}
exit 0

View file

@ -40,6 +40,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=
@ -263,6 +264,10 @@ done
# 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

View file

@ -94,6 +94,15 @@ convert_system_path_to_grub_path ()
echo ${drive}${relative_path}
}
save_default_entry ()
{
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then
cat << EOF
savedefault
EOF
fi
}
prepare_grub_to_access_device ()
{
device=$1

108
util/grub-reboot.in Normal file
View file

@ -0,0 +1,108 @@
#! /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 <http://www.gnu.org/licenses/>.
# 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
Usage: $0 [OPTION] entry
Set the default boot entry for GRUB, for the next boot only.
-h, --help print this message and exit
-v, --version print the version information and exit
--root-directory=DIR expect GRUB images under the directory DIR
instead of the root directory
ENTRY is a number or a menu item title.
Report bugs to <bug-grub@gnu.org>.
EOF
}
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
-v | --version)
echo "grub-reboot (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
# 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"
# Bye.
exit 0

99
util/grub-set-default.in Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
# 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
Usage: $0 [OPTION] entry
Set the default boot entry for GRUB.
-h, --help print this message and exit
-v, --version print the version information and exit
--root-directory=DIR expect GRUB images under the directory DIR
instead of the root directory
ENTRY is a number or a menu item title.
Report bugs to <bug-grub@gnu.org>.
EOF
}
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
-v | --version)
echo "grub-set-default (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

View file

@ -34,11 +34,29 @@ 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
set default=${GRUB_DEFAULT}
if [ -s \$prefix/grubenv ]; then
load_env
fi
set default="${GRUB_DEFAULT}"
if [ \${prev_saved_entry} ]; then
set saved_entry=\${prev_saved_entry}
save_env saved_entry
set prev_saved_entry=
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

View file

@ -76,6 +76,7 @@ cat << EOF
echo $(gettext "Loading GNU Mach ...")
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
echo $(gettext "Loading the Hurd ...")

View file

@ -39,6 +39,7 @@ kfreebsd_entry ()
args="$4" # not used yet
title="$(gettext "%s, with kFreeBSD %s")"
printf "menuentry \"${title}\" {\n" "${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

View file

@ -59,6 +59,7 @@ linux_entry ()
title="$(gettext "%s, with Linux %s")"
fi
printf "menuentry \"${title}\" {\n" "${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

View file

@ -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

View file

@ -41,13 +41,14 @@ osx_entry() {
cat << EOF
menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" {
EOF
save_default_entry | sed -e "s/^/\t/"
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
@ -105,6 +106,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
@ -146,6 +148,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
@ -172,6 +175,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`"

View file

@ -35,6 +35,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=
@ -179,6 +180,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

View file

@ -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