Merge mainline.

This commit is contained in:
Manoel Rebelo Abranches 2011-04-01 04:45:37 -03:00
commit 50ee5d686d
193 changed files with 9983 additions and 1425 deletions

View file

@ -44,7 +44,6 @@ grub-kbdcomp
grub-macho2img grub-macho2img
grub-menulst2cfg grub-menulst2cfg
grub-mk* grub-mk*
grub-pbkdf2
grub-pe2elf grub-pe2elf
grub-probe grub-probe
grub_probe_init.c grub_probe_init.c
@ -131,5 +130,6 @@ grub-core/gnulib/unistd.h
grub-core/gnulib/warn-on-use.h grub-core/gnulib/warn-on-use.h
grub-core/gnulib/wchar.h grub-core/gnulib/wchar.h
grub-core/gnulib/wctype.h grub-core/gnulib/wctype.h
grub-core/rs_decoder.S
widthspec.bin widthspec.bin
widthspec.h widthspec.h

7
BUGS Normal file
View file

@ -0,0 +1,7 @@
GRUB team is aware of following problems:
- Currently search and assembling multidevice abstractions scans
all the devices which can be slow.
- Cache isn't used correctly for video which results in slowness.
While these are bugs their solution has a potential of breaking more and more
seriously. So it was decided for 1.99 that they aren't fixed.

1738
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -33,8 +33,8 @@ grub_script.yy.c: grub_script.yy.h
CLEANFILES += grub_script.yy.c grub_script.yy.h CLEANFILES += grub_script.yy.c grub_script.yy.h
# For libgrub.a # For libgrub.a
libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrub_a_SOURCES) libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrub_a_CPPFLAGS) $(CPPFLAGS) \ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
CLEANFILES += libgrub.pp CLEANFILES += libgrub.pp

View file

@ -1,7 +1,29 @@
AutoGen definitions Makefile.tpl; AutoGen definitions Makefile.tpl;
library = { library = {
name = libgrub.a; name = libgrubkern.a;
cflags = '$(CFLAGS_GNULIB)';
cppflags = '$(CPPFLAGS_GNULIB)';
common = util/misc.c;
common = grub-core/kern/command.c;
common = grub-core/kern/device.c;
common = grub-core/kern/disk.c;
common = grub-core/kern/emu/getroot.c;
common = grub-core/kern/emu/hostdisk.c;
common = grub-core/kern/emu/misc.c;
common = grub-core/kern/emu/mm.c;
common = grub-core/kern/env.c;
common = grub-core/kern/err.c;
common = grub-core/kern/file.c;
common = grub-core/kern/fs.c;
common = grub-core/kern/list.c;
common = grub-core/kern/misc.c;
common = grub-core/kern/partition.c;
};
library = {
name = libgrubmods.a;
cflags = '$(CFLAGS_GCRY)'; cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)';
@ -11,13 +33,6 @@ library = {
common_nodist = grub_script.yy.h; common_nodist = grub_script.yy.h;
common_nodist = grub_script.tab.h; common_nodist = grub_script.tab.h;
common = util/misc.c;
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/getroot.c;
common = grub-core/kern/emu/hostdisk.c;
common = grub-core/commands/blocklist.c; common = grub-core/commands/blocklist.c;
common = grub-core/commands/extcmd.c; common = grub-core/commands/extcmd.c;
common = grub-core/commands/ls.c; common = grub-core/commands/ls.c;
@ -56,15 +71,10 @@ library = {
common = grub-core/fs/ufs2.c; common = grub-core/fs/ufs2.c;
common = grub-core/fs/ufs.c; common = grub-core/fs/ufs.c;
common = grub-core/fs/xfs.c; common = grub-core/fs/xfs.c;
common = grub-core/kern/command.c; common = grub-core/fs/zfs/zfs.c;
common = grub-core/kern/device.c; common = grub-core/fs/zfs/zfs_lzjb.c;
common = grub-core/kern/disk.c; common = grub-core/fs/zfs/zfs_sha256.c;
common = grub-core/kern/env.c; common = grub-core/fs/zfs/zfs_fletcher.c;
common = grub-core/kern/err.c;
common = grub-core/kern/file.c;
common = grub-core/kern/fs.c;
common = grub-core/kern/list.c;
common = grub-core/kern/partition.c;
common = grub-core/lib/arg.c; common = grub-core/lib/arg.c;
common = grub-core/lib/crypto.c; common = grub-core/lib/crypto.c;
common = grub-core/lib/envblk.c; common = grub-core/lib/envblk.c;
@ -94,9 +104,10 @@ library = {
program = { program = {
name = grub-bin2h; name = grub-bin2h;
common = util/bin2h.c; common = util/bin2h.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
mansection = 1; mansection = 1;
}; };
@ -108,10 +119,11 @@ program = {
common = util/resolve.c; common = util/resolve.c;
extra_dist = util/grub-mkimagexx.c; extra_dist = util/grub-mkimagexx.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBLZMA)'; ldadd = libgrubkern.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBLZMA)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"';
}; };
@ -121,9 +133,10 @@ program = {
common = util/grub-mkrelpath.c; common = util/grub-mkrelpath.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -132,9 +145,10 @@ program = {
common = util/grub-script-check.c; common = util/grub-script-check.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -143,9 +157,10 @@ program = {
common = util/grub-editenv.c; common = util/grub-editenv.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -154,9 +169,10 @@ program = {
common = util/grub-mkpasswd-pbkdf2.c; common = util/grub-mkpasswd-pbkdf2.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cflags = '$(CFLAGS_GCRY)'; cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)';
}; };
@ -173,9 +189,10 @@ program = {
mansection = 1; mansection = 1;
common = util/grub-pe2elf.c; common = util/grub-pe2elf.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL)';
condition = COND_GRUB_PE2ELF; condition = COND_GRUB_PE2ELF;
}; };
@ -190,9 +207,10 @@ program = {
cflags = '$(CFLAGS_GCRY)'; cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)';
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -203,10 +221,11 @@ program = {
cflags = '$(freetype_cflags)'; cflags = '$(freetype_cflags)';
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(freetype_libs)'; ldadd = '$(freetype_libs)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_GRUB_MKFONT; condition = COND_GRUB_MKFONT;
}; };
@ -222,9 +241,10 @@ program = {
sparc64_ieee1275 = util/ieee1275/ofpath.c; sparc64_ieee1275 = util/ieee1275/ofpath.c;
sparc64_ieee1275 = util/ieee1275/devicemap.c; sparc64_ieee1275 = util/ieee1275/devicemap.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -233,9 +253,10 @@ program = {
mansection = 8; mansection = 8;
common = util/grub-probe.c; common = util/grub-probe.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -249,9 +270,10 @@ program = {
sparc64_ieee1275 = util/ieee1275/ofpath.c; sparc64_ieee1275 = util/ieee1275/ofpath.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = i386_pc; enable = i386_pc;
enable = sparc64_ieee1275; enable = sparc64_ieee1275;
@ -263,9 +285,11 @@ program = {
ieee1275 = util/ieee1275/grub-ofpathname.c; ieee1275 = util/ieee1275/grub-ofpathname.c;
ieee1275 = util/ieee1275/ofpath.c; ieee1275 = util/ieee1275/ofpath.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)';
enable = sparc64_ieee1275; enable = sparc64_ieee1275;
}; };
@ -275,9 +299,10 @@ program = {
common = util/grub-mklayout.c; common = util/grub-mklayout.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
data = { data = {
@ -584,9 +609,10 @@ program = {
common = grub-core/kern/misc.c; common = grub-core/kern/misc.c;
common = grub-core/tests/lib/test.c; common = grub-core/tests/lib/test.c;
cflags = -Wno-format; cflags = -Wno-format;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBDEVMAPPER)'; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = { program = {
@ -596,7 +622,8 @@ program = {
common = grub-core/lib/legacy_parse.c; common = grub-core/lib/legacy_parse.c;
common = grub-core/lib/i386/pc/vesa_modes_table.c; common = grub-core/lib/i386/pc/vesa_modes_table.c;
ldadd = libgrub.a; ldadd = libgrubmods.a;
ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };

4
NEWS
View file

@ -51,9 +51,7 @@ New in 1.99:
* Add `sendkey' command (i386-pc only). * Add `sendkey' command (i386-pc only).
* ZFS support in `grub-install' and `grub-mkconfig'. Note: complete * ZFS support.
functionality requires external ZFS implementation (available from
grub-extras).
* Support 1.x versions of mdadm metadata. * Support 1.x versions of mdadm metadata.

View file

@ -22,7 +22,7 @@ if COND_i386_ieee1275
CFLAGS_PLATFORM += -mrtd -mregparm=3 CFLAGS_PLATFORM += -mrtd -mregparm=3
endif endif
if COND_mips_yeeloong if COND_mips_yeeloong
CFLAGS_PLATFORM += -march=mips3 -mexplicit-relocs CFLAGS_PLATFORM += -mexplicit-relocs
CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK
CCASFLAGS_PLATFORM = -march=mips3 CCASFLAGS_PLATFORM = -march=mips3
endif endif
@ -45,12 +45,33 @@ CPPFLAGS_DEFAULT += -I$(top_srcdir)/include
CPPFLAGS_DEFAULT += -I$(top_builddir)/include CPPFLAGS_DEFAULT += -I$(top_builddir)/include
CCASFLAGS_DEFAULT = -DASM_FILE=1 CCASFLAGS_DEFAULT = -DASM_FILE=1
LDADD_KERNEL = -lgcc LDADD_KERNEL =
if ! COND_i386_pc
if ! COND_i386_efi
if ! COND_i386_qemu
if ! COND_i386_coreboot
if ! COND_i386_multiboot
if ! COND_i386_ieee1275
if ! COND_x86_64_efi
LDADD_KERNEL += -lgcc
endif
endif
endif
endif
endif
endif
endif
CFLAGS_KERNEL = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding CFLAGS_KERNEL = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N -static-libgcc LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N -static-libgcc
CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
if COND_CYGWIN
STRIPFLAGS_KERNEL = -F elf32-i386 -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve
else
STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment
endif
CFLAGS_MODULE = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding CFLAGS_MODULE = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_MODULE = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N,-r,-d LDFLAGS_MODULE = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N,-r,-d
@ -67,9 +88,9 @@ LDFLAGS_PROGRAM =
CPPFLAGS_PROGRAM = CPPFLAGS_PROGRAM =
CCASFLAGS_PROGRAM = CCASFLAGS_PROGRAM =
CFLAGS_LIBRARY = $(CFLAGS_PROGRAM) CFLAGS_LIBRARY =
CPPFLAGS_LIBRARY = $(CPPFLAGS_PROGRAM) CPPFLAGS_LIBRARY =
CCASFLAGS_LIBRARY = $(CCASFLAGS_PROGRAM) CCASFLAGS_LIBRARY =
# Other variables # Other variables
@ -80,7 +101,7 @@ platformdir = $(pkglibrootdir)/$(target_cpu)-$(platform)
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
CFLAGS_POSIX = -fno-builtin CFLAGS_POSIX = -fno-builtin

View file

@ -13,15 +13,9 @@ SECTIONS
__data_start__ = . ; __data_start__ = . ;
*(.data) *(.data)
__data_end__ = . ; __data_end__ = . ;
}
.rdata :
{
__rdata_start__ = . ; __rdata_start__ = . ;
*(.rdata) *(.rdata)
__rdata_end__ = . ; __rdata_end__ = . ;
}
.pdata :
{
*(.pdata) *(.pdata)
edata = . ; edata = . ;
} }

View file

@ -1,28 +0,0 @@
# -*- makefile -*-
LINK_BASE = 0x80010000
target_machine=qemu-mips
COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3
include $(srcdir)/conf/mips.mk
pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
kern/main.c kern/device.c kern/$(target_cpu)/init.c \
kern/$(target_cpu)/$(target_machine)/init.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary
# For serial.mod.
pkglib_MODULES += serial.mod
serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -1,3 +1,7 @@
#undef _LARGEFILE_SOURCE
#undef _FILE_OFFSET_BITS
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
#include <config-util.h> #include <config-util.h>
#define NESTED_FUNC_ATTR #define NESTED_FUNC_ATTR

View file

@ -32,7 +32,7 @@ dnl type, so there is no conflict. Variables with the prefix "TARGET_"
dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
dnl type. dnl type.
AC_INIT([GRUB],[1.99~beta0],[bug-grub@gnu.org]) AC_INIT([GRUB],[1.99~rc1],[bug-grub@gnu.org])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
@ -103,15 +103,12 @@ else
platform="$with_platform" platform="$with_platform"
fi fi
# Adjust CPU unless target was explicitly specified. case "$target_cpu"-"$platform" in
if test -z "$target_alias"; then x86_64-efi) ;;
case "$target_cpu"-"$platform" in x86_64-emu) ;;
x86_64-efi) ;; x86_64-*) target_cpu=i386 ;;
x86_64-emu) ;; powerpc64-ieee1275) target_cpu=powerpc ;;
x86_64-*) target_cpu=i386 ;; esac
powerpc64-ieee1275) target_cpu=powerpc ;;
esac
fi
# Check if the platform is supported, make final adjustments. # Check if the platform is supported, make final adjustments.
case "$target_cpu"-"$platform" in case "$target_cpu"-"$platform" in
@ -249,7 +246,7 @@ else
fi fi
# These are not a "must". # These are not a "must".
AC_PATH_PROG(MAKEINFO, makeinfo) AC_PATH_PROGS(MAKEINFO, makeinfo true)
# #
# Checks for host programs. # Checks for host programs.
@ -401,6 +398,23 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
fi fi
if test "${target_cpu}-${platform}" = mips-yeeloong; then
AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -march=loongson2f"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_march_loongson2f=yes],
[grub_cv_cc_march_loongson2f=no])
CFLAGS="$SAVE_CFLAGS"
])
if test "x$grub_cv_cc_march_loongson2f" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -march=loongson2f"
else
TARGET_CFLAGS="$TARGET_CFLAGS -march=mips3"
fi
fi
grub_apple_target_cc grub_apple_target_cc
if test x$grub_cv_apple_target_cc = xyes ; then if test x$grub_cv_apple_target_cc = xyes ; then
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1"
@ -440,7 +454,7 @@ fi
# For platforms where ELF is not the default link format. # For platforms where ELF is not the default link format.
AC_MSG_CHECKING([for command to convert module to ELF format]) AC_MSG_CHECKING([for command to convert module to ELF format])
case "${host_os}" in case "${host_os}" in
cygwin) TARGET_OBJ2ELF='$(grub_utildir)/grub-pe2elf'; cygwin) TARGET_OBJ2ELF='$(top_builddir)/grub-pe2elf';
# FIXME: put proper test here # FIXME: put proper test here
NEED_REGISTER_FRAME_INFO=1 NEED_REGISTER_FRAME_INFO=1
;; ;;
@ -562,8 +576,11 @@ else
CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error" CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error"
fi fi
CPPFLAGS="$TARGET_CPPFLAGS" CPPFLAGS="$TARGET_CPPFLAGS"
LDFLAGS="$TARGET_LDFLAGS" if test x$target_cpu = xi386 || test x$target_cpu = xx86_64 ; then
LIBS=
else
LIBS=-lgcc LIBS=-lgcc
fi
grub_ASM_USCORE grub_ASM_USCORE
if test x$grub_cv_asm_uscore = xyes; then if test x$grub_cv_asm_uscore = xyes; then
@ -651,6 +668,23 @@ if test x"$grub_cv_cc_isystem" = xyes ; then
fi fi
fi fi
AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_cc_wnotrampolines], [
SAVED_CFLAGS="$CFLAGS"
# Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion
# in the event of later failures (since -Wno-* is always accepted, but
# produces a diagnostic if something else is wrong).
CFLAGS="$TARGET_CFLAGS -Wtrampolines"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
int va_arg_func (int fixed, va_list args);]], [[]])],
[grub_cv_cc_wnotrampolines=yes],
[grub_cv_cc_wnotrampolines=no])
CFLAGS="$SAVED_CFLAGS"
])
if test x"$grub_cv_cc_wnotrampolines" = xyes ; then
TARGET_CFLAGS="$TARGET_CFLAGS -Wno-trampolines"
fi
# Restore the flags. # Restore the flags.
CC="$tmp_CC" CC="$tmp_CC"
CFLAGS="$tmp_CFLAGS" CFLAGS="$tmp_CFLAGS"
@ -829,6 +863,12 @@ if test x"$enable_device_mapper" = xno ; then
device_mapper_excuse="explicitly disabled" device_mapper_excuse="explicitly disabled"
fi fi
if test x"$device_mapper_excuse" = x ; then
# Check for device-mapper header.
AC_CHECK_HEADER([libdevmapper.h], [],
[device_mapper_excuse="need libdevmapper header"])
fi
if test x"$device_mapper_excuse" = x ; then if test x"$device_mapper_excuse" = x ; then
# Check for device-mapper library. # Check for device-mapper library.
AC_CHECK_LIB([devmapper], [dm_task_create], [], AC_CHECK_LIB([devmapper], [dm_task_create], [],
@ -850,6 +890,15 @@ fi
AC_SUBST([LIBDEVMAPPER]) AC_SUBST([LIBDEVMAPPER])
LIBGEOM=
if test x$host_kernel = xkfreebsd; then
AC_CHECK_LIB([geom], [geom_gettree], [],
[AC_MSG_ERROR([Your platform requires libgeom])])
LIBGEOM="-lgeom"
fi
AC_SUBST([LIBGEOM])
AC_CHECK_LIB([lzma], [lzma_code], AC_CHECK_LIB([lzma], [lzma_code],
[LIBLZMA="-llzma" [LIBLZMA="-llzma"
AC_DEFINE([HAVE_LIBLZMA], [1], AC_DEFINE([HAVE_LIBLZMA], [1],
@ -924,6 +973,7 @@ AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin])
# Output files. # Output files.
grub_CHECK_LINK_DIR grub_CHECK_LINK_DIR

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
[NAME] [NAME]
grub-set-default \- set the default boot entry for GRUB grub-set-default \- set the saved default boot entry for GRUB

View file

@ -30,7 +30,7 @@ CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM)
# gentrigtables # gentrigtables
gentrigtables: gentrigtables.c gentrigtables: gentrigtables.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(CPPFLAGS) -lm $< $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(CPPFLAGS) $< -lm
CLEANFILES += gentrigtables CLEANFILES += gentrigtables
# trigtables.c # trigtables.c
@ -50,7 +50,7 @@ grub_script.yy.h: script/yylex.l
grub_script.yy.c: grub_script.yy.h grub_script.yy.c: grub_script.yy.h
rs_decoder.S: $(srcdir)/lib/reed_solomon.c rs_decoder.S: $(srcdir)/lib/reed_solomon.c
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3
kern/i386/pc/startup.S: $(builddir)/rs_decoder.S kern/i386/pc/startup.S: $(builddir)/rs_decoder.S
@ -238,9 +238,9 @@ command.lst: $(MARKER_FILES)
(for pp in $^; do \ (for pp in $^; do \
b=`basename $$pp .marker`; \ b=`basename $$pp .marker`; \
sed -n \ sed -n \
-e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \
-e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
-e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" $$pp; \ -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
-e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
done) | sort -u > $@ done) | sort -u > $@
platform_DATA += command.lst platform_DATA += command.lst
CLEANFILES += command.lst CLEANFILES += command.lst
@ -304,7 +304,7 @@ platform_DATA += moddep.lst
CLEANFILES += config.log syminfo.lst moddep.lst CLEANFILES += config.log syminfo.lst moddep.lst
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) $(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
sh $^ $@ TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
platform_DATA += $(MOD_FILES) platform_DATA += $(MOD_FILES)
CLEANFILES += $(MOD_FILES) CLEANFILES += $(MOD_FILES)

View file

@ -27,6 +27,8 @@ kernel = {
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
ldadd = '$(LDADD_KERNEL)';
i386_coreboot_ldflags = '-Wl,-Ttext=0x8200'; i386_coreboot_ldflags = '-Wl,-Ttext=0x8200';
i386_multiboot_ldflags = '-Wl,-Ttext=0x8200'; i386_multiboot_ldflags = '-Wl,-Ttext=0x8200';
i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000'; i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000';
@ -39,10 +41,6 @@ kernel = {
emu_cflags = '$(CFLAGS_GNULIB)'; emu_cflags = '$(CFLAGS_GNULIB)';
emu_cppflags = '$(CPPFLAGS_GNULIB)'; emu_cppflags = '$(CPPFLAGS_GNULIB)';
mips_ldadd = '-lgcc';
powerpc_ldadd = '-lgcc';
sparc64_ldadd = '-lgcc';
i386_pc_startup = kern/i386/pc/startup.S; i386_pc_startup = kern/i386/pc/startup.S;
i386_efi_startup = kern/i386/efi/startup.S; i386_efi_startup = kern/i386/efi/startup.S;
x86_64_efi_startup = kern/x86_64/efi/startup.S; x86_64_efi_startup = kern/x86_64/efi/startup.S;
@ -164,6 +162,7 @@ kernel = {
emu = disk/host.c; emu = disk/host.c;
emu = gnulib/progname.c; emu = gnulib/progname.c;
emu = gnulib/error.c; emu = gnulib/error.c;
emu = kern/emu/cache.S;
emu = kern/emu/console.c; emu = kern/emu/console.c;
emu = kern/emu/getroot.c; emu = kern/emu/getroot.c;
emu = kern/emu/hostdisk.c; emu = kern/emu/hostdisk.c;
@ -201,7 +200,7 @@ program = {
ldadd = 'kernel.img$(EXEEXT)'; ldadd = 'kernel.img$(EXEEXT)';
ldadd = '$(MODULE_FILES)'; ldadd = '$(MODULE_FILES)';
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu; enable = emu;
}; };
@ -210,11 +209,10 @@ program = {
name = grub-emu-lite; name = grub-emu-lite;
emu = kern/emu/lite.c; emu = kern/emu/lite.c;
emu = kern/emu/cache.S;
emu_nodist = symlist.c; emu_nodist = symlist.c;
ldadd = 'kernel.img$(EXEEXT)'; ldadd = 'kernel.img$(EXEEXT)';
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
enable = emu; enable = emu;
}; };
@ -302,7 +300,8 @@ image = {
mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
objcopyflags = '-O binary'; objcopyflags = '-O binary';
ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
ldadd = '-lgcc';
cflags = '-static-libgcc'; cflags = '-static-libgcc';
enable = mips; enable = mips;
}; };
@ -315,7 +314,8 @@ image = {
mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
objcopyflags = '-O binary'; objcopyflags = '-O binary';
ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
ldadd = '-lgcc';
cflags = '-static-libgcc'; cflags = '-static-libgcc';
enable = mips; enable = mips;
}; };
@ -324,6 +324,7 @@ image = {
name = fwstart; name = fwstart;
mips_yeeloong = boot/mips/yeeloong/fwstart.S; mips_yeeloong = boot/mips/yeeloong/fwstart.S;
objcopyflags = '-O binary'; objcopyflags = '-O binary';
ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_yeeloong; enable = mips_yeeloong;
}; };
@ -1007,6 +1008,19 @@ module = {
common = fs/xfs.c; common = fs/xfs.c;
}; };
module = {
name = zfs;
common = fs/zfs/zfs.c;
common = fs/zfs/zfs_lzjb.c;
common = fs/zfs/zfs_sha256.c;
common = fs/zfs/zfs_fletcher.c;
};
module = {
name = zfsinfo;
common = fs/zfs/zfsinfo.c;
};
module = { module = {
name = pxe; name = pxe;
i386_pc = net/i386/pc/pxe.c; i386_pc = net/i386/pc/pxe.c;
@ -1136,6 +1150,7 @@ module = {
module = { module = {
name = linux16; name = linux16;
i386_pc = loader/i386/pc/linux.c; i386_pc = loader/i386/pc/linux.c;
i386_pc = lib/cmdline.c;
enable = i386_pc; enable = i386_pc;
}; };
@ -1170,6 +1185,7 @@ module = {
mips = loader/mips/linux.c; mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
common = lib/cmdline.c;
enable = noemu; enable = noemu;
}; };
@ -1448,7 +1464,6 @@ module = {
name = ieee1275_fb; name = ieee1275_fb;
ieee1275 = video/ieee1275.c; ieee1275 = video/ieee1275.c;
enable = powerpc; enable = powerpc;
enable = sparc64;
}; };
module = { module = {

View file

@ -459,6 +459,8 @@ fd_probe_error_string: .asciz "Floppy"
1: 1:
/* perform read */ /* perform read */
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
movw %bx, %es
xorw %bx, %bx
movw $0x201, %ax movw $0x201, %ax
movb $0, %ch movb $0, %ch
movb $0, %dh movb $0, %dh

View file

@ -178,8 +178,13 @@ real_code_2:
pushw %es pushw %es
popw %ds popw %ds
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
movl $0x200, %ecx movl $0x200, %ecx
addl %ecx, %esi addl %ecx, %esi
#else
movl $(GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4), %ecx
addl $0x200, %esi
#endif
movl $DATA_ADDR, %edi movl $DATA_ADDR, %edi
call LOCAL(move_memory) call LOCAL(move_memory)
@ -196,7 +201,11 @@ real_code_2:
1: 1:
movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
#else
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
#endif
2: 2:
call LOCAL(move_memory) call LOCAL(move_memory)

View file

@ -38,7 +38,7 @@ write_bases (void)
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT)
& GRUB_MACHINE_PCI_WIN_MASK) & GRUB_MACHINE_PCI_WIN_MASK)
>> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE)); << (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
GRUB_MACHINE_PCI_IO_CTRL_REG = reg; GRUB_MACHINE_PCI_IO_CTRL_REG = reg;
} }

View file

@ -90,7 +90,14 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
/* Check if there is a device present. */ /* Check if there is a device present. */
if (id >> 16 == 0xFFFF) if (id >> 16 == 0xFFFF)
continue; {
if (dev.function == 0)
/* Devices are required to implement function 0, so if
it's missing then there is no device here. */
break;
else
continue;
}
#ifdef GRUB_MACHINE_MIPS_YEELOONG #ifdef GRUB_MACHINE_MIPS_YEELOONG
/* Skip ghosts. */ /* Skip ghosts. */

View file

@ -749,8 +749,7 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
else if (port == 1) else if (port == 1)
reg = GRUB_UHCI_REG_PORTSC2; reg = GRUB_UHCI_REG_PORTSC2;
else else
return grub_error (GRUB_ERR_OUT_OF_RANGE, return GRUB_USB_SPEED_NONE;
"UHCI Root Hub port does not exist");
status = grub_uhci_readreg16 (u, reg); status = grub_uhci_readreg16 (u, reg);

View file

@ -25,7 +25,7 @@
#include <grub/term.h> #include <grub/term.h>
static grub_usb_controller_dev_t grub_usb_list; static grub_usb_controller_dev_t grub_usb_list;
struct grub_usb_attach_desc *attach_hooks; static struct grub_usb_attach_desc *attach_hooks;
void void
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)

View file

@ -39,7 +39,7 @@ struct grub_usb_hub
grub_usb_device_t dev; grub_usb_device_t dev;
}; };
struct grub_usb_hub *hubs; static struct grub_usb_hub *hubs;
/* Add a device that currently has device number 0 and resides on /* Add a device that currently has device number 0 and resides on
CONTROLLER, the Hub reported that the device speed is SPEED. */ CONTROLLER, the Hub reported that the device speed is SPEED. */
@ -110,7 +110,7 @@ static grub_usb_err_t
grub_usb_add_hub (grub_usb_device_t dev) grub_usb_add_hub (grub_usb_device_t dev)
{ {
struct grub_usb_usb_hubdesc hubdesc; struct grub_usb_usb_hubdesc hubdesc;
grub_err_t err; grub_usb_err_t err;
int i; int i;
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN

View file

@ -97,7 +97,7 @@ grub_usb_control_msg (grub_usb_device_t dev,
if (! transfer) if (! transfer)
{ {
grub_dma_free (data_chunk); grub_dma_free (data_chunk);
return grub_errno; return GRUB_USB_ERR_INTERNAL;
} }
setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata));
@ -105,7 +105,7 @@ grub_usb_control_msg (grub_usb_device_t dev,
{ {
grub_free (transfer); grub_free (transfer);
grub_dma_free (data_chunk); grub_dma_free (data_chunk);
return grub_errno; return GRUB_USB_ERR_INTERNAL;
} }
setupdata = grub_dma_get_virt (setupdata_chunk); setupdata = grub_dma_get_virt (setupdata_chunk);
@ -139,7 +139,7 @@ grub_usb_control_msg (grub_usb_device_t dev,
grub_free (transfer); grub_free (transfer);
grub_dma_free (setupdata_chunk); grub_dma_free (setupdata_chunk);
grub_dma_free (data_chunk); grub_dma_free (data_chunk);
return grub_errno; return GRUB_USB_ERR_INTERNAL;
} }
/* Build a Setup packet. XXX: Endianness. */ /* Build a Setup packet. XXX: Endianness. */

View file

@ -36,6 +36,7 @@ typedef uint8_t grub_uint8_t;
#ifndef GRUB_DSDT_TEST #ifndef GRUB_DSDT_TEST
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/time.h>
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
#endif #endif
@ -324,6 +325,8 @@ grub_acpi_halt (void)
} }
} }
grub_millisleep (1500);
grub_printf ("ACPI shutdown failed\n"); grub_printf ("ACPI shutdown failed\n");
} }
#endif #endif

View file

@ -1,7 +1,7 @@
/* echo.c - Command to display a line of text */ /* echo.c - Command to display a line of text */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007 Free Software Foundation, Inc. * Copyright (C) 2006,2007,2010 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/term.h>
static const struct grub_arg_option options[] = static const struct grub_arg_option options[] =
{ {
@ -43,8 +44,14 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
char *arg = *args; char *arg = *args;
/* Unescaping results in a string no longer than the original. */
char *unescaped = grub_malloc (grub_strlen (arg) + 1);
char *p = unescaped;
args++; args++;
if (!unescaped)
return grub_errno;
while (*arg) while (*arg)
{ {
/* In case `-e' is used, parse backslashes. */ /* In case `-e' is used, parse backslashes. */
@ -57,11 +64,11 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
switch (*arg) switch (*arg)
{ {
case '\\': case '\\':
grub_printf ("\\"); *p++ = '\\';
break; break;
case 'a': case 'a':
grub_printf ("\a"); *p++ = '\a';
break; break;
case 'c': case 'c':
@ -69,23 +76,23 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
break; break;
case 'f': case 'f':
grub_printf ("\f"); *p++ = '\f';
break; break;
case 'n': case 'n':
grub_printf ("\n"); *p++ = '\n';
break; break;
case 'r': case 'r':
grub_printf ("\r"); *p++ = '\r';
break; break;
case 't': case 't':
grub_printf ("\t"); *p++ = '\t';
break; break;
case 'v': case 'v':
grub_printf ("\v"); *p++ = '\v';
break; break;
} }
arg++; arg++;
@ -94,10 +101,14 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
/* This was not an escaped character, or escaping is not /* This was not an escaped character, or escaping is not
enabled. */ enabled. */
grub_printf ("%c", *arg); *p++ = *arg;
arg++; arg++;
} }
*p = '\0';
grub_xputs (unescaped);
grub_free (unescaped);
/* If another argument follows, insert a space. */ /* If another argument follows, insert a space. */
if (i != argc - 1) if (i != argc - 1)
grub_printf (" " ); grub_printf (" " );
@ -106,6 +117,8 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
if (newline) if (newline)
grub_printf ("\n"); grub_printf ("\n");
grub_refresh ();
return 0; return 0;
} }

View file

@ -36,7 +36,7 @@ static const struct grub_arg_option options[] = {
{0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0}
}; };
struct { const char *name; const char *hashname; } aliases[] = static struct { const char *name; const char *hashname; } aliases[] =
{ {
{"sha256sum", "sha256"}, {"sha256sum", "sha256"},
{"sha512sum", "sha512"}, {"sha512sum", "sha512"},

View file

@ -83,9 +83,13 @@ legacy_file (const char *filename)
{ {
char *oldname = NULL; char *oldname = NULL;
char *newsuffix; char *newsuffix;
char *ptr;
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
oldname = entryname; oldname = entryname;
parsed = grub_legacy_parse (buf, &entryname, &newsuffix); parsed = grub_legacy_parse (ptr, &entryname, &newsuffix);
grub_free (buf);
buf = NULL; buf = NULL;
if (newsuffix) if (newsuffix)
{ {
@ -177,9 +181,6 @@ legacy_file (const char *filename)
grub_free (suffix); grub_free (suffix);
grub_free (entrysrc); grub_free (entrysrc);
if (menu && menu->size)
grub_show_menu (menu, 1);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -194,8 +195,8 @@ grub_cmd_legacy_source (struct grub_command *cmd,
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
extractor = (cmd->name[0] == 'e'); extractor = (cmd->name[0] == 'e');
new_env = (cmd->name[extractor ? sizeof ("extract_legacy_entries_") - 1 new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1)
: sizeof ("legacy_") - 1] == 'c'); : (sizeof ("legacy_") - 1)] == 'c');
if (new_env) if (new_env)
grub_cls (); grub_cls ();
@ -207,8 +208,15 @@ grub_cmd_legacy_source (struct grub_command *cmd,
ret = legacy_file (args[0]); ret = legacy_file (args[0]);
if (new_env && !extractor) if (new_env)
grub_env_context_close (); {
grub_menu_t menu;
menu = grub_env_get_menu ();
if (menu && menu->size)
grub_show_menu (menu, 1, 0);
if (!extractor)
grub_env_context_close ();
}
if (extractor) if (extractor)
grub_env_extractor_close (!new_env); grub_env_extractor_close (!new_env);
@ -761,12 +769,12 @@ GRUB_MOD_INIT(legacycfg)
= grub_register_command ("extract_legacy_entries_source", = grub_register_command ("extract_legacy_entries_source",
grub_cmd_legacy_source, grub_cmd_legacy_source,
N_("FILE"), N_("FILE"),
N_("Parse legacy config in same context taking onl entries")); N_("Parse legacy config in same context taking only menu entries"));
cmd_configfile_extract cmd_configfile_extract
= grub_register_command ("extract_legacy_entries_configfile", = grub_register_command ("extract_legacy_entries_configfile",
grub_cmd_legacy_source, grub_cmd_legacy_source,
N_("FILE"), N_("FILE"),
N_("Parse legacy config in new context taking onl entries")); N_("Parse legacy config in new context taking only menu entries"));
cmd_kernel = grub_register_command ("legacy_kernel", cmd_kernel = grub_register_command ("legacy_kernel",
grub_cmd_legacy_kernel, grub_cmd_legacy_kernel,

View file

@ -206,20 +206,6 @@ setparams_prefix (int argc, char **args)
char *p; char *p;
char *result; char *result;
grub_size_t len = 10; grub_size_t len = 10;
static const char *escape_characters = "\"\\";
auto char *strescpy (char *, const char *, const char *);
char * strescpy (char *d, const char *s, const char *escapes)
{
while (*s)
{
if (grub_strchr (escapes, *s))
*d++ = '\\';
*d++ = *s++;
}
*d = '\0';
return d;
}
/* Count resulting string length */ /* Count resulting string length */
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
@ -227,7 +213,7 @@ setparams_prefix (int argc, char **args)
len += 3; /* 3 = 1 space + 2 quotes */ len += 3; /* 3 = 1 space + 2 quotes */
p = args[i]; p = args[i];
while (*p) while (*p)
len += grub_strchr (escape_characters, *p++) ? 2 : 1; len += (*p++ == '\'' ? 3 : 1);
} }
result = grub_malloc (len + 2); result = grub_malloc (len + 2);
@ -235,17 +221,17 @@ setparams_prefix (int argc, char **args)
return 0; return 0;
grub_strcpy (result, "setparams"); grub_strcpy (result, "setparams");
i = 9; p = result + 9;
for (j = 0; j < argc; j++) for (j = 0; j < argc; j++)
{ {
result[i++] = ' '; *p++ = ' ';
result[i++] = '"'; *p++ = '\'';
i = strescpy (result + i, args[j], escape_characters) - result; p = grub_strchrsub (p, args[j], '\'', "'\\''");
result[i++] = '"'; *p++ = '\'';
} }
result[i++] = '\n'; *p++ = '\n';
result[i] = '\0'; *p = '\0';
return result; return result;
} }

View file

@ -87,7 +87,6 @@ set_matches (char **varnames, char *str, grub_size_t nmatches,
static grub_err_t static grub_err_t
grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args) grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int argn = 0;
regex_t regex; regex_t regex;
int ret; int ret;
grub_size_t s; grub_size_t s;

View file

@ -32,7 +32,7 @@ struct pci_register
unsigned size; unsigned size;
}; };
struct pci_register pci_registers[] = static struct pci_register pci_registers[] =
{ {
{"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2}, {"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2},
{"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2}, {"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2},

View file

@ -210,11 +210,11 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init); (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini); (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
return handle_command (argc, args, return handle_command (argc, args,
(struct abstract_terminal **) &grub_term_inputs, (struct abstract_terminal **) (void *) &grub_term_inputs,
(struct abstract_terminal **) &grub_term_inputs_disabled, (struct abstract_terminal **) (void *) &grub_term_inputs_disabled,
grub_term_input_autoload, grub_term_input_autoload,
N_ ("Active input terminals:"), N_ ("Active input terminals:"),
N_ ("Available input terminals:")); N_ ("Available input terminals:"));
} }
static grub_err_t static grub_err_t
@ -225,11 +225,12 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs, return handle_command (argc, args,
(struct abstract_terminal **) &grub_term_outputs_disabled, (struct abstract_terminal **) (void *) &grub_term_outputs,
grub_term_output_autoload, (struct abstract_terminal **) (void *) &grub_term_outputs_disabled,
N_ ("Active output terminals:"), grub_term_output_autoload,
N_ ("Available output terminals:")); N_ ("Active output terminals:"),
N_ ("Available output terminals:"));
} }
static grub_command_t cmd_terminal_input, cmd_terminal_output; static grub_command_t cmd_terminal_input, cmd_terminal_output;

View file

@ -266,7 +266,6 @@ match_files (const char *prefix, const char *suffix, const char *end,
const regex_t *regexp) const regex_t *regexp)
{ {
int i; int i;
int error;
char **files; char **files;
unsigned nfile; unsigned nfile;
char *dir; char *dir;
@ -440,8 +439,6 @@ wildcard_expand (const char *s, char ***strs)
else if (*start == '/') /* no device part */ else if (*start == '/') /* no device part */
{ {
char **r;
unsigned n;
char *root; char *root;
char *prefix; char *prefix;

View file

@ -624,6 +624,11 @@ GRUB_MOD_INIT(biosdisk)
((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
== GRUB_BIOSDISK_CDTYPE_NO_EMUL)) == GRUB_BIOSDISK_CDTYPE_NO_EMUL))
cd_drive = cdrp->drive_no; cd_drive = cdrp->drive_no;
/* Since diskboot.S rejects devices over 0x90 it must be a CD booted with
cdboot.S
*/
if (grub_boot_drive >= 0x90)
cd_drive = grub_boot_drive;
grub_disk_dev_register (&grub_biosdisk_dev); grub_disk_dev_register (&grub_biosdisk_dev);
} }

View file

@ -62,11 +62,10 @@ ofdisk_hash_find (const char *devpath)
} }
static struct ofdisk_hash_ent * static struct ofdisk_hash_ent *
ofdisk_hash_add (char *devpath) ofdisk_hash_add_real (char *devpath)
{ {
struct ofdisk_hash_ent *p;
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
struct ofdisk_hash_ent *p, *pcan;
char *curcan;
p = grub_malloc(sizeof (*p)); p = grub_malloc(sizeof (*p));
if (!p) if (!p)
@ -76,17 +75,27 @@ ofdisk_hash_add (char *devpath)
p->next = *head; p->next = *head;
p->shortest = 0; p->shortest = 0;
*head = p; *head = p;
return p;
}
static struct ofdisk_hash_ent *
ofdisk_hash_add (char *devpath, char *curcan)
{
struct ofdisk_hash_ent *p, *pcan;
p = ofdisk_hash_add_real (devpath);
grub_dprintf ("disk", "devpath = %s, canonical = %s\n", devpath, curcan);
curcan = grub_ieee1275_canonicalise_devname (devpath);
if (!curcan) if (!curcan)
{ {
grub_errno = GRUB_ERR_NONE; p->shortest = devpath;
return p; return p;
} }
pcan = ofdisk_hash_find (curcan); pcan = ofdisk_hash_find (curcan);
if (!pcan) if (!pcan)
pcan = ofdisk_hash_add (curcan); pcan = ofdisk_hash_add_real (curcan);
else else
grub_free (curcan); grub_free (curcan);
@ -118,17 +127,22 @@ scan (void)
return 0; return 0;
grub_dprintf ("disk", "disk name = %s\n", alias->name); grub_dprintf ("disk", "disk name = %s\n", alias->name);
grub_dprintf ("disk", "disk name = %s, path = %s\n", alias->name,
alias->path);
op = ofdisk_hash_find (alias->path); op = ofdisk_hash_find (alias->name);
if (!op) if (!op)
{ {
char *name = grub_strdup (alias->name); char *name = grub_strdup (alias->name);
if (!name) char *can = grub_strdup (alias->path);
if (!name || !can)
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
grub_free (name);
grub_free (can);
return 0; return 0;
} }
op = ofdisk_hash_add (name); op = ofdisk_hash_add (name, can);
} }
return 0; return 0;
} }
@ -247,7 +261,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
struct ofdisk_hash_ent *op; struct ofdisk_hash_ent *op;
op = ofdisk_hash_find (devpath); op = ofdisk_hash_find (devpath);
if (!op) if (!op)
op = ofdisk_hash_add (devpath); op = ofdisk_hash_add (devpath, NULL);
else else
grub_free (devpath); grub_free (devpath);
if (!op) if (!op)

View file

@ -222,7 +222,7 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(loopback) GRUB_MOD_INIT(loopback)
{ {
cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0,
N_("[-d|-p] DEVICENAME FILE."), N_("[-d] DEVICENAME FILE."),
N_("Make a device of a file."), options); N_("Make a device of a file."), options);
grub_disk_dev_register (&grub_loopback_dev); grub_disk_dev_register (&grub_loopback_dev);
} }

View file

@ -45,6 +45,7 @@ grub_lvm_getvalue (char **p, char *str)
return grub_strtoul (*p, NULL, 10); return grub_strtoul (*p, NULL, 10);
} }
#if 0
static int static int
grub_lvm_checkvalue (char **p, char *str, char *tmpl) grub_lvm_checkvalue (char **p, char *str, char *tmpl)
{ {
@ -57,6 +58,7 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl)
return 0; return 0;
return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"');
} }
#endif
static int static int
grub_lvm_check_flag (char *p, char *str, char *flag) grub_lvm_check_flag (char *p, char *str, char *flag)
@ -100,7 +102,7 @@ grub_lvm_iterate (int (*hook) (const char *name))
struct grub_lvm_lv *lv; struct grub_lvm_lv *lv;
if (vg->lvs) if (vg->lvs)
for (lv = vg->lvs; lv; lv = lv->next) for (lv = vg->lvs; lv; lv = lv->next)
if (hook (lv->name)) if (lv->visible && hook (lv->name))
return 1; return 1;
} }
@ -164,11 +166,10 @@ grub_lvm_close (grub_disk_t disk __attribute ((unused)))
} }
static grub_err_t static grub_err_t
grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector,
grub_size_t size, char *buf) grub_size_t size, char *buf)
{ {
grub_err_t err = 0; grub_err_t err = 0;
struct grub_lvm_lv *lv = disk->data;
struct grub_lvm_vg *vg = lv->vg; struct grub_lvm_vg *vg = lv->vg;
struct grub_lvm_segment *seg = lv->segments; struct grub_lvm_segment *seg = lv->segments;
struct grub_lvm_pv *pv; struct grub_lvm_pv *pv;
@ -176,6 +177,9 @@ grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_uint64_t extent; grub_uint64_t extent;
unsigned int i; unsigned int i;
if (!lv)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume");
extent = grub_divmod64 (sector, vg->extent_size, NULL); extent = grub_divmod64 (sector, vg->extent_size, NULL);
/* Find the right segment. */ /* Find the right segment. */
@ -190,59 +194,88 @@ grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
seg++; seg++;
} }
if (seg->stripe_count == 1) if (i == lv->segment_count)
return grub_error (GRUB_ERR_READ_ERROR, "incorrect segment");
switch (seg->type)
{ {
/* This segment is linear, so that's easy. We just need to find case GRUB_LVM_STRIPED:
out the offset in the physical volume and read SIZE bytes if (seg->stripe_count == 1)
from that. */ {
struct grub_lvm_stripe *stripe = seg->stripes; /* This segment is linear, so that's easy. We just need to find
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ out the offset in the physical volume and read SIZE bytes
from that. */
struct grub_lvm_stripe *stripe = seg->stripes;
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */
pv = stripe->pv; pv = stripe->pv;
seg_offset = ((grub_uint64_t) stripe->start seg_offset = ((grub_uint64_t) stripe->start
* (grub_uint64_t) vg->extent_size) + pv->start; * (grub_uint64_t) vg->extent_size) + pv->start;
offset = sector - ((grub_uint64_t) seg->start_extent offset = sector - ((grub_uint64_t) seg->start_extent
* (grub_uint64_t) vg->extent_size) + seg_offset; * (grub_uint64_t) vg->extent_size) + seg_offset;
}
else
{
/* This is a striped segment. We have to find the right PV
similar to RAID0. */
struct grub_lvm_stripe *stripe = seg->stripes;
grub_uint32_t a, b;
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */
unsigned int stripenr;
offset = sector - ((grub_uint64_t) seg->start_extent
* (grub_uint64_t) vg->extent_size);
a = grub_divmod64 (offset, seg->stripe_size, NULL);
grub_divmod64 (a, seg->stripe_count, &stripenr);
a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
grub_divmod64 (offset, seg->stripe_size, &b);
offset = a * seg->stripe_size + b;
stripe += stripenr;
pv = stripe->pv;
seg_offset = ((grub_uint64_t) stripe->start
* (grub_uint64_t) vg->extent_size) + pv->start;
offset += seg_offset;
}
/* Check whether we actually know the physical volume we want to
read from. */
if (pv->disk)
err = grub_disk_read (pv->disk, offset, 0,
size << GRUB_DISK_SECTOR_BITS, buf);
else
err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"physical volume %s not found", pv->name);
return err;
case GRUB_LVM_MIRROR:
i = 0;
while (1)
{
if (!seg->mirrors[i].lv)
err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume '%s'",
seg->mirrors[i].lvname);
else
err = read_lv (seg->mirrors[i].lv, sector, size, buf);
if (!err)
return err;
if (++i >= seg->mirror_count)
return err;
grub_errno = GRUB_ERR_NONE;
}
} }
else return grub_error (GRUB_ERR_IO, "unknown LVM segment");
{ }
/* This is a striped segment. We have to find the right PV
similar to RAID0. */
struct grub_lvm_stripe *stripe = seg->stripes;
grub_uint32_t a, b;
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */
unsigned int stripenr;
offset = sector - ((grub_uint64_t) seg->start_extent static grub_err_t
* (grub_uint64_t) vg->extent_size); grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
a = grub_divmod64 (offset, seg->stripe_size, NULL); {
grub_divmod64 (a, seg->stripe_count, &stripenr); return read_lv (disk->data, sector, size, buf);
a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
grub_divmod64 (offset, seg->stripe_size, &b);
offset = a * seg->stripe_size + b;
stripe += stripenr;
pv = stripe->pv;
seg_offset = ((grub_uint64_t) stripe->start
* (grub_uint64_t) vg->extent_size) + pv->start;
offset += seg_offset;
}
/* Check whether we actually know the physical volume we want to
read from. */
if (pv->disk)
err = grub_disk_read (pv->disk, offset, 0,
size << GRUB_DISK_SECTOR_BITS, buf);
else
err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"physical volume %s not found", pv->name);
return err;
} }
static grub_err_t static grub_err_t
@ -303,7 +336,7 @@ grub_lvm_scan_device (const char *name)
if (i == GRUB_LVM_LABEL_SCAN_SECTORS) if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("no LVM signature found\n"); grub_util_info ("no LVM signature found");
#endif #endif
goto fail; goto fail;
} }
@ -533,11 +566,7 @@ grub_lvm_scan_device (const char *name)
lv->size = 0; lv->size = 0;
if (!grub_lvm_check_flag (p, "status", "VISIBLE")) lv->visible = grub_lvm_check_flag (p, "status", "VISIBLE");
{
skip_lv = 1;
goto lv_parsed;
}
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
if (p == NULL) if (p == NULL)
@ -552,7 +581,6 @@ grub_lvm_scan_device (const char *name)
for (i = 0; i < lv->segment_count; i++) for (i = 0; i < lv->segment_count; i++)
{ {
struct grub_lvm_stripe *stripe;
p = grub_strstr (p, "segment"); p = grub_strstr (p, "segment");
if (p == NULL) if (p == NULL)
@ -580,78 +608,147 @@ grub_lvm_scan_device (const char *name)
goto lvs_segment_fail; goto lvs_segment_fail;
} }
if (grub_lvm_checkvalue (&p, "type = ", "snapshot")) p = grub_strstr (p, "type = \"");
{
/* Found a snapshot, give up and move on. */
skip_lv = 1;
break;
}
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
if (p == NULL) if (p == NULL)
{ goto lvs_segment_fail;
#ifdef GRUB_UTIL p += sizeof("type = \"") - 1;
grub_util_info ("unknown stripe_count\n");
#endif
goto lvs_segment_fail;
}
lv->size += seg->extent_count * vg->extent_size; lv->size += seg->extent_count * vg->extent_size;
if (seg->stripe_count != 1) if (grub_memcmp (p, "striped\"",
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); sizeof ("striped\"") - 1) == 0)
{
struct grub_lvm_stripe *stripe;
seg->stripes = grub_malloc (sizeof (*stripe) seg->type = GRUB_LVM_STRIPED;
* seg->stripe_count); seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
stripe = seg->stripes; if (p == NULL)
{
#ifdef GRUB_UTIL
grub_util_info ("unknown stripe_count\n");
#endif
goto lvs_segment_fail;
}
p = grub_strstr (p, "stripes = ["); if (seg->stripe_count != 1)
if (p == NULL) seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
seg->stripes = grub_malloc (sizeof (*stripe)
* seg->stripe_count);
stripe = seg->stripes;
p = grub_strstr (p, "stripes = [");
if (p == NULL)
{
#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++)
{
char *pvname;
p = grub_strchr (p, '"');
if (p == NULL)
continue;
q = ++p;
while (*q != '"')
q++;
s = q - p;
pvname = grub_malloc (s + 1);
if (pvname == NULL)
goto lvs_segment_fail2;
grub_memcpy (pvname, p, s);
pvname[s] = '\0';
if (vg->pvs)
for (pv = vg->pvs; pv; pv = pv->next)
{
if (! grub_strcmp (pvname, pv->name))
{
stripe->pv = pv;
break;
}
}
grub_free(pvname);
stripe->start = grub_lvm_getvalue (&p, ",");
if (p == NULL)
continue;
stripe++;
}
}
else if (grub_memcmp (p, "mirror\"", sizeof ("mirror\"") - 1)
== 0)
{
seg->type = GRUB_LVM_MIRROR;
seg->mirror_count = grub_lvm_getvalue (&p, "mirror_count = ");
if (p == NULL)
{
#ifdef GRUB_UTIL
grub_util_info ("unknown mirror_count\n");
#endif
goto lvs_segment_fail;
}
seg->mirrors = grub_zalloc (sizeof (seg->mirrors[0])
* seg->mirror_count);
p = grub_strstr (p, "mirrors = [");
if (p == NULL)
{
#ifdef GRUB_UTIL
grub_util_info ("unknown mirrors\n");
#endif
goto lvs_segment_fail2;
}
p += sizeof("mirrors = [") - 1;
for (j = 0; j < seg->mirror_count; j++)
{
char *lvname;
p = grub_strchr (p, '"');
if (p == NULL)
continue;
q = ++p;
while (*q != '"')
q++;
s = q - p;
lvname = grub_malloc (s + 1);
if (lvname == NULL)
goto lvs_segment_fail2;
grub_memcpy (lvname, p, s);
lvname[s] = '\0';
seg->mirrors[j].lvname = lvname;
p = q + 1;
}
}
else
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown stripes\n"); char *p2;
p2 = grub_strchr (p, '"');
if (p2)
*p2 = 0;
grub_util_info ("unknown LVM type %s\n", p);
if (p2)
*p2 ='"';
#endif #endif
goto lvs_segment_fail2; /* Found a non-supported type, give up and move on. */
} skip_lv = 1;
p += sizeof("stripes = [") - 1; break;
for (j = 0; j < seg->stripe_count; j++)
{
char *pvname;
p = grub_strchr (p, '"');
if (p == NULL)
continue;
q = ++p;
while (*q != '"')
q++;
s = q - p;
pvname = grub_malloc (s + 1);
if (pvname == NULL)
goto lvs_segment_fail2;
grub_memcpy (pvname, p, s);
pvname[s] = '\0';
if (vg->pvs)
for (pv = vg->pvs; pv; pv = pv->next)
{
if (! grub_strcmp (pvname, pv->name))
{
stripe->pv = pv;
break;
}
}
grub_free(pvname);
stripe->start = grub_lvm_getvalue (&p, ",");
if (p == NULL)
continue;
stripe++;
} }
seg++; seg++;
@ -663,7 +760,6 @@ grub_lvm_scan_device (const char *name)
goto fail4; goto fail4;
} }
lv_parsed:
if (p != NULL) if (p != NULL)
p = grub_strchr (p, '}'); p = grub_strchr (p, '}');
if (p == NULL) if (p == NULL)
@ -690,6 +786,20 @@ grub_lvm_scan_device (const char *name)
} }
} }
/* Match mirrors */
{
struct grub_lvm_lv *lv1;
struct grub_lvm_lv *lv2;
for (lv1 = vg->lvs; lv1; lv1 = lv1->next)
for (i = 0; i < lv1->segment_count; i++)
if (lv1->segments[i].type == GRUB_LVM_MIRROR)
for (j = 0; j < lv1->segments[i].mirror_count; j++)
for (lv2 = vg->lvs; lv2; lv2 = lv2->next)
if (grub_strcmp (lv2->name + grub_strlen (vg->name) + 1,
lv1->segments[i].mirrors[j].lvname) == 0)
lv1->segments[i].mirrors[j].lv = lv2;
}
vg->next = vg_list; vg->next = vg_list;
vg_list = vg; vg_list = vg;
} }
@ -762,5 +872,6 @@ GRUB_MOD_INIT(lvm)
GRUB_MOD_FINI(lvm) GRUB_MOD_FINI(lvm)
{ {
grub_disk_dev_unregister (&grub_lvm_dev); grub_disk_dev_unregister (&grub_lvm_dev);
vg_list = NULL;
/* FIXME: free the lvm list. */ /* FIXME: free the lvm list. */
} }

View file

@ -105,12 +105,11 @@ static grub_err_t
grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
grub_disk_addr_t *start_sector) grub_disk_addr_t *start_sector)
{ {
grub_disk_addr_t sector; grub_disk_addr_t sector = 0;
grub_uint64_t size; grub_uint64_t size;
struct grub_raid_super_1x sb; struct grub_raid_super_1x sb;
grub_uint8_t minor_version; grub_uint8_t minor_version;
/* The sector where the mdraid 0.90 superblock is stored, if available. */
size = grub_disk_get_size (disk); size = grub_disk_get_size (disk);
/* Check for an 1.x superblock. /* Check for an 1.x superblock.
@ -123,6 +122,9 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
for (minor_version = 0; minor_version < 3; ++minor_version) for (minor_version = 0; minor_version < 3; ++minor_version)
{ {
if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0)
continue;
switch (minor_version) switch (minor_version)
{ {
case 0: case 0:
@ -140,24 +142,28 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
&sb)) &sb))
return grub_errno; return grub_errno;
if (sb.magic != SB_MAGIC) if (grub_le_to_cpu32 (sb.magic) != SB_MAGIC
|| grub_le_to_cpu64 (sb.super_offset) != sector)
continue; continue;
{ {
grub_uint64_t sb_size; grub_uint64_t sb_size;
struct grub_raid_super_1x *real_sb; struct grub_raid_super_1x *real_sb;
grub_uint32_t level;
if (sb.major_version != 1) if (grub_le_to_cpu32 (sb.major_version) != 1)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unsupported RAID version: %d", "Unsupported RAID version: %d",
sb.major_version); grub_le_to_cpu32 (sb.major_version));
level = grub_le_to_cpu32 (sb.level);
/* Multipath. */ /* Multipath. */
if ((int) sb.level == -4) if ((int) level == -4)
sb.level = 1; level = 1;
if (sb.level != 0 && sb.level != 1 && sb.level != 4 && if (level != 0 && level != 1 && level != 4 &&
sb.level != 5 && sb.level != 6 && sb.level != 10) level != 5 && level != 6 && level != 10)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unsupported RAID level: %d", sb.level); "Unsupported RAID level: %d", sb.level);
@ -186,14 +192,19 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
array->level = grub_le_to_cpu32 (real_sb->level); array->level = grub_le_to_cpu32 (real_sb->level);
array->layout = grub_le_to_cpu32 (real_sb->layout); array->layout = grub_le_to_cpu32 (real_sb->layout);
array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks);
array->disk_size = grub_le_to_cpu64 (real_sb->size); if (real_sb->size)
array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); array->disk_size = grub_le_to_cpu64 (real_sb->size);
if (grub_le_to_cpu32 (real_sb->dev_number) <
grub_le_to_cpu32 (real_sb->max_dev))
array->index = grub_le_to_cpu16
(real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
else else
array->index = 0xffff; /* disk will be later not used! */ array->disk_size = grub_le_to_cpu64 (real_sb->data_size);
array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize);
if (grub_le_to_cpu32 (real_sb->dev_number) >=
grub_le_to_cpu32 (real_sb->max_dev))
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"spares aren't implemented");
array->index = grub_le_to_cpu16
(real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
array->uuid_len = 16; array->uuid_len = 16;
array->uuid = grub_malloc (16); array->uuid = grub_malloc (16);
if (!array->uuid) if (!array->uuid)
@ -204,7 +215,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
grub_memcpy (array->uuid, real_sb->set_uuid, 16); grub_memcpy (array->uuid, real_sb->set_uuid, 16);
*start_sector = real_sb->data_offset; *start_sector = grub_le_to_cpu64 (real_sb->data_offset);
grub_free (real_sb); grub_free (real_sb);
return 0; return 0;

View file

@ -167,42 +167,52 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
grub_uint64_t size; grub_uint64_t size;
struct grub_raid_super_09 sb; struct grub_raid_super_09 sb;
grub_uint32_t *uuid; grub_uint32_t *uuid;
grub_uint32_t level;
/* The sector where the mdraid 0.90 superblock is stored, if available. */ /* The sector where the mdraid 0.90 superblock is stored, if available. */
size = grub_disk_get_size (disk); size = grub_disk_get_size (disk);
if (size == GRUB_DISK_SIZE_UNKNOWN)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid");
sector = NEW_SIZE_SECTORS (size); sector = NEW_SIZE_SECTORS (size);
if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb)) if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
return grub_errno; return grub_errno;
/* Look whether there is a mdraid 0.90 superblock. */ /* Look whether there is a mdraid 0.90 superblock. */
if (sb.md_magic != SB_MAGIC) if (grub_le_to_cpu32 (sb.md_magic) != SB_MAGIC)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid"); return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid");
if (sb.major_version != 0 || sb.minor_version != 90) if (grub_le_to_cpu32 (sb.major_version) != 0
|| grub_le_to_cpu32 (sb.minor_version) != 90)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID version: %d.%d", "unsupported RAID version: %d.%d",
sb.major_version, sb.minor_version); grub_le_to_cpu32 (sb.major_version),
grub_le_to_cpu32 (sb.minor_version));
/* FIXME: Check the checksum. */ /* FIXME: Check the checksum. */
level = grub_le_to_cpu32 (sb.level);
/* Multipath. */ /* Multipath. */
if ((int) sb.level == -4) if ((int) level == -4)
sb.level = 1; level = 1;
if (sb.level != 0 && sb.level != 1 && sb.level != 4 && if (level != 0 && level != 1 && level != 4 &&
sb.level != 5 && sb.level != 6 && sb.level != 10) level != 5 && level != 6 && level != 10)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID level: %d", sb.level); "unsupported RAID level: %d", level);
if (grub_le_to_cpu32 (sb.this_disk.number) == 0xffff
|| grub_le_to_cpu32 (sb.this_disk.number) == 0xfffe)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"spares aren't implemented");
array->name = NULL; array->name = NULL;
array->number = sb.md_minor; array->number = grub_le_to_cpu32 (sb.md_minor);
array->level = sb.level; array->level = level;
array->layout = sb.layout; array->layout = grub_le_to_cpu32 (sb.layout);
array->total_devs = sb.raid_disks; array->total_devs = grub_le_to_cpu32 (sb.raid_disks);
array->disk_size = (sb.size) ? sb.size * 2 : sector; array->disk_size = (sb.size) ? grub_le_to_cpu32 (sb.size) * 2 : sector;
array->chunk_size = sb.chunk_size >> 9; array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9;
array->index = sb.this_disk.number; array->index = grub_le_to_cpu32 (sb.this_disk.number);
array->uuid_len = 16; array->uuid_len = 16;
array->uuid = grub_malloc (16); array->uuid = grub_malloc (16);
if (!array->uuid) if (!array->uuid)

View file

@ -97,10 +97,10 @@ grub_raid_memberlist (grub_disk_t disk)
unsigned int i; unsigned int i;
for (i = 0; i < array->total_devs; i++) for (i = 0; i < array->total_devs; i++)
if (array->device[i]) if (array->members[i].device)
{ {
tmp = grub_malloc (sizeof (*tmp)); tmp = grub_malloc (sizeof (*tmp));
tmp->disk = array->device[i]; tmp->disk = array->members[i].device;
tmp->next = list; tmp->next = list;
list = tmp; list = tmp;
} }
@ -255,13 +255,13 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
k = disknr; k = disknr;
for (j = 0; j < far; j++) for (j = 0; j < far; j++)
{ {
if (array->device[k]) if (array->members[k].device)
{ {
if (grub_errno == GRUB_ERR_READ_ERROR) if (grub_errno == GRUB_ERR_READ_ERROR)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
err = grub_disk_read (array->device[k], err = grub_disk_read (array->members[k].device,
array->start_sector[k] + array->members[k].start_sector +
read_sector + j * far_ofs + b, read_sector + j * far_ofs + b,
0, 0,
read_size << GRUB_DISK_SECTOR_BITS, read_size << GRUB_DISK_SECTOR_BITS,
@ -367,14 +367,14 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
read_size = size; read_size = size;
e = 0; e = 0;
if (array->device[disknr]) if (array->members[disknr].device)
{ {
/* Reset read error. */ /* Reset read error. */
if (grub_errno == GRUB_ERR_READ_ERROR) if (grub_errno == GRUB_ERR_READ_ERROR)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
err = grub_disk_read (array->device[disknr], err = grub_disk_read (array->members[disknr].device,
array->start_sector[disknr] + array->members[disknr].start_sector +
read_sector + b, 0, read_sector + b, 0,
read_size << GRUB_DISK_SECTOR_BITS, read_size << GRUB_DISK_SECTOR_BITS,
buf); buf);
@ -500,6 +500,21 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
/* Do some checks before adding the device to the array. */ /* Do some checks before adding the device to the array. */
if (new_array->index >= array->allocated_devs)
{
void *tmp;
unsigned int newnum = 2 * (new_array->index + 1);
tmp = grub_realloc (array->members, newnum
* sizeof (array->members[0]));
if (!tmp)
return grub_errno;
array->members = tmp;
grub_memset (array->members + array->allocated_devs,
0, (newnum - array->allocated_devs)
* sizeof (array->members[0]));
array->allocated_devs = newnum;
}
/* FIXME: Check whether the update time of the superblocks are /* FIXME: Check whether the update time of the superblocks are
the same. */ the same. */
@ -507,14 +522,16 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
/* We found more members of the array than the array /* We found more members of the array than the array
actually has according to its superblock. This shouldn't actually has according to its superblock. This shouldn't
happen normally. */ happen normally. */
grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?", return grub_error (GRUB_ERR_BAD_DEVICE,
array->total_devs); "superfluous RAID member (%d found)",
array->total_devs);
if (array->device[new_array->index] != NULL) if (array->members[new_array->index].device != NULL)
/* We found multiple devices with the same number. Again, /* We found multiple devices with the same number. Again,
this shouldn't happen. */ this shouldn't happen. */
grub_dprintf ("raid", "Found two disks with the number %d?!?", return grub_error (GRUB_ERR_BAD_DEVICE,
new_array->number); "found two disks with the index %d for RAID %s",
new_array->index, array->name);
if (new_array->disk_size < array->disk_size) if (new_array->disk_size < array->disk_size)
array->disk_size = new_array->disk_size; array->disk_size = new_array->disk_size;
@ -536,14 +553,24 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
array->driver = raid; array->driver = raid;
#endif #endif
grub_memset (&array->device, 0, sizeof (array->device)); array->allocated_devs = 32;
grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); if (new_array->index >= array->allocated_devs)
array->allocated_devs = 2 * (new_array->index + 1);
array->members = grub_zalloc (array->allocated_devs
* sizeof (array->members[0]));
if (!array->members)
{
grub_free (new_array->uuid);
return grub_errno;
}
if (! array->name) if (! array->name)
{ {
for (p = array_list; p != NULL; p = p->next) for (p = array_list; p != NULL; p = p->next)
{ {
if (! p->name && p->number == array->number) if (p->number == array->number)
break; break;
} }
} }
@ -582,6 +609,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
array->name = grub_xasprintf ("md%d", array->number); array->name = grub_xasprintf ("md%d", array->number);
if (! array->name) if (! array->name)
{ {
grub_free (array->members);
grub_free (array->uuid); grub_free (array->uuid);
grub_free (array); grub_free (array);
@ -597,6 +625,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
if (! new_name) if (! new_name)
{ {
grub_free (array->members);
grub_free (array->uuid); grub_free (array->uuid);
grub_free (array); grub_free (array);
@ -609,6 +638,10 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
grub_dprintf ("raid", "Found array %s (%s)\n", array->name, grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
scanner_name); scanner_name);
#ifdef GRUB_UTIL
grub_util_info ("Found array %s (%s)", array->name,
scanner_name);
#endif
/* Add our new array to the list. */ /* Add our new array to the list. */
array->next = array_list; array->next = array_list;
@ -621,8 +654,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
} }
/* Add the device to the array. */ /* Add the device to the array. */
array->device[new_array->index] = disk; array->members[new_array->index].device = disk;
array->start_sector[new_array->index] = start_sector; array->members[new_array->index].start_sector = start_sector;
array->nr_devs++; array->nr_devs++;
return 0; return 0;
@ -639,14 +672,15 @@ free_array (void)
while (array) while (array)
{ {
struct grub_raid_array *p; struct grub_raid_array *p;
int i; unsigned int i;
p = array; p = array;
array = array->next; array = array->next;
for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++) for (i = 0; i < p->allocated_devs; i++)
if (p->device[i]) if (p->members[i].device)
grub_disk_close (p->device[i]); grub_disk_close (p->members[i].device);
grub_free (p->members);
grub_free (p->uuid); grub_free (p->uuid);
grub_free (p->name); grub_free (p->name);
@ -666,7 +700,12 @@ grub_raid_register (grub_raid_t raid)
struct grub_raid_array array; struct grub_raid_array array;
grub_disk_addr_t start_sector; grub_disk_addr_t start_sector;
grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n",
grub_raid_list->name, name);
#ifdef GRUB_UTIL
grub_util_info ("Scanning for %s RAID devices on disk %s",
grub_raid_list->name, name);
#endif
disk = grub_disk_open (name); disk = grub_disk_open (name);
if (!disk) if (!disk)

View file

@ -45,7 +45,9 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr,
if (i == disknr) if (i == disknr)
continue; continue;
err = grub_disk_read (array->device[i], sector, 0, size, buf2); err = grub_disk_read (array->members[i].device,
array->members[i].start_sector + sector,
0, size, buf2);
if (err) if (err)
{ {

View file

@ -118,8 +118,10 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
bad1 = i; bad1 = i;
else else
{ {
if ((array->device[pos]) && if ((array->members[pos].device) &&
(! grub_disk_read (array->device[pos], sector, 0, size, buf))) (! grub_disk_read (array->members[pos].device,
array->members[i].start_sector + sector,
0, size, buf)))
{ {
grub_raid_block_xor (pbuf, buf, size); grub_raid_block_xor (pbuf, buf, size);
grub_raid_block_mul (raid6_table2[i][i], buf, size); grub_raid_block_mul (raid6_table2[i][i], buf, size);
@ -148,21 +150,24 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
if (bad2 < 0) if (bad2 < 0)
{ {
/* One bad device */ /* One bad device */
if ((array->device[p]) && if ((array->members[p].device) &&
(! grub_disk_read (array->device[p], sector, 0, size, buf))) (! grub_disk_read (array->members[p].device,
array->members[i].start_sector + sector,
0, size, buf)))
{ {
grub_raid_block_xor (buf, pbuf, size); grub_raid_block_xor (buf, pbuf, size);
goto quit; goto quit;
} }
if (! array->device[q]) if (! array->members[q].device)
{ {
grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
goto quit; goto quit;
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
if (grub_disk_read (array->device[q], sector, 0, size, buf)) if (grub_disk_read (array->members[q].device,
array->members[i].start_sector + sector, 0, size, buf))
goto quit; goto quit;
grub_raid_block_xor (buf, qbuf, size); grub_raid_block_xor (buf, qbuf, size);
@ -174,18 +179,22 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
/* Two bad devices */ /* Two bad devices */
grub_uint8_t c; grub_uint8_t c;
if ((! array->device[p]) || (! array->device[q])) if ((! array->members[p].device) || (! array->members[q].device))
{ {
grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
goto quit; goto quit;
} }
if (grub_disk_read (array->device[p], sector, 0, size, buf)) if (grub_disk_read (array->members[p].device,
array->members[i].start_sector + sector,
0, size, buf))
goto quit; goto quit;
grub_raid_block_xor (pbuf, buf, size); grub_raid_block_xor (pbuf, buf, size);
if (grub_disk_read (array->device[q], sector, 0, size, buf)) if (grub_disk_read (array->members[q].device,
array->members[i].start_sector + sector,
0, size, buf))
goto quit; goto quit;
grub_raid_block_xor (qbuf, buf, size); grub_raid_block_xor (qbuf, buf, size);

View file

@ -506,7 +506,7 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE) if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
{ {
unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS; unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0)) if (spb == 0 || (scsi->blocksize & (GRUB_DISK_SECTOR_SIZE - 1)) != 0)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported SCSI block size"); "unsupported SCSI block size");

View file

@ -70,7 +70,11 @@ static int first_available_slot = 0;
static grub_err_t static grub_err_t
grub_usbms_reset (grub_usb_device_t dev, int interface) grub_usbms_reset (grub_usb_device_t dev, int interface)
{ {
return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); grub_usb_err_t u;
u = grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0);
if (u)
return grub_error (GRUB_ERR_IO, "USB error %d", u);
return GRUB_ERR_NONE;
} }
static void static void
@ -408,7 +412,7 @@ static struct grub_scsi_dev grub_usbms_dev =
.write = grub_usbms_write .write = grub_usbms_write
}; };
struct grub_usb_attach_desc attach_hook = static struct grub_usb_attach_desc attach_hook =
{ {
.class = GRUB_USB_CLASS_MASS_STORAGE, .class = GRUB_USB_CLASS_MASS_STORAGE,
.hook = grub_usbms_attach .hook = grub_usbms_attach

View file

@ -24,7 +24,7 @@
#include <grub/acpi.h> #include <grub/acpi.h>
grub_err_t grub_err_t
grub_machine_efiemu_init_tables () grub_machine_efiemu_init_tables (void)
{ {
grub_uint8_t *ptr; grub_uint8_t *ptr;
void *table; void *table;

View file

@ -208,7 +208,7 @@ grub_affs_mount (grub_disk_t disk)
rblock = (struct grub_affs_rblock *) rootblock; rblock = (struct grub_affs_rblock *) rootblock;
/* Read the rootblock. */ /* Read the rootblock. */
grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0, grub_disk_read (disk, grub_be_to_cpu32 (data->bblock.rootblock), 0,
GRUB_DISK_SECTOR_SIZE * 16, rootblock); GRUB_DISK_SECTOR_SIZE * 16, rootblock);
if (grub_errno) if (grub_errno)
goto fail; goto fail;
@ -240,7 +240,7 @@ grub_affs_mount (grub_disk_t disk)
data->disk = disk; data->disk = disk;
data->htsize = grub_be_to_cpu32 (rblock->htsize); data->htsize = grub_be_to_cpu32 (rblock->htsize);
data->diropen.data = data; data->diropen.data = data;
data->diropen.block = (disk->total_sectors >> 1); data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
grub_free (rootblock); grub_free (rootblock);
@ -507,7 +507,7 @@ grub_affs_label (grub_device_t device, char **label)
{ {
/* The rootblock maps quite well on a file header block, it's /* The rootblock maps quite well on a file header block, it's
something we can use here. */ something we can use here. */
grub_disk_read (data->disk, disk->total_sectors >> 1, grub_disk_read (data->disk, grub_be_to_cpu32 (data->bblock.rootblock),
data->blocksize * (GRUB_DISK_SECTOR_SIZE data->blocksize * (GRUB_DISK_SECTOR_SIZE
- GRUB_AFFS_FILE_LOCATION), - GRUB_AFFS_FILE_LOCATION),
sizeof (file), &file); sizeof (file), &file);
@ -535,6 +535,9 @@ static struct grub_fs grub_affs_fs =
.read = grub_affs_read, .read = grub_affs_read,
.close = grub_affs_close, .close = grub_affs_close,
.label = grub_affs_label, .label = grub_affs_label,
#ifdef GRUB_UTIL
.reserved_first_sector = 0,
#endif
.next = 0 .next = 0
}; };

View file

@ -51,7 +51,7 @@ grub_btrfs_mount (grub_disk_t disk)
&data->sblock) != GRUB_ERR_NONE) &data->sblock) != GRUB_ERR_NONE)
goto fail; goto fail;
if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1)) if (grub_memcmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1))
{ {
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
goto fail; goto fail;
@ -60,6 +60,9 @@ grub_btrfs_mount (grub_disk_t disk)
return data; return data;
fail: fail:
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
grub_free (data); grub_free (data);
return NULL; return NULL;
} }

View file

@ -354,6 +354,9 @@ static struct grub_fs grub_cpio_fs = {
.open = grub_cpio_open, .open = grub_cpio_open,
.read = grub_cpio_read, .read = grub_cpio_read,
.close = grub_cpio_close, .close = grub_cpio_close,
#ifdef GRUB_UTIL
.reserved_first_sector = 0,
#endif
}; };
#ifdef MODE_USTAR #ifdef MODE_USTAR

View file

@ -229,7 +229,7 @@ struct grub_ext2_inode
}; };
grub_uint32_t version; grub_uint32_t version;
grub_uint32_t acl; grub_uint32_t acl;
grub_uint32_t dir_acl; grub_uint32_t size_high;
grub_uint32_t fragment_addr; grub_uint32_t fragment_addr;
grub_uint32_t osd2[3]; grub_uint32_t osd2[3];
}; };
@ -470,10 +470,41 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
blknr = grub_le_to_cpu32 (indir[rblock % perblock]); blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
} }
/* triple indirect. */ /* triple indirect. */
else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)
+ (blksz / 4) * (blksz / 4) * (blksz / 4 + 1))
{
unsigned int perblock = blksz / 4;
unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
* (blksz / 4 + 1));
grub_uint32_t indir[blksz / 4];
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
grub_le_to_cpu32 (inode->blocks.triple_indir_block))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
grub_le_to_cpu32 (indir[(rblock / perblock) / perblock]))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
grub_le_to_cpu32 (indir[(rblock / perblock) % perblock]))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
}
else else
{ {
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"ext2fs doesn't support triple indirect blocks"); "ext2fs doesn't support quadruple indirect blocks");
} }
return blknr; return blknr;
@ -485,11 +516,12 @@ static grub_ssize_t
grub_ext2_read_file (grub_fshelp_node_t node, grub_ext2_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length), unsigned offset, unsigned length),
int pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
return grub_fshelp_read_file (node->data->disk, node, read_hook, return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_ext2_read_block, pos, len, buf, grub_ext2_read_block,
node->inode.size, grub_cpu_to_le32 (node->inode.size)
| (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32),
LOG2_EXT2_BLOCK_SIZE (node->data)); LOG2_EXT2_BLOCK_SIZE (node->data));
} }
@ -523,7 +555,7 @@ grub_ext2_read_inode (struct grub_ext2_data *data,
/* Read the inode. */ /* Read the inode. */
if (grub_disk_read (data->disk, if (grub_disk_read (data->disk,
((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
<< LOG2_EXT2_BLOCK_SIZE (data)), << LOG2_EXT2_BLOCK_SIZE (data)),
EXT2_INODE_SIZE (data) * blkoff, EXT2_INODE_SIZE (data) * blkoff,
sizeof (struct grub_ext2_inode), inode)) sizeof (struct grub_ext2_inode), inode))
@ -756,6 +788,7 @@ grub_ext2_open (struct grub_file *file, const char *name)
grub_free (fdiro); grub_free (fdiro);
file->size = grub_le_to_cpu32 (data->inode->size); file->size = grub_le_to_cpu32 (data->inode->size);
file->size |= ((grub_off_t) grub_le_to_cpu32 (data->inode->size_high)) << 32;
file->data = data; file->data = data;
file->offset = 0; file->offset = 0;

View file

@ -178,7 +178,7 @@ enum grub_hfsplus_filetype
/* Internal representation of a catalog key. */ /* Internal representation of a catalog key. */
struct grub_hfsplus_catkey_internal struct grub_hfsplus_catkey_internal
{ {
int parent; grub_uint32_t parent;
char *name; char *name;
}; };
@ -520,9 +520,12 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
int i; int i;
int diff; int diff;
diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent; /* Safe unsigned comparison */
if (diff) grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent);
return diff; if (aparent > catkey_b->parent)
return 1;
if (aparent < catkey_b->parent)
return -1;
/* Change the filename in keya so the endianness is correct. */ /* Change the filename in keya so the endianness is correct. */
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
@ -555,15 +558,21 @@ grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
{ {
struct grub_hfsplus_extkey *extkey_a = &keya->extkey; struct grub_hfsplus_extkey *extkey_a = &keya->extkey;
struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey; struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey;
int diff; grub_uint32_t akey;
diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid; /* Safe unsigned comparison */
akey = grub_be_to_cpu32 (extkey_a->fileid);
if (akey > extkey_b->fileid)
return 1;
if (akey < extkey_b->fileid)
return -1;
if (diff) akey = grub_be_to_cpu32 (extkey_a->start);
return diff; if (akey > extkey_b->start)
return 1;
diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start; if (akey < extkey_b->start)
return diff; return -1;
return 0;
} }
static char * static char *

View file

@ -808,6 +808,15 @@ grub_iso9660_label (grub_device_t device, char **label)
((grub_uint16_t *) &data->voldesc.volname, 16); ((grub_uint16_t *) &data->voldesc.volname, 16);
else else
*label = grub_strndup ((char *) data->voldesc.volname, 32); *label = grub_strndup ((char *) data->voldesc.volname, 32);
if (*label)
{
char *ptr;
for (ptr = *label; *ptr;ptr++);
ptr--;
while (ptr >= *label && *ptr == ' ')
*ptr-- = 0;
}
grub_free (data); grub_free (data);
} }
else else

View file

@ -1072,7 +1072,11 @@ grub_ntfs_uuid (grub_device_t device, char **uuid)
data = grub_ntfs_mount (disk); data = grub_ntfs_mount (disk);
if (data) if (data)
{ {
char *ptr;
*uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid); *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid);
if (*uuid)
for (ptr = *uuid; *ptr; ptr++)
*ptr = grub_toupper (*ptr);
} }
else else
*uuid = NULL; *uuid = NULL;

View file

@ -579,6 +579,9 @@ static struct grub_fs grub_sfs_fs =
.read = grub_sfs_read, .read = grub_sfs_read,
.close = grub_sfs_close, .close = grub_sfs_close,
.label = grub_sfs_label, .label = grub_sfs_label,
#ifdef GRUB_UTIL
.reserved_first_sector = 0,
#endif
.next = 0 .next = 0
}; };

View file

@ -34,9 +34,6 @@
#define U32 grub_le_to_cpu32 #define U32 grub_le_to_cpu32
#define U64 grub_le_to_cpu64 #define U64 grub_le_to_cpu64
#define GRUB_UDF_LOG2_BLKSZ 2
#define GRUB_UDF_BLKSZ 2048
#define GRUB_UDF_TAG_IDENT_PVD 0x0001 #define GRUB_UDF_TAG_IDENT_PVD 0x0001
#define GRUB_UDF_TAG_IDENT_AVDP 0x0002 #define GRUB_UDF_TAG_IDENT_AVDP 0x0002
#define GRUB_UDF_TAG_IDENT_VDP 0x0003 #define GRUB_UDF_TAG_IDENT_VDP 0x0003
@ -336,6 +333,13 @@ struct grub_udf_lvd
grub_uint8_t part_maps[1608]; grub_uint8_t part_maps[1608];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_udf_aed
{
struct grub_udf_tag tag;
grub_uint32_t prev_ae;
grub_uint32_t ae_len;
} __attribute__ ((packed));
struct grub_udf_data struct grub_udf_data
{ {
grub_disk_t disk; grub_disk_t disk;
@ -343,7 +347,7 @@ struct grub_udf_data
struct grub_udf_pd pds[GRUB_UDF_MAX_PDS]; struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS]; struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
struct grub_udf_long_ad root_icb; struct grub_udf_long_ad root_icb;
int npd, npm; int npd, npm, lbshift;
}; };
struct grub_fshelp_node struct grub_fshelp_node
@ -389,7 +393,7 @@ grub_udf_read_icb (struct grub_udf_data *data,
if (grub_errno) if (grub_errno)
return grub_errno; return grub_errno;
if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (data->disk, block << data->lbshift, 0,
sizeof (struct grub_udf_file_entry), sizeof (struct grub_udf_file_entry),
&node->fe)) &node->fe))
return grub_errno; return grub_errno;
@ -406,19 +410,26 @@ grub_udf_read_icb (struct grub_udf_data *data,
static grub_disk_addr_t static grub_disk_addr_t
grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{ {
char *buf = NULL;
char *ptr; char *ptr;
int len; grub_ssize_t len;
grub_disk_addr_t filebytes; grub_disk_addr_t filebytes;
if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) switch (U16 (node->fe.tag.tag_ident))
{ {
case GRUB_UDF_TAG_IDENT_FE:
ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length); ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length);
len = U32 (node->fe.alloc_descs_length); len = U32 (node->fe.alloc_descs_length);
} break;
else
{ case GRUB_UDF_TAG_IDENT_EFE:
ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length); ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length);
len = U32 (node->efe.alloc_descs_length); len = U32 (node->efe.alloc_descs_length);
break;
default:
grub_error (GRUB_ERR_BAD_FS, "invalid file entry");
return 0;
} }
if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
@ -426,43 +437,115 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{ {
struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr;
len /= sizeof (struct grub_udf_short_ad); filebytes = fileblock * U32 (node->data->lvd.bsize);
filebytes = fileblock * GRUB_UDF_BLKSZ; while (len >= (grub_ssize_t) sizeof (struct grub_udf_short_ad))
while (len > 0)
{ {
if (filebytes < U32 (ad->length)) grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff;
return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 : grub_uint32_t adtype = U32 (ad->length) >> 30;
(grub_udf_get_block (node->data, if (adtype == 3)
node->part_ref, {
ad->position) struct grub_udf_aed *extension;
+ (filebytes / GRUB_UDF_BLKSZ))); grub_disk_addr_t sec = grub_udf_get_block(node->data,
node->part_ref,
ad->position);
if (!buf)
{
buf = grub_malloc (U32 (node->data->lvd.bsize));
if (!buf)
return 0;
}
if (grub_disk_read (node->data->disk, sec << node->data->lbshift,
0, adlen, buf))
goto fail;
filebytes -= U32 (ad->length); extension = (struct grub_udf_aed *) buf;
if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED)
{
grub_error (GRUB_ERR_BAD_FS, "invalid aed tag");
goto fail;
}
len = U32 (extension->ae_len);
ad = (struct grub_udf_short_ad *)
(buf + sizeof (struct grub_udf_aed));
continue;
}
if (filebytes < adlen)
{
grub_uint32_t ad_pos = ad->position;
grub_free (buf);
return ((U32 (ad_pos) & GRUB_UDF_EXT_MASK) ? 0 :
(grub_udf_get_block (node->data, node->part_ref, ad_pos)
+ (filebytes >> (GRUB_DISK_SECTOR_BITS
+ node->data->lbshift))));
}
filebytes -= adlen;
ad++; ad++;
len--; len -= sizeof (struct grub_udf_short_ad);
} }
} }
else else
{ {
struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr;
len /= sizeof (struct grub_udf_long_ad); filebytes = fileblock * U32 (node->data->lvd.bsize);
filebytes = fileblock * GRUB_UDF_BLKSZ; while (len >= (grub_ssize_t) sizeof (struct grub_udf_long_ad))
while (len > 0)
{ {
if (filebytes < U32 (ad->length)) grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff;
return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ? 0 : grub_uint32_t adtype = U32 (ad->length) >> 30;
(grub_udf_get_block (node->data, if (adtype == 3)
ad->block.part_ref, {
ad->block.block_num) struct grub_udf_aed *extension;
+ (filebytes / GRUB_UDF_BLKSZ))); grub_disk_addr_t sec = grub_udf_get_block(node->data,
ad->block.part_ref,
ad->block.block_num);
if (!buf)
{
buf = grub_malloc (U32 (node->data->lvd.bsize));
if (!buf)
return 0;
}
if (grub_disk_read (node->data->disk, sec << node->data->lbshift,
0, adlen, buf))
goto fail;
filebytes -= U32 (ad->length); extension = (struct grub_udf_aed *) buf;
if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED)
{
grub_error (GRUB_ERR_BAD_FS, "invalid aed tag");
goto fail;
}
len = U32 (extension->ae_len);
ad = (struct grub_udf_long_ad *)
(buf + sizeof (struct grub_udf_aed));
continue;
}
if (filebytes < adlen)
{
grub_uint32_t ad_block_num = ad->block.block_num;
grub_uint32_t ad_part_ref = ad->block.part_ref;
grub_free (buf);
return ((U32 (ad_block_num) & GRUB_UDF_EXT_MASK) ? 0 :
(grub_udf_get_block (node->data, ad_part_ref,
ad_block_num)
+ (filebytes >> (GRUB_DISK_SECTOR_BITS
+ node->data->lbshift))));
}
filebytes -= adlen;
ad++; ad++;
len--; len -= sizeof (struct grub_udf_long_ad);
} }
} }
fail:
if (buf)
grub_free (buf);
return 0; return 0;
} }
@ -471,7 +554,7 @@ grub_udf_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR void NESTED_FUNC_ATTR
(*read_hook) (grub_disk_addr_t sector, (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length), unsigned offset, unsigned length),
int pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
{ {
@ -496,21 +579,21 @@ grub_udf_read_file (grub_fshelp_node_t node,
} }
return grub_fshelp_read_file (node->data->disk, node, read_hook, return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_udf_read_block, pos, len, buf, grub_udf_read_block,
U64 (node->fe.file_size), U64 (node->fe.file_size),
GRUB_UDF_LOG2_BLKSZ); node->data->lbshift);
} }
static int sblocklist[] = { 256, 512, 0 }; static unsigned sblocklist[] = { 256, 512, 0 };
static struct grub_udf_data * static struct grub_udf_data *
grub_udf_mount (grub_disk_t disk) grub_udf_mount (grub_disk_t disk)
{ {
struct grub_udf_data *data = 0; struct grub_udf_data *data = 0;
struct grub_udf_fileset root_fs; struct grub_udf_fileset root_fs;
int *sblklist = sblocklist; unsigned *sblklist;
grub_uint32_t block; grub_uint32_t block, vblock;
int i; int i, lbshift;
data = grub_malloc (sizeof (struct grub_udf_data)); data = grub_malloc (sizeof (struct grub_udf_data));
if (!data) if (!data)
@ -518,12 +601,48 @@ grub_udf_mount (grub_disk_t disk)
data->disk = disk; data->disk = disk;
/* Search for Anchor Volume Descriptor Pointer (AVDP)
* and determine logical block size. */
block = 0;
for (lbshift = 0; lbshift < 4; lbshift++)
{
for (sblklist = sblocklist; *sblklist; sblklist++)
{
struct grub_udf_avdp avdp;
if (grub_disk_read (disk, *sblklist << lbshift, 0,
sizeof (struct grub_udf_avdp), &avdp))
{
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
goto fail;
}
if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP &&
U32 (avdp.tag.tag_location) == *sblklist)
{
block = U32 (avdp.vds.start);
break;
}
}
if (block)
break;
}
if (!block)
{
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
goto fail;
}
data->lbshift = lbshift;
/* Search for Volume Recognition Sequence (VRS). */ /* Search for Volume Recognition Sequence (VRS). */
for (block = 16;; block++) for (vblock = (32767 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1;;
vblock += (2047 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1)
{ {
struct grub_udf_vrs vrs; struct grub_udf_vrs vrs;
if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (disk, vblock << lbshift, 0,
sizeof (struct grub_udf_vrs), &vrs)) sizeof (struct grub_udf_vrs), &vrs))
{ {
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
@ -545,39 +664,13 @@ grub_udf_mount (grub_disk_t disk)
} }
} }
/* Search for Anchor Volume Descriptor Pointer (AVDP). */
while (1)
{
struct grub_udf_avdp avdp;
if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0,
sizeof (struct grub_udf_avdp), &avdp))
{
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
goto fail;
}
if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP)
{
block = U32 (avdp.vds.start);
break;
}
sblklist++;
if (*sblklist == 0)
{
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
goto fail;
}
}
data->npd = data->npm = 0; data->npd = data->npm = 0;
/* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD). */ /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD). */
while (1) while (1)
{ {
struct grub_udf_tag tag; struct grub_udf_tag tag;
if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (disk, block << lbshift, 0,
sizeof (struct grub_udf_tag), &tag)) sizeof (struct grub_udf_tag), &tag))
{ {
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
@ -593,7 +686,7 @@ grub_udf_mount (grub_disk_t disk)
goto fail; goto fail;
} }
if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (disk, block << lbshift, 0,
sizeof (struct grub_udf_pd), sizeof (struct grub_udf_pd),
&data->pds[data->npd])) &data->pds[data->npd]))
{ {
@ -609,7 +702,7 @@ grub_udf_mount (grub_disk_t disk)
struct grub_udf_partmap *ppm; struct grub_udf_partmap *ppm;
if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (disk, block << lbshift, 0,
sizeof (struct grub_udf_lvd), sizeof (struct grub_udf_lvd),
&data->lvd)) &data->lvd))
{ {
@ -673,7 +766,7 @@ grub_udf_mount (grub_disk_t disk)
if (grub_errno) if (grub_errno)
goto fail; goto fail;
if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, if (grub_disk_read (disk, block << lbshift, 0,
sizeof (struct grub_udf_fileset), &root_fs)) sizeof (struct grub_udf_fileset), &root_fs))
{ {
grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
@ -695,6 +788,43 @@ fail:
return 0; return 0;
} }
static char *
read_string (grub_uint8_t *raw, grub_size_t sz)
{
grub_uint16_t *utf16 = NULL;
char *ret;
grub_size_t utf16len = 0;
if (raw[0] != 8 && raw[0] != 16)
return NULL;
if (raw[0] == 8)
{
unsigned i;
utf16len = sz - 1;
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
if (!utf16)
return NULL;
for (i = 0; i < utf16len; i++)
utf16[i] = raw[i + 1];
}
if (raw[0] == 16)
{
unsigned i;
utf16len = (sz - 1) / 2;
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
if (!utf16)
return NULL;
for (i = 0; i < utf16len; i++)
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
}
ret = grub_malloc (utf16len * 3 + 1);
if (ret)
*grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0';
grub_free (utf16);
return ret;
}
static int static int
grub_udf_iterate_dir (grub_fshelp_node_t dir, grub_udf_iterate_dir (grub_fshelp_node_t dir,
int NESTED_FUNC_ATTR int NESTED_FUNC_ATTR
@ -704,7 +834,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
{ {
grub_fshelp_node_t child; grub_fshelp_node_t child;
struct grub_udf_file_ident dirent; struct grub_udf_file_ident dirent;
grub_uint32_t offset = 0; grub_off_t offset = 0;
child = grub_malloc (sizeof (struct grub_fshelp_node)); child = grub_malloc (sizeof (struct grub_fshelp_node));
if (!child) if (!child)
@ -729,57 +859,47 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
return 0; return 0;
} }
child = grub_malloc (sizeof (struct grub_fshelp_node));
if (!child)
return 0;
if (grub_udf_read_icb (dir->data, &dirent.icb, child))
return 0;
offset += sizeof (dirent) + U16 (dirent.imp_use_length); offset += sizeof (dirent) + U16 (dirent.imp_use_length);
if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) if (!(dirent.characteristics & GRUB_UDF_FID_CHAR_DELETED))
{ {
/* This is the parent directory. */ child = grub_malloc (sizeof (struct grub_fshelp_node));
if (hook ("..", GRUB_FSHELP_DIR, child)) if (!child)
return 1;
}
else
{
enum grub_fshelp_filetype type;
grub_uint8_t raw[dirent.file_ident_length];
grub_uint16_t utf16[dirent.file_ident_length - 1];
grub_uint8_t filename[dirent.file_ident_length * 2];
grub_size_t utf16len = 0;
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
if ((grub_udf_read_file (dir, 0, offset,
dirent.file_ident_length,
(char *) raw))
!= dirent.file_ident_length)
return 0; return 0;
if (raw[0] == 8) if (grub_udf_read_icb (dir->data, &dirent.icb, child))
{ return 0;
unsigned i;
utf16len = dirent.file_ident_length - 1;
for (i = 0; i < utf16len; i++)
utf16[i] = raw[i + 1];
}
if (raw[0] == 16)
{
unsigned i;
utf16len = (dirent.file_ident_length - 1) / 2;
for (i = 0; i < utf16len; i++)
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
}
if (raw[0] == 8 || raw[0] == 16)
{
*grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0';
if (hook ((char *) filename, type, child)) if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
return 1; {
/* This is the parent directory. */
if (hook ("..", GRUB_FSHELP_DIR, child))
return 1;
}
else
{
enum grub_fshelp_filetype type;
char *filename;
grub_uint8_t raw[dirent.file_ident_length];
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
if ((grub_udf_read_file (dir, 0, offset,
dirent.file_ident_length,
(char *) raw))
!= dirent.file_ident_length)
return 0;
filename = read_string (raw, dirent.file_ident_length);
if (!filename)
grub_print_error ();
if (filename && hook (filename, type, child))
{
grub_free (filename);
return 1;
}
grub_free (filename);
} }
} }
@ -908,7 +1028,7 @@ grub_udf_label (grub_device_t device, char **label)
if (data) if (data)
{ {
*label = grub_strdup ((char *) &data->lvd.ident[1]); *label = read_string (data->lvd.ident, sizeof (data->lvd.ident));
grub_free (data); grub_free (data);
} }
else else

View file

@ -451,18 +451,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
{ {
grub_uint64_t ino; grub_uint64_t ino;
void *inopos = (((char *) de) grub_uint8_t *inopos = (((grub_uint8_t *) de)
+ sizeof (struct grub_xfs_dir_entry) + sizeof (struct grub_xfs_dir_entry)
+ de->len - 1); + de->len - 1);
char name[de->len + 1]; char name[de->len + 1];
/* inopos might be unaligned. */
if (smallino) if (smallino)
{ ino = (((grub_uint32_t) inopos[0]) << 24)
ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos); | (((grub_uint32_t) inopos[1]) << 16)
ino = grub_cpu_to_be64 (ino); | (((grub_uint32_t) inopos[2]) << 8)
} | (((grub_uint32_t) inopos[3]) << 0);
else else
ino = *(grub_uint64_t *) inopos; ino = (((grub_uint64_t) inopos[0]) << 56)
| (((grub_uint64_t) inopos[1]) << 48)
| (((grub_uint64_t) inopos[2]) << 40)
| (((grub_uint64_t) inopos[3]) << 32)
| (((grub_uint64_t) inopos[4]) << 24)
| (((grub_uint64_t) inopos[5]) << 16)
| (((grub_uint64_t) inopos[6]) << 8)
| (((grub_uint64_t) inopos[7]) << 0);
ino = grub_cpu_to_be64 (ino);
grub_memcpy (name, de->name, de->len); grub_memcpy (name, de->name, de->len);
name[de->len] = '\0'; name[de->len] = '\0';
@ -808,6 +817,9 @@ static struct grub_fs grub_xfs_fs =
.close = grub_xfs_close, .close = grub_xfs_close,
.label = grub_xfs_label, .label = grub_xfs_label,
.uuid = grub_xfs_uuid, .uuid = grub_xfs_uuid,
#ifdef GRUB_UTIL
.reserved_first_sector = 0,
#endif
.next = 0 .next = 0
}; };

2548
grub-core/fs/zfs/zfs.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc.
* Copyright 2007 Sun Microsystems, Inc.
*
* GRUB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/zfs/zfs.h>
#include <grub/zfs/zio.h>
#include <grub/zfs/dnode.h>
#include <grub/zfs/uberblock_impl.h>
#include <grub/zfs/vdev_impl.h>
#include <grub/zfs/zio_checksum.h>
#include <grub/zfs/zap_impl.h>
#include <grub/zfs/zap_leaf.h>
#include <grub/zfs/zfs_znode.h>
#include <grub/zfs/dmu.h>
#include <grub/zfs/dmu_objset.h>
#include <grub/zfs/dsl_dir.h>
#include <grub/zfs/dsl_dataset.h>
void
fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian,
zio_cksum_t *zcp)
{
const grub_uint64_t *ip = buf;
const grub_uint64_t *ipend = ip + (size / sizeof (grub_uint64_t));
grub_uint64_t a0, b0, a1, b1;
for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2)
{
a0 += grub_zfs_to_cpu64 (ip[0], endian);
a1 += grub_zfs_to_cpu64 (ip[1], endian);
b0 += a0;
b1 += a1;
}
zcp->zc_word[0] = grub_cpu_to_zfs64 (a0, endian);
zcp->zc_word[1] = grub_cpu_to_zfs64 (a1, endian);
zcp->zc_word[2] = grub_cpu_to_zfs64 (b0, endian);
zcp->zc_word[3] = grub_cpu_to_zfs64 (b1, endian);
}
void
fletcher_4 (const void *buf, grub_uint64_t size, grub_zfs_endian_t endian,
zio_cksum_t *zcp)
{
const grub_uint32_t *ip = buf;
const grub_uint32_t *ipend = ip + (size / sizeof (grub_uint32_t));
grub_uint64_t a, b, c, d;
for (a = b = c = d = 0; ip < ipend; ip++)
{
a += grub_zfs_to_cpu32 (ip[0], endian);;
b += a;
c += b;
d += c;
}
zcp->zc_word[0] = grub_cpu_to_zfs64 (a, endian);
zcp->zc_word[1] = grub_cpu_to_zfs64 (b, endian);
zcp->zc_word[2] = grub_cpu_to_zfs64 (c, endian);
zcp->zc_word[3] = grub_cpu_to_zfs64 (d, endian);
}

View file

@ -0,0 +1,93 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc.
* Copyright 2007 Sun Microsystems, Inc.
*
* GRUB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/zfs/zfs.h>
#include <grub/zfs/zio.h>
#include <grub/zfs/dnode.h>
#include <grub/zfs/uberblock_impl.h>
#include <grub/zfs/vdev_impl.h>
#include <grub/zfs/zio_checksum.h>
#include <grub/zfs/zap_impl.h>
#include <grub/zfs/zap_leaf.h>
#include <grub/zfs/zfs_znode.h>
#include <grub/zfs/dmu.h>
#include <grub/zfs/dmu_objset.h>
#include <grub/zfs/dsl_dir.h>
#include <grub/zfs/dsl_dataset.h>
#define MATCH_BITS 6
#define MATCH_MIN 3
#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1)
/*
* Decompression Entry - lzjb
*/
#ifndef NBBY
#define NBBY 8
#endif
grub_err_t
lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len,
grub_size_t d_len);
grub_err_t
lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len,
grub_size_t d_len)
{
grub_uint8_t *src = s_start;
grub_uint8_t *dst = d_start;
grub_uint8_t *d_end = (grub_uint8_t *) d_start + d_len;
grub_uint8_t *s_end = (grub_uint8_t *) s_start + s_len;
grub_uint8_t *cpy, copymap = 0;
int copymask = 1 << (NBBY - 1);
while (dst < d_end && src < s_end)
{
if ((copymask <<= 1) == (1 << NBBY))
{
copymask = 1;
copymap = *src++;
}
if (src >= s_end)
return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed");
if (copymap & copymask)
{
int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
src += 2;
cpy = dst - offset;
if (src > s_end || cpy < (grub_uint8_t *) d_start)
return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed");
while (--mlen >= 0 && dst < d_end)
*dst++ = *cpy++;
}
else
*dst++ = *src++;
}
if (dst < d_end)
return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed");
return GRUB_ERR_NONE;
}

View file

@ -0,0 +1,143 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc.
* Copyright 2007 Sun Microsystems, Inc.
*
* GRUB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/zfs/zfs.h>
#include <grub/zfs/zio.h>
#include <grub/zfs/dnode.h>
#include <grub/zfs/uberblock_impl.h>
#include <grub/zfs/vdev_impl.h>
#include <grub/zfs/zio_checksum.h>
#include <grub/zfs/zap_impl.h>
#include <grub/zfs/zap_leaf.h>
#include <grub/zfs/zfs_znode.h>
#include <grub/zfs/dmu.h>
#include <grub/zfs/dmu_objset.h>
#include <grub/zfs/dsl_dir.h>
#include <grub/zfs/dsl_dataset.h>
/*
* SHA-256 checksum, as specified in FIPS 180-2, available at:
* http://csrc.nist.gov/cryptval
*
* This is a very compact implementation of SHA-256.
* It is designed to be simple and portable, not to be fast.
*/
/*
* The literal definitions according to FIPS180-2 would be:
*
* Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
* Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
*
* We use logical equivalents which require one less op.
*/
#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
#define Rot32(x, s) (((x) >> s) | ((x) << (32 - s)))
#define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
#define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
#define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
#define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
static const grub_uint32_t SHA256_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
static void
SHA256Transform(grub_uint32_t *H, const grub_uint8_t *cp)
{
grub_uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
for (t = 0; t < 16; t++, cp += 4)
W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
for (t = 16; t < 64; t++)
W[t] = sigma1(W[t - 2]) + W[t - 7] +
sigma0(W[t - 15]) + W[t - 16];
a = H[0]; b = H[1]; c = H[2]; d = H[3];
e = H[4]; f = H[5]; g = H[6]; h = H[7];
for (t = 0; t < 64; t++) {
T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
T2 = SIGMA0(a) + Maj(a, b, c);
h = g; g = f; f = e; e = d + T1;
d = c; c = b; b = a; a = T1 + T2;
}
H[0] += a; H[1] += b; H[2] += c; H[3] += d;
H[4] += e; H[5] += f; H[6] += g; H[7] += h;
}
void
zio_checksum_SHA256(const void *buf, grub_uint64_t size,
grub_zfs_endian_t endian, zio_cksum_t *zcp)
{
grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
grub_uint8_t pad[128];
unsigned padsize = size & 63;
unsigned i;
for (i = 0; i < size - padsize; i += 64)
SHA256Transform(H, (grub_uint8_t *)buf + i);
for (i = 0; i < padsize; i++)
pad[i] = ((grub_uint8_t *)buf)[i];
for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
pad[padsize] = 0;
for (i = 0; i < 8; i++)
pad[padsize++] = (size << 3) >> (56 - 8 * i);
for (i = 0; i < padsize; i += 64)
SHA256Transform(H, pad + i);
zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1],
endian);
zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3],
endian);
zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5],
endian);
zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7],
endian);
}

407
grub-core/fs/zfs/zfsinfo.c Normal file
View file

@ -0,0 +1,407 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc.
* Copyright 2008 Sun Microsystems, Inc.
*
* GRUB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/zfs/zfs.h>
#include <grub/device.h>
#include <grub/file.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/env.h>
static inline void
print_tabs (int n)
{
int i;
for (i = 0; i < n; i++)
grub_printf (" ");
}
static grub_err_t
print_state (char *nvlist, int tab)
{
grub_uint64_t ival;
int isok = 1;
print_tabs (tab);
grub_printf ("State: ");
if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival))
{
grub_printf ("removed ");
isok = 0;
}
if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival))
{
grub_printf ("faulted ");
isok = 0;
}
if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival))
{
grub_printf ("offline ");
isok = 0;
}
if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival))
grub_printf ("degraded ");
if (isok)
grub_printf ("online");
grub_printf ("\n");
return GRUB_ERR_NONE;
}
static grub_err_t
print_vdev_info (char *nvlist, int tab)
{
char *type = 0;
type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE);
if (!type)
{
print_tabs (tab);
grub_printf ("Incorrect VDEV: no type available\n");
return grub_errno;
}
if (grub_strcmp (type, VDEV_TYPE_DISK) == 0)
{
char *bootpath = 0;
char *path = 0;
char *devid = 0;
print_tabs (tab);
grub_printf ("Leaf VDEV\n");
print_state (nvlist, tab);
bootpath =
grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH);
print_tabs (tab);
if (!bootpath)
grub_printf ("Bootpath: unavailable\n");
else
grub_printf ("Bootpath: %s\n", bootpath);
path = grub_zfs_nvlist_lookup_string (nvlist, "path");
print_tabs (tab);
if (!path)
grub_printf ("Path: unavailable\n");
else
grub_printf ("Path: %s\n", path);
devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID);
print_tabs (tab);
if (!devid)
grub_printf ("Devid: unavailable\n");
else
grub_printf ("Devid: %s\n", devid);
grub_free (bootpath);
grub_free (devid);
grub_free (path);
return GRUB_ERR_NONE;
}
if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0)
{
int nelm, i;
nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm
(nvlist, ZPOOL_CONFIG_CHILDREN);
print_tabs (tab);
if (nelm <= 0)
{
grub_printf ("Incorrect mirror VDEV\n");
return GRUB_ERR_NONE;
}
grub_printf ("Mirror VDEV with %d children\n", nelm);
print_state (nvlist, tab);
for (i = 0; i < nelm; i++)
{
char *child;
child = grub_zfs_nvlist_lookup_nvlist_array
(nvlist, ZPOOL_CONFIG_CHILDREN, i);
print_tabs (tab);
if (!child)
{
grub_printf ("Mirror VDEV element %d isn't correct\n", i);
continue;
}
grub_printf ("Mirror VDEV element %d:\n", i);
print_vdev_info (child, tab + 1);
grub_free (child);
}
}
print_tabs (tab);
grub_printf ("Unknown VDEV type: %s\n", type);
return GRUB_ERR_NONE;
}
static grub_err_t
get_bootpath (char *nvlist, char **bootpath, char **devid)
{
char *type = 0;
type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE);
if (!type)
return grub_errno;
if (grub_strcmp (type, VDEV_TYPE_DISK) == 0)
{
*bootpath = grub_zfs_nvlist_lookup_string (nvlist,
ZPOOL_CONFIG_PHYS_PATH);
*devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID);
if (!*bootpath || !*devid)
{
grub_free (*bootpath);
grub_free (*devid);
*bootpath = 0;
*devid = 0;
}
return GRUB_ERR_NONE;
}
if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0)
{
int nelm, i;
nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm
(nvlist, ZPOOL_CONFIG_CHILDREN);
for (i = 0; i < nelm; i++)
{
char *child;
child = grub_zfs_nvlist_lookup_nvlist_array (nvlist,
ZPOOL_CONFIG_CHILDREN,
i);
get_bootpath (child, bootpath, devid);
grub_free (child);
if (*bootpath && *devid)
return GRUB_ERR_NONE;
}
}
return GRUB_ERR_NONE;
}
static char *poolstates[] = {
[POOL_STATE_ACTIVE] = "active",
[POOL_STATE_EXPORTED] = "exported",
[POOL_STATE_DESTROYED] = "destroyed",
[POOL_STATE_SPARE] = "reserved for hot spare",
[POOL_STATE_L2CACHE] = "level 2 ARC device",
[POOL_STATE_UNINITIALIZED] = "uninitialized",
[POOL_STATE_UNAVAIL] = "unavailable",
[POOL_STATE_POTENTIALLY_ACTIVE] = "potentially active"
};
static grub_err_t
grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc,
char **args)
{
grub_device_t dev;
char *devname;
grub_err_t err;
char *nvlist = 0;
char *nv = 0;
char *poolname;
grub_uint64_t guid;
grub_uint64_t pool_state;
int found;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
{
devname = grub_strdup (args[0] + 1);
if (devname)
devname[grub_strlen (devname) - 1] = 0;
}
else
devname = grub_strdup (args[0]);
if (!devname)
return grub_errno;
dev = grub_device_open (devname);
grub_free (devname);
if (!dev)
return grub_errno;
err = grub_zfs_fetch_nvlist (dev, &nvlist);
grub_device_close (dev);
if (err)
return err;
poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
if (!poolname)
grub_printf ("Pool name: unavailable\n");
else
grub_printf ("Pool name: %s\n", poolname);
found =
grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid);
if (!found)
grub_printf ("Pool GUID: unavailable\n");
else
grub_printf ("Pool GUID: %016llx\n", (long long unsigned) guid);
found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE,
&pool_state);
if (!found)
grub_printf ("Unable to retrieve pool state\n");
else if (pool_state >= ARRAY_SIZE (poolstates))
grub_printf ("Unrecognized pool state\n");
else
grub_printf ("Pool state: %s\n", poolstates[pool_state]);
nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);
if (!nv)
grub_printf ("No vdev tree available\n");
else
print_vdev_info (nv, 1);
grub_free (nv);
grub_free (nvlist);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
char **args)
{
grub_device_t dev;
char *devname;
grub_err_t err;
char *nvlist = 0;
char *nv = 0;
char *bootpath = 0, *devid = 0;
char *fsname;
char *bootfs;
char *poolname;
grub_uint64_t mdnobj;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "filesystem name required");
devname = grub_file_get_device_name (args[0]);
if (grub_errno)
return grub_errno;
dev = grub_device_open (devname);
grub_free (devname);
if (!dev)
return grub_errno;
err = grub_zfs_fetch_nvlist (dev, &nvlist);
fsname = grub_strchr (args[0], ')');
if (fsname)
fsname++;
else
fsname = args[0];
if (!err)
err = grub_zfs_getmdnobj (dev, fsname, &mdnobj);
grub_device_close (dev);
if (err)
return err;
poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
if (!poolname)
{
if (!grub_errno)
grub_error (GRUB_ERR_BAD_FS, "No poolname found");
return grub_errno;
}
nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);
if (nv)
get_bootpath (nv, &bootpath, &devid);
grub_free (nv);
grub_free (nvlist);
bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s",
poolname, (unsigned long long) mdnobj,
bootpath ? ",bootpath=\"" : "",
bootpath ? : "",
bootpath ? "\"" : "",
devid ? ",diskdevid=\"" : "",
devid ? : "",
devid ? "\"" : "");
if (!bootfs)
return grub_errno;
if (argc >= 2)
grub_env_set (args[1], bootfs);
else
grub_printf ("%s\n", bootfs);
grub_free (bootfs);
grub_free (poolname);
grub_free (bootpath);
grub_free (devid);
return GRUB_ERR_NONE;
}
static grub_command_t cmd_info, cmd_bootfs;
GRUB_MOD_INIT (zfsinfo)
{
cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo,
"zfsinfo DEVICE",
"Print ZFS info about DEVICE.");
cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs,
"zfs-bootfs FILESYSTEM [VARIABLE]",
"Print ZFS-BOOTFSOBJ or set it to VARIABLE");
}
GRUB_MOD_FINI (zfsinfo)
{
grub_unregister_command (cmd_info);
grub_unregister_command (cmd_bootfs);
}

View file

@ -35,7 +35,7 @@ deps=`grep ^$modname: $moddep | sed s@^.*:@@`
rm -f $tmpfile $outfile rm -f $tmpfile $outfile
# stripout .modname and .moddeps sections from input module # stripout .modname and .moddeps sections from input module
objcopy -R .modname -R .moddeps $infile $tmpfile @OBJCOPY@ -R .modname -R .moddeps $infile $tmpfile
# Attach .modname and .moddeps sections # Attach .modname and .moddeps sections
t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
@ -45,15 +45,15 @@ t2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
for dep in $deps; do printf "$dep\0" >> $t2; done for dep in $deps; do printf "$dep\0" >> $t2; done
if test -n "$deps"; then if test -n "$deps"; then
objcopy --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile @OBJCOPY@ --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile
else else
objcopy --add-section .modname=$t1 $tmpfile @OBJCOPY@ --add-section .modname=$t1 $tmpfile
fi fi
rm -f $t1 $t2 rm -f $t1 $t2
if test x@TARGET_APPLE_CC@ != x1; then if test x@TARGET_APPLE_CC@ != x1; then
if ! test -z "@TARGET_OBJ2ELF@"; then if ! test -z "${TARGET_OBJ2ELF}"; then
./@TARGET_OBJ2ELF@ $tmpfile || exit 1 ./${TARGET_OBJ2ELF} $tmpfile || exit 1
fi fi
if test x@platform@ != xemu; then if test x@platform@ != xemu; then
@STRIP@ --strip-unneeded \ @STRIP@ --strip-unneeded \

View file

@ -49,7 +49,7 @@ struct grub_gettext_msg
const char *translated; const char *translated;
}; };
struct grub_gettext_msg *grub_gettext_msg_list = NULL; static struct grub_gettext_msg *grub_gettext_msg_list = NULL;
#define GETTEXT_MAGIC_NUMBER 0 #define GETTEXT_MAGIC_NUMBER 0
#define GETTEXT_FILE_FORMAT 4 #define GETTEXT_FILE_FORMAT 4
@ -261,24 +261,16 @@ grub_mofile_open (const char *filename)
return fd_mo; return fd_mo;
} }
/* Returning grub_file_t would be more natural, but grub_mofile_open assigns
to fd_mo anyway ... */
static void static void
grub_gettext_init_ext (const char *lang) grub_mofile_open_lang (const char *locale_dir, const char *locale)
{ {
char *mo_file; char *mo_file;
char *locale_dir;
locale_dir = grub_env_get ("locale_dir");
if (locale_dir == NULL)
{
grub_dprintf ("gettext", "locale_dir variable is not set up.\n");
return;
}
fd_mo = NULL;
/* mo_file e.g.: /boot/grub/locale/ca.mo */ /* mo_file e.g.: /boot/grub/locale/ca.mo */
mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang); mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, locale);
if (!mo_file) if (!mo_file)
return; return;
@ -295,6 +287,38 @@ grub_gettext_init_ext (const char *lang)
return; return;
fd_mo = grub_mofile_open (mo_file); fd_mo = grub_mofile_open (mo_file);
} }
}
static void
grub_gettext_init_ext (const char *locale)
{
char *locale_dir;
locale_dir = grub_env_get ("locale_dir");
if (locale_dir == NULL)
{
grub_dprintf ("gettext", "locale_dir variable is not set up.\n");
return;
}
fd_mo = NULL;
grub_mofile_open_lang (locale_dir, locale);
/* ll_CC didn't work, so try ll. */
if (fd_mo == NULL)
{
char *lang = grub_strdup (locale);
char *underscore = grub_strchr (lang, '_');
if (underscore)
{
*underscore = '\0';
grub_mofile_open_lang (locale_dir, lang);
}
grub_free (lang);
}
if (fd_mo) if (fd_mo)
{ {

View file

@ -37,7 +37,7 @@
#include <grub/gfxmenu_view.h> #include <grub/gfxmenu_view.h>
#include <grub/time.h> #include <grub/time.h>
grub_gfxmenu_view_t cached_view; static grub_gfxmenu_view_t cached_view;
static void static void
grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused)))

View file

@ -86,18 +86,21 @@ grub_read_hook_datetime (struct grub_env_var *var,
GRUB_MOD_INIT(datehook) GRUB_MOD_INIT(datehook)
{ {
int i; unsigned i;
for (i = 0; i < 7; i++) for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++)
grub_register_variable_hook (grub_datetime_names[i], {
grub_read_hook_datetime, 0); grub_register_variable_hook (grub_datetime_names[i],
grub_read_hook_datetime, 0);
grub_env_export (grub_datetime_names[i]);
}
} }
GRUB_MOD_FINI(datehook) GRUB_MOD_FINI(datehook)
{ {
int i; unsigned i;
for (i = 0; i < 7; i++) for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++)
{ {
grub_register_variable_hook (grub_datetime_names[i], 0, 0); grub_register_variable_hook (grub_datetime_names[i], 0, 0);
grub_env_unset (grub_datetime_names[i]); grub_env_unset (grub_datetime_names[i]);

View file

@ -74,7 +74,7 @@ grub_bufio_open (grub_file_t io, int size)
file->data = bufio; file->data = bufio;
file->read_hook = 0; file->read_hook = 0;
file->fs = &grub_bufio_fs; file->fs = &grub_bufio_fs;
file->not_easly_seekable = io->not_easly_seekable; file->not_easily_seekable = io->not_easily_seekable;
return file; return file;
} }

View file

@ -212,19 +212,18 @@ test_header (grub_file_t file)
gzio->data_offset = grub_file_tell (gzio->file); gzio->data_offset = grub_file_tell (gzio->file);
grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); /* FIXME: don't do this on not easily seekable files. */
{
if (grub_file_seekable (gzio->file)) grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
{ if (grub_file_read (gzio->file, &orig_len, 4) != 4)
if (grub_file_read (gzio->file, &orig_len, 4) != 4) {
{ grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format"); return 0;
return 0; }
} /* FIXME: this does not handle files whose original size is over 4GB.
} But how can we know the real original size? */
/* FIXME: this does not handle files whose original size is over 4GB. file->size = grub_le_to_cpu32 (orig_len);
But how can we know the real original size? */ }
file->size = grub_le_to_cpu32 (orig_len);
initialize_tables (file); initialize_tables (file);
@ -1137,7 +1136,7 @@ grub_gzio_open (grub_file_t io)
file->data = gzio; file->data = gzio;
file->read_hook = 0; file->read_hook = 0;
file->fs = &grub_gzio_fs; file->fs = &grub_gzio_fs;
file->not_easly_seekable = 1; file->not_easily_seekable = 1;
if (! test_header (file)) if (! test_header (file))
{ {

View file

@ -200,7 +200,7 @@ grub_xzio_open (grub_file_t io)
file->read_hook = 0; file->read_hook = 0;
file->fs = &grub_xzio_fs; file->fs = &grub_xzio_fs;
file->size = GRUB_FILE_SIZE_UNKNOWN; file->size = GRUB_FILE_SIZE_UNKNOWN;
file->not_easly_seekable = 1; file->not_easily_seekable = 1;
if (grub_file_tell (xzio->file) != 0) if (grub_file_tell (xzio->file) != 0)
grub_file_seek (xzio->file, 0); grub_file_seek (xzio->file, 0);
@ -222,7 +222,8 @@ grub_xzio_open (grub_file_t io)
xzio->buf.out_pos = 0; xzio->buf.out_pos = 0;
xzio->buf.out_size = XZBUFSIZ; xzio->buf.out_size = XZBUFSIZ;
if (!test_header (file) || !(grub_file_seekable (io) && test_footer (file))) /* FIXME: don't test footer on not easily seekable files. */
if (!test_header (file) || !test_footer (file))
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
grub_file_seek (io, 0); grub_file_seek (io, 0);

View file

@ -52,13 +52,13 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
grub_efi_status_t status; grub_efi_status_t status;
grub_efi_boot_services_t *b; grub_efi_boot_services_t *b;
#if GRUB_TARGET_SIZEOF_VOID_P < 8 #if 1
/* Limit the memory access to less than 4GB for 32-bit platforms. */ /* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff) if (address > 0xffffffff)
return 0; return 0;
#endif #endif
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) #if 1
if (address == 0) if (address == 0)
{ {
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
@ -251,7 +251,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{ {
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) #if 1
&& desc->physical_start <= 0xffffffff && desc->physical_start <= 0xffffffff
#endif #endif
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
@ -267,7 +267,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc->physical_start = 0x100000; desc->physical_start = 0x100000;
} }
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) #if 1
if (BYTES_TO_PAGES (filtered_desc->physical_start) if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages + filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL)) > BYTES_TO_PAGES (0x100000000LL))

View file

@ -171,11 +171,12 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */ /* Calculate the amount of memory spanned by the segments. */
grub_size_t grub_size_t
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) grub_elf32_size (grub_elf_t elf, Elf32_Addr *base, grub_uint32_t *max_align)
{ {
Elf32_Addr segments_start = (Elf32_Addr) -1; Elf32_Addr segments_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0; Elf32_Addr segments_end = 0;
int nr_phdrs = 0; int nr_phdrs = 0;
grub_uint32_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we /* Run through the program headers to calculate the total memory size we
* should claim. */ * should claim. */
@ -192,6 +193,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
segments_start = phdr->p_paddr; segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end) if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz; segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0; return 0;
} }
@ -215,7 +218,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
if (base) if (base)
*base = segments_start; *base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start; return segments_end - segments_start;
} }
@ -290,7 +294,6 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
return err; return err;
} }
/* 64-bit */ /* 64-bit */
@ -357,16 +360,17 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */ /* Calculate the amount of memory spanned by the segments. */
grub_size_t grub_size_t
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) grub_elf64_size (grub_elf_t elf, Elf64_Addr *base, grub_uint64_t *max_align)
{ {
Elf64_Addr segments_start = (Elf64_Addr) -1; Elf64_Addr segments_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0; Elf64_Addr segments_end = 0;
int nr_phdrs = 0; int nr_phdrs = 0;
grub_uint64_t curr_align = 1;
/* Run through the program headers to calculate the total memory size we /* Run through the program headers to calculate the total memory size we
* should claim. */ * should claim. */
auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
Elf64_Phdr *phdr, Elf64_Phdr *phdr,
void *_arg __attribute__ ((unused))) void *_arg __attribute__ ((unused)))
{ {
@ -378,6 +382,8 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
segments_start = phdr->p_paddr; segments_start = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > segments_end) if (phdr->p_paddr + phdr->p_memsz > segments_end)
segments_end = phdr->p_paddr + phdr->p_memsz; segments_end = phdr->p_paddr + phdr->p_memsz;
if (curr_align < phdr->p_align)
curr_align = phdr->p_align;
return 0; return 0;
} }
@ -401,11 +407,11 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
if (base) if (base)
*base = segments_start; *base = segments_start;
if (max_align)
*max_align = curr_align;
return segments_end - segments_start; return segments_end - segments_start;
} }
/* Load every loadable segment into memory specified by `_load_hook'. */ /* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t grub_err_t
grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook, grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,

View file

@ -17,7 +17,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <config-util.h>
#include <config.h> #include <config.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
@ -135,8 +137,12 @@ find_root_device_from_mountinfo (const char *dir)
continue; /* only a subtree is mounted */ continue; /* only a subtree is mounted */
enc_path_len = strlen (enc_path); enc_path_len = strlen (enc_path);
/* Check that enc_path is a prefix of dir. The prefix must either be
the entire string, or end with a slash, or be immediately followed
by a slash. */
if (strncmp (dir, enc_path, enc_path_len) != 0 || if (strncmp (dir, enc_path, enc_path_len) != 0 ||
(dir[enc_path_len] && dir[enc_path_len] != '/')) (enc_path_len && dir[enc_path_len - 1] != '/' &&
dir[enc_path_len] && dir[enc_path_len] != '/'))
continue; continue;
/* This is a parent of the requested directory. /proc/self/mountinfo /* This is a parent of the requested directory. /proc/self/mountinfo
@ -178,7 +184,7 @@ find_root_device_from_mountinfo (const char *dir)
static char * static char *
find_root_device_from_libzfs (const char *dir) find_root_device_from_libzfs (const char *dir)
{ {
char *device; char *device = NULL;
char *poolname; char *poolname;
char *poolfs; char *poolfs;
@ -219,7 +225,10 @@ find_root_device_from_libzfs (const char *dir)
struct stat st; struct stat st;
if (stat (device, &st) == 0) if (stat (device, &st) == 0)
break; {
device = xstrdup (device);
break;
}
device = NULL; device = NULL;
} }
@ -582,6 +591,8 @@ grub_util_is_dmraid (const char *os_dev)
return 1; return 1;
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
return 1; return 1;
else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17))
return 1;
return 0; return 0;
} }
@ -792,11 +803,36 @@ grub_util_get_grub_dev (const char *os_dev)
#ifdef __linux__ #ifdef __linux__
{ {
char *mdadm_name = get_mdadm_name (os_dev); char *mdadm_name = get_mdadm_name (os_dev);
struct stat st;
if (mdadm_name) if (mdadm_name)
{ {
free (grub_dev); char *newname;
grub_dev = xasprintf ("md/%s", mdadm_name); char *q;
for (q = os_dev + strlen (os_dev) - 1; q >= os_dev && isdigit (*q);
q--);
if (q >= os_dev && *q == 'p')
{
newname = xasprintf ("/dev/md/%sp%s", mdadm_name, q + 1);
if (stat (newname, &st) == 0)
{
free (grub_dev);
grub_dev = xasprintf ("md/%s,%s", mdadm_name, q + 1);
goto done;
}
free (newname);
}
newname = xasprintf ("/dev/md/%s", mdadm_name);
if (stat (newname, &st) == 0)
{
free (grub_dev);
grub_dev = xasprintf ("md/%s", mdadm_name);
}
done:
free (newname);
free (mdadm_name); free (mdadm_name);
} }
} }

View file

@ -92,6 +92,8 @@ struct hd_geometry
# include <sys/disk.h> /* DIOCGMEDIASIZE */ # include <sys/disk.h> /* DIOCGMEDIASIZE */
# include <sys/param.h> # include <sys/param.h>
# include <sys/sysctl.h> # include <sys/sysctl.h>
# define MAJOR(dev) major(dev)
# define FLOPPY_MAJOR 2
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
@ -102,7 +104,9 @@ struct hd_geometry
# include <libdevmapper.h> # include <libdevmapper.h>
#endif #endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <libgeom.h>
#elif defined(__NetBSD__)
# define HAVE_DIOCGDINFO # define HAVE_DIOCGDINFO
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include <sys/disklabel.h> /* struct disklabel */ # include <sys/disklabel.h> /* struct disklabel */
@ -337,7 +341,68 @@ device_is_mapped (const char *dev)
} }
#endif /* HAVE_DEVICE_MAPPER */ #endif /* HAVE_DEVICE_MAPPER */
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FIXME: geom actually gives us the whole container hierarchy.
It can be used more efficiently than this. */
static void
follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out)
{
struct gmesh mesh;
struct gclass *class;
int error;
struct ggeom *geom;
grub_util_info ("following geom '%s'", name);
error = geom_gettree (&mesh);
if (error != 0)
grub_util_error ("couldn't open geom");
LIST_FOREACH (class, &mesh.lg_class, lg_class)
if (strcasecmp (class->lg_name, "part") == 0)
break;
if (!class)
grub_util_error ("couldn't open geom part");
LIST_FOREACH (geom, &class->lg_geom, lg_geom)
{
struct gprovider *provider;
LIST_FOREACH (provider, &geom->lg_provider, lg_provider)
if (strcmp (provider->lg_name, name) == 0)
{
char *name_tmp = xstrdup (geom->lg_name);
grub_disk_addr_t off = 0;
struct gconfig *config;
grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name);
follow_geom_up (name_tmp, &off, name_out);
free (name_tmp);
LIST_FOREACH (config, &provider->lg_config, lg_config)
if (strcasecmp (config->lg_name, "start") == 0)
off += strtoull (config->lg_val, 0, 10);
if (off_out)
*off_out = off;
return;
}
}
grub_util_info ("geom '%s' has no parent", name);
if (name_out)
*name_out = xstrdup (name);
if (off_out)
*off_out = 0;
}
static grub_disk_addr_t
find_partition_start (const char *dev)
{
grub_disk_addr_t out;
if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return 0;
follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL);
return out;
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO)
static grub_disk_addr_t static grub_disk_addr_t
find_partition_start (const char *dev) find_partition_start (const char *dev)
{ {
@ -453,9 +518,12 @@ devmapper_fail:
# if !defined(HAVE_DIOCGDINFO) # if !defined(HAVE_DIOCGDINFO)
return hdg.start; return hdg.start;
# else /* defined(HAVE_DIOCGDINFO) */ # else /* defined(HAVE_DIOCGDINFO) */
p_index = dev[strlen(dev) - 1] - 'a'; if (dev[0])
p_index = dev[strlen(dev) - 1] - 'a';
else
p_index = -1;
if (p_index >= label.d_npartitions) if (p_index >= label.d_npartitions || p_index < 0)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
"no disk label entry for `%s'", dev); "no disk label entry for `%s'", dev);
@ -1152,16 +1220,22 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|| strncmp ("sd", p, 2) == 0) || strncmp ("sd", p, 2) == 0)
&& p[2] >= 'a' && p[2] <= 'z') && p[2] >= 'a' && p[2] <= 'z')
{ {
/* /dev/[hsv]d[a-z][0-9]* */ char *pp = p + 2;
p[3] = '\0'; while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/[hsv]d[a-z]+[0-9]* */
*pp = '\0';
return path; return path;
} }
/* If this is a Xen virtual block device. */ /* If this is a Xen virtual block device. */
if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z') if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
{ {
/* /dev/xvd[a-z][0-9]* */ char *pp = p + 3;
p[4] = '\0'; while (*pp >= 'a' && *pp <= 'z')
pp++;
/* /dev/xvd[a-z]+[0-9]* */
*pp = '\0';
return path; return path;
} }
@ -1278,7 +1352,17 @@ devmapper_out:
path[8] = 0; path[8] = 0;
return path; return path;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
char *out, *out2;
if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0)
return xstrdup (os_dev);
follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out);
out2 = xasprintf ("/dev/%s", out);
free (out);
return out2;
#elif defined(__APPLE__)
char *path = xstrdup (os_dev); char *path = xstrdup (os_dev);
if (strncmp ("/dev/", path, 5) == 0) if (strncmp ("/dev/", path, 5) == 0)
{ {
@ -1434,6 +1518,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
if (stat (os_dev, &st) < 0) if (stat (os_dev, &st) < 0)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev); grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev);
grub_util_info ("cannot stat `%s'", os_dev);
return 0; return 0;
} }
@ -1442,6 +1527,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
{ {
grub_error (GRUB_ERR_UNKNOWN_DEVICE, grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"no mapping exists for `%s'", os_dev); "no mapping exists for `%s'", os_dev);
grub_util_info ("no mapping exists for `%s'", os_dev);
return 0; return 0;
} }
@ -1456,7 +1542,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
#endif #endif
return make_device_name (drive, -1, -1); return make_device_name (drive, -1, -1);
#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) #if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS /* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial. partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and Here, get the start sector of a partition by HDIO_GETGEO, and

View file

@ -240,3 +240,23 @@ grub_register_variable_hook (const char *name,
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
grub_err_t
grub_env_export (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
{
grub_err_t err;
err = grub_env_set (name, "");
if (err)
return err;
var = grub_env_find (name);
}
var->global = 1;
return GRUB_ERR_NONE;
}

View file

@ -140,36 +140,27 @@ compact_mem_regions (void)
} }
} }
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
void void
grub_machine_init (void) grub_machine_init (void)
{ {
int i; int i;
#if 0
int grub_lower_mem; int grub_lower_mem;
#endif
/* Initialize the console as early as possible. */ /* Initialize the console as early as possible. */
grub_console_init (); grub_console_init ();
/* This sanity check is useless since top of GRUB_MEMORY_MACHINE_RESERVED_END
is used for stack and if it's unavailable we wouldn't have gotten so far.
*/
#if 0
grub_lower_mem = grub_get_conv_memsize () << 10; grub_lower_mem = grub_get_conv_memsize () << 10;
/* Sanity check. */ /* Sanity check. */
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END) if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
grub_fatal ("too small memory"); grub_fatal ("too small memory");
#endif
/* FIXME: This prevents loader/i386/linux.c from using low memory. When our /* FIXME: This prevents loader/i386/linux.c from using low memory. When our
heap implements support for requesting a chunk in low memory, this should heap implements support for requesting a chunk in low memory, this should

View file

@ -36,6 +36,22 @@ struct grub_machine_mmap_entry
} __attribute__((packed)); } __attribute__((packed));
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
/* /*
* grub_get_ext_memsize() : return the extended memory size in KB. * grub_get_ext_memsize() : return the extended memory size in KB.
* BIOS call "INT 15H, AH=88H" to get extended memory size * BIOS call "INT 15H, AH=88H" to get extended memory size
@ -155,6 +171,10 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
{ {
grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE))
return 0;
if (eisa_mmap) if (eisa_mmap)
{ {
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10,
@ -162,7 +182,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE); hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE);
} }
else else
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE); hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE);
} }
return 0; return 0;

View file

@ -151,8 +151,6 @@ LOCAL (codestart):
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx
movl reed_solomon_redundancy, %ecx movl reed_solomon_redundancy, %ecx
leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
testl %edx, %edx
jz post_reed_solomon
call EXT_C (grub_reed_solomon_recover) call EXT_C (grub_reed_solomon_recover)
jmp post_reed_solomon jmp post_reed_solomon
@ -224,6 +222,7 @@ multiboot_trampoline:
movb $0xFF, %dh movb $0xFF, %dh
/* enter the usual booting */ /* enter the usual booting */
call prot_to_real call prot_to_real
jmp LOCAL (codestart)
post_reed_solomon: post_reed_solomon:
@ -649,7 +648,7 @@ FUNCTION(grub_console_getkey)
jae 2f jae 2f
movl %edx, %eax movl %edx, %eax
leal LOCAL(bypass_table), %edi leal LOCAL(bypass_table), %edi
movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx
repne scasw repne scasw
jz 3f jz 3f

View file

@ -84,6 +84,9 @@ grub_ieee1275_find_options (void)
if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC")) if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC"))
is_qemu = 1; is_qemu = 1;
if (grub_strncmp (tmp, "PowerMac", sizeof ("PowerMac") - 1) == 0)
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS);
if (is_smartfirmware) if (is_smartfirmware)
{ {
/* Broken in all versions */ /* Broken in all versions */

View file

@ -50,6 +50,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"couldn't examine /memory/available property"); "couldn't examine /memory/available property");
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
{
address_cells = 1;
size_cells = 1;
}
/* Decode each entry and call `hook'. */ /* Decode each entry and call `hook'. */
i = 0; i = 0;
available_size /= sizeof (grub_uint32_t); available_size /= sizeof (grub_uint32_t);

View file

@ -189,6 +189,8 @@ grub_main (void)
for convenience. */ for convenience. */
grub_machine_set_prefix (); grub_machine_set_prefix ();
grub_set_root_dev (); grub_set_root_dev ();
grub_env_export ("root");
grub_env_export ("prefix");
grub_register_core_commands (); grub_register_core_commands ();

View file

@ -41,6 +41,7 @@ extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void); extern void grub_serial_init (void);
extern void grub_terminfo_init (void); extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void); extern void grub_keylayouts_init (void);
extern void grub_boot_init (void);
/* FIXME: use interrupt to count high. */ /* FIXME: use interrupt to count high. */
grub_uint64_t grub_uint64_t
@ -210,6 +211,8 @@ grub_machine_init (void)
grub_terminfo_init (); grub_terminfo_init ();
grub_serial_init (); grub_serial_init ();
grub_boot_init ();
} }
void void
@ -223,6 +226,8 @@ grub_halt (void)
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); & ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_millisleep (1500);
grub_printf ("Shutdown failed\n"); grub_printf ("Shutdown failed\n");
grub_refresh (); grub_refresh ();
while (1); while (1);
@ -239,6 +244,8 @@ grub_reboot (void)
{ {
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
grub_millisleep (1500);
grub_printf ("Reboot failed\n"); grub_printf ("Reboot failed\n");
grub_refresh (); grub_refresh ();
while (1); while (1);

View file

@ -37,80 +37,80 @@
.text .text
FUNCTION(efi_wrap_0) FUNCTION(efi_wrap_0)
subq $40, %rsp subq $48, %rsp
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_1) FUNCTION(efi_wrap_1)
subq $40, %rsp subq $48, %rsp
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_2) FUNCTION(efi_wrap_2)
subq $40, %rsp subq $48, %rsp
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_3) FUNCTION(efi_wrap_3)
subq $40, %rsp subq $48, %rsp
mov %rcx, %r8 mov %rcx, %r8
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_4) FUNCTION(efi_wrap_4)
subq $40, %rsp subq $48, %rsp
mov %r8, %r9 mov %r8, %r9
mov %rcx, %r8 mov %rcx, %r8
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_5) FUNCTION(efi_wrap_5)
subq $40, %rsp subq $48, %rsp
mov %r9, 32(%rsp) mov %r9, 32(%rsp)
mov %r8, %r9 mov %r8, %r9
mov %rcx, %r8 mov %rcx, %r8
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $40, %rsp addq $48, %rsp
ret ret
FUNCTION(efi_wrap_6) FUNCTION(efi_wrap_6)
subq $56, %rsp subq $64, %rsp
mov 56+8(%rsp), %rax mov 64+8(%rsp), %rax
mov %rax, 40(%rsp) mov %rax, 40(%rsp)
mov %r9, 32(%rsp) mov %r9, 32(%rsp)
mov %r8, %r9 mov %r8, %r9
mov %rcx, %r8 mov %rcx, %r8
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $56, %rsp addq $64, %rsp
ret ret
FUNCTION(efi_wrap_10) FUNCTION(efi_wrap_10)
subq $88, %rsp subq $96, %rsp
mov 88+40(%rsp), %rax mov 96+40(%rsp), %rax
mov %rax, 72(%rsp) mov %rax, 72(%rsp)
mov 88+32(%rsp), %rax mov 96+32(%rsp), %rax
mov %rax, 64(%rsp) mov %rax, 64(%rsp)
mov 88+24(%rsp), %rax mov 96+24(%rsp), %rax
mov %rax, 56(%rsp) mov %rax, 56(%rsp)
mov 88+16(%rsp), %rax mov 96+16(%rsp), %rax
mov %rax, 48(%rsp) mov %rax, 48(%rsp)
mov 88+8(%rsp), %rax mov 96+8(%rsp), %rax
mov %rax, 40(%rsp) mov %rax, 40(%rsp)
mov %r9, 32(%rsp) mov %r9, 32(%rsp)
mov %r8, %r9 mov %r8, %r9
mov %rcx, %r8 mov %rcx, %r8
mov %rsi, %rcx mov %rsi, %rcx
call *%rdi call *%rdi
addq $88, %rsp addq $96, %rsp
ret ret

View file

@ -340,17 +340,20 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
} }
option = grub_strchr (arg, '='); option = grub_strchr (arg, '=');
if (option) { if (option)
arglen = option - arg - 2; {
option++; arglen = option - arg - 2;
} else { option++;
}
else
arglen = grub_strlen (arg) - 2; arglen = grub_strlen (arg) - 2;
if (argv[curarg + 1])
option = argv[curarg + 1][0] == '-' ? 0 : argv[++curarg];
}
opt = find_long (cmd->options, arg + 2, arglen); opt = find_long (cmd->options, arg + 2, arglen);
if (!option && argv[curarg + 1] && argv[curarg + 1][0] != '-'
&& opt->type != ARG_TYPE_NONE)
option = argv[++curarg];
if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH)) if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH))
{ {
if (add_arg (arg) != 0) if (add_arg (arg) != 0)

105
grub-core/lib/cmdline.c Normal file
View file

@ -0,0 +1,105 @@
/* cmdline.c - linux command line handling */
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/lib/cmdline.h>
#include <grub/misc.h>
static unsigned int check_arg (char *c, int *has_space)
{
int space = 0;
unsigned int size = 0;
while (*c)
{
if (*c == '\\' || *c == '\'' || *c == '"')
size++;
else if (*c == ' ')
space = 1;
size++;
c++;
}
if (space)
size += 2;
if (has_space)
*has_space = space;
return size;
}
unsigned int grub_loader_cmdline_size (int argc, char *argv[])
{
int i;
unsigned int size = 0;
for (i = 0; i < argc; i++)
{
size += check_arg (argv[i], 0);
size++; /* Separator space or NULL. */
}
return size;
}
int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
grub_size_t size)
{
int i, space;
unsigned int arg_size;
char *c;
for (i = 0; i < argc; i++)
{
c = argv[i];
arg_size = check_arg(argv[i], &space);
arg_size++; /* Separator space or NULL. */
if (size < arg_size)
break;
size -= arg_size;
if (space)
*buf++ = '"';
while (*c)
{
if (*c == '\\' || *c == '\'' || *c == '"')
*buf++ = '\\';
*buf++ = *c;
c++;
}
if (space)
*buf++ = '"';
*buf++ = ' ';
}
/* Replace last space with null. */
if (i)
buf--;
*buf = 0;
return i;
}

View file

@ -62,13 +62,25 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
(char *) desc < ((char *) descs + mmapsize); (char *) desc < ((char *) descs + mmapsize);
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{ {
grub_uint64_t start = desc->physical_start;
grub_uint64_t end = desc->physical_start + (desc->num_pages << 12);
/* post-4G addresses are never supported on 32-bit EFI.
Moreover it has been reported that some 64-bit EFI contrary to the
spec don't map post-4G pages. So if you enable post-4G allocations,
map pages manually or check that they are mapped.
*/
if (end >= 0x100000000ULL)
end = 0x100000000ULL;
if (end <= start)
continue;
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
continue; continue;
events[counter].type = REG_FIRMWARE_START; events[counter].type = REG_FIRMWARE_START;
events[counter].pos = desc->physical_start; events[counter].pos = start;
counter++; counter++;
events[counter].type = REG_FIRMWARE_END; events[counter].type = REG_FIRMWARE_END;
events[counter].pos = desc->physical_start + (desc->num_pages << 12); events[counter].pos = end;
counter++; counter++;
} }
@ -85,6 +97,9 @@ grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size)
if (grub_efi_is_finished) if (grub_efi_is_finished)
return 1; return 1;
grub_dprintf ("relocator", "EFI alloc: %llx, %llx\n",
(unsigned long long) start, (unsigned long long) size);
b = grub_efi_system_table->boot_services; b = grub_efi_system_table->boot_services;
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS, status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
GRUB_EFI_LOADER_DATA, size >> 12, &address); GRUB_EFI_LOADER_DATA, size >> 12, &address);

View file

@ -19,6 +19,7 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/machine/biosnum.h>
static int static int
grub_get_root_biosnumber_default (void) grub_get_root_biosnumber_default (void)

View file

@ -58,7 +58,7 @@ struct legacy_command
const char *longdesc; const char *longdesc;
}; };
struct legacy_command legacy_commands[] = static struct legacy_command legacy_commands[] =
{ {
{"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE",
"Print the blocklist notation of the file FILE."}, "Print the blocklist notation of the file FILE."},
@ -322,24 +322,23 @@ struct legacy_command legacy_commands[] =
char * char *
grub_legacy_escape (const char *in, grub_size_t len) grub_legacy_escape (const char *in, grub_size_t len)
{ {
const char *ptr; char *ptr;
char *ret, *outptr; char *ret;
char saved;
int overhead = 0; int overhead = 0;
for (ptr = in; ptr < in + len && *ptr; ptr++)
if (*ptr == '\'' || *ptr == '\\') for (ptr = (char*)in; ptr < in + len && *ptr; ptr++)
overhead++; if (*ptr == '\'')
overhead += 3;
ret = grub_malloc (ptr - in + overhead + 1); ret = grub_malloc (ptr - in + overhead + 1);
if (!ret) if (!ret)
return NULL; return NULL;
outptr = ret;
for (ptr = in; ptr < in + len && *ptr; ptr++)
{
if (*ptr == '\'' || *ptr == '\\')
*outptr++ = '\\';
*outptr++ = *ptr; ptr = (char*)in;
} saved = ptr[len];
*outptr++ = 0; ptr[len] = '\0';
grub_strchrsub (ret, ptr, '\'', "'\\''");
ptr[len] = saved;
return ret; return ret;
} }
@ -622,12 +621,13 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix)
{ {
for (; *ptr && grub_isspace (*ptr); ptr++); for (; *ptr && grub_isspace (*ptr); ptr++);
for (; *ptr && !grub_isspace (*ptr); ptr++) for (; *ptr && !grub_isspace (*ptr); ptr++)
if (*ptr == '\\' || *ptr == '\'') if (*ptr == '\'')
overhead++; overhead += 3;
if (*ptr) if (*ptr)
ptr++; ptr++;
overhead += 3; overhead += 3;
} }
outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg));
if (!outptr0) if (!outptr0)
return NULL; return NULL;
@ -641,9 +641,15 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix)
*outptr++ = '\''; *outptr++ = '\'';
for (; *ptr && !grub_isspace (*ptr); ptr++) for (; *ptr && !grub_isspace (*ptr); ptr++)
{ {
if (*ptr == '\\' || *ptr == '\'') if (*ptr == '\'')
*outptr++ = '\\'; {
*outptr++ = *ptr; *outptr++ = '\'';
*outptr++ = '\\';
*outptr++ = '\'';
*outptr++ = '\'';
}
else
*outptr++ = *ptr;
} }
*outptr++ = '\''; *outptr++ = '\'';
if (*ptr) if (*ptr)

View file

@ -25,6 +25,12 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/crypto.h> #include <grub/crypto.h>
#ifdef GRUB_CPU_WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#else
#undef WORDS_BIGENDIAN
#endif
#define __GNU_LIBRARY__ #define __GNU_LIBRARY__
#define DIM ARRAY_SIZE #define DIM ARRAY_SIZE

View file

@ -0,0 +1 @@
#include <sys/types.h>

View file

@ -32,4 +32,15 @@ typedef grub_uint16_t uint16_t;
typedef grub_uint32_t uint32_t; typedef grub_uint32_t uint32_t;
typedef grub_uint64_t uint64_t; typedef grub_uint64_t uint64_t;
typedef grub_int8_t int8_t;
typedef grub_int16_t int16_t;
typedef grub_int32_t int32_t;
typedef grub_int64_t int64_t;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#else
#undef WORDS_BIGENDIAN
#endif
#endif #endif

View file

@ -18,6 +18,8 @@
#ifdef TEST #ifdef TEST
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define xmalloc malloc #define xmalloc malloc
#define grub_memset memset #define grub_memset memset
#define grub_memcpy memcpy #define grub_memcpy memcpy
@ -25,8 +27,6 @@
#ifndef STANDALONE #ifndef STANDALONE
#ifdef TEST #ifdef TEST
#include <string.h>
#include <stdlib.h>
typedef unsigned int grub_size_t; typedef unsigned int grub_size_t;
typedef unsigned char grub_uint8_t; typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t; typedef unsigned short grub_uint16_t;
@ -45,6 +45,7 @@ typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t; typedef unsigned short grub_uint16_t;
#else #else
#include <grub/types.h> #include <grub/types.h>
#include <grub/misc.h>
#endif #endif
void void
grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs); grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs);
@ -59,7 +60,9 @@ typedef grub_uint16_t gf_double_t;
static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000;
static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100;
#else #else
#if defined (STANDALONE)
static char *scratch; static char *scratch;
#endif
static grub_uint8_t gf_invert[256]; static grub_uint8_t gf_invert[256];
#endif #endif
@ -207,11 +210,12 @@ gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol)
#ifndef STANDALONE #ifndef STANDALONE
chosen = xmalloc (n * sizeof (int)); chosen = xmalloc (n * sizeof (int));
grub_memset (chosen, -1, n * sizeof (int));
#else #else
chosen = (void *) scratch; chosen = (void *) scratch;
scratch += n; scratch += n * sizeof (int);
#endif #endif
for (i = 0; i < n; i++)
chosen[i] = -1;
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
sol[i] = 0; sol[i] = 0;
gauss_eliminate (eq, n, m, chosen); gauss_eliminate (eq, n, m, chosen);
@ -228,7 +232,7 @@ gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol)
#ifndef STANDALONE #ifndef STANDALONE
free (chosen); free (chosen);
#else #else
scratch -= n; scratch -= n * sizeof (int);
#endif #endif
} }
@ -370,6 +374,10 @@ decode_block (gf_single_t *ptr, grub_size_t s,
grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
gf_single_t m[ds + rr]; gf_single_t m[ds + rr];
/* Nothing to do. */
if (!ds || !rr)
continue;
for (j = 0; j < (int) ds; j++) for (j = 0; j < (int) ds; j++)
m[j] = ptr[SECTOR_SIZE * j + i]; m[j] = ptr[SECTOR_SIZE * j + i];
for (j = 0; j < (int) rr; j++) for (j = 0; j < (int) rr; j++)
@ -412,6 +420,10 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
gf_single_t *ptr = buffer; gf_single_t *ptr = buffer;
gf_single_t *rptr = ptr + s; gf_single_t *rptr = ptr + s;
/* Nothing to do. */
if (!rs)
return;
while (s > 0) while (s > 0)
{ {
grub_size_t tt; grub_size_t tt;
@ -421,8 +433,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
tt = cs + crs; tt = cs + crs;
if (tt > MAX_BLOCK_SIZE) if (tt > MAX_BLOCK_SIZE)
{ {
cs = (cs * MAX_BLOCK_SIZE) / tt; cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
crs = (crs * MAX_BLOCK_SIZE) / tt; crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
} }
encode_block (ptr, cs, rptr, crs); encode_block (ptr, cs, rptr, crs);
ptr += cs; ptr += cs;
@ -439,6 +451,10 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs)
gf_single_t *ptr = ptr_; gf_single_t *ptr = ptr_;
gf_single_t *rptr = ptr + s; gf_single_t *rptr = ptr + s;
/* Nothing to do. */
if (!rs)
return;
#if defined (STANDALONE) #if defined (STANDALONE)
init_inverts (); init_inverts ();
#endif #endif
@ -452,8 +468,8 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs)
tt = cs + crs; tt = cs + crs;
if (tt > MAX_BLOCK_SIZE) if (tt > MAX_BLOCK_SIZE)
{ {
cs = cs * MAX_BLOCK_SIZE / tt; cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
crs = crs * MAX_BLOCK_SIZE / tt; crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
} }
decode_block (ptr, cs, rptr, crs); decode_block (ptr, cs, rptr, crs);
ptr += cs; ptr += cs;
@ -485,14 +501,10 @@ main (int argc, char **argv)
fseek (in, 0, SEEK_END); fseek (in, 0, SEEK_END);
s = ftell (in); s = ftell (in);
fseek (in, 0, SEEK_SET); fseek (in, 0, SEEK_SET);
rs = 1024 * ((s + MAX_BLOCK_SIZE - 1) / (MAX_BLOCK_SIZE - 1024)); rs = s / 3;
buf = xmalloc (s + rs + SECTOR_SIZE); buf = xmalloc (s + rs + SECTOR_SIZE);
fread (buf, 1, s, in); fread (buf, 1, s, in);
s = 0x5fbb;
rs = 0x6af9;
#if 0
grub_reed_solomon_add_redundancy (buf, s, rs); grub_reed_solomon_add_redundancy (buf, s, rs);
out = fopen ("tst_rs.bin", "wb"); out = fopen ("tst_rs.bin", "wb");
@ -504,9 +516,6 @@ main (int argc, char **argv)
out = fopen ("tst_dam.bin", "wb"); out = fopen ("tst_dam.bin", "wb");
fwrite (buf, 1, s + rs, out); fwrite (buf, 1, s + rs, out);
fclose (out); fclose (out);
#endif
s = 0x5fbb;
rs = 0x6af9;
grub_reed_solomon_recover (buf, s, rs); grub_reed_solomon_recover (buf, s, rs);
out = fopen ("tst_rec.bin", "wb"); out = fopen ("tst_rec.bin", "wb");

View file

@ -77,10 +77,10 @@ struct grub_relocator_fw_leftover
grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8]; grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8];
}; };
struct grub_relocator_fw_leftover *leftovers; static struct grub_relocator_fw_leftover *leftovers;
#endif #endif
struct grub_relocator_extra_block *extra_blocks; static struct grub_relocator_extra_block *extra_blocks;
void * void *
get_virtual_current_address (grub_relocator_chunk_t in) get_virtual_current_address (grub_relocator_chunk_t in)
@ -135,8 +135,9 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb,
grub_mm_header_t new_header; grub_mm_header_t new_header;
grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); grub_mm_header_t hb = (grub_mm_header_t) (rb + 1);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb);
#endif
newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN); newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN);
newreg_presize = newreg_start - newreg_raw_start; newreg_presize = newreg_start - newreg_raw_start;
newreg_size = rb->size - (newreg_start - (grub_addr_t) rb); newreg_size = rb->size - (newreg_start - (grub_addr_t) rb);
@ -179,11 +180,12 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb,
if ((void *) h < (void *) (newreg + 1)) if ((void *) h < (void *) (newreg + 1))
grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p", grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p",
newreg, newreg->first, h, hp, hb); newreg, newreg->first, h, hp, hb);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
if ((void *) h == (void *) (newreg + 1)) if ((void *) h == (void *) (newreg + 1))
grub_dprintf ("relocator", grub_dprintf ("relocator",
"Free start memory region: %p, %p, %p, %p, %p", "Free start memory region: %p, %p, %p, %p, %p",
newreg, newreg->first, h, hp, hb); newreg, newreg->first, h, hp, hb);
#endif
hp = h; hp = h;
h = h->next; h = h->next;
} }
@ -200,10 +202,12 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
struct grub_mm_header *foll = NULL; struct grub_mm_header *foll = NULL;
grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb));
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu,"
" hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n",
(unsigned long) paddr, (unsigned long) size, hb, hbp, (unsigned long) paddr, (unsigned long) size, hb, hbp,
rb, (unsigned long) vaddr); rb, (unsigned long) vaddr);
#endif
if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN
<= (grub_addr_t) (hb + hb->size)) <= (grub_addr_t) (hb + hb->size))
@ -211,8 +215,10 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN); foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN);
foll->magic = GRUB_MM_FREE_MAGIC; foll->magic = GRUB_MM_FREE_MAGIC;
foll->size = hb + hb->size - foll; foll->size = hb + hb->size - foll;
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll, grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll,
(unsigned long) foll->size); (unsigned long) foll->size);
#endif
} }
if (vaddr - (grub_addr_t) hb >= sizeof (*hb)) if (vaddr - (grub_addr_t) hb >= sizeof (*hb))
@ -597,7 +603,8 @@ malloc_in_range (struct grub_relocator *rel,
events[N].hancestor = pa; events[N].hancestor = pa;
N++; N++;
events[N].type = REG_BEG_END; events[N].type = REG_BEG_END;
events[N].pos = grub_vtop (p + p->size) - sizeof (*r); events[N].pos = grub_vtop (p + p->size) - sizeof (*r)
- sizeof (struct grub_mm_header);
N++; N++;
} }
else else
@ -818,9 +825,11 @@ malloc_in_range (struct grub_relocator *rel,
fend fend
= ALIGN_UP (alloc_end, = ALIGN_UP (alloc_end,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf ("relocator", "requesting %lx-%lx\n", grub_dprintf ("relocator", "requesting %lx-%lx\n",
(unsigned long) fstart, (unsigned long) fstart,
(unsigned long) fend); (unsigned long) fend);
#endif
/* The failure here can be very expensive. */ /* The failure here can be very expensive. */
if (!grub_relocator_firmware_alloc_region (fstart, if (!grub_relocator_firmware_alloc_region (fstart,
fend - fstart)) fend - fstart))
@ -1281,23 +1290,8 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
chunk->srcv = grub_map_memory (chunk->src, chunk->size); chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*out = chunk; *out = chunk;
#ifdef DEBUG_RELOCATOR #ifdef DEBUG_RELOCATOR
{ grub_memset (chunk->srcv, 0xfa, chunk->size);
grub_mm_region_t r; grub_mm_check ();
grub_mm_header_t p;
grub_memset (chunk->srcv, 0xfa, chunk->size);
for (r = grub_mm_base; r; r = r->next)
{
p = r->first;
do
{
if ((grub_addr_t) p < (grub_addr_t) (r + 1)
|| (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
grub_fatal (__FILE__ ":%d: out of range pointer: %p\n", __LINE__, p);
p = p->next;
}
while (p != r->first);
}
}
#endif #endif
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -1435,24 +1429,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
chunk->srcv = grub_map_memory (chunk->src, chunk->size); chunk->srcv = grub_map_memory (chunk->src, chunk->size);
*out = chunk; *out = chunk;
#ifdef DEBUG_RELOCATOR #ifdef DEBUG_RELOCATOR
{ grub_memset (chunk->srcv, 0xfa, chunk->size);
grub_mm_region_t r; grub_mm_check ();
grub_mm_header_t p;
grub_memset (chunk->srcv, 0xfa, chunk->size);
for (r = grub_mm_base; r; r = r->next)
{
p = r->first;
do
{
if ((grub_addr_t) p < (grub_addr_t) (r + 1)
|| (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
grub_fatal (__FILE__ "%d: out of range pointer: %p\n", __LINE__, p);
p = p->next;
}
while (p != r->first);
}
}
#endif #endif
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -65,7 +65,7 @@ static void *kern_chunk_src;
static grub_uint32_t bootflags; static grub_uint32_t bootflags;
static int is_elf_kernel, is_64bit; static int is_elf_kernel, is_64bit;
static grub_uint32_t openbsd_root; static grub_uint32_t openbsd_root;
struct grub_relocator *relocator = NULL; static struct grub_relocator *relocator = NULL;
static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk; static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk;
struct bsd_tag struct bsd_tag
@ -252,7 +252,7 @@ struct grub_e820_mmap
#define GRUB_E820_RESERVED 2 #define GRUB_E820_RESERVED 2
#define GRUB_E820_ACPI 3 #define GRUB_E820_ACPI 3
#define GRUB_E820_NVS 4 #define GRUB_E820_NVS 4
#define GRUB_E820_EXEC_CODE 5 #define GRUB_E820_BADRAM 5
static void static void
generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf)
@ -521,6 +521,8 @@ grub_netbsd_list_modules (void)
/* This function would be here but it's under different license. */ /* This function would be here but it's under different license. */
#include "bsd_pagetable.c" #include "bsd_pagetable.c"
static grub_uint32_t freebsd_bootdev, freebsd_biosdev;
static grub_err_t static grub_err_t
grub_freebsd_boot (void) grub_freebsd_boot (void)
{ {
@ -528,7 +530,6 @@ grub_freebsd_boot (void)
grub_uint8_t *p, *p0; grub_uint8_t *p, *p0;
grub_addr_t p_target; grub_addr_t p_target;
grub_size_t p_size = 0; grub_size_t p_size = 0;
grub_uint32_t bootdev, biosdev, unit, slice, part;
grub_err_t err; grub_err_t err;
grub_size_t tag_buf_len = 0; grub_size_t tag_buf_len = 0;
@ -564,11 +565,7 @@ grub_freebsd_boot (void)
bi.version = FREEBSD_BOOTINFO_VERSION; bi.version = FREEBSD_BOOTINFO_VERSION;
bi.length = sizeof (bi); bi.length = sizeof (bi);
grub_bsd_get_device (&biosdev, &unit, &slice, &part); bi.boot_device = freebsd_biosdev;
bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
(unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
bi.boot_device = biosdev;
p_size = 0; p_size = 0;
grub_env_iterate (iterate_env_count); grub_env_iterate (iterate_env_count);
@ -741,7 +738,7 @@ grub_freebsd_boot (void)
state.ebp = stack_target; state.ebp = stack_target;
stack[0] = entry; /* "Return" address. */ stack[0] = entry; /* "Return" address. */
stack[1] = bootflags | FREEBSD_RB_BOOTINFO; stack[1] = bootflags | FREEBSD_RB_BOOTINFO;
stack[2] = bootdev; stack[2] = freebsd_bootdev;
stack[3] = 0; stack[3] = 0;
stack[4] = 0; stack[4] = 0;
stack[5] = 0; stack[5] = 0;
@ -1371,6 +1368,8 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
{ {
grub_uint32_t unit, slice, part;
kern_end = ALIGN_PAGE (kern_end); kern_end = ALIGN_PAGE (kern_end);
if (is_elf_kernel) if (is_elf_kernel)
{ {
@ -1414,6 +1413,10 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (err) if (err)
return err; return err;
} }
grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part);
freebsd_bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
(unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0); grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
} }
@ -1611,7 +1614,7 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)),
char *buf = 0, *curr, *next; char *buf = 0, *curr, *next;
int len; int len;
if (kernel_type == KERNEL_TYPE_NONE) if (! grub_loader_is_loaded ())
return grub_error (GRUB_ERR_BAD_ARGUMENT, return grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the kernel first"); "you need to load the kernel first");
@ -1844,7 +1847,7 @@ grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)),
grub_file_t file = 0; grub_file_t file = 0;
grub_err_t err; grub_err_t err;
if (kernel_type == KERNEL_TYPE_NONE) if (! grub_loader_is_loaded ())
return grub_error (GRUB_ERR_BAD_ARGUMENT, return grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the kernel first"); "you need to load the kernel first");

View file

@ -195,6 +195,11 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
chunk_size = s->sh_addr + s->sh_size; chunk_size = s->sh_addr + s->sh_size;
} }
if (chunk_size < sizeof (e))
chunk_size = sizeof (e);
chunk_size += e.e_phnum * e.e_phentsize;
chunk_size += e.e_shnum * e.e_shentsize;
{ {
grub_relocator_chunk_t ch; grub_relocator_chunk_t ch;
@ -394,7 +399,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
grub_err_t err; grub_err_t err;
Elf_Ehdr e; Elf_Ehdr e;
Elf_Shdr *s, *symsh, *strsh; Elf_Shdr *s, *symsh, *strsh;
char *shdr; char *shdr = NULL;
unsigned symsize, strsize; unsigned symsize, strsize;
void *sym_chunk; void *sym_chunk;
grub_uint8_t *curload; grub_uint8_t *curload;
@ -511,7 +516,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
grub_err_t err; grub_err_t err;
Elf_Ehdr e; Elf_Ehdr e;
Elf_Shdr *s; Elf_Shdr *s;
char *shdr; char *shdr = NULL;
err = read_headers (file, &e, &shdr); err = read_headers (file, &e, &shdr);
if (err) if (err)

View file

@ -33,6 +33,7 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/i386/relocator.h> #include <grub/i386/relocator.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#ifdef GRUB_MACHINE_PCBIOS #ifdef GRUB_MACHINE_PCBIOS
#include <grub/i386/pc/vesa_modes_table.h> #include <grub/i386/pc/vesa_modes_table.h>
@ -135,7 +136,8 @@ find_efi_mmap_size (void)
later, and EFI itself may allocate more. */ later, and EFI itself may allocate more. */
mmap_size += (1 << 12); mmap_size += (1 << 12);
return page_align (mmap_size); mmap_size = page_align (mmap_size);
return mmap_size;
} }
#endif #endif
@ -312,6 +314,13 @@ grub_linux_setup_video (struct linux_kernel_params *params)
struct grub_video_mode_info mode_info; struct grub_video_mode_info mode_info;
void *framebuffer; void *framebuffer;
grub_err_t err; grub_err_t err;
grub_video_driver_id_t driver_id;
char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb");
driver_id = grub_video_get_driver_id ();
if (driver_id == GRUB_VIDEO_DRIVER_NONE)
return 1;
err = grub_video_get_info_and_fini (&mode_info, &framebuffer); err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
@ -338,12 +347,40 @@ grub_linux_setup_video (struct linux_kernel_params *params)
params->reserved_mask_size = mode_info.reserved_mask_size; params->reserved_mask_size = mode_info.reserved_mask_size;
params->reserved_field_pos = mode_info.reserved_field_pos; params->reserved_field_pos = mode_info.reserved_field_pos;
if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y'))
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
else
{
switch (driver_id)
{
case GRUB_VIDEO_DRIVER_VBE:
params->lfb_size >>= 16;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
break;
case GRUB_VIDEO_DRIVER_EFI_UGA:
case GRUB_VIDEO_DRIVER_EFI_GOP:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB;
break;
/* FIXME: check if better id is available. */
case GRUB_VIDEO_DRIVER_SM712:
case GRUB_VIDEO_DRIVER_VGA:
case GRUB_VIDEO_DRIVER_CIRRUS:
case GRUB_VIDEO_DRIVER_BOCHS:
/* Make gcc happy. */
case GRUB_VIDEO_DRIVER_SDL:
case GRUB_VIDEO_DRIVER_NONE:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
break;
}
}
#ifdef GRUB_MACHINE_PCBIOS #ifdef GRUB_MACHINE_PCBIOS
/* VESA packed modes may come with zeroed mask sizes, which need /* VESA packed modes may come with zeroed mask sizes, which need
to be set here according to DAC Palette width. If we don't, to be set here according to DAC Palette width. If we don't,
this results in Linux displaying a black screen. */ this results in Linux displaying a black screen. */
if (mode_info.bpp <= 8) if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8)
{ {
struct grub_vbe_info_block controller_info; struct grub_vbe_info_block controller_info;
int status; int status;
@ -418,9 +455,9 @@ grub_linux_boot (void)
addr, size, GRUB_E820_NVS); addr, size, GRUB_E820_NVS);
break; break;
case GRUB_MEMORY_CODE: case GRUB_MEMORY_BADRAM:
grub_e820_add_region (params->e820_map, &e820_num, grub_e820_add_region (params->e820_map, &e820_num,
addr, size, GRUB_E820_EXEC_CODE); addr, size, GRUB_E820_BADRAM);
break; break;
default: default:
@ -456,15 +493,7 @@ grub_linux_boot (void)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
if (! grub_linux_setup_video (params)) if (grub_linux_setup_video (params))
{
/* Use generic framebuffer unless VESA is known to be supported. */
if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA)
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
else
params->lfb_size >>= 16;
}
else
{ {
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
@ -575,7 +604,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_size_t real_size, prot_size; grub_size_t real_size, prot_size;
grub_ssize_t len; grub_ssize_t len;
int i; int i;
char *dest;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@ -655,7 +683,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail; goto fail;
} }
params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4); params->type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
/* These two are used (instead of cmd_line_ptr) by older versions of Linux, /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
and otherwise ignored. */ and otherwise ignored. */
@ -719,6 +747,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_err_t err; grub_err_t err;
char *buf; char *buf;
grub_dl_load ("vbe");
if (grub_strcmp (val, "normal") == 0) if (grub_strcmp (val, "normal") == 0)
vid_mode = GRUB_LINUX_VID_MODE_NORMAL; vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
else if (grub_strcmp (val, "ext") == 0) else if (grub_strcmp (val, "ext") == 0)
@ -769,10 +799,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
break; break;
} }
/* We can't detect VESA, but user is implicitly telling us that it
is built-in because `vga=' parameter was used. */
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
linux_mode = &grub_vesa_mode_table[vid_mode linux_mode = &grub_vesa_mode_table[vid_mode
- GRUB_VESA_MODE_TABLE_START]; - GRUB_VESA_MODE_TABLE_START];
@ -834,22 +860,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
params->loadflags |= GRUB_LINUX_FLAG_QUIET; params->loadflags |= GRUB_LINUX_FLAG_QUIET;
} }
/* Create kernel command line. */
/* Specify the boot file. */ grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE,
dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET, sizeof (LINUX_IMAGE));
"BOOT_IMAGE="); grub_create_loader_cmdline (argc, argv,
dest = grub_stpcpy (dest, argv[0]); (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
+ sizeof (LINUX_IMAGE) - 1,
/* Copy kernel parameters. */ GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
for (i = 1; - (sizeof (LINUX_IMAGE) - 1));
i < argc
&& dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+ GRUB_LINUX_CL_END_OFFSET);
i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
len = prot_size; len = prot_size;
if (grub_file_read (file, prot_mode_mem, len) != len) if (grub_file_read (file, prot_mode_mem, len) != len)

View file

@ -47,7 +47,7 @@ struct module
int cmdline_size; int cmdline_size;
}; };
struct module *modules, *modules_last; static struct module *modules, *modules_last;
static grub_size_t cmdline_size; static grub_size_t cmdline_size;
static grub_size_t total_modcmd; static grub_size_t total_modcmd;
static unsigned modcnt; static unsigned modcnt;
@ -142,7 +142,7 @@ grub_multiboot_load (grub_file_t file)
} }
if (header->bss_end_addr) if (header->bss_end_addr)
grub_memset ((grub_uint32_t *) source + load_size, 0, grub_memset ((grub_uint8_t *) source + load_size, 0,
header->bss_end_addr - header->load_addr - load_size); header->bss_end_addr - header->load_addr - load_size);
grub_multiboot_payload_eip = header->entry_addr; grub_multiboot_payload_eip = header->entry_addr;
@ -454,7 +454,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
if (err) if (err)
return err; return err;
ptrorig = get_virtual_current_address (ch); ptrorig = get_virtual_current_address (ch);
ptrdest = (grub_addr_t) get_virtual_current_address (ch); ptrdest = get_physical_target_address (ch);
*target = ptrdest; *target = ptrdest;
@ -566,6 +566,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
mbi->u.elf_sec.shndx = elf_sec_shstrndx; mbi->u.elf_sec.shndx = elf_sec_shstrndx;
mbi->flags |= MULTIBOOT_INFO_ELF_SHDR; mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;
ptrorig += elf_sec_entsize * elf_sec_num;
ptrdest += elf_sec_entsize * elf_sec_num;
} }
err = retrieve_video_parameters (mbi, ptrorig, ptrdest); err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
@ -574,6 +577,16 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
grub_print_error (); grub_print_error ();
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
if ((mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
&& mbi->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED)
{
ptrorig += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
ptrdest += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
}
#if GRUB_MACHINE_HAS_VBE #if GRUB_MACHINE_HAS_VBE
ptrorig += sizeof (struct grub_vbe_info_block); ptrorig += sizeof (struct grub_vbe_info_block);
ptrdest += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block);
@ -668,6 +681,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
return grub_errno; return grub_errno;
newmod->start = start; newmod->start = start;
newmod->size = size; newmod->size = size;
newmod->next = 0;
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
len += grub_strlen (argv[i]) + 1; len += grub_strlen (argv[i]) + 1;

View file

@ -34,6 +34,7 @@
#include <grub/cpu/relocator.h> #include <grub/cpu/relocator.h>
#include <grub/video.h> #include <grub/video.h>
#include <grub/i386/floppy.h> #include <grub/i386/floppy.h>
#include <grub/lib/cmdline.h>
#define GRUB_LINUX_CL_OFFSET 0x9000 #define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF #define GRUB_LINUX_CL_END_OFFSET 0x90FF
@ -86,7 +87,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_size_t real_size; grub_size_t real_size;
grub_ssize_t len; grub_ssize_t len;
int i; int i;
char *dest;
char *grub_linux_prot_chunk; char *grub_linux_prot_chunk;
int grub_linux_is_bzimage; int grub_linux_is_bzimage;
grub_addr_t grub_linux_prot_target; grub_addr_t grub_linux_prot_target;
@ -286,21 +286,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1) ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
<< GRUB_DISK_SECTOR_BITS)); << GRUB_DISK_SECTOR_BITS));
/* Specify the boot file. */ /* Create kernel command line. */
dest = grub_stpcpy (grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET, grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
"BOOT_IMAGE="); LINUX_IMAGE, sizeof (LINUX_IMAGE));
dest = grub_stpcpy (dest, argv[0]); grub_create_loader_cmdline (argc, argv,
(char *)grub_linux_real_chunk
/* Copy kernel parameters. */ + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
for (i = 1; GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
i < argc - (sizeof (LINUX_IMAGE) - 1));
&& dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk
+ GRUB_LINUX_CL_END_OFFSET);
i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
if (grub_linux_is_bzimage) if (grub_linux_is_bzimage)
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR; grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;

View file

@ -49,7 +49,7 @@ struct tbl_alias
char *name; char *name;
}; };
struct tbl_alias table_aliases[] = static struct tbl_alias table_aliases[] =
{ {
{GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"}, {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
{GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
@ -219,7 +219,7 @@ struct property_descriptor
void *data; void *data;
}; };
struct grub_xnu_devprop_device_descriptor *devices = 0; static struct grub_xnu_devprop_device_descriptor *devices = 0;
grub_err_t grub_err_t
grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
@ -951,10 +951,11 @@ grub_err_t
grub_xnu_boot (void) grub_xnu_boot (void)
{ {
struct grub_xnu_boot_params *bootparams; struct grub_xnu_boot_params *bootparams;
void *bp_in;
grub_addr_t bootparams_target; grub_addr_t bootparams_target;
grub_err_t err; grub_err_t err;
grub_efi_uintn_t memory_map_size = 0; grub_efi_uintn_t memory_map_size = 0;
grub_efi_memory_descriptor_t *memory_map; void *memory_map;
grub_addr_t memory_map_target; grub_addr_t memory_map_target;
grub_efi_uintn_t map_key = 0; grub_efi_uintn_t map_key = 0;
grub_efi_uintn_t descriptor_size = 0; grub_efi_uintn_t descriptor_size = 0;
@ -1006,9 +1007,10 @@ grub_xnu_boot (void)
/* Relocate the boot parameters to heap. */ /* Relocate the boot parameters to heap. */
err = grub_xnu_heap_malloc (sizeof (*bootparams), err = grub_xnu_heap_malloc (sizeof (*bootparams),
(void **) &bootparams, &bootparams_target); &bp_in, &bootparams_target);
if (err) if (err)
return err; return err;
bootparams = bp_in;
/* Set video. */ /* Set video. */
err = grub_xnu_set_video (bootparams); err = grub_xnu_set_video (bootparams);
@ -1035,7 +1037,7 @@ grub_xnu_boot (void)
memory map growth. */ memory map growth. */
memory_map_size += 20 * descriptor_size; memory_map_size += 20 * descriptor_size;
err = grub_xnu_heap_malloc (memory_map_size, err = grub_xnu_heap_malloc (memory_map_size,
(void **) &memory_map, &memory_map_target); &memory_map, &memory_map_target);
if (err) if (err)
return err; return err;
@ -1109,7 +1111,7 @@ grub_xnu_boot (void)
grub_xnu_arg1 = bootparams_target; grub_xnu_arg1 = bootparams_target;
grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
descriptor_version,memory_map); descriptor_version, memory_map);
state.eip = grub_xnu_entry_point; state.eip = grub_xnu_entry_point;
state.eax = grub_xnu_arg1; state.eax = grub_xnu_arg1;

View file

@ -32,6 +32,14 @@
#include <grub/pci.h> #include <grub/pci.h>
#include <grub/machine/time.h> #include <grub/machine/time.h>
#ifdef GRUB_MACHINE_MIPS_YEELOONG
/* This can be detected on runtime from PMON, but:
a) it wouldn't work when GRUB is the firmware
and
b) for now we only support Yeeloong anyway. */
#define LOONGSON_MACHTYPE "machtype=lemote-yeeloong-2f-8.9inches"
#endif
static grub_dl_t my_mod; static grub_dl_t my_mod;
static int loaded; static int loaded;
@ -83,7 +91,7 @@ grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
/* Linux's entry point incorrectly contains a virtual address. */ /* Linux's entry point incorrectly contains a virtual address. */
entry_addr = elf->ehdr.ehdr32.e_entry; entry_addr = elf->ehdr.ehdr32.e_entry;
linux_size = grub_elf32_size (elf, &base); linux_size = grub_elf32_size (elf, &base, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
target_addr = base; target_addr = base;
@ -138,7 +146,7 @@ grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
/* Linux's entry point incorrectly contains a virtual address. */ /* Linux's entry point incorrectly contains a virtual address. */
entry_addr = elf->ehdr.ehdr64.e_entry; entry_addr = elf->ehdr.ehdr64.e_entry;
linux_size = grub_elf64_size (elf, &base); linux_size = grub_elf64_size (elf, &base, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
target_addr = base; target_addr = base;
@ -214,6 +222,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* For arguments. */ /* For arguments. */
linux_argc = argc; linux_argc = argc;
#ifdef LOONGSON_MACHTYPE
linux_argc++;
#endif
/* Main arguments. */ /* Main arguments. */
size = (linux_argc) * sizeof (grub_uint32_t); size = (linux_argc) * sizeof (grub_uint32_t);
/* Initrd address and size. */ /* Initrd address and size. */
@ -226,6 +237,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Normal arguments. */ /* Normal arguments. */
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
#ifdef LOONGSON_MACHTYPE
size += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4);
#endif
/* rd arguments. */ /* rd arguments. */
size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
@ -263,6 +277,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
linux_argv++; linux_argv++;
linux_args += ALIGN_UP (sizeof ("a0"), 4); linux_args += ALIGN_UP (sizeof ("a0"), 4);
#ifdef LOONGSON_MACHTYPE
/* In Loongson platform, it is the responsibility of the bootloader/firmware
to supply the OS kernel with machine type information. */
grub_memcpy (linux_args, LOONGSON_MACHTYPE, sizeof (LOONGSON_MACHTYPE));
*linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
+ target_addr;
linux_argv++;
linux_args += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4);
#endif
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1);

View file

@ -54,7 +54,7 @@ struct module
int cmdline_size; int cmdline_size;
}; };
struct module *modules, *modules_last; static struct module *modules, *modules_last;
static grub_size_t cmdline_size; static grub_size_t cmdline_size;
static grub_size_t total_modcmd; static grub_size_t total_modcmd;
static unsigned modcnt; static unsigned modcnt;

View file

@ -26,6 +26,8 @@
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/memory.h>
#include <grub/lib/cmdline.h>
#define ELF32_LOADMASK (0xc0000000UL) #define ELF32_LOADMASK (0xc0000000UL)
#define ELF64_LOADMASK (0xc000000000000000ULL) #define ELF64_LOADMASK (0xc000000000000000ULL)
@ -45,6 +47,51 @@ static char *linux_args;
typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
unsigned long, unsigned long); unsigned long, unsigned long);
static grub_addr_t
grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size,
grub_size_t align)
{
grub_addr_t found_addr = (grub_addr_t) -1;
auto int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
grub_memory_type_t type);
int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
grub_memory_type_t type)
{
grub_uint64_t end = addr + len;
addr = ALIGN_UP (addr, align);
target = ALIGN_UP (target, align);
/* Target above the memory chunk. */
if (type != GRUB_MEMORY_AVAILABLE || target > end)
return 0;
/* Target inside the memory chunk. */
if (target >= addr && target < end && size <= end - target)
{
if (grub_claimmap (target, size) == GRUB_ERR_NONE)
{
found_addr = target;
return 1;
}
}
/* Target below the memory chunk. */
if (target < addr && addr + size <= end)
{
if (grub_claimmap (addr, size) == GRUB_ERR_NONE)
{
found_addr = addr;
return 1;
}
}
return 0;
}
grub_machine_mmap_iterate (alloc_mem);
return found_addr;
}
static grub_err_t static grub_err_t
grub_linux_boot (void) grub_linux_boot (void)
{ {
@ -102,34 +149,34 @@ grub_linux_unload (void)
static grub_err_t static grub_err_t
grub_linux_load32 (grub_elf_t elf) grub_linux_load32 (grub_elf_t elf)
{ {
Elf32_Addr base_addr;
grub_addr_t seg_addr;
grub_uint32_t align;
grub_uint32_t offset;
Elf32_Addr entry; Elf32_Addr entry;
int found_addr = 0;
/* Linux's entry point incorrectly contains a virtual address. */ linux_size = grub_elf32_size (elf, &base_addr, &align);
entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
if (entry == 0)
entry = 0x01400000;
linux_size = grub_elf32_size (elf, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
/* Pad it; the kernel scribbles over memory beyond its load address. */ /* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000; linux_size += 0x100000;
/* Linux's entry point incorrectly contains a virtual address. */
entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
/* Linux's incorrectly contains a virtual address. */
base_addr &= ~ELF32_LOADMASK;
offset = entry - base_addr;
/* On some systems, firmware occupies the memory we're trying to use. /* On some systems, firmware occupies the memory we're trying to use.
* Happily, Linux can be loaded anywhere (it relocates itself). Iterate * Happily, Linux can be loaded anywhere (it relocates itself). Iterate
* until we find an open area. */ * until we find an open area. */
for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF32_LOADMASK, linux_size, align);
{ if (seg_addr == (grub_addr_t) -1)
grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
linux_addr, linux_size);
found_addr = grub_claimmap (linux_addr, linux_size);
if (found_addr != -1)
break;
}
if (found_addr == -1)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory");
linux_addr = seg_addr + offset;
/* Now load the segments into the area we claimed. */ /* Now load the segments into the area we claimed. */
auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load) grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
@ -141,9 +188,7 @@ grub_linux_load32 (grub_elf_t elf)
} }
*do_load = 1; *do_load = 1;
/* Linux's program headers incorrectly contain virtual addresses. *addr = (phdr->p_paddr - base_addr) + seg_addr;
* Translate those to physical, and offset to the area we claimed. */
*addr = (phdr->p_paddr & ~ELF32_LOADMASK) + linux_addr;
return 0; return 0;
} }
return grub_elf32_load (elf, offset_phdr, 0, 0); return grub_elf32_load (elf, offset_phdr, 0, 0);
@ -152,34 +197,32 @@ grub_linux_load32 (grub_elf_t elf)
static grub_err_t static grub_err_t
grub_linux_load64 (grub_elf_t elf) grub_linux_load64 (grub_elf_t elf)
{ {
Elf64_Addr base_addr;
grub_addr_t seg_addr;
grub_uint64_t align;
grub_uint64_t offset;
Elf64_Addr entry; Elf64_Addr entry;
int found_addr = 0;
/* Linux's entry point incorrectly contains a virtual address. */ linux_size = grub_elf64_size (elf, &base_addr, &align);
entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
if (entry == 0)
entry = 0x01400000;
linux_size = grub_elf64_size (elf, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
/* Pad it; the kernel scribbles over memory beyond its load address. */ /* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000; linux_size += 0x100000;
base_addr &= ~ELF64_LOADMASK;
entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
offset = entry - base_addr;
/* Linux's incorrectly contains a virtual address. */
/* On some systems, firmware occupies the memory we're trying to use. /* On some systems, firmware occupies the memory we're trying to use.
* Happily, Linux can be loaded anywhere (it relocates itself). Iterate * Happily, Linux can be loaded anywhere (it relocates itself). Iterate
* until we find an open area. */ * until we find an open area. */
for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF64_LOADMASK, linux_size, align);
{ if (seg_addr == (grub_addr_t) -1)
grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
linux_addr, linux_size);
found_addr = grub_claimmap (linux_addr, linux_size);
if (found_addr != -1)
break;
}
if (found_addr == -1)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory");
linux_addr = seg_addr + offset;
/* Now load the segments into the area we claimed. */ /* Now load the segments into the area we claimed. */
auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load) grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
@ -190,9 +233,8 @@ grub_linux_load64 (grub_elf_t elf)
return 0; return 0;
} }
*do_load = 1; *do_load = 1;
/* Linux's program headers incorrectly contain virtual addresses.
* Translate those to physical, and offset to the area we claimed. */ *addr = (phdr->p_paddr - base_addr) + seg_addr;
*addr = (phdr->p_paddr & ~ELF64_LOADMASK) + linux_addr;
return 0; return 0;
} }
return grub_elf64_load (elf, offset_phdr, 0, 0); return grub_elf64_load (elf, offset_phdr, 0, 0);
@ -203,9 +245,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
grub_elf_t elf = 0; grub_elf_t elf = 0;
int i;
int size; int size;
char *dest;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@ -240,23 +280,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out; goto out;
} }
size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); size = grub_loader_cmdline_size(argc, argv);
for (i = 0; i < argc; i++) linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
size += grub_strlen (argv[i]) + 1;
linux_args = grub_malloc (size);
if (! linux_args) if (! linux_args)
goto out; goto out;
/* Specify the boot file. */ /* Create kernel command line. */
dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
dest = grub_stpcpy (dest, argv[0]); grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
size);
for (i = 1; i < argc; i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
out: out:
@ -287,7 +319,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
grub_ssize_t size; grub_ssize_t size;
grub_addr_t first_addr; grub_addr_t first_addr;
grub_addr_t addr; grub_addr_t addr;
int found_addr = 0;
if (argc == 0) if (argc == 0)
{ {
@ -311,20 +342,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
/* Attempt to claim at a series of addresses until successful in /* Attempt to claim at a series of addresses until successful in
the same way that grub_rescue_cmd_linux does. */ the same way that grub_rescue_cmd_linux does. */
for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000) addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000);
{ if (addr == (grub_addr_t) -1)
grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", goto fail;
addr, size);
found_addr = grub_claimmap (addr, size);
if (found_addr != -1)
break;
}
if (found_addr == -1)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot claim memory");
goto fail;
}
grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);

View file

@ -27,6 +27,7 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/memory.h> #include <grub/memory.h>
#include <grub/lib/cmdline.h>
static grub_dl_t my_mod; static grub_dl_t my_mod;
@ -247,7 +248,7 @@ grub_linux_load64 (grub_elf_t elf)
linux_entry = elf->ehdr.ehdr64.e_entry; linux_entry = elf->ehdr.ehdr64.e_entry;
linux_addr = 0x40004000; linux_addr = 0x40004000;
off = 0x4000; off = 0x4000;
linux_size = grub_elf64_size (elf, 0); linux_size = grub_elf64_size (elf, 0, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
@ -295,9 +296,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{ {
grub_file_t file = 0; grub_file_t file = 0;
grub_elf_t elf = 0; grub_elf_t elf = 0;
int i;
int size; int size;
char *dest;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@ -333,23 +332,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out; goto out;
} }
size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); size = grub_loader_cmdline_size(argc, argv);
for (i = 0; i < argc; i++)
size += grub_strlen (argv[i]) + 1;
linux_args = grub_malloc (size); linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
if (! linux_args) if (! linux_args)
goto out; goto out;
/* Specify the boot file. */ /* Create kernel command line. */
dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
dest = grub_stpcpy (dest, argv[0]); grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
size);
for (i = 1; i < argc; i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
out: out:
if (elf) if (elf)

View file

@ -34,6 +34,10 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
#include <grub/autoefi.h>
#endif
struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
static int driverspackagenum = 0; static int driverspackagenum = 0;
static int driversnum = 0; static int driversnum = 0;
@ -338,7 +342,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
grub_macho_t macho; grub_macho_t macho;
grub_uint32_t startcode, endcode; grub_uint32_t startcode, endcode;
int i; int i;
char *ptr, *loadaddr; char *ptr;
void *loadaddr;
grub_addr_t loadaddr_target; grub_addr_t loadaddr_target;
if (argc < 1) if (argc < 1)
@ -371,7 +376,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
if (!grub_xnu_relocator) if (!grub_xnu_relocator)
return grub_errno; return grub_errno;
grub_xnu_heap_target_start = startcode; grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr, err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
&loadaddr_target); &loadaddr_target);
if (err) if (err)
@ -382,7 +387,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
} }
/* Load kernel. */ /* Load kernel. */
err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); err = grub_macho_load32 (macho, (char *) loadaddr - startcode,
GRUB_MACHO_NOBSS);
if (err) if (err)
{ {
grub_macho_close (macho); grub_macho_close (macho);
@ -424,6 +430,12 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
if (ptr != grub_xnu_cmdline) if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0; *(ptr - 1) = 0;
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
return err;
#endif
grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
grub_xnu_lock (); grub_xnu_lock ();
@ -440,7 +452,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
grub_macho_t macho; grub_macho_t macho;
grub_uint64_t startcode, endcode; grub_uint64_t startcode, endcode;
int i; int i;
char *ptr, *loadaddr; char *ptr;
void *loadaddr;
grub_addr_t loadaddr_target; grub_addr_t loadaddr_target;
if (argc < 1) if (argc < 1)
@ -476,7 +489,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
if (!grub_xnu_relocator) if (!grub_xnu_relocator)
return grub_errno; return grub_errno;
grub_xnu_heap_target_start = startcode; grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr, err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
&loadaddr_target); &loadaddr_target);
if (err) if (err)
@ -487,7 +500,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
} }
/* Load kernel. */ /* Load kernel. */
err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); err = grub_macho_load64 (macho, (char *) loadaddr - startcode,
GRUB_MACHO_NOBSS);
if (err) if (err)
{ {
grub_macho_close (macho); grub_macho_close (macho);
@ -529,6 +543,12 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
if (ptr != grub_xnu_cmdline) if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0; *(ptr - 1) = 0;
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
return err;
#endif
grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
grub_xnu_lock (); grub_xnu_lock ();
@ -620,7 +640,8 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
grub_file_t infoplist; grub_file_t infoplist;
struct grub_xnu_extheader *exthead; struct grub_xnu_extheader *exthead;
int neededspace = sizeof (*exthead); int neededspace = sizeof (*exthead);
grub_uint8_t *buf, *buf0; grub_uint8_t *buf;
void *buf0;
grub_addr_t buf_target; grub_addr_t buf_target;
grub_size_t infoplistsize = 0, machosize = 0; grub_size_t infoplistsize = 0, machosize = 0;
char *name, *nameend; char *name, *nameend;
@ -676,7 +697,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
if (err) if (err)
return err; return err;
err = grub_xnu_heap_malloc (neededspace, (void **) &buf0, &buf_target); err = grub_xnu_heap_malloc (neededspace, &buf0, &buf_target);
if (err) if (err)
return err; return err;
buf = buf0; buf = buf0;
@ -688,7 +709,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the binary. */ /* Load the binary. */
if (macho) if (macho)
{ {
exthead->binaryaddr = buf_target + (buf - buf0); exthead->binaryaddr = buf_target + (buf - (grub_uint8_t *) buf0);
exthead->binarysize = machosize; exthead->binarysize = machosize;
if (grub_xnu_is_64bit) if (grub_xnu_is_64bit)
err = grub_macho_readfile64 (macho, buf); err = grub_macho_readfile64 (macho, buf);
@ -707,7 +728,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the plist. */ /* Load the plist. */
if (infoplist) if (infoplist)
{ {
exthead->infoplistaddr = buf_target + (buf - buf0); exthead->infoplistaddr = buf_target + (buf - (grub_uint8_t *) buf0);
exthead->infoplistsize = infoplistsize + 1; exthead->infoplistsize = infoplistsize + 1;
if (grub_file_read (infoplist, buf, infoplistsize) if (grub_file_read (infoplist, buf, infoplistsize)
!= (grub_ssize_t) (infoplistsize)) != (grub_ssize_t) (infoplistsize))
@ -723,7 +744,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
exthead->nameaddr = (buf - buf0) + buf_target; exthead->nameaddr = (buf - (grub_uint8_t *) buf0) + buf_target;
exthead->namesize = namelen + 1; exthead->namesize = namelen + 1;
grub_memcpy (buf, name, namelen); grub_memcpy (buf, name, namelen);
buf[namelen] = 0; buf[namelen] = 0;
@ -1198,6 +1219,10 @@ grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)),
int argc, char *args[]) int argc, char *args[])
{ {
grub_file_t binfile = 0; grub_file_t binfile = 0;
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
if (argc == 2) if (argc == 2)
{ {
/* User explicitly specified plist and binary. */ /* User explicitly specified plist and binary. */
@ -1229,6 +1254,9 @@ grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)),
if (argc != 1 && argc != 2) if (argc != 1 && argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
if (argc == 1) if (argc == 1)
return grub_xnu_scan_dir_for_kexts (args[0], return grub_xnu_scan_dir_for_kexts (args[0],
"console,root,local-root,network-root", "console,root,local-root,network-root",
@ -1370,6 +1398,9 @@ grub_cmd_xnu_splash (grub_extcmd_context_t ctxt,
if (argc != 1) if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
"stretch") == 0) "stretch") == 0)
@ -1398,7 +1429,7 @@ grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)),
#endif #endif
void void
grub_xnu_lock () grub_xnu_lock (void)
{ {
if (!locked) if (!locked)
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@ -1406,7 +1437,7 @@ grub_xnu_lock ()
} }
void void
grub_xnu_unlock () grub_xnu_unlock (void)
{ {
if (locked) if (locked)
grub_dl_unref (my_mod); grub_dl_unref (my_mod);

Some files were not shown because too many files have changed in this diff Show more