diff --git a/.bzrignore b/.bzrignore index cfdd069fd..411daae47 100644 --- a/.bzrignore +++ b/.bzrignore @@ -18,7 +18,6 @@ config.log config.status config.sub configure -conf/*.mk *.d DISTLIST docs/*.info diff --git a/ChangeLog b/ChangeLog index 04c526d98..330656cc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,277 @@ +2010-09-11 Szymon Janc + + * grub-core/commands/lsacpi.c (grub_cmd_lsacpi): Fix prototype. + +2010-09-11 Vladimir Serbinenko + + Shutdown using ACPI. + + * grub-core/Makefile.core.def (halt): Add commands/acpihalt.c on i386-pc. + * grub-core/commands/acpihalt.c: New file. + * grub-core/commands/i386/pc/halt.c (grub_cmd_halt): Call grub_acpi_halt. + * include/grub/acpi.h (grub_acpi_fadt): New member pm1a. + (grub_acpi_halt): New proto. + (GRUB_ACPI_SLP_EN): New const. + (GRUB_ACPI_SLP_TYP_OFFSET): Likewise. + (GRUB_ACPI_OPCODE_*): New enum. + (GRUB_ACPI_EXTOPCODE_*): Likewise. + +2010-09-11 Tristan Gingold +2010-09-11 Robert Millan +2010-09-11 Vladimir Serbinenko + + * commands/lsacpi.c: New file. + * grub-core/Makefile.core.def (lsacpi): New module. + * include/grub/acpi.h (GRUB_ACPI_FADT_SIGNATURE): New definition. + (GRUB_ACPI_MADT_SIGNATURE): Likewise. + (grub_acpi_madt_entry_header): New struct. + (grub_acpi_madt): Likewise. + (grub_acpi_madt_entry_interrupt_override): Likewise. + (grub_acpi_madt_entry_sapic): Likewise. + (grub_acpi_madt_entry_lsapic): Likewise. + (grub_acpi_madt_entry_platform_int_source): Likewise. + * include/grub/types.h (PRIxGRUB_UINT32_T): New definition. + (PRIuGRUB_UINT32_T): Likewise. + (PRIxGRUB_UINT64_T): Likewise. + +2010-09-11 Vladimir Serbinenko + + Implement loading palette on ieee1275_fb. + + * grub-core/video/ieee1275.c (stdout_ihandle): New variable. + (have_setcolors): Likewise. + (grub_video_ieee1275_init): Fill stdout_ihandle and have_setcolors. + (grub_video_ieee1275_setup): Use grub_video_ieee1275_set_palette. + (grub_video_ieee1275_set_palette): Implement. + +2010-09-11 Vladimir Serbinenko +2010-09-11 Colin Watson + + * util/grub-install.in (grub_partition): New variable. + Set prefix_drive on EFI and PC to (,$grub_partition) as last resort. + * util/i386/pc/grub-setup.c (setup): Don't touch prefix. + Fixes a bug reported by Yves Blusseau. + +2010-09-11 Vladimir Serbinenko + + Fix emu on mipsel. + + * conf/Makefile.common (CFLAGS_PLATFORM): Add -mflush-func + =grub_cpu_flush_cache on all mips and not only yeeloong. + * configure.ac (COND_mips): New conditional. + * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add libgcc on all + platforms. + * grub-core/kern/emu/cache.S (__mips__): Use _flush_cache. + * grub-core/kern/emu/full.c (grub_arch_dl_init_linker) + [GRUB_LINKER_HAVE_INIT]: New function. + (grub_emu_post_init): Likewise. + * grub-core/kern/emu/lite.c (grub_emu_post_init): Likewise. + * grub-core/kern/emu/main.c: Use grub_emu_post_init. + * include/grub/cache.h (_mips): Include mips/cache.h. + * include/grub/disk.h [GRUB_UTIL || GRUB_MACHINE_EMU]: Add missing + LVM and RAID prototypes. + * include/grub/emu/misc.h (grub_emu_post_init): New proto. + * include/grub/mips/time.h (grub_cpu_idle) [GRUB_MACHINE_EMU]: New + function. + +2010-09-10 Colin Watson + + * util/grub-install.in: Don't try to verify core.img until after + running grub-mkimage to create it. + +2010-09-10 Robert Millan + + * util/grub.d/10_hurd.in: Add misc readability checks. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + +2010-09-10 Colin Watson + + * util/grub-install.in: ${imgext} won't be defined here until the + install branch is merged. For the meantime, only verify core.img on + i386-pc and sparc64-ieee1275 platforms. + +2010-09-10 Robert Millan + + Solaris support in grub_find_zpool_from_dir(). Thanks + Seth Goldberg for referring to getextmntent() facility. + + * configure.ac: Check for getextmntent(), `sys/mnttab.h' and + `sys/mkdev.h'. + * grub-core/kern/emu/misc.c [HAVE_SYS_MNTTAB_H]: Include + `'. + [HAVE_SYS_MKDEV_H]: Include `'. + [HAVE_GETEXTMNTENT] (grub_find_zpool_from_dir): Add getextmntent() + method for finding zpool name. + +2010-09-10 Colin Watson + + grub-fstest needs the host and hostfs modules while other utilities + actively require those modules to be absent, so grub-fstest needs + its own initialisation and finalisation code. + + * Makefile.am (grub_fstest.pp): New target. + (grub_fstest_init.lst): Likewise. + (grub_fstest_init.c): Likewise. + * Makefile.util.def (grub-fstest): Add grub_fstest_init.c. + +2010-09-10 Robert Millan + + * configure.ac: Check for `struct statfs.f_fstypename' and + `struct statfs.f_mntfromname'. + + * grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): Conditionalize + kFreeBSD-specific code. + +2010-09-10 Robert Millan + + * util/grub.d/10_kfreebsd.in: Fix ${kfreebsd_device} initialization + on ZFS. Now non-main filesystems are supported as / too. + +2010-09-09 Colin Watson + + * Makefile.util.def (libgrub.a): Move grub-core/kern/emu/hostfs.c + and grub-core/disk/host.c to ... + (grub-fstest): ... here. Having the host disk implementation + present confuses grub-probe and other utility programs. + + * util/grub-mkconfig.in: Only verify readability of grub.cfg.new + when writing to a file, not when writing to stdout. + +2010-09-09 BVK Chaitanya + + * tests/partmap_test.in: New test for partitions. + * Makefile.util.def: Rules for new test. + +2010-09-09 Robert Millan + + * util/grub-probe.c (probe): Fix a pair of unhandled error + conditions. + +2010-09-09 Robert Millan + + Basic Btrfs support (detection and UUID). + + * grub-core/fs/btrfs.c: New file. + * Makefile.util.def (library): Register btrfs.c. + * grub-core/Makefile.core.def: Likewise. + +2010-09-08 Robert Millan + + * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve + with (optional) parameters to specify device and relative path. + * util/grub-install.in: Use is_path_readable_by_grub() to + verify readability of a few critical files. + * util/grub-mkconfig.in: Use is_path_readable_by_grub() to + verify readability of grub.cfg.new. + +2010-09-08 Vladimir Serbinenko + + Split minix.mod into minix.mod and minix2.mod. + + * Makefile.util.def (libgrub.a): Add grub-core/fs/minix2.c. + * grub-core/Makefile.core.def (minix2): New module. + * grub-core/fs/minix.c: Use definitions instead of runtime version + checking. + * grub-core/fs/minix2.c: New file. + +2010-09-08 Yves Blusseau + + Add new --boot-directory option to replace --root-directory + + * util/grub-install.in: Add new --boot-directory option + * util/grub-reboot.in: Likewise. + * util/grub-set-default.in: Likewise. + +2010-09-08 Yves Blusseau + + * util/grub-mkconfig.in: Use new variable. + +2010-09-08 Yves Blusseau + + * configure.ac: Define some useful variables. + +2010-09-08 Vladimir Serbinenko + + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_HAS_CURSORONOFF when appropriate. + * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_setcursor): + Use terminfo and don't use cursor-on/cursor-off unless it's known + to work. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New element + GRUB_IEEE1275_FLAG_HAS_CURSORONOFF. + +2010-09-08 Colin Watson + + * grub-core/kern/efi/init.c (grub_efi_set_prefix): If the prefix + starts with "(,", fill the drive containing the loaded image in + between those two characters, but expect that a full partition + specification including partition map names will follow. + +2010-09-08 Robert Millan + + * configure.ac: Remove `--enable-grub-fstest' option. + * Makefile.util.def (grub-fstest): Remove COND_GRUB_FSTEST condition. + + * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Use + `grub-fstest' instead of `grub-probe' for readability verification. + * util/grub-probe.c (probe): Remove readability verification kludge. + +2010-09-08 Robert Millan + + * util/grub-mkconfig.in: Pass `--device ${GRUB_DEVICE}' when + initializing `GRUB_FS'. + +2010-09-08 BVK Chaitanya + + Not command (!) support to GRUB script. + + * tests/grub_script_not.in: New test. + * Makefile.util.def: Rules for new test. + + * grub-core/script/execute.c (grub_script_execute_cmdline): Handle + ! command as a special case. + * grub-core/script/yylex.l (GRUB_PARSER_TOKEN_NOT): Removed. + +2010-09-07 BVK Chaitanya + + * grub-core/commands/wildcard.c (wildcard_expand): Fix wrong + grub_free. + +2010-09-07 BVK Chaitanya + + * docs/grub.texi (Shell-like scripting): Fix @dots to @dots{}. + +2010-09-07 BVK Chaitanya + + * docs/grub.texi (Shell-like scripting): Documentation for break, + continue, shift and return commands. + +2010-09-06 Vladimir Serbinenko + + Rename CD-ROM to cd on BIOS. + + * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_get_drive): Recognise + "cd". + (grub_biosdisk_call_hook): Call with "cd" instead of arbitrary hdX. + +2010-09-05 Vladimir Serbinenko + + * grub-core/kern/emu/main.c (main): Reinit LVM and RAID. + * util/grub-probe.c (main): Likewise. + * util/i386/pc/grub-setup.c (main): Likewise. + * util/sparc64/ieee1275/grub-setup.c (main): Likewise. + Reported and debugged by: alexxy + +2010-09-05 Vladimir Serbinenko + + * grub-core/disk/lvm.c (grub_lvm_scan_device) [GRUB_UTIL]: Output more + diagnostic info. + +2010-09-05 Jo Shields + + * util/grub.d/30_os-prober.in: Add missing classes. + 2010-09-05 Vladimir Serbinenko * docs/grub.texi (Theme file format): Document new position format. diff --git a/Makefile.am b/Makefile.am index 1cf2297bd..e0f2f013f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,6 +44,20 @@ libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1) CLEANFILES += libgrub_a_init.c +# For grub-fstest +grub_fstest.pp: $(grub_fstest_SOURCES) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(grub_fstest_CPPFLAGS) $(CPPFLAGS) \ + -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) +CLEANFILES += grub_fstest.pp + +grub_fstest_init.lst: libgrub.pp grub_fstest.pp + cat $^ | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1) +CLEANFILES += grub_fstest_init.lst + +grub_fstest_init.c: grub_fstest_init.lst $(top_srcdir)/geninit.sh + sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1) +CLEANFILES += grub_fstest_init.c + if COND_GRUB_MKFONT if COND_HAVE_FONT_SOURCE grubdata_DATA = unicode.pf2 ascii.pf2 ascii.h widthspec.h diff --git a/Makefile.util.def b/Makefile.util.def index d3a4ac290..febbfd0ed 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -23,7 +23,6 @@ library = { common = grub-core/kern/misc.c; common = grub-core/kern/emu/mm.c; common = grub-core/kern/emu/misc.c; - common = grub-core/kern/emu/hostfs.c; common = grub-core/kern/emu/getroot.c; common = grub-core/kern/emu/hostdisk.c; @@ -31,7 +30,6 @@ library = { common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; common = grub-core/disk/dmraid_nvidia.c; - common = grub-core/disk/host.c; common = grub-core/disk/loopback.c; common = grub-core/disk/lvm.c; common = grub-core/disk/mdraid_linux.c; @@ -43,6 +41,7 @@ library = { common = grub-core/fs/afs.c; common = grub-core/fs/befs_be.c; common = grub-core/fs/befs.c; + common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; common = grub-core/fs/fat.c; @@ -52,6 +51,7 @@ library = { common = grub-core/fs/iso9660.c; common = grub-core/fs/jfs.c; common = grub-core/fs/minix.c; + common = grub-core/fs/minix2.c; common = grub-core/fs/nilfs2.c; common = grub-core/fs/ntfs.c; common = grub-core/fs/ntfscomp.c; @@ -179,11 +179,13 @@ program = { program = { name = grub-fstest; mansection = 1; + common_nodist = grub_fstest_init.c; common = util/grub-fstest.c; + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; - condition = COND_GRUB_FSTEST; }; program = { @@ -531,6 +533,18 @@ script = { common = tests/grub_script_expansion.in; }; +script = { + testcase; + name = grub_script_not; + common = tests/grub_script_not.in; +}; + +script = { + testcase; + name = partmap_test; + common = tests/partmap_test.in; +}; + program = { testcase; name = example_unit_test; diff --git a/conf/Makefile.common b/conf/Makefile.common index fca0f67ae..afa57b986 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -1,8 +1,10 @@ # -*- makefile -*- +CFLAGS_PLATFORM= + # Platform specific options if COND_i386_pc - CFLAGS_PLATFORM = -mrtd -mregparm=3 + CFLAGS_PLATFORM += -mrtd -mregparm=3 endif if COND_i386_efi LDFLAGS_PLATFORM = -melf_i386 @@ -11,21 +13,24 @@ if COND_x86_64_efi LDFLAGS_PLATFORM = -melf_x86_64 endif if COND_i386_qemu - CFLAGS_PLATFORM = -mrtd -mregparm=3 + CFLAGS_PLATFORM += -mrtd -mregparm=3 endif if COND_i386_coreboot - CFLAGS_PLATFORM = -mrtd -mregparm=3 + CFLAGS_PLATFORM += -mrtd -mregparm=3 endif if COND_i386_ieee1275 - CFLAGS_PLATFORM = -mrtd -mregparm=3 + CFLAGS_PLATFORM += -mrtd -mregparm=3 endif if COND_mips_yeeloong - CFLAGS_PLATFORM = -march=mips3 -mexplicit-relocs -mflush-func=grub_cpu_flush_cache + CFLAGS_PLATFORM += -march=mips3 -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK CCASFLAGS_PLATFORM = -march=mips3 endif +if COND_mips + CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache +endif if COND_sparc64_ieee1275 - CFLAGS_PLATFORM = -mno-app-regs + CFLAGS_PLATFORM += -mno-app-regs LDFLAGS_PLATFORM = -melf64_sparc -mno-relax endif diff --git a/configure.ac b/configure.ac index d362f68a5..9578f6518 100644 --- a/configure.ac +++ b/configure.ac @@ -176,6 +176,19 @@ AC_SUBST(host_kernel) AC_SUBST(target_cpu) AC_SUBST(platform) +# Define default variables +case "$host_os" in + netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, + bootdirname='' ;; + *) bootdirname='boot' ;; +esac +bootdirname=`echo "$bootdirname" | sed "$program_transform_name"` +AC_SUBST(bootdirname) + +grubdirname=`echo "$PACKAGE" | sed "$program_transform_name"` +AC_SUBST(grubdirname) + # # Checks for build programs. # @@ -264,8 +277,16 @@ else fi # Check for functions and headers. -AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) -AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h) +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getextmntent) +AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h sys/mnttab.h sys/mkdev.h) + +AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default +#include +#include ]) + +AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default +#include +#include ]) # For opendisk() and getrawpartition() on NetBSD. # Used in util/deviceiter.c and in util/hostdisk.c. @@ -762,19 +783,6 @@ AC_SUBST([enable_grub_emu_usb]) AC_SUBST([enable_grub_emu_pci]) fi -AC_ARG_ENABLE([grub-fstest], - [AS_HELP_STRING([--enable-grub-fstest], - [build and install the `grub-fstest' debugging utility (default=guessed)])]) -if test x"$enable_grub_fstest" = xno ; then - grub_fstest_excuse="explicitly disabled" -fi -if test x"$grub_fstest_excuse" = x ; then -enable_grub_fstest=yes -else -enable_grub_fstest=no -fi -AC_SUBST([enable_grub_fstest]) - AC_ARG_ENABLE([grub-mkfont], [AS_HELP_STRING([--enable-grub-mkfont], [build and install the `grub-mkfont' utility (default=guessed)])]) @@ -892,6 +900,7 @@ AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform = AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips]) AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips]) AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) @@ -905,7 +914,6 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) -AM_CONDITIONAL([COND_GRUB_FSTEST], [test x$enable_grub_fstest = xyes]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) @@ -970,11 +978,6 @@ echo efiemu runtime: Yes else echo efiemu runtime: No "($efiemu_excuse)" fi -if [ x"$grub_fstest_excuse" = x ]; then -echo grub-fstest: Yes -else -echo grub-fstest: No "($grub_fstest_excuse)" -fi if [ x"$grub_mkfont_excuse" = x ]; then echo grub-mkfont: Yes else diff --git a/docs/grub.texi b/docs/grub.texi index 80c6e50db..af6d42ccb 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1227,8 +1227,10 @@ The @samp{$} character retains its special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A backslash-newline pair is treated as a line continuation (that is, it is -removed from the input stream and effectively ignored). A double quote may -be quoted within double quotes by preceding it with a backslash. +removed from the input stream and effectively ignored@footnote{Currently a +backslash-newline pair within a variable name is not handled properly, so +use this feature with some care.}). A double quote may be quoted within +double quotes by preceding it with a backslash. @heading Variable expansion @@ -1240,11 +1242,15 @@ which could be interpreted as part of the name. Normal variable names begin with an alphabetic character, followed by zero or more alphanumeric characters. -Positional variable names consist of one or more digits. These are reserved -for future expansion. +Positional variable names consist of one or more digits. They represent +parameters passed to function calls, with @samp{$1} representing the first +parameter, and so on. The special variable name @samp{?} expands to the exit status of the most -recently executed command. +recently executed command. When positional variable names are active, other +special variable names @samp{@@}, @samp{*} and @samp{#} are defined and they +expand to all positional parameters with necessary quoting, positional +parameters without any quoting, and positional parameter count respectively. @heading Comments @@ -1305,6 +1311,45 @@ the body. @xref{menuentry}. @end table +@heading Built-in Commands + +Some built-in commands are also provided by GRUB script to help script +writers perform actions that are otherwise not possible. For example, these +include commands to jump out of a loop without fully completing it, etc. + +@table @asis +@item break [@code{n}] +Exit from within a @code{for}, @code{while}, or @code{until} loop. If +@code{n} is specified, break @code{n} levels. @code{n} must be greater than +or equal to 1. If @code{n} is greater than the number of enclosing loops, +all enclosing loops are exited. The return value is 0 unless @code{n} is +not greater than or equal to 1. + +@item continue [@code{n}] +Resume the next iteration of the enclosing @code{for}, @code{while} or +@code{until} loop. If @code{n} is specified, resume at the @code{n}th +enclosing loop. @code{n} must be greater than or equal to 1. If @code{n} +is greater than the number of enclosing loops, the last enclosing loop (the +@dfn{top-level} loop) is resumed. The return value is 0 unless @code{n} is +not greater than or equal to 1. + +@item return [@code{n}] +Causes a function to exit with the return value specified by @code{n}. If +@code{n} is omitted, the return status is that of the last command executed +in the function body. If used outside a function the return status is +false. + +@item shift [@code{n}] +The positional parameters from @code{n}+1 @dots{} are renamed to +@code{$1}@dots{}. Parameters represented by the numbers @code{$#} down to +@code{$#}-@code{n}+1 are unset. @code{n} must be a non-negative number less +than or equal to @code{$#}. If @code{n} is 0, no parameters are changed. +If @code{n} is not given, it is assumed to be 1. If @code{n} is greater +than @code{$#}, the positional parameters are not changed. The return +status is greater than zero if @code{n} is greater than @code{$#} or less +than zero; otherwise 0. + +@end table @node Embedded configuration @section Embedding a configuration file into GRUB diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..7fa00b744 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -74,6 +74,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h if COND_i386_pc KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h @@ -132,7 +133,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h @@ -140,11 +140,9 @@ endif if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h endif if COND_sparc64_ieee1275 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h endif diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index a72f61b66..cbc5b7438 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -404,7 +404,7 @@ module = { module = { name = acpi; - x86 = commands/acpi.c; + common = commands/acpi.c; x86_efi = commands/efi/acpi.c; i386_pc = commands/i386/pc/acpi.c; i386_coreboot = commands/i386/pc/acpi.c; @@ -416,6 +416,17 @@ module = { enable = i386_multiboot; }; +module = { + name = lsacpi; + + common = commands/lsacpi.c; + + enable = x86_efi; + enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; +}; + module = { name = blocklist; common = commands/blocklist.c; @@ -493,6 +504,7 @@ module = { name = halt; nopc = commands/halt.c; i386_pc = commands/i386/pc/halt.c; + i386_pc = commands/acpihalt.c; i386_multiboot = lib/i386/halt.c; i386_coreboot = lib/i386/halt.c; i386_qemu = lib/i386/halt.c; @@ -835,6 +847,11 @@ module = { common = fs/befs_be.c; }; +module = { + name = btrfs; + common = fs/btrfs.c; +}; + module = { name = cpio; common = fs/cpio.c; @@ -880,6 +897,11 @@ module = { common = fs/minix.c; }; +module = { + name = minix2; + common = fs/minix2.c; +}; + module = { name = nilfs2; common = fs/nilfs2.c; @@ -1389,7 +1411,7 @@ module = { common = commands/legacycfg.c; common = lib/legacy_parse.c; enable = i386_pc; -} +}; module = { name = test_blockarg; @@ -1408,5 +1430,4 @@ module = { module = { name = testload; common = commands/testload.c; ->>>>>>> MERGE-SOURCE }; diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index b2edcc9cd..9d5e93495 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -324,7 +324,7 @@ setup_common_tables (void) /* If it's FADT correct DSDT and FACS addresses. */ fadt = (struct grub_acpi_fadt *) cur->addr; - if (grub_memcmp (fadt->hdr.signature, "FACP", + if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE, sizeof (fadt->hdr.signature)) == 0) { fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt); @@ -527,7 +527,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable; /* Set root header variables to the same values - as FACP by default. */ + as FADT by default. */ grub_memcpy (&root_oemid, &(fadt->hdr.oemid), sizeof (root_oemid)); grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable), diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c new file mode 100644 index 000000000..2ba15468b --- /dev/null +++ b/grub-core/commands/acpihalt.c @@ -0,0 +1,266 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static inline grub_uint32_t +decode_length (const grub_uint8_t *ptr, int *numlen) +{ + int num_bytes, i; + grub_uint32_t ret; + if (*ptr < 64) + { + if (numlen) + *numlen = 1; + return *ptr; + } + num_bytes = *ptr >> 6; + if (numlen) + *numlen = num_bytes + 1; + ret = *ptr & 0xf; + ptr++; + for (i = 0; i < num_bytes; i++) + { + ret |= *ptr << (8 * i + 4); + ptr++; + } + return ret; +} + +static inline grub_uint32_t +skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end) +{ + const grub_uint8_t *ptr0 = ptr; + + while (ptr < end && (*ptr == '^' || *ptr == '\\')) + ptr++; + switch (*ptr) + { + case '.': + ptr++; + ptr += 8; + break; + case '/': + ptr++; + ptr += 1 + (*ptr) * 4; + break; + case 0: + ptr++; + break; + default: + ptr += 4; + break; + } + return ptr - ptr0; +} + +static inline grub_uint32_t +skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end) +{ + grub_dprintf ("acpi", "data type = 0x%x\n", *ptr); + switch (*ptr) + { + case GRUB_ACPI_OPCODE_PACKAGE: + return 1 + decode_length (ptr + 1, 0); + case GRUB_ACPI_OPCODE_ZERO: + case GRUB_ACPI_OPCODE_ONES: + case GRUB_ACPI_OPCODE_ONE: + return 1; + case GRUB_ACPI_OPCODE_BYTE_CONST: + return 2; + case GRUB_ACPI_OPCODE_WORD_CONST: + return 3; + case GRUB_ACPI_OPCODE_DWORD_CONST: + return 5; + default: + if (*ptr == '^' || *ptr == '\\' || *ptr == '_' + || (*ptr >= 'A' && *ptr <= 'Z')) + return skip_name_string (ptr, end); + grub_printf ("Unknown opcode 0x%x\n", *ptr); + return 0; + } +} + +static inline grub_uint32_t +skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) +{ + const grub_uint8_t *ptr0 = ptr; + int add; + grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr); + switch (*ptr) + { + case GRUB_ACPI_EXTOPCODE_MUTEX: + ptr++; + ptr += skip_name_string (ptr, end); + ptr++; + break; + case GRUB_ACPI_EXTOPCODE_OPERATION_REGION: + ptr++; + ptr += skip_name_string (ptr, end); + ptr++; + ptr += add = skip_data_ref_object (ptr, end); + if (!add) + return 0; + ptr += add = skip_data_ref_object (ptr, end); + if (!add) + return 0; + break; + case GRUB_ACPI_EXTOPCODE_FIELD_OP: + ptr++; + ptr += decode_length (ptr, 0); + break; + default: + grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr); + return 0; + } + return ptr - ptr0; +} + +static int +get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) +{ + grub_uint8_t *ptr, *prev; + int sleep_type = -1; + + ptr = table + sizeof (struct grub_acpi_table_header); + while (ptr < end && prev < ptr) + { + int add; + prev = ptr; + grub_dprintf ("acpi", "Opcode %x\n", *ptr); + grub_dprintf ("acpi", "Tell %x\n", ptr - table); + switch (*ptr) + { + case GRUB_ACPI_OPCODE_EXTOP: + ptr++; + ptr += add = skip_ext_op (ptr, end); + if (!add) + return -1; + break; + case GRUB_ACPI_OPCODE_NAME: + ptr++; + if (memcmp (ptr, "_S5_", 4) == 0) + { + int ll; + grub_uint8_t *ptr2 = ptr; + ptr2 += 4; + if (*ptr2 != 0x12) + { + grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2); + return -1; + } + ptr2++; + decode_length (ptr2, &ll); + ptr2 += ll; + ptr2++; + switch (*ptr2) + { + case GRUB_ACPI_OPCODE_ZERO: + sleep_type = 0; + break; + case GRUB_ACPI_OPCODE_ONE: + sleep_type = 1; + break; + case GRUB_ACPI_OPCODE_BYTE_CONST: + sleep_type = ptr2[1]; + break; + default: + grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2); + return -1; + } + } + ptr += add = skip_name_string (ptr, end); + if (!add) + return -1; + ptr += add = skip_data_ref_object (ptr, end); + if (!add) + return -1; + break; + case GRUB_ACPI_OPCODE_SCOPE: + case GRUB_ACPI_OPCODE_IF: + case GRUB_ACPI_OPCODE_METHOD: + { + ptr++; + ptr += decode_length (ptr, 0); + break; + } + } + } + + grub_dprintf ("acpi", "TYP = %d\n", sleep_type); + return sleep_type; +} + +void +grub_acpi_halt (void) +{ + struct grub_acpi_rsdp_v20 *rsdp2; + struct grub_acpi_rsdp_v10 *rsdp1; + struct grub_acpi_table_header *rsdt; + grub_uint32_t *entry_ptr; + + rsdp2 = grub_acpi_get_rsdpv2 (); + if (rsdp2) + rsdp1 = &(rsdp2->rsdpv1); + else + rsdp1 = grub_acpi_get_rsdpv1 (); + grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1); + if (!rsdp1) + return; + + rsdt = (struct grub_acpi_table_header *) rsdp1->rsdt_addr; + for (entry_ptr = (grub_uint32_t *) (rsdt + 1); + entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) + + rsdt->length); + entry_ptr++) + { + if (grub_memcmp ((void *)*entry_ptr, "FACP", 4) == 0) + { + grub_uint32_t port; + struct grub_acpi_fadt *fadt + = ((struct grub_acpi_fadt *) *entry_ptr); + struct grub_acpi_table_header *dsdt + = (struct grub_acpi_table_header *) fadt->dsdt_addr; + int sleep_type = -1; + + port = fadt->pm1a; + + grub_dprintf ("acpi", "PM1a port=%x\n", port); + + if (grub_memcmp (dsdt->signature, "DSDT", + sizeof (dsdt->signature)) != 0) + break; + + sleep_type = get_sleep_type ((grub_uint8_t *) dsdt, + (grub_uint8_t *) dsdt + dsdt->length); + + if (sleep_type < 0 || sleep_type >= 8) + break; + + grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", + sleep_type, port); + + grub_outw (GRUB_ACPI_SLP_EN + | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff); + } + } + + grub_printf ("ACPI shutdown failed\n"); +} diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c index 1e0aefa50..8afae8eb7 100644 --- a/grub-core/commands/i386/pc/halt.c +++ b/grub-core/commands/i386/pc/halt.c @@ -22,6 +22,7 @@ #include #include #include +#include static const struct grub_arg_option options[] = { @@ -100,6 +101,9 @@ grub_cmd_halt (grub_extcmd_context_t ctxt, { struct grub_arg_list *state = ctxt->state; int no_apm = 0; + + grub_acpi_halt (); + if (state[0].set) no_apm = 1; grub_halt (no_apm); diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 100464e69..b0253e707 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,7 @@ legacy_file (const char *filename) char *entryname = NULL, *entrysrc = NULL; grub_menu_t menu; - file = grub_gzfile_open (filename, 1); + file = grub_file_open (filename); if (! file) return grub_errno; @@ -80,7 +79,8 @@ legacy_file (const char *filename) return grub_errno; } args[0] = oldname; - grub_normal_add_menu_entry (1, args, entrysrc); + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, + entrysrc); } } @@ -132,7 +132,7 @@ legacy_file (const char *filename) return grub_errno; } args[0] = entryname; - grub_normal_add_menu_entry (1, args, entrysrc); + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); } if (menu && menu->size) @@ -238,9 +238,9 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required"); - cutargs = grub_malloc (sizeof (cutargsp[0]) * (argc - 1)); + cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); cutargc = argc - 1; - grub_memcpy (cutargs + 1, args + 2, sizeof (cutargsp[0]) * (argc - 2)); + grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2)); cutargs[0] = args[0]; do diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c new file mode 100644 index 000000000..149de6b79 --- /dev/null +++ b/grub-core/commands/lsacpi.c @@ -0,0 +1,251 @@ +/* acpi.c - Display acpi tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 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 . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void +print_strn (grub_uint8_t *str, grub_size_t len) +{ + for (; *str && len; str++, len--) + grub_printf ("%c", *str); + for (len++; len; len--) + grub_printf (" "); +} + +#define print_field(x) print_strn(x, sizeof (x)) + +static void +disp_acpi_table (struct grub_acpi_table_header *t) +{ + print_field (t->signature); + grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision); + print_field (t->oemid); + print_field (t->oemtable); + grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev); + print_field (t->creator_id); + grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev); +} + +static void +disp_madt_table (struct grub_acpi_madt *t) +{ + struct grub_acpi_madt_entry_header *d; + grub_uint32_t len; + + disp_acpi_table (&t->hdr); + grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08" + PRIxGRUB_UINT32_T "\n", + t->lapic_addr, t->flags); + len = t->hdr.length - sizeof (struct grub_acpi_madt); + d = t->entries; + for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len)) + { + grub_printf (" type=%x l=%u ", d->type, d->len); + + switch (d->type) + { + case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE: + { + struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d; + grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n", + dt->bus, dt->source, dt->global_sys_interrupt, + dt->flags); + } + break; + case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC: + { + struct grub_acpi_madt_entry_sapic *dt = (void *) d; + grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T + "\n", + dt->id, dt->global_sys_interrupt_base, + dt->addr); + } + break; + case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC: + { + struct grub_acpi_madt_entry_lsapic *dt = (void *) d; + grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x", + dt->cpu_id, dt->id, dt->eid, dt->flags); + if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED) + grub_printf (" Enabled\n"); + else + grub_printf (" Disabled\n"); + if (d->len > sizeof (struct grub_acpi_madt_entry_sapic)) + grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid, + dt->cpu_uid_str); + } + break; + case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE: + { + struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d; + static const char * const platint_type[] = + {"Nul", "PMI", "INIT", "CPEI"}; + + grub_printf ("Platform INT flags=%04x type=%02x (%s)" + " ID=%02x EID=%02x\n", + dt->flags, dt->inttype, + (dt->inttype < ARRAY_SIZE (platint_type)) + ? platint_type[dt->inttype] : "??", dt->cpu_id, + dt->cpu_eid); + grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n", + dt->sapic_vector, dt->global_sys_int, dt->src_flags); + } + break; + default: + grub_printf (" ??\n"); + } + } +} + +static void +disp_acpi_xsdt_table (struct grub_acpi_table_header *t) +{ + grub_uint32_t len; + grub_uint64_t *desc; + + disp_acpi_table (t); + len = t->length - sizeof (*t); + desc = (grub_uint64_t *) (t + 1); + for (; len > 0; desc++, len -= sizeof (*desc)) + { + if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32)) + { + grub_printf ("Unreachable table\n"); + continue; + } + t = (struct grub_acpi_table_header *) (grub_addr_t) *desc; + + if (t == NULL) + continue; + + if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, + sizeof (t->signature)) == 0) + disp_madt_table ((struct grub_acpi_madt *) t); + else + disp_acpi_table (t); + } +} + +static void +disp_acpi_rsdt_table (struct grub_acpi_table_header *t) +{ + grub_uint32_t len; + grub_uint32_t *desc; + + disp_acpi_table (t); + len = t->length - sizeof (*t); + desc = (grub_uint32_t *) (t + 1); + for (; len > 0; desc++, len -= sizeof (*desc)) + { + t = (struct grub_acpi_table_header *) (grub_addr_t) *desc; + + if (t == NULL) + continue; + + if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, + sizeof (t->signature)) == 0) + disp_madt_table ((struct grub_acpi_madt *) t); + else + disp_acpi_table (t); + } +} + +static void +disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp) +{ + print_field (rsdp->signature); + grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum); + print_field (rsdp->oemid); + grub_printf ("rev=%d\n", rsdp->revision); + grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr); +} + +static void +disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) +{ + disp_acpi_rsdpv1 (&rsdp->rsdpv1); + grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, + rsdp->xsdt_addr); +} + +static const struct grub_arg_option options[] = { + {"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE}, + {"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE} +}; + +static grub_err_t +grub_cmd_lsacpi (struct grub_extcmd_context *ctxt, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + if (!ctxt->state[1].set) + { + struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 (); + if (!rsdp1) + grub_printf ("No RSDPv1\n"); + else + { + grub_printf ("RSDPv1 signature:"); + disp_acpi_rsdpv1 (rsdp1); + disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr); + } + } + + if (!ctxt->state[0].set) + { + struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 (); + if (!rsdp2) + grub_printf ("No RSDPv2\n"); + else + { + if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32)) + grub_printf ("Unreachable RSDPv2\n"); + else + { + grub_printf ("RSDPv2 signature:"); + disp_acpi_rsdpv2 (rsdp2); + disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr); + grub_printf ("\n"); + } + } + } + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(lsapi) +{ + cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, GRUB_COMMAND_FLAG_BOTH, + N_("[-1|-2]"), + N_("Show ACPI information."), options); +} + +GRUB_MOD_FINI(lsacpi) +{ + grub_unregister_extcmd (cmd); +} + + diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index fc1ae71c7..cd5f38f69 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -52,10 +52,10 @@ static struct /* Add a menu entry to the current menu context (as given by the environment variable data slot `menu'). As the configuration file is read, the script parser calls this when a menu entry is to be created. */ -static grub_err_t -append_menu_entry (int argc, const char **args, char **classes, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode) +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode) { unsigned i; int menu_hotkey = 0; @@ -243,9 +243,10 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); if (! ctxt->script) - return append_menu_entry (argc, (const char **) args, - ctxt->state[0].args, ctxt->state[1].arg, - ctxt->state[2].arg, 0, ctxt->state[3].arg); + return grub_normal_add_menu_entry (argc, (const char **) args, + ctxt->state[0].args, ctxt->state[1].arg, + ctxt->state[2].arg, 0, + ctxt->state[3].arg); src = args[argc - 1]; args[argc - 1] = NULL; @@ -258,9 +259,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) if (! prefix) return grub_errno; - r = append_menu_entry (argc - 1, (const char **) args, - ctxt->state[0].args, ctxt->state[1].arg, - ctxt->state[2].arg, prefix, src + 1); + r = grub_normal_add_menu_entry (argc - 1, (const char **) args, + ctxt->state[0].args, ctxt->state[1].arg, + ctxt->state[2].arg, prefix, src + 1); src[len - 1] = ch; args[argc - 1] = src; diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index cbe32e0ff..64e2e3a54 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -488,7 +488,7 @@ wildcard_expand (const char *s, char ***strs) for (i = 0; paths && paths[i]; i++) grub_free (paths[i]); - grub_free (paths[i]); + grub_free (paths); regfree (®exp); return grub_errno; } diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 17de0c1a1..9c0209693 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -248,6 +248,9 @@ grub_biosdisk_get_drive (const char *name) { unsigned long drive; + if (name[0] == 'c' && name[1] == 'd' && name[2] == 0 && cd_drive) + return cd_drive; + if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') goto fail; @@ -270,6 +273,9 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) { char name[10]; + if (cd_drive && drive == cd_drive) + return hook ("cd"); + grub_snprintf (name, sizeof (name), (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); return hook (name); diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 71860e853..3981d9811 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -274,6 +274,10 @@ grub_lvm_scan_device (const char *name) struct grub_lvm_vg *vg; struct grub_lvm_pv *pv; +#ifdef GRUB_UTIL + grub_util_info ("scanning %s for LVM", name); +#endif + disk = grub_disk_open (name); if (!disk) return 0; @@ -294,7 +298,12 @@ grub_lvm_scan_device (const char *name) /* Return if we didn't find a label. */ if (i == GRUB_LVM_LABEL_SCAN_SECTORS) - goto fail; + { +#ifdef GRUB_UTIL + grub_util_info ("no LVM signature found\n"); +#endif + goto fail; + } pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl)); @@ -318,6 +327,9 @@ grub_lvm_scan_device (const char *name) grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "we don't support multiple LVM data areas"); +#ifdef GRUB_UTIL + grub_util_info ("we don't support multiple LVM data areas\n"); +#endif goto fail; } @@ -344,6 +356,9 @@ grub_lvm_scan_device (const char *name) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unknown LVM metadata header"); +#ifdef GRUB_UTIL + grub_util_info ("unknown LVM metadata header\n"); +#endif goto fail2; } @@ -364,7 +379,12 @@ grub_lvm_scan_device (const char *name) q++; if (q == metadatabuf + mda_size) - goto fail2; + { +#ifdef GRUB_UTIL + grub_util_info ("error parsing metadata\n"); +#endif + goto fail2; + } vgname_len = q - p; vgname = grub_malloc (vgname_len + 1); @@ -376,7 +396,12 @@ grub_lvm_scan_device (const char *name) p = grub_strstr (q, "id = \""); if (p == NULL) - goto fail3; + { +#ifdef GRUB_UTIL + grub_util_info ("couldn't find ID\n"); +#endif + goto fail3; + } p += sizeof ("id = \"") - 1; grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN); vg_id[GRUB_LVM_ID_STRLEN] = '\0'; @@ -399,7 +424,12 @@ grub_lvm_scan_device (const char *name) vg->extent_size = grub_lvm_getvalue (&p, "extent_size = "); if (p == NULL) - goto fail4; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown extent size\n"); +#endif + goto fail4; + } vg->lvs = NULL; vg->pvs = NULL; @@ -439,11 +469,21 @@ grub_lvm_scan_device (const char *name) pv->start = grub_lvm_getvalue (&p, "pe_start = "); if (p == NULL) - goto pvs_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown pe_start\n"); +#endif + goto pvs_fail; + } p = grub_strchr (p, '}'); if (p == NULL) - goto pvs_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("error parsing pe_start\n"); +#endif + goto pvs_fail; + } p++; pv->disk = NULL; @@ -500,7 +540,12 @@ grub_lvm_scan_device (const char *name) lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); if (p == NULL) - goto lvs_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown segment_count\n"); +#endif + goto lvs_fail; + } lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count); seg = lv->segments; @@ -510,14 +555,29 @@ grub_lvm_scan_device (const char *name) p = grub_strstr (p, "segment"); if (p == NULL) - goto lvs_segment_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown segment\n"); +#endif + goto lvs_segment_fail; + } seg->start_extent = grub_lvm_getvalue (&p, "start_extent = "); if (p == NULL) - goto lvs_segment_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown start_extent\n"); +#endif + goto lvs_segment_fail; + } seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); if (p == NULL) - goto lvs_segment_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown extent_count\n"); +#endif + goto lvs_segment_fail; + } if (grub_lvm_checkvalue (&p, "type = ", "snapshot")) { @@ -528,7 +588,12 @@ grub_lvm_scan_device (const char *name) seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); if (p == NULL) - goto lvs_segment_fail; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown stripe_count\n"); +#endif + goto lvs_segment_fail; + } lv->size += seg->extent_count * vg->extent_size; @@ -541,7 +606,12 @@ grub_lvm_scan_device (const char *name) p = grub_strstr (p, "stripes = ["); if (p == NULL) - goto lvs_segment_fail2; + { +#ifdef GRUB_UTIL + grub_util_info ("unknown stripes\n"); +#endif + goto lvs_segment_fail2; + } p += sizeof("stripes = [") - 1; for (j = 0; j < seg->stripe_count; j++) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c new file mode 100644 index 000000000..a50bae000 --- /dev/null +++ b/grub-core/fs/btrfs.c @@ -0,0 +1,132 @@ +/* btrfs.c - B-tree file system. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BTRFS_SIGNATURE "_BHRfS_M" + +struct btrfs_superblock +{ + grub_uint8_t dummy1[32]; + grub_uint16_t uuid[8]; + grub_uint8_t dummy2[16]; + grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1]; +} __attribute__ ((packed)); + +struct grub_btrfs_data +{ + struct btrfs_superblock sblock; +}; + +static struct grub_btrfs_data * +grub_btrfs_mount (grub_disk_t disk) +{ + struct grub_btrfs_data *data = grub_malloc (sizeof (*data)); + if (! data) + return NULL; + + if (grub_disk_read (disk, 128, 0, sizeof (data->sblock), + &data->sblock) != GRUB_ERR_NONE) + goto fail; + + if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1)) + { + grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); + goto fail; + } + + return data; + + fail: + grub_free (data); + return NULL; +} + +static grub_err_t +grub_btrfs_open (struct grub_file *file __attribute__ ((unused)), + const char *name __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs"); +} + +static grub_err_t +grub_btrfs_dir (grub_device_t device, + const char *path __attribute__ ((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) + __attribute__ ((unused))) +{ + struct grub_btrfs_data *data = grub_btrfs_mount (device->disk); + if (grub_errno) + return grub_errno; + + grub_free (data); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_btrfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_btrfs_data *data; + + *uuid = NULL; + + data = grub_btrfs_mount (device->disk); + if (! data) + return grub_errno; + + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); + + grub_free (data); + + return grub_errno; +} + +static struct grub_fs grub_btrfs_fs = + { + .name = "btrfs", + .dir = grub_btrfs_dir, + .open = grub_btrfs_open, + .uuid = grub_btrfs_uuid, + }; + +GRUB_MOD_INIT(btrfs) +{ + grub_fs_register (&grub_btrfs_fs); +} + +GRUB_MOD_FINI(btrfs) +{ + grub_fs_unregister (&grub_btrfs_fs); +} diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index a856e38c4..aa5b9a0c9 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -25,10 +25,13 @@ #include #include +#ifdef MODE_MINIX2 +#define GRUB_MINIX_MAGIC 0x2468 +#define GRUB_MINIX_MAGIC_30 0x2478 +#else #define GRUB_MINIX_MAGIC 0x137F -#define GRUB_MINIX2_MAGIC 0x2468 #define GRUB_MINIX_MAGIC_30 0x138F -#define GRUB_MINIX2_MAGIC_30 0x2478 +#endif #define GRUB_MINIX_BSIZE 1024U #define GRUB_MINIX_LOG2_BSIZE 1 #define GRUB_MINIX_ROOT_INODE 1 @@ -38,20 +41,25 @@ #define GRUB_MINIX_IFDIR 0040000U #define GRUB_MINIX_IFLNK 0120000U -#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \ - data->inode. field : data->inode2. field) -#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ? \ - grub_le_to_cpu##bits1 (data->inode.field) : \ - grub_le_to_cpu##bits2 (data->inode2.field)) -#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32) -#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16) -#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN \ - (data,dir_zones[blk],16,32) -#define GRUB_MINIX_INODE_INDIR_ZONE(data) \ - GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32) -#define GRUB_MINIX_INODE_DINDIR_ZONE(data) \ - GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32) -#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4) +#ifdef MODE_MINIX2 +typedef grub_uint32_t grub_minix_uintn_t; +#define grub_minix_le_to_cpu_n grub_le_to_cpu32 +#else +typedef grub_uint16_t grub_minix_uintn_t; +#define grub_minix_le_to_cpu_n grub_le_to_cpu16 +#endif + +#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t) + +#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size)) +#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode)) +#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \ + (data->inode.dir_zones[blk])) +#define GRUB_MINIX_INODE_INDIR_ZONE(data) (grub_minix_le_to_cpu_n \ + (data->inode.indir_zone)) +#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \ + (data->inode.double_indir_zone)) + #define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ + grub_le_to_cpu16 (sblock->log2_zone_size)) #define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \ @@ -69,6 +77,7 @@ struct grub_minix_sblock grub_uint16_t magic; }; +#ifndef MODE_MINIX2 struct grub_minix_inode { grub_uint16_t mode; @@ -82,7 +91,9 @@ struct grub_minix_inode grub_uint16_t double_indir_zone; }; -struct grub_minix2_inode +#else + +struct grub_minix_inode { grub_uint16_t mode; grub_uint16_t nlinks; @@ -99,16 +110,16 @@ struct grub_minix2_inode }; +#endif + /* Information about a "mounted" minix filesystem. */ struct grub_minix_data { struct grub_minix_sblock sblock; struct grub_minix_inode inode; - struct grub_minix2_inode inode2; int ino; int linknest; grub_disk_t disk; - int version; int filename_size; }; @@ -128,24 +139,12 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) /* Read the block pointer in ZONE, on the offset NUM. */ int grub_get_indir (int zone, int num) { - if (data->version == 1) - { - grub_uint16_t indir16; - grub_disk_read (data->disk, - zone << GRUB_MINIX_LOG2_ZONESZ, - sizeof (grub_uint16_t) * num, - sizeof (grub_uint16_t), (char *) &indir16); - return grub_le_to_cpu16 (indir16); - } - else - { - grub_uint32_t indir32; - grub_disk_read (data->disk, - zone << GRUB_MINIX_LOG2_ZONESZ, - sizeof (grub_uint32_t) * num, - sizeof (grub_uint32_t), (char *) &indir32); - return grub_le_to_cpu32 (indir32); - } + grub_minix_uintn_t indirn; + grub_disk_read (data->disk, + zone << GRUB_MINIX_LOG2_ZONESZ, + sizeof (grub_minix_uintn_t) * num, + sizeof (grub_minix_uintn_t), (char *) &indirn); + return grub_minix_le_to_cpu_n (indirn); } /* Direct block. */ @@ -259,27 +258,13 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino) + grub_le_to_cpu16 (sblock->zone_bmap_size)) << GRUB_MINIX_LOG2_BSIZE); - if (data->version == 1) - { - block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)); - int offs = (ino % (GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_minix_inode)) - * sizeof (struct grub_minix_inode)); - - grub_disk_read (data->disk, block, offs, - sizeof (struct grub_minix_inode), &data->inode); - } - else - { - block += ino / (GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_minix2_inode)); - int offs = (ino - % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode)) - * sizeof (struct grub_minix2_inode)); - - grub_disk_read (data->disk, block, offs, - sizeof (struct grub_minix2_inode),&data->inode2); - } + block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)); + int offs = (ino % (GRUB_DISK_SECTOR_SIZE + / sizeof (struct grub_minix_inode)) + * sizeof (struct grub_minix_inode)); + + grub_disk_read (data->disk, block, offs, + sizeof (struct grub_minix_inode), &data->inode); return GRUB_ERR_NONE; } @@ -424,25 +409,9 @@ grub_minix_mount (grub_disk_t disk) goto fail; if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC) - { - data->version = 1; - data->filename_size = 14; - } - else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC) - { - data->version = 2; - data->filename_size = 14; - } + data->filename_size = 14; else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30) - { - data->version = 1; - data->filename_size = 30; - } - else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30) - { - data->version = 2; - data->filename_size = 30; - } + data->filename_size = 30; else goto fail; @@ -453,7 +422,11 @@ grub_minix_mount (grub_disk_t disk) fail: grub_free (data); +#ifdef MODE_MINIX2 + grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem"); +#else grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem"); +#endif return 0; } @@ -583,32 +556,36 @@ grub_minix_close (grub_file_t file) } -static grub_err_t -grub_minix_label (grub_device_t device __attribute ((unused)), - char **label __attribute ((unused))) -{ - return GRUB_ERR_NONE; -} - static struct grub_fs grub_minix_fs = { +#ifdef MODE_MINIX2 + .name = "minix2", +#else .name = "minix", +#endif .dir = grub_minix_dir, .open = grub_minix_open, .read = grub_minix_read, .close = grub_minix_close, - .label = grub_minix_label, .next = 0 }; +#ifdef MODE_MINIX2 +GRUB_MOD_INIT(minix2) +#else GRUB_MOD_INIT(minix) +#endif { grub_fs_register (&grub_minix_fs); my_mod = mod; } +#ifdef MODE_MINIX2 +GRUB_MOD_FINI(minix2) +#else GRUB_MOD_FINI(minix) +#endif { grub_fs_unregister (&grub_minix_fs); } diff --git a/grub-core/fs/minix2.c b/grub-core/fs/minix2.c new file mode 100644 index 000000000..0fcd4b139 --- /dev/null +++ b/grub-core/fs/minix2.c @@ -0,0 +1,2 @@ +#define MODE_MINIX2 1 +#include "minix.c" diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index c124aa292..1b0a872b4 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -66,10 +66,33 @@ grub_efi_set_prefix (void) path = grub_strdup (pptr); } - if (!device || !path) + if ((!device || device[0] == ',' || !device[0]) || !path) image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image && !device) - device = grub_efidisk_get_device_name (image->device_handle); + if (image) + { + if (!device) + device = grub_efidisk_get_device_name (image->device_handle); + else if (device[0] == ',' || !device[0]) + { + /* We have a partition, but still need to fill in the drive. */ + char *image_device, *comma, *new_device; + + image_device = grub_efidisk_get_device_name (image->device_handle); + comma = grub_strchr (image_device, ','); + if (comma) + { + char *drive = grub_strndup (image_device, comma - image_device); + new_device = grub_xasprintf ("%s%s", drive, device); + grub_free (drive); + } + else + new_device = grub_xasprintf ("%s%s", image_device, device); + + grub_free (image_device); + grub_free (device); + device = new_device; + } + } if (image && !path) { diff --git a/grub-core/kern/emu/cache.S b/grub-core/kern/emu/cache.S index 90a5b5396..abd81c910 100644 --- a/grub-core/kern/emu/cache.S +++ b/grub-core/kern/emu/cache.S @@ -7,7 +7,20 @@ #elif defined(__sparc__) #include "../sparc64/cache.S" #elif defined(__mips__) -#include "../mips/cache.S" +/* On MIPS we must go through standard functions. */ +#include + +FUNCTION (grub_cpu_flush_cache) +FUNCTION (grub_arch_sync_caches) + .set nomacro + .set noreorder + lui $t0, %hi(_flush_cache) + addui $t0, $t0, %lo(_flush_cache) + move $a3, $zero + jr $t0 + nop + .set reorder + .set macro #elif defined(__powerpc__) #include "../powerpc/cache.S" #else diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 0bd33337f..a5801db2f 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -22,6 +22,7 @@ #include #include #include +#include void grub_register_exported_symbols (void) @@ -48,3 +49,21 @@ grub_emu_init (void) { grub_no_autoload = 1; } + +#ifdef GRUB_LINKER_HAVE_INIT +void +grub_arch_dl_init_linker (void) +{ +} +#endif + +void +grub_emu_post_init (void) +{ + grub_lvm_fini (); + grub_mdraid_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid_init (); + grub_lvm_init (); +} diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index 9b3728717..32e12a079 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -38,3 +38,8 @@ grub_emu_init (void) { return; } + +void +grub_emu_post_init (void) +{ +} diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 9156aa890..23b8516f1 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -197,6 +197,8 @@ main (int argc, char *argv[]) grub_init_all (); + grub_emu_post_init (); + /* Make sure that there is a root device. */ if (! root_dev) { diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 82f579616..c710777ea 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -61,6 +61,15 @@ # include #endif +#ifdef HAVE_SYS_MNTTAB_H +# include /* Needed by sys/mnttab.h. */ +# include +#endif + +#ifdef HAVE_SYS_MKDEV_H +# include /* makedev */ +#endif + int verbosity; void @@ -282,18 +291,52 @@ grub_get_libzfs_handle (void) void grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) { - struct statfs mnt; char *slash; *poolname = *poolfs = NULL; - if (statfs (dir, &mnt) != 0) - return; +#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME) + /* FreeBSD and GNU/kFreeBSD. */ + { + struct statfs mnt; - if (strcmp (mnt.f_fstypename, "zfs") != 0) - return; + if (statfs (dir, &mnt) != 0) + return; - *poolname = xstrdup (mnt.f_mntfromname); + if (strcmp (mnt.f_fstypename, "zfs") != 0) + return; + + *poolname = xstrdup (mnt.f_mntfromname); + } +#elif defined(HAVE_GETEXTMNTENT) + /* Solaris. */ + { + struct stat st; + struct extmnttab mnt; + + if (stat (dir, &st) != 0) + return; + + FILE *mnttab = fopen ("/etc/mnttab", "r"); + if (! mnttab) + return; + + while (getextmntent (mnttab, &mnt, sizeof (mnt)) == 0) + { + if (makedev (mnt.mnt_major, mnt.mnt_minor) == st.st_dev + && !strcmp (mnt.mnt_fstype, "zfs")) + { + *poolname = xstrdup (mnt.mnt_special); + break; + } + } + + fclose (mnttab); + } +#endif + + if (! *poolname) + return; slash = strchr (*poolname, '/'); if (slash) diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index d3c3a8d88..30eacbbdd 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -138,11 +138,16 @@ grub_ieee1275_find_options (void) */ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); } if (is_qemu) - /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); + { + /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); + + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); + } if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) { diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 694de097b..832b6cd1a 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -296,6 +296,7 @@ adjust_file (const char *in, grub_size_t len) *outptr++ = *ptr; } + *outptr = 0; return ret; } diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index a7baee96c..e24c4b1af 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -547,13 +547,32 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_script_function_t func = 0; char errnobuf[18]; char *cmdname; + int argc; + char **args; + int invert; struct grub_script_argv argv = { 0, 0, 0 }; /* Lookup the command. */ if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0]) return grub_errno; + invert = 0; + argc = argv.argc - 1; + args = argv.args + 1; cmdname = argv.args[0]; + if (grub_strcmp (cmdname, "!") == 0) + { + if (argv.argc < 2 || ! argv.args[1]) + { + grub_script_argv_free (&argv); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments"); + } + + invert = 1; + argc = argv.argc - 2; + args = argv.args + 2; + cmdname = argv.args[1]; + } grubcmd = grub_command_find (cmdname); if (! grubcmd) { @@ -594,13 +613,25 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) { if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) - ret = grub_extcmd_dispatcher (grubcmd, argv.argc - 1, argv.args + 1, - argv.script); + ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script); else - ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1); + ret = (grubcmd->func) (grubcmd, argc, args); } else - ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1); + ret = grub_script_function_call (func, argc, args); + + if (invert) + { + if (ret == GRUB_ERR_TEST_FAILURE) + grub_errno = ret = GRUB_ERR_NONE; + else if (ret == GRUB_ERR_NONE) + ret = grub_error (GRUB_ERR_TEST_FAILURE, "false"); + else + { + grub_print_error (); + ret = GRUB_ERR_NONE; + } + } /* Free arguments. */ grub_script_argv_free (&argv); diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index d4cad8097..55620b6bd 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -155,7 +155,6 @@ MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n)) ">" { RECORD; return GRUB_PARSER_TOKEN_GT; } /* Reserved words */ -"!" { RECORD; return GRUB_PARSER_TOKEN_NOT; } "{" { RECORD; return GRUB_PARSER_TOKEN_LBR; } "}" { RECORD; return GRUB_PARSER_TOKEN_RBR; } "[[" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; } diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c index 9ec85631b..1e8fbd1ad 100644 --- a/grub-core/term/ieee1275/ofconsole.c +++ b/grub-core/term/ieee1275/ofconsole.c @@ -117,9 +117,14 @@ grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused))) } static void -grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)), +grub_ofconsole_setcursor (struct grub_term_output *term, int on) { + grub_terminfo_setcursor (term, on); + + if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF)) + return; + /* Understood by the Open Firmware flavour in OLPC. */ if (on) grub_ieee1275_interpret ("cursor-on", 0); diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c index 9c9477c2b..501ba7c2f 100644 --- a/grub-core/video/ieee1275.c +++ b/grub-core/video/ieee1275.c @@ -32,6 +32,8 @@ static unsigned old_width, old_height; static int restore_needed; static char *display; +static grub_ieee1275_ihandle_t stdout_ihandle; +static int have_setcolors = 0; static struct { @@ -72,7 +74,17 @@ find_display (void) static grub_err_t grub_video_ieee1275_init (void) { + grub_ssize_t actual; + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS) + && !grub_ieee1275_get_integer_property (grub_ieee1275_chosen, + "stdout", &stdout_ihandle, + sizeof (stdout_ihandle), &actual) + && actual == sizeof (stdout_ihandle)) + have_setcolors = 1; + return grub_video_fb_init (); } @@ -169,9 +181,6 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, /* For some reason sparc64 uses 32-bit pointer too. */ framebuffer.ptr = (void *) (grub_addr_t) address; - grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); @@ -192,15 +201,10 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n"); return err; } - - err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - if (err) - grub_dprintf ("video", "IEEE1275: Couldn't set palette\n"); - else - grub_dprintf ("video", "IEEE1275: Success\n"); - + grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + return err; } @@ -243,9 +247,17 @@ grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, if (err) return err; - grub_video_fb_get_palette (0, 256, fb_palette_data); + grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data); - /* TODO. */ + /* Set colors. */ + if (have_setcolors) + { + unsigned col; + for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++) + grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r, + fb_palette_data[col].g, + fb_palette_data[col].b); + } return GRUB_ERR_NONE; } diff --git a/include/grub/acpi.h b/include/grub/acpi.h index 7933db824..aebc8dd4f 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -53,17 +53,92 @@ struct grub_acpi_table_header grub_uint32_t creator_rev; } __attribute__ ((packed)); +#define GRUB_ACPI_FADT_SIGNATURE "FACP" + struct grub_acpi_fadt { struct grub_acpi_table_header hdr; grub_uint32_t facs_addr; grub_uint32_t dsdt_addr; - grub_uint8_t somefields1[88]; + grub_uint8_t somefields1[20]; + grub_uint32_t pm1a; + grub_uint8_t somefields2[64]; grub_uint64_t facs_xaddr; grub_uint64_t dsdt_xaddr; - grub_uint8_t somefields2[96]; + grub_uint8_t somefields3[96]; } __attribute__ ((packed)); +#define GRUB_ACPI_MADT_SIGNATURE "APIC" + +struct grub_acpi_madt_entry_header +{ + grub_uint8_t type; + grub_uint8_t len; +}; + +struct grub_acpi_madt +{ + struct grub_acpi_table_header hdr; + grub_uint32_t lapic_addr; + grub_uint32_t flags; + struct grub_acpi_madt_entry_header entries[0]; +}; + +enum + { + GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2, + GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6, + GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7, + GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8 + }; + +struct grub_acpi_madt_entry_interrupt_override +{ + struct grub_acpi_madt_entry_header hdr; + grub_uint8_t bus; + grub_uint8_t source; + grub_uint32_t global_sys_interrupt; + grub_uint16_t flags; +}; + +struct grub_acpi_madt_entry_sapic +{ + struct grub_acpi_madt_entry_header hdr; + grub_uint8_t id; + grub_uint8_t pad; + grub_uint32_t global_sys_interrupt_base; + grub_uint64_t addr; +}; + +struct grub_acpi_madt_entry_lsapic +{ + struct grub_acpi_madt_entry_header hdr; + grub_uint8_t cpu_id; + grub_uint8_t id; + grub_uint8_t eid; + grub_uint8_t pad[3]; + grub_uint32_t flags; + grub_uint32_t cpu_uid; + grub_uint8_t cpu_uid_str[0]; +}; + +struct grub_acpi_madt_entry_platform_int_source +{ + struct grub_acpi_madt_entry_header hdr; + grub_uint16_t flags; + grub_uint8_t inttype; + grub_uint8_t cpu_id; + grub_uint8_t cpu_eid; + grub_uint8_t sapic_vector; + grub_uint32_t global_sys_int; + grub_uint32_t src_flags; +}; + +enum + { + GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1 + }; + struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void); struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void); struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void); @@ -72,4 +147,25 @@ grub_uint8_t grub_byte_checksum (void *base, grub_size_t size); grub_err_t grub_acpi_create_ebda (void); +void grub_acpi_halt (void); + +#define GRUB_ACPI_SLP_EN (1 << 13) +#define GRUB_ACPI_SLP_TYP_OFFSET 10 + +enum + { + GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1, + GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a, + GRUB_ACPI_OPCODE_WORD_CONST = 0x0b, GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c, + GRUB_ACPI_OPCODE_SCOPE = 0x10, GRUB_ACPI_OPCODE_PACKAGE = 0x12, + GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b, + GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff + }; +enum + { + GRUB_ACPI_EXTOPCODE_MUTEX = 0x01, + GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80, + GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81 + }; + #endif /* ! GRUB_ACPI_HEADER */ diff --git a/include/grub/cache.h b/include/grub/cache.h index 27e44f0a2..4f913f5c8 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -23,6 +23,10 @@ #include #include +#ifdef _mips +#include +#endif + #if defined (__i386__) || defined (__x86_64__) static inline void grub_arch_sync_caches (void *address __attribute__ ((unused)), diff --git a/include/grub/disk.h b/include/grub/disk.h index e7f807e0e..b41f89b38 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -177,4 +177,13 @@ struct grub_disk_ata_pass_through_parms extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t, struct grub_disk_ata_pass_through_parms *); +#if defined (GRUB_UTIL) || defined (GRUB_MACHINE_EMU) +void grub_lvm_init (void); +void grub_mdraid_init (void); +void grub_raid_init (void); +void grub_lvm_fini (void); +void grub_mdraid_fini (void); +void grub_raid_fini (void); +#endif + #endif /* ! GRUB_DISK_HEADER */ diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e9038c916..972bc4efc 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -45,6 +45,7 @@ extern const char *program_name; void grub_emu_init (void); void grub_init_all (void); void grub_fini_all (void); +void grub_emu_post_init (void); void grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs); diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index b30909c68..6835b5abc 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -103,6 +103,9 @@ enum grub_ieee1275_flag /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM, + + /* OLPC / XO firmware has the cursor ON/OFF routines. */ + GRUB_IEEE1275_FLAG_HAS_CURSORONOFF, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/include/grub/mips/time.h b/include/grub/mips/time.h index e69de29bb..b143a48e0 100644 --- a/include/grub/mips/time.h +++ b/include/grub/mips/time.h @@ -0,0 +1,6 @@ +#ifdef GRUB_MACHINE_EMU +static inline void +grub_cpu_idle(void) +{ +} +#endif diff --git a/include/grub/normal.h b/include/grub/normal.h index 51ab46b12..df7f70142 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -115,4 +115,9 @@ void grub_normal_reset_more (void); void grub_xputs_normal (const char *str); +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode); + #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/types.h b/include/grub/types.h index 4499e4538..1cabc2ecf 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -69,10 +69,14 @@ typedef long long grub_int64_t; typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; typedef unsigned grub_uint32_t; +# define PRIxGRUB_UINT32_T "x" +# define PRIuGRUB_UINT32_T "u" #if GRUB_CPU_SIZEOF_LONG == 8 typedef unsigned long grub_uint64_t; +# define PRIxGRUB_UINT64_T "lx" #else typedef unsigned long long grub_uint64_t; +# define PRIxGRUB_UINT64_T "llx" #endif /* Misc types. */ diff --git a/tests/grub_script_not.in b/tests/grub_script_not.in new file mode 100644 index 000000000..ff71039a6 --- /dev/null +++ b/tests/grub_script_not.in @@ -0,0 +1,62 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +true +echo $? + +! true +echo $? + +false +echo $? + +! false +echo $? + +# +# Negated forms (copied from grub_script_if.in) +# + +#basic if, execute +if ! true; then echo yes; fi + +#basic if, no execution +if ! false; then echo no; fi + +#if else, execute if path +if ! true; then echo yes; else echo no; fi + +#if else, execute else path +if ! false; then echo no; else echo yes; fi + +#if elif, execute elif +if ! false; then echo no; elif ! true; then echo yes; fi + +#if elif else, execute else +if ! false; then echo no; elif ! false; then echo no; else echo yes; fi + +#if elif(1) elif(2), execute elif(2) +if false; then echo no; elif ! false; then echo no; elif ! true; then echo yes; fi + +#if elif(1) elif(2) else, execute else +if false; then echo no; elif false; then echo no; elif ! false; then echo no; else echo yes; fi + +#if {if elif else}, execute elif +if true; then if false; then echo no; elif ! true; then echo yes; else echo no; fi; fi + +#if {if elif} else, execute elif. ofcourse no dangling-else problem due to "fi" +if true; then if ! false; then echo no; elif true; then echo yes; fi; else echo no; fi diff --git a/tests/partmap_test.in b/tests/partmap_test.in new file mode 100644 index 000000000..14897e9da --- /dev/null +++ b/tests/partmap_test.in @@ -0,0 +1,274 @@ +#! /bin/sh -e +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +parted=/sbin/parted +grubshell=@builddir@/grub-shell + +create_disk_image () { + name=$1 + size=$2 + qemu-img create ${name} ${size} >/dev/null +} + +check_output () { + outfile=$1 + shift + + for disk in $@; do + if ! grep "($disk)" ${outfile} >/dev/null + then + echo "($disk): disk/partiton not found" + exit 1 + fi + done +} + +list_parts () { + mod=$1; + shift; + imgfile=$1 + shift + outfile=$1 + shift + + echo ls | ${grubshell} --boot=cd --qemu-opts="-hda ${imgfile}" \ + --modules=$mod | tr -d "\n\r" > ${outfile} + cat ${outfile} + echo +} + +imgfile=`mktemp` +outfile=`mktemp` + +# +# MSDOS partition types +# + +echo "Checking MSDOS partition types..." + +# 0 primary +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel msdos +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 + +# 1 primary +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 + +# 2 primary +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos2 + +# 3 primary +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart primary 20M 30M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos2 hd0,msdos3 + +# 4 primary +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart primary 20M 30M mkpart primary 30M 40M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos2 hd0,msdos3 hd0,msdos4 + +# 1 primary, 1 extended +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart extended 20M 100% +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 + +# 1 primary, 1 extended, 1 logical +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart extended 20M 100% mkpart logical 20M 30M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos5 + +# 1 primary, 1 extended, 2 logical +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart extended 20M 100% mkpart logical 20M 30M mkpart logical 30M 40M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos5 hd0,msdos6 + +# 1 primary, 1 extended, 3 logical +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart extended 20M 100% mkpart logical 20M 30M mkpart logical 30M 40M mkpart logical 40M 50M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos5 hd0,msdos6 hd0,msdos7 + +# 1 primary, 1 extended, 4 logical +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel msdos mkpart primary 0 10M mkpart primary 10M 20M mkpart extended 20M 100% mkpart logical 20M 30M mkpart logical 30M 40M mkpart logical 40M 50M mkpart logical 50M 60M +list_parts part_msdos ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,msdos1 hd0,msdos5 hd0,msdos6 hd0,msdos7 hd0,msdos8 + + +# +# GPT partition types +# + +echo "Checking GPT partition types..." + +# 0 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel gpt +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 + +# 1 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 + +# 2 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M mkpart 2 10M 20M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 hd0,gpt2 + +# 3 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M mkpart 2 10M 20M mkpart 3 20M 30M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 hd0,gpt2 hd0,gpt3 + +# 4 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M mkpart 2 10M 20M mkpart 4 20M 30M mkpart 5 30M 40M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 hd0,gpt2 hd0,gpt3 hd0,gpt4 + +# 5 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M mkpart 2 10M 20M mkpart 3 20M 30M mkpart 4 30M 40M mkpart 5 40M 50M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 hd0,gpt2 hd0,gpt3 hd0,gpt4 hd0,gpt5 + +# 6 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel gpt mkpart 1 0 10M mkpart 2 10M 20M mkpart 3 20M 30M mkpart 4 30M 40M mkpart 5 40M 50M mkpart 6 50M 60M +list_parts part_gpt ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,gpt1 hd0,gpt2 hd0,gpt3 hd0,gpt4 hd0,gpt5 hd0,gpt6 + + +# +# SUN partition types +# +# It seems partition #3 is reserved for whole disk by parted. +# + +echo "Checking SUN partition types..." + +# 0 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel sun +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 + +# 1 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 + +# 2 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M mkpart 10M 20M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 hd0,sun2 + +# 3 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M mkpart 10M 20M mkpart 20M 30M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 hd0,sun2 hd0,sun4 + +# 4 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M mkpart 10M 20M mkpart 20M 30M mkpart 30M 40M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 hd0,sun2 hd0,sun4 hd0,sun5 + +# 5 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M mkpart 10M 20M mkpart 20M 30M mkpart 30M 40M mkpart 40M 50M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 hd0,sun2 hd0,sun4 hd0,sun5 hd0,sun6 + +# 6 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel sun mkpart 0 10M mkpart 10M 20M mkpart 20M 30M mkpart 30M 40M mkpart 40M 50M mkpart 50M 60M +list_parts part_sun ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,sun1 hd0,sun2 hd0,sun4 hd0,sun5 hd0,sun6 hd0,sun7 + + +# +# Apple partition types +# +# Partition table itself is part of some partition, so there is always +# a partition by default. But I don't understand why GRUB displays +# two partitions by default :-( +# + +echo "Checking APPLE partition types..." + +# 0 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel mac +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 + +# 1 parts +create_disk_image ${imgfile} 64M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple3 + +# 2 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M mkpart b 10M 20M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple3 hd0,apple4 + +# 3 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M mkpart b 10M 20M mkpart c 20M 30M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple4 hd0,apple5 + +# 4 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M mkpart b 10M 20M mkpart c 20M 30M mkpart d 30M 40M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple4 hd0,apple5 hd0,apple6 + +# 5 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M mkpart b 10M 20M mkpart c 20M 30M mkpart d 30M 40M mkpart e 40M 50M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple4 hd0,apple5 hd0,apple6 hd0,apple7 + +# 6 parts +create_disk_image ${imgfile} 128M +${parted} -a none -s ${imgfile} mklabel mac mkpart a 1M 10M mkpart b 10M 20M mkpart c 20M 30M mkpart d 30M 40M mkpart e 40M 50M mkpart f 50M 60M +list_parts part_apple ${imgfile} ${outfile} +check_output ${outfile} hd0 hd0,apple1 hd0,apple2 hd0,apple4 hd0,apple5 hd0,apple6 hd0,apple7 hd0,apple8 diff --git a/util/grub-install.in b/util/grub-install.in index e6521f069..ef1778b2a 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -1,7 +1,7 @@ #! /bin/sh # Install GRUB on your drive. -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,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 @@ -41,7 +41,8 @@ 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}` +bootdir= +grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` modules= install_device= @@ -69,8 +70,8 @@ Install GRUB on your drive. -h, --help print this message and exit -v, --version print the version information and exit --modules=MODULES pre-load specified modules MODULES - --root-directory=DIR install GRUB images under the directory DIR - instead of the root directory + --boot-directory=DIR install GRUB images under the directory DIR/@grubdirname@ + instead of the $grubdir directory --grub-setup=FILE use FILE as grub-setup --grub-mkimage=FILE use FILE as grub-mkimage --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap @@ -88,11 +89,8 @@ fi INSTALL_DEVICE can be a GRUB device name or a system device filename. -$self copies GRUB images into /boot/grub (or /grub on NetBSD and -OpenBSD), and uses grub-setup to install grub into the boot sector. - -If the --root-directory option is used, then $self will copy -images into the operating system installation rooted at that directory. +$self copies GRUB images into $grubdir, and uses grub-setup +to install grub into the boot sector. Report bugs to . EOF @@ -134,11 +132,17 @@ do --font=*) ;; +# Accept for compatibility --root-directory) rootdir=`argument $option "$@"`; shift;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --boot-directory) + bootdir=`argument $option "$@"`; shift;; + --boot-directory=*) + bootdir=`echo "$option" | sed 's/--boot-directory=//'` ;; + --grub-setup) grub_setup=`argument $option "$@"`; shift;; --grub-setup=*) @@ -215,23 +219,18 @@ if test $debug = yes; then setup_verbose="--verbose" 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 +if [ -z "$bootdir" ]; then + # Default bootdir if bootdir not initialized. + bootdir=/@bootdirname@ -grubdir=${bootdir}/`echo grub | sed ${transform}` + if [ -n "$rootdir" ] ; then + # Initialize bootdir if rootdir was initialized. + bootdir=${rootdir}/@bootdirname@ + fi +fi + +grubdir=`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'` device_map=${grubdir}/device.map - grub_probe="${grub_probe} --device-map=${device_map}" # Check if GRUB is installed. @@ -328,8 +327,7 @@ if test "x$fs_module" = x -a "x$modules" = x; then fi # Then the partition map module. In order to support partition-less media, -# this command is allowed to fail (--target=fs already grants us that the -# filesystem will be accessible). +# this command is allowed to fail. partmap_module= for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do partmap_module="$partmap_module part_$x"; @@ -369,6 +367,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 # Strip partition number + grub_partition="`echo ${grub_drive} | sed -e 's/^[^,]*,//; s/)$//'`" grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) @@ -391,6 +390,9 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" + elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then + # we need to hardcode the partition number in the core image's prefix. + prefix_drive="(,$grub_partition)" fi else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 @@ -403,9 +405,24 @@ case "${target_cpu}-${platform}" in *) mkimage_target=i386-coreboot; esac +# Verify readability of a few critical files +for file in grubenv normal.mod ; do + if is_path_readable_by_grub ${grubdir}/${file} ${grub_device} ${relative_grubdir}/${file} ; then : ; else + echo "GRUB is unable to read ${grubdir}/${file}" >&2 + exit 1 + fi +done + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + # This is a temporary workaround; it can be merged back into the check + # above once the install branch is merged. + if is_path_readable_by_grub ${grubdir}/core.img ${grub_device} ${relative_grubdir}/core.img ; then : ; else + echo "GRUB is unable to read ${grubdir}/core.img" >&2 + exit 1 + fi + # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 828b54bce..fa84c63d1 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -38,6 +38,8 @@ self=`basename $0` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +GRUB_PREFIX=`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"` + # Usage: usage # Print the usage. usage () { @@ -93,18 +95,6 @@ done . ${libdir}/grub/grub-mkconfig_lib -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}` - ;; -*) - # Use /boot/grub by default. - GRUB_PREFIX=`echo /boot/grub | sed ${transform}` - ;; -esac - if [ "x$EUID" = "x" ] ; then EUID=`id -u` fi @@ -158,7 +148,7 @@ GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_u # Filesystem for the device containing our userland. Used for stuff like # choosing Hurd filesystem module. -GRUB_FS="`${grub_probe} --target=fs / 2> /dev/null || echo unknown`" +GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub @@ -200,7 +190,7 @@ for x in ${GRUB_TERMINAL_OUTPUT}; do exit 1 fi else - for dir in ${pkgdatadir} /boot/grub /usr/share/grub ; do + for dir in ${pkgdatadir} ${GRUB_PREFIX} /usr/share/grub ; do for basename in unicode unifont ascii; do path="${dir}/${basename}.pf2" if is_path_readable_by_grub ${path} > /dev/null ; then @@ -313,6 +303,14 @@ for i in ${grub_mkconfig_dir}/* ; do esac done +# Verify readability of ${grub_cfg}.new +if test "x${grub_cfg}" != "x"; then + if is_path_readable_by_grub ${grub_cfg}.new ; then : ; else + echo "GRUB is unable to read ${grubdir}/${file}" >&2 + exit 1 + fi +fi + if test "x${grub_cfg}" != "x" ; then # none of the children aborted with error, install the new grub.cfg mv -f ${grub_cfg}.new ${grub_cfg} diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 9a77d1bdf..6d4f9f3bb 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -30,6 +30,9 @@ fi if test "x$grub_mkrelpath" = x; then grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` fi +if test "x$grub_fstest" = x; then + grub_fstest=${bindir}/`echo grub-fstest | sed ${transform}` +fi if $(which gettext >/dev/null 2>/dev/null) ; then gettext="gettext" @@ -50,14 +53,24 @@ make_system_path_relative_to_its_root () is_path_readable_by_grub () { path=$1 + device=$2 + relpath=$3 # abort if path doesn't exist if test -e $path ; then : ;else return 1 fi - # abort if file is in a filesystem we can't read - if ${grub_probe} -t fs $path > /dev/null 2>&1 ; then : ; else + if [ "${device}" = "" ] ; then + device=$(${grub_probe} --target=device $path) + fi + if [ "${relpath}" = "" ] ; then + relpath=$(${grub_mkrelpath} $path) + fi + + # abort if file read through GRUB doesn't match file read through system + # facilities + if ${grub_fstest} $device cmp $relpath $path > /dev/null 2>&1 ; then : ; else return 1 fi diff --git a/util/grub-probe.c b/util/grub-probe.c index 62206bf0e..9f8a443c8 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -226,49 +226,16 @@ probe (const char *path, char *device_name) if (print == PRINT_FS) { - if (path) - { - struct stat st; - - stat (path, &st); - - if (S_ISREG (st.st_mode)) - { - /* Regular file. Verify that we can read it properly. */ - - grub_file_t file; - char *rel_path; - grub_util_info ("reading %s via OS facilities", path); - filebuf_via_sys = grub_util_read_image (path); - - rel_path = grub_make_system_path_relative_to_its_root (path); - grub_path = xasprintf ("(%s)%s", drive_name, rel_path); - free (rel_path); - grub_util_info ("reading %s via GRUB facilities", grub_path); - grub_file_filter_disable_compression (); - file = grub_file_open (grub_path); - if (! file) - grub_util_error ("cannot open %s via GRUB facilities", grub_path); - filebuf_via_grub = xmalloc (file->size); - grub_file_read (file, filebuf_via_grub, file->size); - - grub_util_info ("comparing"); - - if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size)) - grub_util_error ("files differ"); - } - } - printf ("%s\n", fs->name); } - - if (print == PRINT_FS_UUID) + else if (print == PRINT_FS_UUID) { char *uuid; if (! fs->uuid) grub_util_error ("%s does not support UUIDs", fs->name); - fs->uuid (dev, &uuid); + if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); printf ("%s\n", uuid); } @@ -278,7 +245,8 @@ probe (const char *path, char *device_name) if (! fs->label) grub_util_error ("%s does not support labels", fs->name); - fs->label (dev, &label); + if (fs->label (dev, &label) != GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); printf ("%s\n", label); } @@ -422,6 +390,13 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_lvm_fini (); + grub_mdraid_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid_init (); + grub_lvm_init (); + /* Do it. */ if (argument_is_device) probe (NULL, argument); diff --git a/util/grub-reboot.in b/util/grub-reboot.in index e7a41f68f..929cf5202 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -29,6 +29,8 @@ self=`basename $0` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= +bootdir= +grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` # Usage: usage # Print the usage. @@ -39,8 +41,8 @@ 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 + --boot-directory=DIR expect GRUB images under the directory DIR/@grubdirname@ + instead of the $grubdir directory ENTRY is a number or a menu item title. @@ -73,11 +75,17 @@ do echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; +# Accept for compatibility --root-directory) rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --boot-directory) + bootdir=`argument $option "$@"`; shift;; + --boot-directory=*) + bootdir=`echo "$option" | sed 's/--boot-directory=//'` ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -99,21 +107,17 @@ if test "x$entry" = x; then 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 +if [ -z "$bootdir" ]; then + # Default bootdir if bootdir not initialized. + bootdir=/@bootdirname@ -grubdir=${bootdir}/`echo grub | sed ${transform}` + if [ -n "$rootdir" ] ; then + # Initialize bootdir if rootdir was initialized. + bootdir=${rootdir}/@bootdirname@ + fi +fi + +grubdir=`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'` prev_saved_entry=`$grub_editenv ${grubdir}/grubenv list | sed -n 's/^saved_entry=//p'` if [ "$prev_saved_entry" ]; then diff --git a/util/grub-set-default.in b/util/grub-set-default.in index 389c504c7..b09727de2 100644 --- a/util/grub-set-default.in +++ b/util/grub-set-default.in @@ -29,6 +29,8 @@ self=`basename $0` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= +bootdir= +grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` # Usage: usage # Print the usage. @@ -39,8 +41,8 @@ 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 + --boot-directory=DIR expect GRUB images under the directory DIR/@grubdirname@ + instead of the $grubdir directory ENTRY is a number or a menu item title. @@ -73,11 +75,17 @@ do echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; +# Accept for compatibility --root-directory) rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --boot-directory) + bootdir=`argument $option "$@"`; shift;; + --boot-directory=*) + bootdir=`echo "$option" | sed 's/--boot-directory=//'` ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -99,21 +107,17 @@ if test "x$entry" = x; then 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 +if [ -z "$bootdir" ]; then + # Default bootdir if bootdir not initialized. + bootdir=/@bootdirname@ -grubdir=${bootdir}/`echo grub | sed ${transform}` + if [ -n "$rootdir" ] ; then + # Initialize bootdir if rootdir was initialized. + bootdir=${rootdir}/@bootdirname@ + fi +fi + +grubdir=`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'` $grub_editenv ${grubdir}/grubenv unset prev_saved_entry $grub_editenv ${grubdir}/grubenv set saved_entry="$entry" diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 350eb30a8..d8cc7aea4 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -41,6 +41,14 @@ for i in /boot/gnumach* ; do basename=`basename $i` dirname=`dirname $i` rel_dirname=`make_system_path_relative_to_its_root $dirname` + + if ! is_path_readable_by_grub ${dirname}/${basename} \ + ${GRUB_DEVICE_BOOT} \ + ${rel_dirname}/${basename} ; then + echo "${dirname}/${basename} is not readable by GRUB" >&2 + exit 1 + fi + echo "Found GNU Mach: $i" >&2 kernels="${kernels} ${rel_dirname}/${basename}" at_least_one=true diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 40ac240c7..bf1632bd6 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -44,7 +44,7 @@ load_kfreebsd_module () mod="$1" allow_fail="$2" - if ! test -e "${module_dir}/${mod}.ko" ; then + if ! is_path_readable_by_grub "${module_dir}/${mod}.ko" ; then if [ "${allow_fail}" = "true" ] ; then # Return silently return @@ -77,6 +77,13 @@ kfreebsd_entry () prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi + if ! is_path_readable_by_grub ${dirname}/${basename} \ + ${GRUB_DEVICE_BOOT} \ + ${rel_dirname}/${basename} ; then + echo "${dirname}/${basename} is not readable by GRUB" >&2 + exit 1 + fi + printf '%s\n' "${prepare_boot_cache}" cat << EOF echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' @@ -95,7 +102,13 @@ EOF zfs) load_kfreebsd_module opensolaris false - ls "${dirname}/zfs/zpool.cache" > /dev/null + if ! is_path_readable_by_grub ${dirname}/zfs/zpool.cache \ + ${GRUB_DEVICE_BOOT} \ + ${rel_dirname}/zfs/zpool.cache ; then + echo "${dirname}/zfs/zpool.cache is not readable by GRUB" >&2 + exit 1 + fi + printf '%s\n' "${prepare_boot_cache}" cat << EOF kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache @@ -138,7 +151,12 @@ while [ "x$list" != "x" ] ; do esac case ${GRUB_FS} in - zfs) kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) ;; + zfs) + # zpool name + kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) + # filesystem name (empty string for the main filesystem) + kfreebsd_device="${kfreebsd_device}$(grub-mkrelpath / | sed -e "s,/*@$,,")" + ;; *) kfreebsd_device=${GRUB_DEVICE} ;; esac diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 14b85c7f1..765a7fab6 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -83,6 +83,15 @@ EOF EOF fi + for i in ${basename} ${initrd} ; do + if ! is_path_readable_by_grub ${dirname}/${i} \ + ${GRUB_DEVICE_BOOT} \ + ${rel_dirname}/${i} ; then + echo "${dirname}/${i} is not readable by GRUB" >&2 + exit 1 + fi + done + 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/30_os-prober.in b/util/grub.d/30_os-prober.in index 76857aeea..728ac2378 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -40,7 +40,7 @@ fi osx_entry() { cat << EOF -menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" { +menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" --class osx --class darwin --class os { EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" @@ -105,7 +105,7 @@ for OS in ${OSPROBED} ; do chain) cat << EOF -menuentry "${LONGNAME} (on ${DEVICE})" { +menuentry "${LONGNAME} (on ${DEVICE})" --class windows --class os { EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" @@ -147,7 +147,7 @@ EOF fi cat << EOF -menuentry "${LLABEL} (on ${DEVICE})" { +menuentry "${LLABEL} (on ${DEVICE})" --class gnu-linux --class gnu --class os { EOF save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then @@ -174,7 +174,7 @@ EOF ;; hurd) cat << EOF -menuentry "${LONGNAME} (on ${DEVICE})" { +menuentry "${LONGNAME} (on ${DEVICE})" --class hurd --class gnu --class os { EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 642d9d104..987e2d05a 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -81,8 +81,6 @@ setup (const char *dir, struct grub_boot_blocklist *first_block, *block; grub_int32_t *install_dos_part, *install_bsd_part; grub_int32_t dos_part, bsd_part; - char *install_prefix; - char *prefix = NULL; char *tmp_img; int i; grub_disk_addr_t first_sector; @@ -214,8 +212,6 @@ setup (const char *dir, + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); - install_prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE + - GRUB_KERNEL_MACHINE_PREFIX); /* Open the root device and the destination device. */ root_dev = grub_device_open (root); @@ -291,16 +287,6 @@ setup (const char *dir, dos_part = root_dev->disk->partition->number; bsd_part = -1; } - - if (install_prefix[0] != '(') - { - char *root_part_name; - - root_part_name = - grub_partition_get_name (root_dev->disk->partition); - prefix = xasprintf ("(,%s)%s", root_part_name, install_prefix); - free (root_part_name); - } } else dos_part = bsd_part = -1; @@ -389,8 +375,6 @@ setup (const char *dir, *install_dos_part = grub_cpu_to_le32 (dos_part); *install_bsd_part = grub_cpu_to_le32 (bsd_part); - if (prefix) - strcpy (install_prefix, prefix); /* The first blocklist contains the whole sectors. */ first_block->start = grub_cpu_to_le64 (embed_region.start + 1); @@ -553,8 +537,6 @@ unable_to_embed: *install_dos_part = grub_cpu_to_le32 (dos_part); *install_bsd_part = grub_cpu_to_le32 (bsd_part); - if (prefix) - strcpy (install_prefix, prefix); /* Write the first two sectors of the core image onto the disk. */ grub_util_info ("opening the core image `%s'", core_path); @@ -574,7 +556,6 @@ unable_to_embed: /* Sync is a Good Thing. */ sync (); - free (prefix); free (core_path); free (core_img); free (boot_img); @@ -751,6 +732,13 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_lvm_fini (); + grub_mdraid_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid_init (); + grub_lvm_init (); + dest_dev = get_device_name (argv[optind]); if (! dest_dev) { diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index d8481295f..1b1a80911 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -614,6 +614,13 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_lvm_fini (); + grub_mdraid_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid_init (); + grub_lvm_init (); + find_dest_dev (&ginfo, argv); ginfo.prefix = grub_make_system_path_relative_to_its_root (ginfo.dir ?