Merge pull request #44 from dm0-/sync

Merge with upstream master
This commit is contained in:
David Michael 2017-01-24 12:00:11 -08:00 committed by GitHub
commit ff8d967eff
183 changed files with 5507 additions and 2653 deletions

1
.gitignore vendored
View file

@ -247,3 +247,4 @@ build-aux/test-driver
/garbage-gen
/garbage-gen.exe
/grub-fs-tester
grub-core/build-grub-module-verifier

View file

@ -89,16 +89,21 @@ CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT)
if COND_STARFIELD
starfield_DATA = dejavu_10.pf2 dejavu_12.pf2 dejavu_bold_14.pf2 dejavu_14.pf2 dejavu_16.pf2 $(starfield_theme_files)
dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -s 10 -o $@ $(DJVU_FONT_SOURCE)
dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -s 12 -o $@ $(DJVU_FONT_SOURCE)
dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -s 14 -o $@ $(DJVU_FONT_SOURCE)
dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -b -s 14 -o $@ $(DJVU_FONT_SOURCE)
dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -s 16 -o $@ $(DJVU_FONT_SOURCE)
dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -s 10 -o $@ $(DJVU_FONT_SOURCE)
CLEANFILES += dejavu_10.pf2
dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -s 12 -o $@ $(DJVU_FONT_SOURCE)
CLEANFILES += dejavu_12.pf2
dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -s 14 -o $@ $(DJVU_FONT_SOURCE)
CLEANFILES += dejavu_14.pf2
dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -b -s 14 -o $@ $(DJVU_FONT_SOURCE)
CLEANFILES += dejavu_bold_14.pf2
dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -s 16 -o $@ $(DJVU_FONT_SOURCE)
CLEANFILES += dejavu_16.pf2
else
starfield_DATA =
endif
@ -106,28 +111,28 @@ endif
EXTRA_DIST += $(starfield_theme_files)
EXTRA_DIST += $(srcdir)/themes/starfield/src/slider_s.xcf $(srcdir)/themes/starfield/src/slider_n.xcf $(srcdir)/themes/starfield/src/slider_c.xcf $(srcdir)/themes/starfield/src/blob_nw.xcf $(srcdir)/themes/starfield/src/bootmenu/center.xcf $(srcdir)/themes/starfield/src/bootmenu/corner.xcf $(srcdir)/themes/starfield/src/bootmenu/side.xcf $(srcdir)/themes/starfield/src/terminalbox/side.xcf $(srcdir)/themes/starfield/src/terminalbox/corner.xcf $(srcdir)/themes/starfield/src/terminalbox/center.xcf
unicode.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
unicode.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
CLEANFILES += unicode.pf2
# Arrows and lines are needed to draw the menu, so always include them
UNICODE_ARROWS=0x2190-0x2193
UNICODE_LINES=0x2501-0x251B
ascii.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
ascii.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += ascii.pf2
euro.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
euro.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += euro.pf2
ascii.h: $(FONT_SOURCE) build-grub-gen-asciih
./build-grub-gen-asciih $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
ascii.h: $(FONT_SOURCE) build-grub-gen-asciih$(BUILD_EXEEXT)
./build-grub-gen-asciih$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += ascii.h
widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec
./build-grub-gen-widthspec $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec$(BUILD_EXEEXT)
./build-grub-gen-widthspec$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += widthspec.h
# Install config.h into platformdir
@ -340,33 +345,35 @@ bootcheck-ntldr: ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg grub-shell
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ntldr.bin=ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
if COND_i386_efi
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
# NetBSD has no support for finding ACPI on EFI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
endif
if COND_x86_64_efi
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
# NetBSD has no support for finding ACPI on EFI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
endif
if COND_i386_multiboot
# FreeBSD requires ACPI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64
# *BSD requires ACPI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64
endif
if COND_i386_qemu
# *BSD requires ACPI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64
endif
if COND_i386_coreboot
# Freebsd requires ACPI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64
endif
if COND_i386_qemu
# FreeBSD requires ACPI
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
endif
if COND_i386_pc
#pc chainloader by definition is only for i386-pc
#ntldr and bootmgr require BIOS.
#legacy protocol makes early BIOS calls.
# NetBSD crashes early on non-BIOS
#legacy protocol (linux16) makes early BIOS calls.
# 32-bit NetBSD crashes early on non-BIOS
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386 bootcheck-pc-chainloader bootcheck-ntldr bootcheck-linux16-i386 bootcheck-linux16-x86_64 bootcheck-knetbsd-i386
endif
@ -402,8 +409,9 @@ BOOTCHECK_TIMEOUT=180
bootcheck: $(BOOTCHECKS)
if COND_i386_coreboot
default_payload.elf: grub-mkstandalone grub-mkimage
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
default_payload.elf: grub-mkstandalone grub-mkimage FORCE
test -f $@ && rm $@ || true
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(shell cat grub-core/fs.lst) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
endif
endif

View file

@ -172,6 +172,8 @@ program = {
common = util/grub-mkimage.c;
common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
@ -414,7 +416,7 @@ program = {
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
data = {
@ -510,6 +512,8 @@ program = {
common = util/render-label.c;
common = util/glue-efi.c;
common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
@ -552,6 +556,8 @@ program = {
common = util/render-label.c;
common = util/glue-efi.c;
common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
@ -595,6 +601,8 @@ program = {
common = util/grub-install.c;
common = util/probe.c;
common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
@ -632,6 +640,8 @@ program = {
common = util/grub-mknetdir.c;
common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;

14
NEWS
View file

@ -18,6 +18,7 @@ New in 2.02:
* ZFS features support.
* ZFS LZ4 support.
* XFS V5 format support.
* LVM RAID1 support.
* New/improved terminal and video support:
* Monochrome text (matching `hercules' in GRUB Legacy).
@ -49,6 +50,9 @@ New in 2.02:
* Improve TFTP robustness.
* Parse `nd' disk names in GRUB Legacy configuration files.
* Issue separate DNS queries for IPv4 and IPv6.
* Support IPv6 Router Advertisement to configure default router.
* New variable net_<interface>_next_server containing next server
from BOOTP reply.
* Coreboot improvements:
* CBFS support both in on-disk images (loopback) and flash.
@ -96,6 +100,8 @@ New in 2.02:
EFI Stall. If everything fails, use hardcoded frequency 800MHz.
* Support Hyper-V Gen2 platforms which lack PIT for TSC calibration.
* Map UEFI Persistent Memory to E820 persistent memory.
* New Xen loader on ARM64.
* Respect alignment requirement for block device IO buffers on EFI.
* Security:
* Add optional facility to enforce that all files read by the core image
@ -134,6 +140,11 @@ New in 2.02:
menu entry immediately.
* New `file' command and grub-file utility to check file types.
* New syslinux configuration file parser.
* Set menu entry class to primary OS name returned by os-prober to display
OS specific icon.
* On Linux x86 detect EFI word size in grub-install and automatically select
correct platform (x86_64-efi or i386-efi) to install. Requires Linux kernel
4.0 or higher.
* Build system:
* Remove all uses of nested functions; GRUB no longer requires an
@ -160,6 +171,9 @@ New in 2.02:
* emu libusb support removed (was broken and unmaintained).
* powerpc64le compile support.
* Use fixed timestamp when generating GRUB image for reproducible builds.
* Verify at build time that modules contain only supported relocations and their
structure matches what boot-time module loader expects.
* Do not require fonts on powerpc-ieee1275.
* Revision control moved to git.

4
TODO
View file

@ -7,7 +7,3 @@ glance. So write to <grub-devel@gnu.org> first.
For bug tracking, refer to:
http://savannah.gnu.org/bugs/?group=grub
Our wiki also lists some areas that need work:
http://grub.enbug.org/

View file

@ -390,6 +390,24 @@ else
[fi]
])
dnl Check if the Linker supports `-no-pie'.
AC_DEFUN([grub_CHECK_NO_PIE],
[AC_MSG_CHECKING([whether linker accepts -no-pie])
AC_CACHE_VAL(grub_cv_cc_ld_no_pie,
[save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -no-pie"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_ld_no_pie=yes],
[grub_cv_cc_ld_no_pie=no])
LDFLAGS="$save_LDFLAGS"
])
AC_MSG_RESULT([$grub_cv_cc_ld_no_pie])
nopie_possible=no
if test "x$grub_cv_cc_ld_no_pie" = xyes ; then
nopie_possible=yes
fi
])
dnl Check if the C compiler supports `-fPIC'.
AC_DEFUN([grub_CHECK_PIC],[
[# Position independent executable.

View file

@ -1,12 +1,16 @@
/* on x86 old clang doesn't support .code16
newer clang supports it but creates 6-byte jumps instead of 3-byte ones
which makes us go over boot sector size. */
which makes us go over boot sector size.
Starting with 3.9 clang emits 3-byte jumps but still creates 8-bytes movl
instead of 5-bytes, so code overflows into data. */
.code16
jmp far
.org 4
jmp nearer
.org 6
movl nearer, %ebx
.org 11
.space 100
nearer:
.space 200

View file

@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC)
CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags
STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx
CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d

View file

@ -50,8 +50,13 @@ EXTRA_DIST += util/import_gcrypth.sed
EXTRA_DIST += util/bin2h.c
EXTRA_DIST += util/grub-gen-asciih.c
EXTRA_DIST += util/grub-gen-widthspec.c
EXTRA_DIST += util/grub-module-verifier.c
EXTRA_DIST += util/grub-module-verifier32.c
EXTRA_DIST += util/grub-module-verifier64.c
EXTRA_DIST += util/grub-module-verifierXX.c
EXTRA_DIST += util/grub-pe2elf.c
EXTRA_DIST += m4/gnulib-cache.m4
EXTRA_DIST += m4/glibc2.m4
EXTRA_DIST += m4/gnulib-tool.m4

View file

@ -31,7 +31,7 @@ dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
dnl used for the target type. See INSTALL for full list of variables.
AC_INIT([GRUB],[2.02~beta2],[bug-grub@gnu.org])
AC_INIT([GRUB],[2.02~beta3],[bug-grub@gnu.org])
AC_CONFIG_AUX_DIR([build-aux])
@ -388,7 +388,15 @@ fi
# Check for functions and headers.
AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h sys/mkdev.h limits.h)
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation
# warning which causes compilation failure later with -Werror. So use -Werror here
# as well to force proper sys/sysmacros.h detection.
SAVED_CFLAGS="$CFLAGS"
CFLAGS="$HOST_CFLAGS -Werror"
AC_HEADER_MAJOR
CFLAGS="$SAVED_CFLAGS"
AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
#include <sys/param.h>
@ -910,12 +918,24 @@ if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xy
TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions"
fi
AC_CACHE_CHECK([whether -mno-stack-arg-probe works], [grub_cv_cc_mno_stack_arg_probe], [
CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_mno_stack_arg_probe=yes],
[grub_cv_cc_mno_stack_arg_probe=no])
])
if test "x$grub_cv_cc_mno_stack_arg_probe" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
fi
# By default, GCC 4.6 generates .eh_frame sections containing unwind
# information in some cases where it previously did not. GRUB doesn't need
# these and they just use up vital space. Restore the old compiler
# behaviour.
AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [
CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_fno_asynchronous_unwind_tables=yes],
[grub_cv_cc_fno_asynchronous_unwind_tables=no])
@ -925,66 +945,17 @@ if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
fi
AC_ARG_ENABLE([efiemu],
[AS_HELP_STRING([--enable-efiemu],
[build and install the efiemu runtimes (default=guessed)])])
if test x"$enable_efiemu" = xno ; then
efiemu_excuse="explicitly disabled"
AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [
CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_fno_unwind_tables=yes],
[grub_cv_cc_fno_unwind_tables=no])
])
if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
fi
if test x"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then
efiemu_excuse="not available on cygwin"
fi
if test x"$target_cpu" != xi386 ; then
efiemu_excuse="only available on i386"
fi
if test x"$platform" = xefi ; then
efiemu_excuse="not available on efi"
fi
if test x"$efiemu_excuse" = x ; then
AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_efiemu=yes],
[grub_cv_cc_efiemu=no])
])
if test x$grub_cv_cc_efiemu = xno; then
efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
fi
fi
if test x"$efiemu_excuse" = x ; then
AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [
grub_cv_target_cc_efiemu64_link_format=unknown
for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do
CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
LDFLAGS="-m64 -Wl,$format -nostdlib -static"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
]], [[]])], [flag=1], [flag=0])
if test x"$flag" = x1; then
grub_cv_target_cc_efiemu64_link_format="$format"
break
fi
done])
if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then
efiemu_excuse="no suitable link format for efiemu64 found"
else
EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format"
fi
fi
if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled ($efiemu_excuse)])
fi
if test x"$efiemu_excuse" = x ; then
enable_efiemu=yes
else
enable_efiemu=no
fi
AC_SUBST([enable_efiemu])
AC_SUBST([EFIEMU64_LINK_FORMAT])
CFLAGS="$TARGET_CFLAGS"
@ -1078,6 +1049,73 @@ else
TARGET_IMG_CFLAGS=
fi
CFLAGS="$TARGET_CFLAGS"
AC_ARG_ENABLE([efiemu],
[AS_HELP_STRING([--enable-efiemu],
[build and install the efiemu runtimes (default=guessed)])])
if test x"$enable_efiemu" = xno ; then
efiemu_excuse="explicitly disabled"
fi
if test x"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then
efiemu_excuse="not available on cygwin"
fi
if test x"$target_cpu" != xi386 ; then
efiemu_excuse="only available on i386"
fi
if test x"$platform" = xefi ; then
efiemu_excuse="not available on efi"
fi
if test x"$efiemu_excuse" = x ; then
AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_efiemu=yes],
[grub_cv_cc_efiemu=no])
])
if test x$grub_cv_cc_efiemu = xno; then
efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
fi
fi
if test x"$efiemu_excuse" = x ; then
AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [
grub_cv_target_cc_efiemu64_link_format=unknown
for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do
CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
LDFLAGS="-m64 -Wl,$format -nostdlib -static"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
]], [[]])], [flag=1], [flag=0])
if test x"$flag" = x1; then
grub_cv_target_cc_efiemu64_link_format="$format"
break
fi
done])
if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then
efiemu_excuse="no suitable link format for efiemu64 found"
else
EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format"
fi
fi
if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled ($efiemu_excuse)])
fi
if test x"$efiemu_excuse" = x ; then
enable_efiemu=yes
else
enable_efiemu=no
fi
AC_SUBST([enable_efiemu])
AC_SUBST([EFIEMU64_LINK_FORMAT])
CFLAGS="$TARGET_CFLAGS"
AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
@ -1154,13 +1192,18 @@ CFLAGS="$TARGET_CFLAGS"
# Position independent executable.
grub_CHECK_PIE
grub_CHECK_NO_PIE
[# Need that, because some distributions ship compilers that include
# `-fPIE' in the default specs.
# `-fPIE' or '-fpie' and '-pie' in the default specs.
if [ x"$pie_possible" = xyes ]; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
fi
if [ x"$nopie_possible" = xyes ] && [ x"$pie_possible" = xyes ]; then
TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie"
fi]
CFLAGS="$TARGET_CFLAGS"
LDFLAGS="$TARGET_LDFLAGS"
# Position independent executable.
grub_CHECK_PIC
@ -1524,11 +1567,11 @@ if test x"$grub_build_mkfont_excuse" = x ; then
else
enable_build_grub_mkfont=no
fi
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
if test x"$grub_build_mkfont_excuse" = x ; then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont])
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont])
else
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont ($grub_build_mkfont_excuse)])
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)])
fi
fi
@ -1598,11 +1641,11 @@ if test x"$enable_build_grub_mkfont" = xno ; then
FONT_SOURCE=
fi
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
if test x"$grub_build_mkfont_excuse" = x ; then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont])
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont])
else
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
fi
fi

View file

@ -2446,6 +2446,10 @@ The boot file name provided by DHCP. Read-only.
The name of the DHCP server responsible for these boot parameters.
Read-only.
@item net_@var{<interface>}_next_server
The IP address of the next (usually, TFTP) server provided by DHCP.
Read-only.
@item net_default_interface
Initially set to name of network interface that was used to load grub.
Read-write, although setting it affects only interpretation of
@ -2538,6 +2542,8 @@ team are:
85:3
@item Asus EeePC 1005PE
84:1 (unconfirmed)
@item LENOVO ThinkPad T410s (2912W1C)
101:3
@end table
To take full advantage of this function, install GRUB into the MBR
@ -3060,6 +3066,7 @@ These variables have special meaning to GRUB.
* net_@var{<interface>}_hostname::
* net_@var{<interface>}_ip::
* net_@var{<interface>}_mac::
* net_@var{<interface>}_next_server::
* net_@var{<interface>}_rootpath::
* net_default_interface::
* net_default_ip::
@ -3420,6 +3427,12 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
@xref{Network}.
@node net_@var{<interface>}_next_server
@subsection net_@var{<interface>}_next_server
@xref{Network}.
@node net_@var{<interface>}_rootpath
@subsection net_@var{<interface>}_rootpath
@ -4074,12 +4087,15 @@ after @command{configfile} returns.
@node cpuid
@subsection cpuid
@deffn Command cpuid [-l]
@deffn Command cpuid [-l] [-p]
Check for CPU features. This command is only available on x86 systems.
With the @option{-l} option, return true if the CPU supports long mode
(64-bit).
With the @option{-p} option, return true if the CPU supports Physical
Address Extension (PAE).
If invoked without options, this command currently behaves as if it had been
invoked with @option{-l}. This may change in the future.
@end deffn
@ -5111,6 +5127,8 @@ the length of @var{string} is zero
@var{expression} is false
@item @var{expression1} @code{-a} @var{expression2}
both @var{expression1} and @var{expression2} are true
@item @var{expression1} @var{expression2}
both @var{expression1} and @var{expression2} are true. This syntax is not POSIX-compliant and is not recommended.
@item @var{expression1} @code{-o} @var{expression2}
either @var{expression1} or @var{expression2} is true
@end table

View file

@ -729,9 +729,11 @@ def kernel(defn, platform):
"""if test x$(TARGET_APPLE_LINKER) = x1; then \
$(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \
$(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \
rm -f $@.bin; \
elif test ! -z '$(TARGET_OBJ2ELF)'; then \
""" + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \
$(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \
rm -f $@.bin; \
else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \
fi"""))
@ -759,7 +761,7 @@ def image(defn, platform):
if test x$(TARGET_APPLE_LINKER) = x1; then \
$(MACHO2IMG) $< $@; \
else \
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \
fi
""")

View file

@ -39,6 +39,10 @@ gentrigtables$(BUILD_EXEEXT): gentrigtables.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM)
CLEANFILES += gentrigtables$(BUILD_EXEEXT)
build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^
CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT)
# trigtables.c
trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac
./gentrigtables$(BUILD_EXEEXT) > $@
@ -104,6 +108,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
endif
if COND_i386_coreboot
@ -159,6 +164,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
endif
if COND_ia64_efi
@ -391,7 +397,7 @@ moddep.lst: syminfo.lst genmoddep.awk video.lst
platform_DATA += 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) build-grub-module-verifier$(BUILD_EXEEXT)
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
platform_DATA += $(MOD_FILES)
platform_DATA += modinfo.sh

View file

@ -90,7 +90,7 @@ kernel = {
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
emu_cflags = '$(CFLAGS_GNULIB)';
emu_cppflags = '$(CPPFLAGS_GNULIB)';
arm_uboot_ldflags = '-Wl,-Ttext=0x08000000';
arm_uboot_ldflags = '-Wl,-r,-d';
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_startup = kern/i386/pc/startup.S;
@ -214,8 +214,10 @@ kernel = {
arm_efi = kern/arm/efi/init.c;
arm_efi = kern/arm/efi/misc.c;
arm_efi = kern/efi/fdt.c;
arm64_efi = kern/arm/efi/init.c;
arm64_efi = kern/arm64/efi/init.c;
arm64_efi = kern/efi/fdt.c;
i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c;
@ -1585,6 +1587,7 @@ module = {
i386_xen = lib/i386/xen/relocator.S;
x86_64_xen = lib/x86_64/xen/relocator.S;
xen = lib/i386/relocator_common_c.c;
x86_64_efi = lib/x86_64/efi/relocator.c;
extra_dist = lib/i386/relocator_common.S;
extra_dist = kern/powerpc/cache_flush.S;
@ -1739,7 +1742,32 @@ module = {
x86 = loader/i386/xnu.c;
x86 = loader/xnu.c;
enable = x86;
/* Code is pretty generic but relies on RNG which
is available only on few platforms. It's not a
big deal as xnu needs ACPI anyway and we have
RNG on all platforms with ACPI.
*/
enable = i386_multiboot;
enable = i386_coreboot;
enable = i386_pc;
enable = i386_efi;
enable = x86_64_efi;
};
module = {
name = random;
x86 = lib/i386/random.c;
common = lib/random.c;
i386_multiboot = kern/i386/tsc_pmtimer.c;
i386_coreboot = kern/i386/tsc_pmtimer.c;
i386_pc = kern/i386/tsc_pmtimer.c;
enable = i386_multiboot;
enable = i386_coreboot;
enable = i386_pc;
enable = i386_efi;
enable = x86_64_efi;
};
module = {

View file

@ -29,6 +29,7 @@
#include <grub/loader.h>
#include <grub/cs5536.h>
#include <grub/disk.h>
#include <grub/cache.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -337,6 +338,21 @@ struct grub_ehci
static struct grub_ehci *ehci;
static void
sync_all_caches (struct grub_ehci *e)
{
if (!e)
return;
if (e->td_virt)
grub_arch_sync_dma_caches (e->td_virt, sizeof (struct grub_ehci_td) *
GRUB_EHCI_N_TD);
if (e->qh_virt)
grub_arch_sync_dma_caches (e->qh_virt, sizeof (struct grub_ehci_qh) *
GRUB_EHCI_N_QH);
if (e->framelist_virt)
grub_arch_sync_dma_caches (e->framelist_virt, 4096);
}
/* EHCC registers access functions */
static inline grub_uint32_t
grub_ehci_ehcc_read32 (struct grub_ehci *e, grub_uint32_t addr)
@ -437,6 +453,8 @@ grub_ehci_reset (struct grub_ehci *e)
{
grub_uint64_t maxtime;
sync_all_caches (e);
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
GRUB_EHCI_CMD_HC_RESET
| grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
@ -840,6 +858,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
e->next = ehci;
ehci = e;
sync_all_caches (e);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n");
grub_dprintf ("ehci",
@ -1020,6 +1040,7 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer)
/* Found proper existing (and linked) QH, do setup of QH */
grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter);
grub_ehci_setup_qh (qh_iter, transfer);
sync_all_caches (e);
return qh_iter;
}
@ -1121,7 +1142,7 @@ grub_ehci_free_tds (struct grub_ehci *e, grub_ehci_td_t td,
token = grub_le_to_cpu32 (td->token);
to_transfer = (token & GRUB_EHCI_TOTAL_MASK) >> GRUB_EHCI_TOTAL_OFF;
/* Check state of TD - if it did not transfered
/* Check state of TD - if it did not transfer
* whole data then set last_trans - it should be last executed TD
* in case when something went wrong. */
if (transfer && (td->size != to_transfer))
@ -1289,16 +1310,28 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
grub_ehci_td_t td_prev = NULL;
int i;
struct grub_ehci_transfer_controller_data *cdata;
grub_uint32_t status;
sync_all_caches (e);
/* Check if EHCI is running and AL is enabled */
if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
& GRUB_EHCI_ST_HC_HALTED) != 0)
status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
if ((status & GRUB_EHCI_ST_HC_HALTED) != 0)
/* XXX: Fix it: Currently we don't do anything to restart EHCI */
return GRUB_USB_ERR_INTERNAL;
if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
{
grub_dprintf ("ehci", "setup_transfer: halted, status = 0x%x\n",
status);
return GRUB_USB_ERR_INTERNAL;
}
status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
if ((status
& (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)
/* XXX: Fix it: Currently we don't do anything to restart EHCI */
return GRUB_USB_ERR_INTERNAL;
{
grub_dprintf ("ehci", "setup_transfer: no AS/PS, status = 0x%x\n",
status);
return GRUB_USB_ERR_INTERNAL;
}
/* Allocate memory for controller transfer data. */
cdata = grub_malloc (sizeof (*cdata));
@ -1310,6 +1343,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
cdata->qh_virt = grub_ehci_find_qh (e, transfer);
if (!cdata->qh_virt)
{
grub_dprintf ("ehci", "setup_transfer: no QH\n");
grub_free (cdata);
return GRUB_USB_ERR_INTERNAL;
}
@ -1319,6 +1353,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
cdata->td_alt_virt = grub_ehci_alloc_td (e);
if (!cdata->td_alt_virt)
{
grub_dprintf ("ehci", "setup_transfer: no TDs\n");
grub_free (cdata);
return GRUB_USB_ERR_INTERNAL;
}
@ -1345,6 +1380,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
grub_ehci_free_tds (e, cdata->td_first_virt, NULL, &actual);
grub_free (cdata);
grub_dprintf ("ehci", "setup_transfer: no TD\n");
return GRUB_USB_ERR_INTERNAL;
}
@ -1386,6 +1422,8 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
* i.e. reset token */
cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0);
sync_all_caches (e);
/* Finito */
transfer->controller_data = cdata;
@ -1434,6 +1472,8 @@ grub_ehci_parse_notrun (grub_usb_controller_t dev,
grub_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata);
sync_all_caches (e);
/* Additionally, do something with EHCI to make it running (what?) */
/* Try enable EHCI and AL */
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
@ -1469,6 +1509,8 @@ grub_ehci_parse_halt (grub_usb_controller_t dev,
grub_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata);
sync_all_caches (e);
/* Evaluation of error code - currently we don't have GRUB USB error
* codes for some EHCI states, GRUB_USB_ERR_DATA is used for them.
* Order of evaluation is critical, specially bubble/stall. */
@ -1502,6 +1544,8 @@ grub_ehci_parse_success (grub_usb_controller_t dev,
grub_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata);
sync_all_caches (e);
return GRUB_USB_ERR_NONE;
}
@ -1515,6 +1559,8 @@ grub_ehci_check_transfer (grub_usb_controller_t dev,
transfer->controller_data;
grub_uint32_t token, token_ftd;
sync_all_caches (e);
grub_dprintf ("ehci",
"check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS),
@ -1581,6 +1627,9 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
int i;
grub_uint64_t maxtime;
grub_uint32_t qh_phys;
sync_all_caches (e);
grub_uint32_t interrupt =
cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK;
@ -1600,6 +1649,7 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual);
grub_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata);
sync_all_caches (e);
grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n");
return GRUB_USB_ERR_NONE;
}
@ -1622,6 +1672,8 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
/* Unlink QH from AL */
e->qh_virt[i].qh_hptr = cdata->qh_virt->qh_hptr;
sync_all_caches (e);
/* If this is an interrupt transfer, we just wait for the periodic
* schedule to advance a few times and then assume that the EHCI
* controller has read the updated QH. */
@ -1676,6 +1728,8 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
grub_dprintf ("ehci", "cancel_transfer: end\n");
sync_all_caches (e);
return GRUB_USB_ERR_NONE;
}
@ -1777,11 +1831,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
status = grub_ehci_port_read (e, port);
grub_dprintf ("ehci", "detect_dev: EHCI STATUS: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
grub_dprintf ("ehci", "detect_dev: iobase=%p, port=%d, status=0x%02x\n",
e->iobase, port, status);
/* Connect Status Change bit - it detects change of connection */
if (status & GRUB_EHCI_PORT_CONNECT_CH)
{

View file

@ -24,6 +24,7 @@
#include <grub/usb.h>
#include <grub/usbtrans.h>
#include <grub/time.h>
#include <grub/cache.h>
static inline unsigned int
@ -101,6 +102,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
data_addr = grub_dma_get_phys (data_chunk);
grub_memcpy ((char *) data, data_in, size);
grub_arch_sync_dma_caches (data, size);
grub_dprintf ("usb",
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n",
reqtype, request, value, index, (unsigned long)size);
@ -161,6 +164,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
setupdata->value = value;
setupdata->index = index;
setupdata->length = size;
grub_arch_sync_dma_caches (setupdata, sizeof (*setupdata));
transfer->transactions[0].size = sizeof (*setupdata);
transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
transfer->transactions[0].data = setupdata_addr;
@ -202,11 +207,13 @@ grub_usb_control_msg (grub_usb_device_t dev,
grub_free (transfer->transactions);
grub_free (transfer);
grub_dma_free (data_chunk);
grub_dma_free (setupdata_chunk);
grub_arch_sync_dma_caches (data, size0);
grub_memcpy (data_in, (char *) data, size0);
grub_dma_free (data_chunk);
return err;
}
@ -236,7 +243,10 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
grub_memcpy ((char *) data, data_in, size);
{
grub_memcpy ((char *) data, data_in, size);
grub_arch_sync_dma_caches (data, size);
}
/* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer));
@ -306,9 +316,13 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
dev->toggle[transfer->endpoint] = toggle;
if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN)
grub_memcpy (transfer->data, (void *)
grub_dma_get_virt (transfer->data_chunk),
transfer->size + 1);
{
grub_arch_sync_dma_caches (grub_dma_get_virt (transfer->data_chunk),
transfer->size + 1);
grub_memcpy (transfer->data, (void *)
grub_dma_get_virt (transfer->data_chunk),
transfer->size + 1);
}
grub_free (transfer->transactions);
grub_dma_free (transfer->data_chunk);

View file

@ -593,6 +593,9 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
if (! table->addr)
{
free_tables ();
grub_free (exclude);
grub_free (load_only);
grub_free (table);
return grub_errno;
}
table->next = acpi_tables;

View file

@ -26,6 +26,8 @@
#define grub_dprintf(cond, args...) printf ( args )
#define grub_printf printf
#define grub_util_fopen fopen
#define grub_memcmp memcmp
typedef uint64_t grub_uint64_t;
typedef uint32_t grub_uint32_t;
typedef uint16_t grub_uint16_t;
@ -246,6 +248,7 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
if (!add)
return -1;
break;
case GRUB_ACPI_OPCODE_CREATE_DWORD_FIELD:
case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
{

View file

@ -140,10 +140,13 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
}
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
for (j = 0; j < utcount; j++)
grub_printf ("<%x>", (unsigned int) utbuf[j]);
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
if (utcount)
{
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
for (j = 0; j < utcount; j++)
grub_printf ("<%x>", (unsigned int) utbuf[j]);
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
}
grub_xputs ("\n");
grub_refresh ();

View file

@ -45,7 +45,7 @@ static grub_err_t
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int byte, bit;
int byte = 0, bit = 0;
grub_err_t err;
grub_uint8_t value;
@ -67,7 +67,7 @@ static grub_err_t
grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int byte, bit;
int byte = 0, bit = 0;
grub_err_t err;
grub_uint8_t value;
@ -85,7 +85,7 @@ static grub_err_t
grub_cmd_cmosset (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int byte, bit;
int byte = 0, bit = 0;
grub_err_t err;
grub_uint8_t value;

View file

@ -253,6 +253,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
struct grub_command *cmd;
char **cutargs;
int cutargc;
grub_err_t err = GRUB_ERR_NONE;
for (i = 0; i < 2; i++)
{
@ -314,6 +315,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
if (!cutargs)
return grub_errno;
cutargc = argc - 1;
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
cutargs[0] = args[0];
@ -333,7 +336,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, cutargc, cutargs))
{
kernel_type = LINUX;
return GRUB_ERR_NONE;
goto out;
}
}
grub_errno = GRUB_ERR_NONE;
@ -348,7 +351,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, argc, args))
{
kernel_type = MULTIBOOT;
return GRUB_ERR_NONE;
goto out;
}
}
grub_errno = GRUB_ERR_NONE;
@ -413,7 +416,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, cutargc, cutargs))
{
kernel_type = KFREEBSD;
return GRUB_ERR_NONE;
goto out;
}
}
grub_errno = GRUB_ERR_NONE;
@ -422,6 +425,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
char **bsdargs;
int bsdargc;
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
int found = 0;
if (bsd_device == -1)
{
bsdargs = cutargs;
@ -432,6 +437,11 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
char rbuf[3] = "-r";
bsdargc = cutargc + 2;
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
if (!bsdargs)
{
err = grub_errno;
goto out;
}
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
bsdargs[argc] = rbuf;
bsdargs[argc + 1] = bsddevname;
@ -447,7 +457,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, bsdargc, bsdargs))
{
kernel_type = KNETBSD;
return GRUB_ERR_NONE;
found = 1;
goto free_bsdargs;
}
}
grub_errno = GRUB_ERR_NONE;
@ -460,20 +471,28 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, bsdargc, bsdargs))
{
kernel_type = KOPENBSD;
return GRUB_ERR_NONE;
found = 1;
goto free_bsdargs;
}
}
grub_errno = GRUB_ERR_NONE;
}
free_bsdargs:
if (bsdargs != cutargs)
grub_free (bsdargs);
if (found)
goto out;
}
}
}
while (0);
return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
args[0]);
err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
args[0]);
out:
grub_free (cutargs);
return err;
}
static grub_err_t
@ -534,15 +553,17 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
char **newargs;
grub_err_t err;
char nounzipbuf[10] = "--nounzip";
cmd = grub_command_find ("module");
if (!cmd)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
"module");
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
if (!newargs)
return grub_errno;
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
newargs[0] = nounzipbuf;
cmd = grub_command_find ("module");
if (!cmd)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
"module");
err = cmd->func (cmd, argc + 1, newargs);
grub_free (newargs);

View file

@ -198,7 +198,10 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
if (get_uuid (NULL, &uuid_root, 0))
return grub_errno;
{
grub_free (mods);
return grub_errno;
}
prefdev = grub_file_get_device_name (prefix);
if (grub_errno)
@ -210,6 +213,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
if (get_uuid (prefdev, &uuid_prefix, 0))
{
grub_free (uuid_root);
grub_free (prefdev);
grub_free (mods);
return grub_errno;
}
@ -289,12 +294,15 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
}
grub_free (uuid_root);
grub_free (uuid_prefix);
grub_free (prefdev);
grub_free (mods);
return GRUB_ERR_NONE;
fail:
grub_free (uuid_root);
grub_free (uuid_prefix);
grub_free (prefdev);
for (i = 0; i < mods_loaded; i++)
if (mods[i])
@ -302,6 +310,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
mods[i]->fini = 0;
grub_dl_unload (mods[i]);
}
grub_free (mods);
return grub_errno;
}

View file

@ -283,6 +283,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
}
if (! cur)
{
grub_free (parsed);
grub_device_close (dev);
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"),
args[i]);

View file

@ -45,6 +45,7 @@ check_password (const char *user, const char *entered, void *pin)
grub_uint8_t *buf;
struct pbkdf2_password *pass = pin;
gcry_err_code_t err;
grub_err_t ret;
buf = grub_malloc (pass->buflen);
if (!buf)
@ -55,17 +56,17 @@ check_password (const char *user, const char *entered, void *pin)
pass->salt, pass->saltlen, pass->c,
buf, pass->buflen);
if (err)
ret = grub_crypto_gcry_error (err);
else if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
ret = GRUB_ACCESS_DENIED;
else
{
grub_free (buf);
return grub_crypto_gcry_error (err);
grub_auth_authenticate (user);
ret = GRUB_ERR_NONE;
}
if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
return GRUB_ACCESS_DENIED;
grub_auth_authenticate (user);
return GRUB_ERR_NONE;
grub_free (buf);
return ret;
}
static inline int

View file

@ -68,7 +68,7 @@ iterate_device (const char *name, void *data)
/* Skip floppy drives when requested. */
if (ctx->no_floppy &&
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
return 0;
return 1;
#if defined(DO_SEARCH_FS_UUID) || defined(DO_SEARCH_DISK_UUID)
#define compare_fn grub_strcasecmp

View file

@ -338,19 +338,19 @@ grub_load_public_key (grub_file_t f)
if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
goto fail;
break;
}
lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
goto fail;
break;
}
if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
goto fail;
break;
}
grub_memcpy (buffer, &l, sizeof (l));
@ -360,10 +360,16 @@ grub_load_public_key (grub_file_t f)
buffer, lb + sizeof (grub_uint16_t), 0))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
goto fail;
break;
}
}
if (i < pkalgos[pk].nmpipub)
{
grub_free (sk);
goto fail;
}
GRUB_MD_SHA1->final (fingerprint_context);
grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);

View file

@ -32,7 +32,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
struct grub_ahci_cmd_head
{
grub_uint32_t config;
grub_uint32_t transfered;
grub_uint32_t transferred;
grub_uint64_t command_table_base;
grub_uint32_t unused[4];
};
@ -954,7 +954,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
grub_dprintf ("ahci", "AHCI tfd = %x\n",
dev->hba->ports[dev->port].task_file_data);
dev->command_list[0].transfered = 0;
dev->command_list[0].transferred = 0;
dev->command_list[0].command_table_base
= grub_dma_get_phys (dev->command_table_chunk);
@ -1044,7 +1044,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
dev->hba->ports[dev->port].command_issue,
dev->hba->ports[dev->port].intstatus,
dev->hba->ports[dev->port].task_file_data,
dev->command_list[0].transfered,
dev->command_list[0].transferred,
dev->hba->ports[dev->port].sata_error,
((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x00],
((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]);

View file

@ -85,6 +85,12 @@ make_devices (void)
{
/* Uggh. */
grub_free (handles);
while (devices)
{
d = devices->next;
grub_free (devices);
devices = d;
}
return 0;
}
@ -487,8 +493,15 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
m = d->block_io->media;
/* FIXME: Probably it is better to store the block size in the disk,
and total sectors should be replaced with total blocks. */
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
m, (unsigned long long) m->last_block, m->block_size);
grub_dprintf ("efidisk",
"m = %p, last block = %llx, block size = %x, io align = %x\n",
m, (unsigned long long) m->last_block, m->block_size,
m->io_align);
/* Ensure required buffer alignment is a power of two (or is zero). */
if (m->io_align & (m->io_align - 1))
return grub_error (GRUB_ERR_IO, "invalid buffer alignment %d", m->io_align);
disk->total_sectors = m->last_block + 1;
/* Don't increase this value due to bug in some EFI. */
disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
@ -518,15 +531,42 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector,
{
struct grub_efidisk_data *d;
grub_efi_block_io_t *bio;
grub_efi_status_t status;
grub_size_t io_align, num_bytes;
char *aligned_buf;
d = disk->data;
bio = d->block_io;
return efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
bio->media->media_id,
(grub_efi_uint64_t) sector,
(grub_efi_uintn_t) size << disk->log_sector_size,
buf);
/* Set alignment to 1 if 0 specified */
io_align = bio->media->io_align ? bio->media->io_align : 1;
num_bytes = size << disk->log_sector_size;
if ((grub_addr_t) buf & (io_align - 1))
{
aligned_buf = grub_memalign (io_align, num_bytes);
if (! aligned_buf)
return GRUB_EFI_OUT_OF_RESOURCES;
if (wr)
grub_memcpy (aligned_buf, buf, num_bytes);
}
else
{
aligned_buf = buf;
}
status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
bio->media->media_id, (grub_efi_uint64_t) sector,
(grub_efi_uintn_t) num_bytes, aligned_buf);
if ((grub_addr_t) buf & (io_align - 1))
{
if (!wr)
grub_memcpy (buf, aligned_buf, num_bytes);
grub_free (aligned_buf);
}
return status;
}
static grub_err_t
@ -541,7 +581,9 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
status = grub_efidisk_readwrite (disk, sector, size, buf, 0);
if (status != GRUB_EFI_SUCCESS)
if (status == GRUB_EFI_NO_MEDIA)
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
else if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR,
N_("failure reading sector 0x%llx from `%s'"),
(unsigned long long) sector,
@ -562,7 +604,9 @@ grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
status = grub_efidisk_readwrite (disk, sector, size, (char *) buf, 1);
if (status != GRUB_EFI_SUCCESS)
if (status == GRUB_EFI_NO_MEDIA)
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
else if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_WRITE_ERROR,
N_("failure writing sector 0x%llx to `%s'"),
(unsigned long long) sector, disk->name);

View file

@ -154,7 +154,10 @@ grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
: GRUB_EFI_RUNTIME_SERVICES_DATA);
if (seg->handle < 0)
return grub_errno;
{
grub_free (seg);
return grub_errno;
}
seg->off = 0;
}
@ -343,7 +346,7 @@ SUFFIX (grub_efiemu_loadcore_init) (void *core, const char *filename,
return grub_error (GRUB_ERR_BAD_MODULE, N_("this ELF file is not of the right type"));
/* Make sure that every section is within the core. */
if ((grub_size_t) core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
if ((grub_size_t) core_size < e->e_shoff + (grub_uint32_t) e->e_shentsize * e->e_shnum)
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
filename);

View file

@ -196,7 +196,7 @@ grub_efiemu_load_file (const char *filename)
{
grub_file_close (file);
grub_efiemu_unload ();
return grub_errno;
return err;
}
grub_dprintf ("efiemu", "mm initialized\n");

View file

@ -99,7 +99,8 @@ grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
grub_size_t align_overhead;
struct grub_efiemu_memrequest *ret, *cur, *prev;
/* Check that the request is correct */
if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
if (type <= GRUB_EFI_LOADER_CODE || type == GRUB_EFI_PERSISTENT_MEMORY ||
type >= GRUB_EFI_MAX_MEMORY_TYPE)
return -2;
/* Add new size to requested size */
@ -166,6 +167,13 @@ efiemu_alloc_requests (void)
GRUB_EFI_MEMORY_MAPPED_IO,
GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
GRUB_EFI_PAL_CODE
/*
* These are not allocatable:
* GRUB_EFI_RESERVED_MEMORY_TYPE
* GRUB_EFI_PERSISTENT_MEMORY
* >= GRUB_EFI_MAX_MEMORY_TYPE
*/
};
/* Compute total memory needed */
@ -402,6 +410,10 @@ fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_ACPI_MEMORY_NVS);
case GRUB_MEMORY_PERSISTENT:
case GRUB_MEMORY_PERSISTENT_LEGACY:
return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_PERSISTENT_MEMORY);
default:
grub_dprintf ("efiemu",
"Unknown memory type %d. Assuming unusable\n", type);
@ -445,7 +457,7 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
case GRUB_EFI_MEMORY_MAPPED_IO:
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case GRUB_EFI_PAL_CODE:
case GRUB_EFI_MAX_MEMORY_TYPE:
default:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_MEMORY_RESERVED, hook_data);
break;
@ -468,6 +480,12 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_MEMORY_NVS, hook_data);
break;
case GRUB_EFI_PERSISTENT_MEMORY:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_MEMORY_PERSISTENT, hook_data);
break;
}
return 0;
@ -503,7 +521,8 @@ grub_efiemu_mmap_sort_and_uniq (void)
[GRUB_EFI_ACPI_MEMORY_NVS] = 3,
[GRUB_EFI_MEMORY_MAPPED_IO] = 4,
[GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
[GRUB_EFI_PAL_CODE] = 4
[GRUB_EFI_PAL_CODE] = 4,
[GRUB_EFI_PERSISTENT_MEMORY] = 4
};
int i, j, k, done;

View file

@ -83,10 +83,16 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
/* Put pointer to the list of configuration tables in system table */
grub_efiemu_write_value
(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
conftable_handle, 0, 1,
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
err = grub_efiemu_write_value
(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
conftable_handle, 0, 1,
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
if (err)
{
grub_efiemu_unload ();
return err;
}
SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
/* Fill the list of configuration tables */

View file

@ -681,7 +681,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
ctxt->dir.file_size
= grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
ctxt->dir.have_stream = 1;
ctxt->dir.is_contiguous = !!(dir.type_specific.stream_extension.flags
ctxt->dir.is_contiguous = !!(sec.type_specific.stream_extension.flags
& grub_cpu_to_le16_compile_time (FLAG_CONTIGUOUS));
break;
case 0xc1:

View file

@ -1308,6 +1308,7 @@ grub_hfs_open (struct grub_file *file, const char *name)
if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG))
{
grub_free (data);
grub_free (found);
grub_dl_unref (my_mod);
return grub_errno;
}

View file

@ -750,19 +750,15 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
if (dir->data->joliet && !ctx.filename)
{
char *oldname, *semicolon;
char *semicolon;
oldname = name;
ctx.filename = grub_iso9660_convert_string
((grub_uint8_t *) oldname, dirent.namelen >> 1);
((grub_uint8_t *) name, dirent.namelen >> 1);
semicolon = grub_strrchr (ctx.filename, ';');
if (semicolon)
*semicolon = '\0';
if (ctx.filename_alloc)
grub_free (oldname);
ctx.filename_alloc = 1;
}

View file

@ -104,7 +104,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest)
if (tag & 1)
{
grub_uint32_t i, len, delta, code, lmask, dshift;
grub_uint16_t word;
grub_uint16_t word = 0;
if (decomp_get16 (cc, &word))
return grub_errno;

View file

@ -76,8 +76,13 @@ GRUB_MOD_LICENSE ("GPLv3+");
/* incompat feature flags */
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
/* We do not currently verify metadata UUID so it is safe to read such filesystem */
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
(XFS_SB_FEAT_INCOMPAT_FTYPE)
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
XFS_SB_FEAT_INCOMPAT_META_UUID)
struct grub_xfs_sblock
{
@ -775,7 +780,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
c = de->name[de->len];
de->name[de->len] = '\0';
if (iterate_dir_call_hook (ino, de->name, &ctx))
return 1;
{
de->name[de->len] = c;
return 1;
}
de->name[de->len] = c;
de = grub_xfs_inline_next_de(dir->data, head, de);

View file

@ -3132,7 +3132,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
{
void *osp;
blkptr_t *bp;
grub_size_t ospsize;
grub_size_t ospsize = 0;
grub_err_t err;
grub_dprintf ("zfs", "endian = %d\n", mdn->endian);

View file

@ -184,6 +184,8 @@ LZ4_uncompress_unknownOutputSize(const char *source,
}
}
/* copy literals */
if ((grub_addr_t) length > ~(grub_addr_t)op)
goto _output_error;
cpy = op + length;
if ((cpy > oend - COPYLENGTH) ||
(ip + length > iend - COPYLENGTH)) {

View file

@ -15,12 +15,12 @@ set -e
#
# Example:
#
# genmod.sh moddep.lst normal.module normal.mod
# genmod.sh moddep.lst normal.module build-grub-module-verifier normal.mod
#
moddep=$1
infile=$2
outfile=$3
outfile=$4
tmpfile=${outfile}.tmp
modname=`echo $infile | sed -e 's@\.module.*$@@'`
@ -58,7 +58,7 @@ if test x@TARGET_APPLE_LINKER@ != x1; then
-K grub_mod_init -K grub_mod_fini \
-K _grub_mod_init -K _grub_mod_fini \
-R .note.gnu.gold-version -R .note.GNU-stack \
-R .note -R .comment $tmpfile || exit 1
-R .note -R .comment -R .ARM.exidx $tmpfile || exit 1
fi
if ! test -z "${TARGET_OBJ2ELF}"; then
"${TARGET_OBJ2ELF}" $tmpfile || exit 1
@ -91,6 +91,9 @@ else
-nr:_grub_mod_init:grub_mod_init \
-nr:_grub_mod_fini:grub_mod_fini \
-wd1106 -nu -nd $tmpfile.bin $tmpfile || exit 1
rm -f $name.bin
rm -f $tmpfile.bin
fi
if test x@platform@ != xemu; then
./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@
fi
mv $tmpfile $outfile

View file

@ -45,6 +45,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
grub_err_t err;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
@ -56,24 +57,28 @@ grub_font_draw_string (const char *str, grub_font_t font,
if (visual_len < 0)
return grub_errno;
err = GRUB_ERR_NONE;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
struct grub_font_glyph *glyph;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
{
err = grub_errno;
goto out;
}
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width;
if (err)
return err;
goto out;
x += glyph->device_width;
}
out:
for (ptr = visual; ptr < visual + visual_len; ptr++)
grub_unicode_destroy_glyph (ptr);
grub_free (visual);
return GRUB_ERR_NONE;
return err;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in

View file

@ -63,14 +63,14 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"),
"theme");
instance = grub_zalloc (sizeof (*instance));
if (!instance)
return grub_errno;
err = grub_video_get_info (&mode_info);
if (err)
return err;
instance = grub_zalloc (sizeof (*instance));
if (!instance)
return grub_errno;
if (theme_path[0] != '/' && theme_path[0] != '(')
{
const char *prefix;

View file

@ -32,3 +32,88 @@ grub_byte_checksum (void *base, grub_size_t size)
ret += *ptr;
return ret;
}
static void *
grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig)
{
grub_size_t s;
grub_unaligned_uint32_t *ptr;
if (!rsdt)
return 0;
if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0)
return 0;
ptr = (grub_unaligned_uint32_t *) (rsdt + 1);
s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t);
for (; s; s--, ptr++)
{
struct grub_acpi_table_header *tbl;
tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val;
if (grub_memcmp (tbl->signature, sig, 4) == 0)
return tbl;
}
return 0;
}
static void *
grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig)
{
grub_size_t s;
grub_unaligned_uint64_t *ptr;
if (!xsdt)
return 0;
if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0)
return 0;
ptr = (grub_unaligned_uint64_t *) (xsdt + 1);
s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t);
for (; s; s--, ptr++)
{
struct grub_acpi_table_header *tbl;
#if GRUB_CPU_SIZEOF_VOID_P != 8
if (ptr->val >> 32)
continue;
#endif
tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val;
if (grub_memcmp (tbl->signature, sig, 4) == 0)
return tbl;
}
return 0;
}
struct grub_acpi_fadt *
grub_acpi_find_fadt (void)
{
struct grub_acpi_fadt *fadt = 0;
struct grub_acpi_rsdp_v10 *rsdpv1;
struct grub_acpi_rsdp_v20 *rsdpv2;
rsdpv1 = grub_machine_acpi_get_rsdpv1 ();
if (rsdpv1)
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv1->rsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
rsdpv2 = grub_machine_acpi_get_rsdpv2 ();
if (rsdpv2)
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv2->rsdpv1.rsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
if (rsdpv2
#if GRUB_CPU_SIZEOF_VOID_P != 8
&& !(rsdpv2->xsdt_addr >> 32)
#endif
)
fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv2->xsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
return 0;
}

View file

@ -38,7 +38,7 @@ static void
increment_timer (grub_efi_event_t event __attribute__ ((unused)),
void *context __attribute__ ((unused)))
{
tmr++;
tmr += 10;
}
void
@ -52,7 +52,7 @@ grub_machine_init (void)
efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL,
GRUB_EFI_TPL_CALLBACK, increment_timer, NULL, &tmr_evt);
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 10000);
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000);
grub_install_get_time_ms (grub_efi_get_time_ms);
}

View file

@ -55,10 +55,6 @@ FUNCTION(_start)
VARIABLE(grub_total_module_size)
.long 0
VARIABLE(grub_uboot_machine_type)
.long 0
VARIABLE(grub_uboot_boot_data)
.long 0
VARIABLE(grub_modbase)
.long 0
bss_start_ptr:
@ -66,29 +62,66 @@ bss_start_ptr:
end_ptr:
.long EXT_C(_end)
@ Memory map at start:
@ * text+data
@ * list relocations
@ * modules
@ Before we enter C, we need to apply the relocations
@ and get following map:
@ * text+data
@ * BSS (cleared)
@ * stack
@ * modules
@
@ To make things easier we ensure
@ that BSS+stack is larger than list of relocations
@ by increasing stack if necessarry.
@ This allows us to always unconditionally copy backwards
@ Currently list of relocations is ~5K and stack is set
@ to be at least 256K
FUNCTION(codestart)
@ Store context: Machine ID, atags/dtb, ...
@ U-Boot API signature is stored on the U-Boot heap
@ Stack pointer used as start address for signature probing
mov r12, sp
adr sp, entry_state
push {r4-r12,lr} @ store U-Boot context (sp in r12)
push {r1-r12,lr} @ store U-Boot context (sp in r12)
str r1, EXT_C(grub_uboot_machine_type)
str r2, EXT_C(grub_uboot_boot_data)
@ Modules have been stored as a blob in BSS,
@ they need to be manually relocated to _end
adr r1, _start
ldr r0, bss_start_ptr @ src
add r0, r0, r1
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
mvn r2, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
and r0, r0, r2
1:
ldr r3, [r0], #4 @load next offset
@ both -2 and -1 are treated the same as we have only one type of relocs
@ -2 means "end of this type of relocs" and -1 means "end of all relocs"
add r2, r3, #2
cmp r2, #1
bls reloc_done
@ Adjust next offset
ldr r2, [r3, r1]
add r2, r2, r1
str r2, [r3, r1]
b 1b
reloc_done:
@ Modules have been stored as a blob
@ they need to be manually relocated to _end
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
and r0, r0, r1
and r0, r0, r1 @ src = aligned end of relocations
ldr r1, end_ptr @ dst = End of BSS
ldr r2, grub_total_module_size @ blob size
add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE
and r1, r1, #~0x7 @ Ensure 8-byte alignment
sub sp, r1, #8
add r1, r1, #1024
@ -157,6 +190,11 @@ FUNCTION(grub_uboot_return)
.align 3
@ U-boot context stack space
entry_state_end:
VARIABLE(grub_uboot_machine_type)
.long 0 @ r1
VARIABLE(grub_uboot_boot_data)
.long 0 @ r2
.long 0 @ r3
.long 0 @ r4
.long 0 @ r5
.long 0 @ r6

View file

@ -132,6 +132,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
*abs_place = (grub_uint64_t) sym_addr;
}
break;
case R_AARCH64_ADD_ABS_LO12_NC:
grub_arm64_set_abs_lo12 (place, sym_addr);
break;
case R_AARCH64_LDST64_ABS_LO12_NC:
grub_arm64_set_abs_lo12_ldst64 (place, sym_addr);
break;
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
{
@ -154,6 +160,18 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
grub_arm64_set_xxxx26_offset (place, offset);
}
break;
case R_AARCH64_ADR_PREL_PG_HI21:
{
grub_int64_t offset = (sym_addr & ~0xfffULL) - (((grub_uint64_t) place) & ~0xfffULL);
if (!grub_arm64_check_hi21_signed (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
"HI21 out of range");
grub_arm64_set_hi21 (place, offset);
}
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),

View file

@ -53,3 +53,43 @@ grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset)
*place &= insmask;
*place |= grub_cpu_to_le32 (offset >> 2) & ~insmask;
}
int
grub_arm64_check_hi21_signed (grub_int64_t offset)
{
if (offset != (grub_int64_t)(grub_int32_t)offset)
return 0;
return 1;
}
void
grub_arm64_set_hi21 (grub_uint32_t *place, grub_int64_t offset)
{
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0x9f00001f);
grub_uint32_t val;
offset >>= 12;
val = ((offset & 3) << 29) | (((offset >> 2) & 0x7ffff) << 5);
*place &= insmask;
*place |= grub_cpu_to_le32 (val) & ~insmask;
}
void
grub_arm64_set_abs_lo12 (grub_uint32_t *place, grub_int64_t target)
{
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff);
*place &= insmask;
*place |= grub_cpu_to_le32 (target << 10) & ~insmask;
}
void
grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target)
{
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfff803ff);
*place &= insmask;
*place |= grub_cpu_to_le32 (target << 7) & ~insmask;
}

View file

@ -0,0 +1,60 @@
/* init.c - initialize an arm-based EFI system */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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/env.h>
#include <grub/kernel.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/efi/efi.h>
#include <grub/loader.h>
static grub_uint64_t timer_frequency_in_khz;
static grub_uint64_t
grub_efi_get_time_ms (void)
{
grub_uint64_t tmr;
asm volatile("mrs %0, cntvct_el0" : "=r" (tmr));
return tmr / timer_frequency_in_khz;
}
void
grub_machine_init (void)
{
grub_uint64_t timer_frequency;
grub_efi_init ();
asm volatile("mrs %0, cntfrq_el0" : "=r" (timer_frequency));
timer_frequency_in_khz = timer_frequency / 1000;
grub_install_get_time_ms (grub_efi_get_time_ms);
}
void
grub_machine_fini (int flags)
{
if (!(flags & GRUB_LOADER_FLAG_NORETURN))
return;
grub_efi_fini ();
}

View file

@ -342,8 +342,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
if (s->sh_type == SHT_SYMTAB)
break;
/* Module without symbol table may still be used to pull in dependencies.
We verify at build time that such modules do not contain any relocations
that may reference symbol table. */
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
return GRUB_ERR_NONE;
#ifdef GRUB_MODULES_MACHINE_READONLY
mod->symtab = grub_malloc (s->sh_size);
@ -585,6 +588,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (seg)
{
if (!mod->symtab)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
if (err)
return err;
@ -614,7 +620,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
}
/* Make sure that every section is within the core. */
if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
if (size < e->e_shoff + (grub_uint32_t) e->e_shentsize * e->e_shnum)
{
grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
return 0;

43
grub-core/kern/efi/fdt.c Normal file
View file

@ -0,0 +1,43 @@
/* fdt.c - EFI Flattened Device Tree interaction */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007 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/efi/efi.h>
#include <grub/mm.h>
void *
grub_efi_get_firmware_fdt (void)
{
grub_efi_configuration_table_t *tables;
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
void *firmware_fdt = NULL;
unsigned int i;
/* Look for FDT in UEFI config tables. */
tables = grub_efi_system_table->configuration_table;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
{
firmware_fdt = tables[i].vendor_table;
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
break;
}
return firmware_fdt;
}

View file

@ -59,10 +59,13 @@ grub_machine_get_bootlocation (char **device, char **path)
if (!image)
return;
*device = grub_efidisk_get_device_name (image->device_handle);
*path = grub_efi_get_filename (image->file_path);
if (!*device && grub_efi_net_config)
grub_efi_net_config (image->device_handle, device, path);
{
grub_efi_net_config (image->device_handle, device, path);
return;
}
*path = grub_efi_get_filename (image->file_path);
if (*path)
{
/* Get the directory. */

View file

@ -12,7 +12,7 @@ grub_elfXX_load_phdrs (grub_elf_t elf)
if (elf->phdrs)
return GRUB_ERR_NONE;
phdrs_size = elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize;
phdrs_size = (grub_uint32_t) elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize;
grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
(unsigned long long) elf->ehdr.ehdrXX.e_phoff,

View file

@ -161,9 +161,9 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
{
struct stat st;
# if GRUB_DISK_DEVS_ARE_CHAR
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
if (fstat (fd, &st) >= 0 && S_ISCHR (st.st_mode))
# else
if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
if (fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode))
# endif
data->is_disk = 1;
}

View file

@ -65,6 +65,12 @@ grub_reboot (void)
longjmp (main_env, 1);
}
void
grub_exit (void)
{
grub_reboot ();
}
void
grub_machine_init (void)
{
@ -86,11 +92,16 @@ grub_machine_fini (int flags)
#define OPT_MEMDISK 257
static struct argp_option options[] = {
{"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2},
{"device-map", 'm', N_("FILE"), 0,
/* TRANSLATORS: There are many devices in device map. */
N_("use FILE as the device map [default=%s]"), 0},
{"memdisk", OPT_MEMDISK, N_("FILE"), 0,
/* TRANSLATORS: There are many devices in device map. */
N_("use FILE as memdisk"), 0},
{"directory", 'd', N_("DIR"), 0,
N_("use GRUB files in the directory DIR [default=%s]"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
@ -119,6 +130,7 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused)))
struct arguments
{
const char *dev_map;
const char *mem_disk;
int hold;
};
@ -131,6 +143,9 @@ argp_parser (int key, char *arg, struct argp_state *state)
switch (key)
{
case OPT_MEMDISK:
arguments->mem_disk = arg;
break;
case 'r':
free (root_dev);
root_dev = xstrdup (arg);
@ -180,9 +195,13 @@ main (int argc, char *argv[])
struct arguments arguments =
{
.dev_map = DEFAULT_DEVICE_MAP,
.hold = 0
.hold = 0,
.mem_disk = 0,
};
volatile int hold = 0;
size_t total_module_size = sizeof (struct grub_module_info), memdisk_size = 0;
struct grub_module_info *modinfo;
void *mods;
grub_util_host_init (&argc, &argv);
@ -194,6 +213,33 @@ main (int argc, char *argv[])
exit(1);
}
if (arguments.mem_disk)
{
memdisk_size = ALIGN_UP(grub_util_get_image_size (arguments.mem_disk), 512);
total_module_size += memdisk_size + sizeof (struct grub_module_header);
}
mods = xmalloc (total_module_size);
modinfo = grub_memset (mods, 0, total_module_size);
mods = (char *) (modinfo + 1);
modinfo->magic = GRUB_MODULE_MAGIC;
modinfo->offset = sizeof (struct grub_module_info);
modinfo->size = total_module_size;
if (arguments.mem_disk)
{
struct grub_module_header *header = (struct grub_module_header *) mods;
header->type = OBJ_TYPE_MEMDISK;
header->size = memdisk_size + sizeof (*header);
mods = header + 1;
grub_util_load_image (arguments.mem_disk, mods);
mods = (char *) mods + memdisk_size;
}
grub_modbase = (grub_addr_t) modinfo;
hold = arguments.hold;
/* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
if (hold && verbosity > 0)

View file

@ -127,6 +127,7 @@ xasprintf (const char *fmt, ...)
va_start (ap, fmt);
result = grub_xvasprintf (fmt, ap);
va_end (ap);
if (!result)
grub_util_error ("%s", _("out of memory"));
@ -134,11 +135,13 @@ xasprintf (const char *fmt, ...)
}
#endif
#if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
void
grub_exit (void)
{
exit (1);
}
#endif
grub_uint64_t
grub_get_time_ms (void)
@ -149,3 +152,51 @@ grub_get_time_ms (void)
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
size_t
grub_util_get_image_size (const char *path)
{
FILE *f;
size_t ret;
off_t sz;
f = grub_util_fopen (path, "rb");
if (!f)
grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
fseeko (f, 0, SEEK_END);
sz = ftello (f);
if (sz < 0)
grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
if (sz != (size_t) sz)
grub_util_error (_("file `%s' is too big"), path);
ret = (size_t) sz;
fclose (f);
return ret;
}
void
grub_util_load_image (const char *path, char *buf)
{
FILE *fp;
size_t size;
grub_util_info ("reading %s", path);
size = grub_util_get_image_size (path);
fp = grub_util_fopen (path, "rb");
if (! fp)
grub_util_error (_("cannot open `%s': %s"), path,
strerror (errno));
if (fread (buf, 1, size, fp) != size)
grub_util_error (_("cannot read `%s': %s"), path,
strerror (errno));
fclose (fp);
}

View file

@ -44,6 +44,13 @@ FUNCTION(grub_bios_interrupt)
movl 24(%edx), %esi
movl 28(%edx), %edx
/*
Via C3 CPUs have cache coherence problems, so we need to call
wbinvd at these 2 points. As wbinvd slows down boot, don't do
it on non-VIA. 9090 is nop nop. */
VARIABLE(grub_bios_via_workaround1)
.byte 0x90, 0x90
PROT_TO_REAL
.code16
pushf
@ -92,6 +99,10 @@ intno:
movw %ax, LOCAL(bios_register_es)
popf
VARIABLE(grub_bios_via_workaround2)
.byte 0x90, 0x90
REAL_TO_PROT
.code32

View file

@ -32,6 +32,7 @@
#include <grub/env.h>
#include <grub/cache.h>
#include <grub/time.h>
#include <grub/cpu/cpuid.h>
#include <grub/cpu/tsc.h>
#include <grub/machine/time.h>
@ -184,6 +185,26 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
return 0;
}
extern grub_uint16_t grub_bios_via_workaround1, grub_bios_via_workaround2;
/* Via needs additional wbinvd. */
static void
grub_via_workaround_init (void)
{
grub_uint32_t manufacturer[3], max_cpuid;
if (! grub_cpu_is_cpuid_supported ())
return;
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
if (grub_memcmp (manufacturer, "CentaurHauls", 12) != 0)
return;
grub_bios_via_workaround1 = 0x090f;
grub_bios_via_workaround2 = 0x090f;
asm volatile ("wbinvd");
}
void
grub_machine_init (void)
{
@ -193,6 +214,9 @@ grub_machine_init (void)
#endif
grub_addr_t modend;
/* This has to happen before any BIOS calls. */
grub_via_workaround_init ();
grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
/* Initialize the console as early as possible. */

View file

@ -43,22 +43,6 @@ grub_tsc_get_time_ms (void)
return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate;
}
static __inline int
grub_cpu_is_tsc_supported (void)
{
#ifndef GRUB_MACHINE_XEN
grub_uint32_t a,b,c,d;
if (! grub_cpu_is_cpuid_supported ())
return 0;
grub_cpuid(1,a,b,c,d);
return (d & (1 << 4)) != 0;
#else
return 1;
#endif
}
static int
calibrate_tsc_hardcode (void)
{

View file

@ -24,129 +24,35 @@
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/i386/tsc.h>
#include <grub/i386/pmtimer.h>
#include <grub/acpi.h>
#include <grub/cpu/io.h>
static void *
grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig)
{
grub_size_t s;
grub_uint32_t *ptr;
if (!rsdt)
return 0;
if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0)
return 0;
ptr = (grub_uint32_t *) (rsdt + 1);
s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t);
for (; s; s--, ptr++)
{
struct grub_acpi_table_header *tbl;
tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr;
if (grub_memcmp (tbl->signature, sig, 4) == 0)
return tbl;
}
return 0;
}
static void *
grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig)
{
grub_size_t s;
grub_uint64_t *ptr;
if (!xsdt)
return 0;
if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0)
return 0;
ptr = (grub_uint64_t *) (xsdt + 1);
s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t);
for (; s; s--, ptr++)
{
struct grub_acpi_table_header *tbl;
#if GRUB_CPU_SIZEOF_VOID_P != 8
if (*ptr >> 32)
continue;
#endif
tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr;
if (grub_memcmp (tbl->signature, sig, 4) == 0)
return tbl;
}
return 0;
}
struct grub_acpi_fadt *
grub_acpi_find_fadt (void)
{
struct grub_acpi_fadt *fadt = 0;
struct grub_acpi_rsdp_v10 *rsdpv1;
struct grub_acpi_rsdp_v20 *rsdpv2;
rsdpv1 = grub_machine_acpi_get_rsdpv1 ();
if (rsdpv1)
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv1->rsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
rsdpv2 = grub_machine_acpi_get_rsdpv2 ();
if (rsdpv2)
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv2->rsdpv1.rsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
if (rsdpv2
#if GRUB_CPU_SIZEOF_VOID_P != 8
&& !(rsdpv2->xsdt_addr >> 32)
#endif
)
fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *)
(grub_addr_t) rsdpv2->xsdt_addr,
GRUB_ACPI_FADT_SIGNATURE);
if (fadt)
return fadt;
return 0;
}
int
grub_tsc_calibrate_from_pmtimer (void)
grub_uint64_t
grub_pmtimer_wait_count_tsc (grub_port_t pmtimer,
grub_uint16_t num_pm_ticks)
{
grub_uint32_t start;
grub_uint32_t last;
grub_uint32_t cur, end;
struct grub_acpi_fadt *fadt;
grub_port_t p;
grub_uint64_t start_tsc;
grub_uint64_t end_tsc;
int num_iter = 0;
fadt = grub_acpi_find_fadt ();
if (!fadt)
return 0;
p = fadt->pmtimer;
if (!p)
return 0;
start = grub_inl (p) & 0xffffff;
start = grub_inl (pmtimer) & 0xffffff;
last = start;
/* It's 3.579545 MHz clock. Wait 1 ms. */
end = start + 3580;
end = start + num_pm_ticks;
start_tsc = grub_get_tsc ();
while (1)
{
cur = grub_inl (p) & 0xffffff;
cur = grub_inl (pmtimer) & 0xffffff;
if (cur < last)
cur |= 0x1000000;
num_iter++;
if (cur >= end)
{
end_tsc = grub_get_tsc ();
grub_tsc_rate = grub_divmod64 ((1ULL << 32), end_tsc - start_tsc, 0);
return 1;
return end_tsc - start_tsc;
}
/* Check for broken PM timer.
50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz)
@ -158,3 +64,25 @@ grub_tsc_calibrate_from_pmtimer (void)
}
}
}
int
grub_tsc_calibrate_from_pmtimer (void)
{
struct grub_acpi_fadt *fadt;
grub_port_t pmtimer;
grub_uint64_t tsc_diff;
fadt = grub_acpi_find_fadt ();
if (!fadt)
return 0;
pmtimer = fadt->pmtimer;
if (!pmtimer)
return 0;
/* It's 3.579545 MHz clock. Wait 1 ms. */
tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580);
if (tsc_diff == 0)
return 0;
grub_tsc_rate = grub_divmod64 ((1ULL << 32), tsc_diff, 0);
return 1;
}

View file

@ -46,11 +46,19 @@
#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
/* The maximum heap size we're going to claim */
#ifdef __i386__
#define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024)
#else
#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024)
#endif
/* If possible, we will avoid claiming heap above this address, because it
seems to cause relocation problems with OSes that link at 4 MiB */
#ifdef __i386__
#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024)
#else
#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024)
#endif
extern char _start[];
extern char _end[];

View file

@ -25,7 +25,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
grub_ieee1275_phandle_t root;
grub_ieee1275_phandle_t memory;
grub_uint32_t available[32];
grub_uint32_t available[128];
grub_ssize_t available_size;
grub_uint32_t address_cells = 1;
grub_uint32_t size_cells = 1;
@ -49,6 +49,9 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
sizeof available, &available_size))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"couldn't examine /memory/available property");
if (available_size < 0 || (grub_size_t) available_size > sizeof (available))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"/memory response buffer exceeded");
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
{

View file

@ -740,6 +740,12 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
fmt++;
c = *fmt++;
if (c == '%')
{
n--;
continue;
}
if (c == 'l')
{
c = *fmt++;
@ -876,6 +882,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
if (c == '%')
{
write_char (str, &count, max_len,c);
n--;
continue;
}
@ -1099,6 +1106,8 @@ grub_fatal (const char *fmt, ...)
grub_vprintf (_(fmt), ap);
va_end (ap);
grub_refresh ();
grub_abort ();
}

View file

@ -325,6 +325,15 @@ grub_memalign (grub_size_t align, grub_size_t size)
if (!grub_mm_base)
goto fail;
if (size > ~(grub_size_t) align)
goto fail;
/* We currently assume at least a 32-bit grub_size_t,
so limiting allocations to <adress space size> - 1MiB
in name of sanity is beneficial. */
if ((size + align) > ~(grub_size_t) 0x100000)
goto fail;
align = (align >> GRUB_MM_ALIGN_LOG2);
if (align == 0)
align = 1;

View file

@ -43,13 +43,17 @@ grub_rescue_parse_line (char *line,
/* In case of an assignment set the environment accordingly
instead of calling a function. */
if (n == 1 && grub_strchr (line, '='))
if (n == 1)
{
char *val = grub_strchr (args[0], '=');
val[0] = 0;
grub_env_set (args[0], val + 1);
val[0] = '=';
goto quit;
if (val)
{
val[0] = 0;
grub_env_set (args[0], val + 1);
val[0] = '=';
goto quit;
}
}
/* Get the command name. */
@ -72,6 +76,7 @@ grub_rescue_parse_line (char *line,
}
quit:
/* Arguments are returned in single memory chunk separated by zeroes */
grub_free (args[0]);
grub_free (args);

View file

@ -50,6 +50,7 @@ FUNCTION(grub_longjmp)
ldp x29, x30, [x0], #16
ldr x2, [x0]
mov sp, x2
mov x0, #1
cmp x1, #0
csel x0, x1, x0, ne
ret

View file

@ -56,11 +56,11 @@ void
grub_backtrace (void)
{
#ifdef __x86_64__
asm volatile ("movq %rbp, %rdi\n"
"call " EXT_C("grub_backtrace_pointer"));
asm volatile ("movq %%rbp, %%rdi\n"
"callq *%%rax": :"a"(grub_backtrace_pointer));
#else
asm volatile ("movl %ebp, %eax\n"
"call " EXT_C("grub_backtrace_pointer"));
asm volatile ("movl %%ebp, %%eax\n"
"calll *%%ecx": :"c"(grub_backtrace_pointer));
#endif
}

103
grub-core/lib/i386/random.c Normal file
View file

@ -0,0 +1,103 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2016 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/random.h>
#include <grub/i386/io.h>
#include <grub/i386/tsc.h>
#include <grub/i386/pmtimer.h>
#include <grub/acpi.h>
static int have_tsc = -1, have_pmtimer = -1;
static grub_port_t pmtimer_port;
static int
detect_pmtimer (void)
{
struct grub_acpi_fadt *fadt;
fadt = grub_acpi_find_fadt ();
if (!fadt)
return 0;
pmtimer_port = fadt->pmtimer;
if (!pmtimer_port)
return 0;
return 1;
}
static int
pmtimer_tsc_get_random_bit (void)
{
/* It's hard to come up with figures about pmtimer and tsc jitter but
50 ppm seems to be typical. So we need 10^6/50 tsc cycles to get drift
of one tsc cycle. With TSC at least of 800 MHz it means 1/(50*800)
= 1/40000 s or about 3579545 / 40000 = 90 pmtimer ticks.
This gives us rate of 40000 bit/s or 5 kB/s.
*/
grub_uint64_t tsc_diff;
tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer_port, 90);
if (tsc_diff == 0)
{
have_pmtimer = 0;
return -1;
}
return tsc_diff & 1;
}
static int
pmtimer_tsc_get_random_byte (void)
{
grub_uint8_t ret = 0;
int i, c;
for (i = 0; i < 8; i++)
{
c = pmtimer_tsc_get_random_bit ();
if (c < 0)
return -1;
ret |= c << i;
}
return ret;
}
static int
pmtimer_fill_buffer (void *buffer, grub_size_t sz)
{
grub_uint8_t *p = buffer;
int c;
while (sz)
{
c = pmtimer_tsc_get_random_byte ();
if (c < 0)
return 0;
*p++ = c;
sz--;
}
return 1;
}
int
grub_crypto_arch_get_random (void *buffer, grub_size_t sz)
{
if (have_tsc == -1)
have_tsc = grub_cpu_is_tsc_supported ();
if (!have_tsc)
return 0;
if (have_pmtimer == -1)
have_pmtimer = detect_pmtimer ();
if (!have_pmtimer)
return 0;
return pmtimer_fill_buffer (buffer, sz);
}

View file

@ -73,6 +73,14 @@ VARIABLE(grub_relocator64_rsp)
movq %rax, %rsp
/*
* Here is grub_relocator64_efi_start() entry point.
* Following code is shared between grub_relocator64_efi_start()
* and grub_relocator64_start().
*
* Think twice before changing anything below!!!
*/
VARIABLE(grub_relocator64_efi_start)
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
@ -120,6 +128,9 @@ LOCAL(jump_addr):
VARIABLE(grub_relocator64_rip)
.quad 0
/* Here grub_relocator64_efi_start() ends. Ufff... */
VARIABLE(grub_relocator64_efi_end)
#ifndef __x86_64__
.p2align 4
LOCAL(gdt):

View file

@ -16,6 +16,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/memory.h>
#include <grub/i386/types.h>
#include <grub/symbol.h>
#include <grub/xen.h>
@ -23,78 +25,86 @@
VARIABLE(grub_relocator_xen_remap_start)
LOCAL(base):
/* mov imm32, %ebx */
/* Remap the remapper to it's new address. */
/* mov imm32, %ebx - %ebx: new virtual address of remapper */
.byte 0xbb
VARIABLE(grub_relocator_xen_remapper_virt)
.long 0
/* mov imm32, %ecx */
/* mov imm32, %ecx - %ecx: low part of page table entry */
.byte 0xb9
VARIABLE(grub_relocator_xen_remapper_map)
.long 0
/* mov imm32, %edx */
/* mov imm32, %edx - %edx: high part of page table entry */
.byte 0xba
VARIABLE(grub_relocator_xen_remapper_map_high)
.long 0
movl %ebx, %ebp
movl %ebx, %ebp /* %ebx is clobbered by hypercall */
movl $2, %esi
movl $UVMF_INVLPG, %esi /* esi: flags (inv. single entry) */
movl $__HYPERVISOR_update_va_mapping, %eax
int $0x82
movl %ebp, %ebx
addl $(LOCAL(cont) - LOCAL(base)), %ebx
jmp *%ebx
jmp *%ebx /* Continue with new virtual address */
LOCAL(cont):
xorl %eax, %eax
movl %eax, %ebp
/* Modify mappings of new page tables to be read-only. */
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_relocator_xen_paging_areas_addr)
.long 0
movl %eax, %ebx
1:
movl 0(%ebx), %ebp /* Get start pfn of the current area */
movl GRUB_TARGET_SIZEOF_LONG(%ebx), %ecx /* Get # of pg tables */
testl %ecx, %ecx /* 0 -> last area reached */
jz 3f
addl $(2 * GRUB_TARGET_SIZEOF_LONG), %ebx
movl %ebx, %esp /* Save current area pointer */
2:
movl %ecx, %edi
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_relocator_xen_mfn_list)
.long 0
movl %eax, %edi
movl %ebp, %eax
movl 0(%edi, %eax, 4), %ecx
/* mov imm32, %ebx */
.byte 0xbb
VARIABLE(grub_relocator_xen_paging_start)
.long 0
shll $12, %eax
addl %eax, %ebx
movl 0(%eax, %ebp, 4), %ecx /* mfn */
movl %ebp, %ebx
shll $PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */
movl %ecx, %edx
shll $12, %ecx
shrl $20, %edx
orl $5, %ecx
movl $2, %esi
shll $PAGE_SHIFT, %ecx /* prepare pte low part */
shrl $(32 - PAGE_SHIFT), %edx /* pte high part */
orl $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %ecx /* pte low */
movl $UVMF_INVLPG, %esi
movl $__HYPERVISOR_update_va_mapping, %eax
int $0x82
int $0x82 /* parameters: eax, ebx, ecx, edx, esi */
incl %ebp
/* mov imm32, %ecx */
.byte 0xb9
VARIABLE(grub_relocator_xen_paging_size)
.long 0
cmpl %ebp, %ecx
incl %ebp /* next pfn */
movl %edi, %ecx
ja 1b
loop 2b
mov %esp, %ebx /* restore area poniter */
jmp 1b
3:
/* Switch page tables: pin new L3 pt, load cr3, unpin old L3. */
/* mov imm32, %ebx */
.byte 0xbb
VARIABLE(grub_relocator_xen_mmu_op_addr)
.long 0
movl $3, %ecx
movl $0, %edx
movl $0x7FF0, %esi
movl $3, %ecx /* 3 mmu ops */
movl $0, %edx /* pdone (not used) */
movl $DOMID_SELF, %esi
movl $__HYPERVISOR_mmuext_op, %eax
int $0x82
/* Continue in virtual kernel mapping. */
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_relocator_xen_remap_continue)
@ -102,6 +112,9 @@ VARIABLE(grub_relocator_xen_remap_continue)
jmp *%eax
VARIABLE(grub_relocator_xen_paging_areas)
.long 0, 0, 0, 0, 0, 0, 0, 0
VARIABLE(grub_relocator_xen_mmu_op)
.space 256
@ -109,6 +122,7 @@ VARIABLE(grub_relocator_xen_remap_end)
VARIABLE(grub_relocator_xen_start)
/* Unmap old remapper area. */
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_relocator_xen_remapper_virt2)
@ -116,14 +130,14 @@ VARIABLE(grub_relocator_xen_remapper_virt2)
movl %eax, %edi
xorl %ecx, %ecx
xorl %ecx, %ecx /* Invalid pte */
xorl %edx, %edx
movl $2, %esi
movl $UVMF_INVLPG, %esi
movl $__HYPERVISOR_update_va_mapping, %eax
int $0x82
/* Prepare registers for starting kernel. */
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_relocator_xen_stack)
@ -145,6 +159,7 @@ VARIABLE(grub_relocator_xen_start_info)
VARIABLE(grub_relocator_xen_entry_point)
.long 0
/* Now start the new kernel. */
jmp *%eax
VARIABLE(grub_relocator_xen_end)

View file

@ -95,7 +95,7 @@ grub_get_datetime (struct grub_datetime *datetime)
datetime->year = args.year;
datetime->month = args.month;
datetime->day = args.day;
datetime->day = args.day + 1;
datetime->hour = args.hour;
datetime->minute = args.minute;
datetime->second = args.second;
@ -140,7 +140,7 @@ grub_set_datetime (struct grub_datetime *datetime)
args.year = datetime->year;
args.month = datetime->month;
args.day = datetime->day;
args.day = datetime->day - 1;
args.hour = datetime->hour;
args.minute = datetime->minute;
args.second = datetime->second;

View file

@ -31,7 +31,6 @@ GRUB_MOD_LICENSE ("GPLv2+");
desired derived output length DKLEN. Output buffer is DK which
must have room for at least DKLEN octets. The output buffer will
be filled with the derived data. */
#pragma GCC diagnostic ignored "-Wunreachable-code"
gcry_err_code_t
grub_crypto_pbkdf2 (const struct gcry_md_spec *md,

View file

@ -38,11 +38,17 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
grub_uint64_t now;
static grub_uint64_t last_progress_update_time;
grub_file_t file = data;
const char *e;
file->progress_offset += length;
if (call_depth)
return;
e = grub_env_get ("enable_progress_indicator");
if (e && e[0] == '0') {
return;
}
call_depth = 1;
now = grub_get_time_ms ();

120
grub-core/lib/random.c Normal file
View file

@ -0,0 +1,120 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2016 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/random.h>
#include <grub/dl.h>
#include <grub/lib/hexdump.h>
#include <grub/command.h>
#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
grub_err_t
grub_crypto_get_random (void *buffer, grub_size_t sz)
{
/* This is an arbitrer between different methods.
TODO: Add more methods in the future. */
/* TODO: Add some PRNG smartness to reduce damage from bad entropy. */
if (grub_crypto_arch_get_random (buffer, sz))
return GRUB_ERR_NONE;
return grub_error (GRUB_ERR_IO, "no random sources found");
}
static int
get_num_digits (int val)
{
int ret = 0;
while (val != 0)
{
ret++;
val /= 10;
}
if (ret == 0)
return 1;
return ret;
}
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
static grub_err_t
grub_cmd_hexdump_random (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
{
grub_size_t length = 64;
grub_err_t err;
void *buffer;
grub_uint8_t *ptr;
int stats[256];
int i, digits = 2;
char template[10];
if (argc >= 1)
length = grub_strtoull (args[0], 0, 0);
if (length == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "length pust be positive");
buffer = grub_malloc (length);
if (!buffer)
return grub_errno;
err = grub_crypto_get_random (buffer, length);
if (err)
{
grub_free (buffer);
return err;
}
hexdump (0, buffer, length);
grub_memset(stats, 0, sizeof(stats));
for (ptr = buffer; ptr < (grub_uint8_t *) buffer + length; ptr++)
stats[*ptr]++;
grub_printf ("Statistics:\n");
for (i = 0; i < 256; i++)
{
int z = get_num_digits (stats[i]);
if (z > digits)
digits = z;
}
grub_snprintf (template, sizeof (template), "%%0%dd ", digits);
for (i = 0; i < 256; i++)
{
grub_printf ("%s", template);//, stats[i]);
if ((i & 0xf) == 0xf)
grub_printf ("\n");
}
grub_free (buffer);
return 0;
}
static grub_command_t cmd;
GRUB_MOD_INIT (random)
{
cmd = grub_register_command ("hexdump_random", grub_cmd_hexdump_random,
N_("[LENGTH]"),
N_("Hexdump random data."));
}
GRUB_MOD_FINI (random)
{
grub_unregister_command (cmd);
}

View file

@ -736,26 +736,36 @@ malloc_in_range (struct grub_relocator *rel,
}
isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw)
&& !nblockfw)));
if (!isinsidebefore && isinsideafter)
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
: ALIGN_DOWN (events[j].pos - size, align) + size;
if (isinsidebefore && !isinsideafter && from_low_priv)
{
target = starta;
if (target < start)
target = start;
if (target + size <= end && target + size <= events[j].pos)
/* Found an usable address. */
goto found;
}
if (isinsidebefore && !isinsideafter && !from_low_priv)
{
target = starta - size;
if (target > end - size)
target = end - size;
if (target >= start && target >= events[j].pos)
goto found;
}
if (from_low_priv) {
if (!isinsidebefore && isinsideafter)
starta = ALIGN_UP (events[j].pos, align);
if (isinsidebefore && !isinsideafter)
{
target = starta;
if (target < start)
target = start;
if (target + size <= end && target + size <= events[j].pos)
/* Found an usable address. */
goto found;
}
} else {
if (!isinsidebefore && isinsideafter)
{
if (events[j].pos >= size)
starta = ALIGN_DOWN (events[j].pos - size, align) + size;
else
starta = 0;
}
if (isinsidebefore && !isinsideafter && starta >= size)
{
target = starta - size;
if (target > end - size)
target = end - size;
if (target >= start && target >= events[j].pos)
goto found;
}
}
}
}

View file

@ -0,0 +1,80 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved.
*
* 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/mm.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/i386/relocator.h>
#include <grub/relocator_private.h>
extern grub_uint64_t grub_relocator64_rax;
extern grub_uint64_t grub_relocator64_rbx;
extern grub_uint64_t grub_relocator64_rcx;
extern grub_uint64_t grub_relocator64_rdx;
extern grub_uint64_t grub_relocator64_rip;
extern grub_uint64_t grub_relocator64_rsi;
extern grub_uint8_t grub_relocator64_efi_start;
extern grub_uint8_t grub_relocator64_efi_end;
#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start)
grub_err_t
grub_relocator64_efi_boot (struct grub_relocator *rel,
struct grub_relocator64_efi_state state)
{
grub_err_t err;
void *relst;
grub_relocator_chunk_t ch;
/*
* 64-bit relocator code may live above 4 GiB quite well.
* However, I do not want ask for problems. Just in case.
*/
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
0x100000000 - RELOCATOR_SIZEOF (64_efi),
RELOCATOR_SIZEOF (64_efi), 16,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
return err;
/* Do not touch %rsp! It points to EFI created stack. */
grub_relocator64_rax = state.rax;
grub_relocator64_rbx = state.rbx;
grub_relocator64_rcx = state.rcx;
grub_relocator64_rdx = state.rdx;
grub_relocator64_rip = state.rip;
grub_relocator64_rsi = state.rsi;
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_efi_start,
RELOCATOR_SIZEOF (64_efi));
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
&relst, NULL);
if (err)
return err;
((void (*) (void)) relst) ();
/* Not reached. */
return GRUB_ERR_NONE;
}

View file

@ -16,94 +16,85 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/x86_64/memory.h>
#include <grub/x86_64/types.h>
#include <grub/symbol.h>
#include <grub/xen.h>
/* Macro to load an imm64 value stored by the C-part into %rax: */
#define MOV_IMM64_RAX(var) .byte 0x48, 0xb8; VARIABLE(var); .quad 0
.p2align 4 /* force 16-byte alignment */
VARIABLE(grub_relocator_xen_remap_start)
LOCAL(base):
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_remapper_virt)
.quad 0
/* Remap the remapper to it's new address. */
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt)
movq %rax, %rdi
movq %rax, %rbx
movq %rax, %rdi /* %rdi: new virtual address of remapper */
movq %rax, %rbx /* Remember new virtual address */
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_remapper_map)
.quad 0
MOV_IMM64_RAX(grub_relocator_xen_remapper_map)
movq %rax, %rsi
movq %rax, %rsi /* %rsi: page table entry */
movq $2, %rdx
movq $UVMF_INVLPG, %rdx /* %rdx: flags (inv. single entry) */
movq $__HYPERVISOR_update_va_mapping, %rax
syscall
syscall /* Do the remap operation */
addq $(LOCAL(cont) - LOCAL(base)), %rbx
jmp *%rbx
jmp *%rbx /* Continue with new virtual address */
LOCAL(cont):
/* mov imm64, %rcx */
.byte 0x48
.byte 0xb9
VARIABLE(grub_relocator_xen_paging_size)
.quad 0
/* Modify mappings of new page tables to be read-only. */
MOV_IMM64_RAX(grub_relocator_xen_mfn_list)
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_paging_start)
.quad 0
movq %rax, %rbx /* %rbx is the base of the p2m list */
leaq EXT_C(grub_relocator_xen_paging_areas) (%rip), %r8
movq %rax, %r12
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_mfn_list)
.quad 0
movq %rax, %rsi
1:
movq 0(%r8), %r12 /* Get start pfn of the current area */
movq GRUB_TARGET_SIZEOF_LONG(%r8), %rcx /* Get # of pg tables */
testq %rcx, %rcx /* 0 -> last area reached */
jz 3f
2:
movq %r12, %rdi
movq %rsi, %rbx
movq 0(%rsi), %rsi
shlq $12, %rsi
orq $5, %rsi
movq $2, %rdx
movq %rcx, %r9
shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */
movq (%rbx, %r12, 8), %rsi /* mfn */
shlq $PAGE_SHIFT, %rsi
orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */
movq $UVMF_INVLPG, %rdx
movq %rcx, %r9 /* %rcx clobbered by hypercall */
movq $__HYPERVISOR_update_va_mapping, %rax
syscall
movq %r9, %rcx
addq $8, %rbx
addq $4096, %r12
movq %rbx, %rsi
incq %r12 /* next pfn */
loop 1b
loop 2b
addq $(2 * GRUB_TARGET_SIZEOF_LONG), %r8 /* next pg table area */
jmp 1b
3:
/* Switch page tables: pin new L4 pt, load cr3, unpin old L4. */
leaq EXT_C(grub_relocator_xen_mmu_op) (%rip), %rdi
movq $3, %rsi
movq $0, %rdx
movq $0x7FF0, %r10
movq $3, %rsi /* 3 mmu ops */
movq $0, %rdx /* pdone (not used) */
movq $DOMID_SELF, %r10
movq $__HYPERVISOR_mmuext_op, %rax
syscall
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_remap_continue)
.quad 0
/* Continue in virtual kernel mapping. */
MOV_IMM64_RAX(grub_relocator_xen_remap_continue)
jmp *%rax
VARIABLE(grub_relocator_xen_paging_areas)
/* array of start, size pairs, size 0 is end marker */
.quad 0, 0, 0, 0, 0, 0, 0, 0
VARIABLE(grub_relocator_xen_mmu_op)
.space 256
@ -111,46 +102,32 @@ VARIABLE(grub_relocator_xen_remap_end)
VARIABLE(grub_relocator_xen_start)
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_remapper_virt2)
.quad 0
/* Unmap old remapper area. */
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt2)
movq %rax, %rdi
xorq %rax, %rax
xorq %rax, %rax /* Invalid pte */
movq %rax, %rsi
movq $2, %rdx
movq $UVMF_INVLPG, %rdx
movq $__HYPERVISOR_update_va_mapping, %rax
syscall
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_stack)
.quad 0
/* Prepare registers for starting kernel. */
MOV_IMM64_RAX(grub_relocator_xen_stack)
movq %rax, %rsp
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_start_info)
.quad 0
MOV_IMM64_RAX(grub_relocator_xen_start_info)
movq %rax, %rsi
cld
/* mov imm64, %rax */
.byte 0x48
.byte 0xb8
VARIABLE(grub_relocator_xen_entry_point)
.quad 0
MOV_IMM64_RAX(grub_relocator_xen_entry_point)
/* Now start the new kernel. */
jmp *%rax
VARIABLE(grub_relocator_xen_end)

View file

@ -29,6 +29,11 @@
typedef grub_addr_t grub_xen_reg_t;
struct grub_relocator_xen_paging_area {
grub_xen_reg_t start;
grub_xen_reg_t size;
} GRUB_PACKED;
extern grub_uint8_t grub_relocator_xen_start;
extern grub_uint8_t grub_relocator_xen_end;
extern grub_uint8_t grub_relocator_xen_remap_start;
@ -36,15 +41,16 @@ extern grub_uint8_t grub_relocator_xen_remap_end;
extern grub_xen_reg_t grub_relocator_xen_stack;
extern grub_xen_reg_t grub_relocator_xen_start_info;
extern grub_xen_reg_t grub_relocator_xen_entry_point;
extern grub_xen_reg_t grub_relocator_xen_paging_start;
extern grub_xen_reg_t grub_relocator_xen_paging_size;
extern grub_xen_reg_t grub_relocator_xen_remapper_virt;
extern grub_xen_reg_t grub_relocator_xen_remapper_virt2;
extern grub_xen_reg_t grub_relocator_xen_remapper_map;
extern grub_xen_reg_t grub_relocator_xen_mfn_list;
extern struct grub_relocator_xen_paging_area
grub_relocator_xen_paging_areas[XEN_MAX_MAPPINGS];
extern grub_xen_reg_t grub_relocator_xen_remap_continue;
#ifdef __i386__
extern grub_xen_reg_t grub_relocator_xen_mmu_op_addr;
extern grub_xen_reg_t grub_relocator_xen_paging_areas_addr;
extern grub_xen_reg_t grub_relocator_xen_remapper_map_high;
#endif
extern mmuext_op_t grub_relocator_xen_mmu_op[3];
@ -61,6 +67,7 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
{
grub_err_t err;
void *relst;
int i;
grub_relocator_chunk_t ch, ch_tramp;
grub_xen_mfn_t *mfn_list =
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
@ -77,8 +84,11 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
grub_relocator_xen_stack = state.stack;
grub_relocator_xen_start_info = state.start_info;
grub_relocator_xen_entry_point = state.entry_point;
grub_relocator_xen_paging_start = state.paging_start << 12;
grub_relocator_xen_paging_size = state.paging_size;
for (i = 0; i < XEN_MAX_MAPPINGS; i++)
{
grub_relocator_xen_paging_areas[i].start = state.paging_start[i];
grub_relocator_xen_paging_areas[i].size = state.paging_size[i];
}
grub_relocator_xen_remapper_virt = remapper_virt;
grub_relocator_xen_remapper_virt2 = remapper_virt;
grub_relocator_xen_remap_continue = trampoline_virt;
@ -88,10 +98,12 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
grub_relocator_xen_remapper_map_high = (mfn_list[remapper_pfn] >> 20);
grub_relocator_xen_mmu_op_addr = (char *) &grub_relocator_xen_mmu_op
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
grub_relocator_xen_paging_areas_addr =
(char *) &grub_relocator_xen_paging_areas
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
#endif
grub_relocator_xen_mfn_list = state.mfn_list
+ state.paging_start * sizeof (grub_addr_t);
grub_relocator_xen_mfn_list = state.mfn_list;
grub_memset (grub_relocator_xen_mmu_op, 0,
sizeof (grub_relocator_xen_mmu_op));
@ -100,9 +112,9 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
#else
grub_relocator_xen_mmu_op[0].cmd = MMUEXT_PIN_L4_TABLE;
#endif
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start];
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start[0]];
grub_relocator_xen_mmu_op[1].cmd = MMUEXT_NEW_BASEPTR;
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start];
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start[0]];
grub_relocator_xen_mmu_op[2].cmd = MMUEXT_UNPIN_TABLE;
grub_relocator_xen_mmu_op[2].arg1.mfn =
mfn_list[grub_xen_start_page_addr->pt_base >> 12];

View file

@ -28,28 +28,6 @@
static void *loaded_fdt;
static void *fdt;
static void *
get_firmware_fdt (void)
{
grub_efi_configuration_table_t *tables;
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
void *firmware_fdt = NULL;
unsigned int i;
/* Look for FDT in UEFI config tables. */
tables = grub_efi_system_table->configuration_table;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
{
firmware_fdt = tables[i].vendor_table;
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
break;
}
return firmware_fdt;
}
void *
grub_fdt_load (grub_size_t additional_size)
{
@ -65,7 +43,7 @@ grub_fdt_load (grub_size_t additional_size)
if (loaded_fdt)
raw_fdt = loaded_fdt;
else
raw_fdt = get_firmware_fdt();
raw_fdt = grub_efi_get_firmware_fdt();
size =
raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ;

View file

@ -37,16 +37,6 @@
GRUB_MOD_LICENSE ("GPLv3+");
#define XEN_HYPERVISOR_NAME "xen_hypervisor"
#define MODULE_DEFAULT_ALIGN (0x0)
#define MODULE_IMAGE_MIN_ALIGN MODULE_DEFAULT_ALIGN
#define MODULE_INITRD_MIN_ALIGN MODULE_DEFAULT_ALIGN
#define MODULE_XSM_MIN_ALIGN MODULE_DEFAULT_ALIGN
#define MODULE_CUSTOM_MIN_ALIGN MODULE_DEFAULT_ALIGN
#define MODULE_IMAGE_COMPATIBLE "multiboot,kernel\0multiboot,module"
#define MODULE_INITRD_COMPATIBLE "multiboot,ramdisk\0multiboot,module"
#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0multiboot,module"
#define MODULE_CUSTOM_COMPATIBLE "multiboot,module"
/* This maximum size is defined in Power.org ePAPR V1.1
@ -74,14 +64,6 @@ enum module_type
};
typedef enum module_type module_type_t;
struct fdt_node_info
{
module_type_t type;
const char *compat_string;
grub_size_t compat_string_size;
};
struct xen_hypervisor_header
{
struct grub_arm64_linux_kernel_header efi_head;
@ -98,7 +80,7 @@ struct xen_boot_binary
{
struct xen_boot_binary *next;
struct xen_boot_binary **prev;
const char *name;
int is_hypervisor;
grub_addr_t start;
grub_size_t size;
@ -106,8 +88,6 @@ struct xen_boot_binary
char *cmdline;
int cmdline_size;
struct fdt_node_info node_info;
};
static grub_dl_t my_mod;
@ -116,19 +96,6 @@ static int loaded;
static struct xen_boot_binary *xen_hypervisor;
static struct xen_boot_binary *module_head;
static const grub_size_t module_default_align[] = {
MODULE_IMAGE_MIN_ALIGN,
MODULE_INITRD_MIN_ALIGN,
MODULE_XSM_MIN_ALIGN,
MODULE_CUSTOM_MIN_ALIGN
};
static const compat_string_struct_t default_compat_string[] = {
FDT_COMPATIBLE (MODULE_IMAGE_COMPATIBLE),
FDT_COMPATIBLE (MODULE_INITRD_COMPATIBLE),
FDT_COMPATIBLE (MODULE_XSM_COMPATIBLE),
FDT_COMPATIBLE (MODULE_CUSTOM_COMPATIBLE)
};
static __inline grub_addr_t
xen_boot_address_align (grub_addr_t start, grub_size_t align)
@ -136,20 +103,6 @@ xen_boot_address_align (grub_addr_t start, grub_size_t align)
return (align ? (ALIGN_UP (start, align)) : start);
}
/* set module type according to command name. */
static grub_err_t
set_module_type (grub_command_t cmd, struct xen_boot_binary *module)
{
if (!grub_strcmp (cmd->name, "xen_linux"))
module->node_info.type = MODULE_IMAGE;
else if (!grub_strcmp (cmd->name, "xen_initrd"))
module->node_info.type = MODULE_INITRD;
else if (!grub_strcmp (cmd->name, "xen_xsm"))
module->node_info.type = MODULE_XSM;
return GRUB_ERR_NONE;
}
static grub_err_t
prepare_xen_hypervisor_params (void *xen_boot_fdt)
{
@ -203,15 +156,11 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name);
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible",
module->node_info.compat_string,
(grub_uint32_t) module->
node_info.compat_string_size);
MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE) - 1);
if (retval)
return grub_error (GRUB_ERR_IO, "failed to update FDT");
grub_dprintf ("xen_loader", "Module %s compatible = %s size = 0x%lx\n",
module->name, module->node_info.compat_string,
module->node_info.compat_string_size);
grub_dprintf ("xen_loader", "Module\n");
retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node,
xen_boot_address_align (module->start,
@ -223,7 +172,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
if (module->cmdline && module->cmdline_size > 0)
{
grub_dprintf ("xen_loader",
"Module %s cmdline : %s @ %p size:%d\n", module->name,
"Module cmdline : %s @ %p size:%d\n",
module->cmdline, module->cmdline, module->cmdline_size);
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs",
@ -233,8 +182,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
}
else
{
grub_dprintf ("xen_loader", "Module %s has not bootargs!\n",
module->name);
grub_dprintf ("xen_loader", "Module has no bootargs!\n");
}
return GRUB_ERR_NONE;
@ -251,8 +199,8 @@ finalize_params_xen_boot (void)
additional_size += FDT_NODE_NAME_MAX_SIZE + xen_hypervisor->cmdline_size;
FOR_LIST_ELEMENTS (module, module_head)
{
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + module->
node_info.compat_string_size + module->cmdline_size;
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + sizeof(MODULE_CUSTOM_COMPATIBLE) - 1
+ module->cmdline_size;
}
xen_boot_fdt = grub_fdt_load (additional_size);
@ -275,8 +223,7 @@ finalize_params_xen_boot (void)
{
if (module->start && module->size > 0)
{
grub_dprintf ("xen_loader", "Module %s @ 0x%lx size:0x%lx\n",
module->name,
grub_dprintf ("xen_loader", "Module @ 0x%lx size:0x%lx\n",
xen_boot_address_align (module->start, module->align),
module->size);
if (prepare_xen_module_params (module, xen_boot_fdt) != GRUB_ERR_NONE)
@ -284,7 +231,7 @@ finalize_params_xen_boot (void)
}
else
{
grub_dprintf ("xen_loader", "Module info error: %s!\n", module->name);
grub_dprintf ("xen_loader", "Module info error!\n");
goto fail;
}
}
@ -327,19 +274,16 @@ single_binary_unload (struct xen_boot_binary *binary)
{
grub_free (binary->cmdline);
grub_dprintf ("xen_loader",
"Module %s cmdline memory free @ %p size: %d\n",
binary->name, binary->cmdline, binary->cmdline_size);
"Module cmdline memory free @ %p size: %d\n",
binary->cmdline, binary->cmdline_size);
}
if (binary->node_info.type == MODULE_CUSTOM)
grub_free ((void *) binary->node_info.compat_string);
if (grub_strcmp (binary->name, XEN_HYPERVISOR_NAME))
if (!binary->is_hypervisor)
grub_list_remove (GRUB_AS_LIST (binary));
grub_dprintf ("xen_loader",
"Module %s struct memory free @ %p size: 0x%lx\n",
binary->name, binary, sizeof (binary));
"Module struct memory free @ %p size: 0x%lx\n",
binary, sizeof (binary));
grub_free (binary);
return;
@ -377,8 +321,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
int argc, char *argv[])
{
binary->size = grub_file_size (file);
grub_dprintf ("xen_loader", "Xen_boot %s file size: 0x%lx\n",
binary->name, binary->size);
grub_dprintf ("xen_loader", "Xen_boot file size: 0x%lx\n", binary->size);
binary->start
= (grub_addr_t) grub_efi_allocate_pages (0,
@ -391,8 +334,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
return;
}
grub_dprintf ("xen_loader", "Xen_boot %s numpages: 0x%lx\n",
binary->name, GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
grub_dprintf ("xen_loader", "Xen_boot numpages: 0x%lx\n",
GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
if (grub_file_read (file, (void *) xen_boot_address_align (binary->start,
binary->align),
@ -416,7 +359,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
binary->cmdline_size);
grub_dprintf ("xen_loader",
"Xen_boot %s cmdline @ %p %s, size: %d\n", binary->name,
"Xen_boot cmdline @ %p %s, size: %d\n",
binary->cmdline, binary->cmdline, binary->cmdline_size);
}
else
@ -430,7 +373,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
}
static grub_err_t
grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)),
int argc, char *argv[])
{
struct xen_boot_binary *module = NULL;
@ -454,34 +398,10 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
if (!module)
return grub_errno;
/* process all the options and get module type */
if (set_module_type (cmd, module) != GRUB_ERR_NONE)
goto fail;
switch (module->node_info.type)
{
case MODULE_IMAGE:
case MODULE_INITRD:
case MODULE_XSM:
module->node_info.compat_string =
default_compat_string[module->node_info.type].compat_string;
module->node_info.compat_string_size =
default_compat_string[module->node_info.type].size;
break;
module->is_hypervisor = 0;
module->align = 4096;
case MODULE_CUSTOM:
/* we have set the node_info in set_module_type */
break;
default:
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
}
module->name = module->node_info.compat_string;
module->align = module_default_align[module->node_info.type];
grub_dprintf ("xen_loader", "Init %s module and node info:\n"
"compatible %s\ncompat_string_size 0x%lx\n",
module->name, module->node_info.compat_string,
module->node_info.compat_string_size);
grub_dprintf ("xen_loader", "Init module and node info\n");
file = grub_file_open (argv[0]);
if (!file)
@ -491,7 +411,7 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
if (grub_errno == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module));
fail:
fail:
if (file)
grub_file_close (file);
if (grub_errno != GRUB_ERR_NONE)
@ -535,7 +455,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
if (!xen_hypervisor)
return grub_errno;
xen_hypervisor->name = XEN_HYPERVISOR_NAME;
xen_hypervisor->is_hypervisor = 1;
xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
xen_boot_binary_load (xen_hypervisor, file, argc, argv);
@ -559,29 +479,21 @@ fail:
}
static grub_command_t cmd_xen_hypervisor;
static grub_command_t cmd_xen_linux, cmd_xen_initrd, cmd_xen_xsm;
static grub_command_t cmd_xen_module;
GRUB_MOD_INIT (xen_boot)
{
cmd_xen_hypervisor =
grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
N_("Load a xen hypervisor."));
cmd_xen_linux =
grub_register_command ("xen_linux", grub_cmd_xen_module, 0,
N_("Load a xen linux kernel for dom0."));
cmd_xen_initrd =
grub_register_command ("xen_initrd", grub_cmd_xen_module, 0,
N_("Load a xen initrd for dom0."));
cmd_xen_xsm =
grub_register_command ("xen_xsm", grub_cmd_xen_module, 0,
N_("Load a xen security module."));
cmd_xen_module =
grub_register_command ("xen_module", grub_cmd_xen_module, 0,
N_("Load a xen module."));
my_mod = mod;
}
GRUB_MOD_FINI (xen_boot)
{
grub_unregister_command (cmd_xen_hypervisor);
grub_unregister_command (cmd_xen_linux);
grub_unregister_command (cmd_xen_initrd);
grub_unregister_command (cmd_xen_xsm);
grub_unregister_command (cmd_xen_module);
}

View file

@ -122,6 +122,8 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
if (*p == '/')
*p = '\\';
/* File Path is NULL terminated */
fp->path_name[size++] = '\0';
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
}
@ -156,8 +158,10 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
}
/* File Path is NULL terminated. Allocate space for 2 extra characters */
/* FIXME why we split path in two components? */
file_path = grub_malloc (size
+ ((grub_strlen (dir_start) + 1)
+ ((grub_strlen (dir_start) + 2)
* GRUB_MAX_UTF16_PER_UTF8
* sizeof (grub_efi_char16_t))
+ sizeof (grub_efi_file_path_device_path_t) * 2);

View file

@ -1889,6 +1889,10 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
grub_err_t err;
void *src;
if (! grub_loader_is_loaded ())
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("you need to load the kernel first"));
if (kernel_type != KERNEL_TYPE_FREEBSD)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no FreeBSD loaded");
@ -1992,6 +1996,10 @@ grub_cmd_netbsd_module (grub_command_t cmd,
{
grub_uint32_t type;
if (! grub_loader_is_loaded ())
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("you need to load the kernel first"));
if (kernel_type != KERNEL_TYPE_NETBSD)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no NetBSD loaded");
@ -2070,6 +2078,10 @@ grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)),
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
if (! grub_loader_is_loaded ())
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("you need to load the kernel first"));
if (kernel_type != KERNEL_TYPE_OPENBSD)
return grub_error (GRUB_ERR_BAD_OS, "no kOpenBSD loaded");

View file

@ -48,15 +48,15 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr)
if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
*shdr = grub_malloc (e->e_shnum * e->e_shentsize);
*shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize);
if (! *shdr)
return grub_errno;
if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
return grub_errno;
if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
!= e->e_shnum * e->e_shentsize)
if (grub_file_read (file, *shdr, (grub_uint32_t) e->e_shnum * e->e_shentsize)
!= (grub_ssize_t) ((grub_uint32_t) e->e_shnum * e->e_shentsize))
{
if (grub_errno)
return grub_errno;
@ -200,8 +200,8 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
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;
chunk_size += (grub_uint32_t) e.e_phnum * e.e_phentsize;
chunk_size += (grub_uint32_t) e.e_shnum * e.e_shentsize;
{
grub_relocator_chunk_t ch;
@ -253,14 +253,14 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
curload = module + sizeof (e);
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff,
e.e_shnum * e.e_shentsize);
(grub_uint32_t) e.e_shnum * e.e_shentsize);
e.e_shoff = curload - module;
curload += e.e_shnum * e.e_shentsize;
curload += (grub_uint32_t) e.e_shnum * e.e_shentsize;
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff,
e.e_phnum * e.e_phentsize);
(grub_uint32_t) e.e_phnum * e.e_phentsize);
e.e_phoff = curload - module;
curload += e.e_phnum * e.e_phentsize;
curload += (grub_uint32_t) e.e_phnum * e.e_phentsize;
*kern_end = curload;
@ -462,7 +462,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
+ ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t))
+ sizeof (e) + e.e_shnum * e.e_shentsize;
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
{
@ -498,10 +498,10 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
s2 = (Elf_Shdr *) curload;
grub_memcpy (curload, s, e.e_shentsize);
if (s == symsh)
s2->sh_offset = sizeof (e) + e.e_shnum * e.e_shentsize;
s2->sh_offset = sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
else if (s == strsh)
s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
+ sizeof (e) + e.e_shnum * e.e_shentsize;
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
else
s2->sh_offset = 0;
s2->sh_addr = s2->sh_offset;

View file

@ -929,8 +929,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_env_set ("gfxpayload", "text");
grub_printf_ (N_("%s is deprecated. "
"Use set gfxpayload=%s before "
"linux command instead.\n"), "text",
argv[i]);
"linux command instead.\n"),
argv[i], "text");
break;
case 1:
@ -939,8 +939,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_env_set ("gfxpayload", "text");
grub_printf_ (N_("%s is deprecated. "
"Use set gfxpayload=%s before "
"linux command instead.\n"), "text",
argv[i]);
"linux command instead.\n"),
argv[i], "text");
break;
default:
/* Ignore invalid values. */

View file

@ -71,9 +71,18 @@ load_kernel (grub_file_t file, const char *filename,
char *buffer, struct multiboot_header *header)
{
grub_err_t err;
mbi_load_data_t mld;
mld.file = file;
mld.filename = filename;
mld.buffer = buffer;
mld.mbi_ver = 1;
mld.relocatable = 0;
mld.avoid_efi_boot_services = 0;
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE)
{
err = grub_multiboot_load_elf (file, filename, buffer);
err = grub_multiboot_load_elf (&mld);
if (err == GRUB_ERR_NONE) {
return GRUB_ERR_NONE;
}
@ -122,7 +131,7 @@ load_kernel (grub_file_t file, const char *filename,
return GRUB_ERR_NONE;
}
return grub_multiboot_load_elf (file, filename, buffer);
return grub_multiboot_load_elf (&mld);
}
static struct multiboot_header *

View file

@ -205,7 +205,7 @@ grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)),
fail:
if (!grub_errno)
return grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
if (file)
grub_file_close (file);

File diff suppressed because it is too large Load diff

View file

@ -65,14 +65,14 @@ grub_xen_file_and_cmdline (grub_file_t file,
grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n",
(unsigned long long) (lh.setup_sects + 1) * 512
+ lh.payload_offset,
(unsigned long long) lh.payload_length - 4);
(unsigned long long) lh.payload_length);
if (cmdline)
grub_pass_verity_hash (&lh, cmdline, cmdline_max_len);
off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512
+ lh.payload_offset,
lh.payload_length - 4);
lh.payload_length);
if (!off_file)
goto fail;

View file

@ -18,6 +18,7 @@
#include <grub/xen_file.h>
#include <grub/misc.h>
#include <xen/elfnote.h>
static grub_err_t
parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
@ -26,6 +27,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
char *buf;
char *ptr;
int has_paddr = 0;
grub_errno = GRUB_ERR_NONE;
if (grub_file_seek (elf->file, off) == (grub_off_t) -1)
return grub_errno;
buf = grub_malloc (sz);
@ -35,7 +38,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz)
{
if (grub_errno)
return grub_errno;
goto out;
grub_free (buf);
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
elf->file->name);
}
@ -123,14 +127,14 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
{
xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16);
if (grub_errno)
return grub_errno;
goto out;
continue;
}
if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0)
{
xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16);
if (grub_errno)
return grub_errno;
goto out;
continue;
}
if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0)
@ -138,7 +142,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16);
xi->has_hypercall_page = 1;
if (grub_errno)
return grub_errno;
goto out;
continue;
}
if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0)
@ -146,7 +150,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16);
has_paddr = 1;
if (grub_errno)
return grub_errno;
goto out;
continue;
}
}
@ -154,7 +158,11 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base;
if (!has_paddr)
xi->paddr_offset = xi->virt_base;
return GRUB_ERR_NONE;
out:
grub_free (buf);
return grub_errno;
}
#pragma GCC diagnostic ignored "-Wcast-align"
@ -196,35 +204,35 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
xi->has_note = 1;
switch (nh->n_type)
{
case 1:
case XEN_ELFNOTE_ENTRY:
xi->entry_point = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
break;
case 2:
case XEN_ELFNOTE_HYPERCALL_PAGE:
xi->hypercall_page = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
xi->has_hypercall_page = 1;
break;
case 3:
case XEN_ELFNOTE_VIRT_BASE:
xi->virt_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
break;
case 4:
case XEN_ELFNOTE_PADDR_OFFSET:
xi->paddr_offset = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
break;
case 5:
case XEN_ELFNOTE_XEN_VERSION:
grub_dprintf ("xen", "xenversion = `%s'\n", (char *) desc);
break;
case 6:
case XEN_ELFNOTE_GUEST_OS:
grub_dprintf ("xen", "name = `%s'\n", (char *) desc);
break;
case 7:
case XEN_ELFNOTE_GUEST_VERSION:
grub_dprintf ("xen", "version = `%s'\n", (char *) desc);
break;
case 8:
case XEN_ELFNOTE_LOADER:
if (descsz < 7
|| grub_memcmp (desc, "generic", descsz == 7 ? 7 : 8) != 0)
return grub_error (GRUB_ERR_BAD_OS, "invalid loader");
break;
/* PAE */
case 9:
case XEN_ELFNOTE_PAE_MODE:
grub_dprintf ("xen", "pae = `%s', %d, %d\n", (char *) desc,
xi->arch, descsz);
if (xi->arch != GRUB_XEN_FILE_I386
@ -253,6 +261,13 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
descsz == 2 ? 2 : 3) == 0)
xi->arch = GRUB_XEN_FILE_I386;
break;
case XEN_ELFNOTE_INIT_P2M:
xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
xi->has_p2m_base = 1;
break;
case XEN_ELFNOTE_MOD_START_PFN:
xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc);
break;
default:
grub_dprintf ("xen", "unknown note type %d\n", nh->n_type);
break;

View file

@ -35,6 +35,7 @@
#include <grub/i18n.h>
#include <grub/bitmap_scale.h>
#include <grub/cpu/io.h>
#include <grub/random.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
@ -338,7 +339,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *
utf8 = grub_malloc (namelen * 4 + 1);
if (!utf8)
{
grub_free (utf8);
grub_free (utf16);
return grub_errno;
}
@ -577,11 +578,31 @@ static grub_err_t
grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
{
struct grub_xnu_devtree_key *efikey;
struct grub_xnu_devtree_key *chosenkey;
struct grub_xnu_devtree_key *cfgtablekey;
struct grub_xnu_devtree_key *curval;
struct grub_xnu_devtree_key *runtimesrvkey;
struct grub_xnu_devtree_key *platformkey;
unsigned i, j;
grub_err_t err;
chosenkey = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
if (! chosenkey)
return grub_errno;
/* Random seed. */
curval = grub_xnu_create_value (&(chosenkey->first_child), "random-seed");
if (! curval)
return grub_errno;
curval->datasize = 64;
curval->data = grub_malloc (curval->datasize);
if (! curval->data)
return grub_errno;
/* Our random is not peer-reviewed but xnu uses this seed only for
ASLR in kernel. */
err = grub_crypto_get_random (curval->data, curval->datasize);
if (err)
return err;
/* The value "model". */
/* FIXME: may this value be sometimes different? */
@ -897,6 +918,28 @@ grub_xnu_set_video (struct grub_xnu_boot_params_common *params)
return GRUB_ERR_NONE;
}
static int
total_ram_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size,
grub_memory_type_t type,
void *data)
{
grub_uint64_t *result = data;
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
*result += size;
return 0;
}
static grub_uint64_t
get_total_ram (void)
{
grub_uint64_t result = 0;
grub_mmap_iterate (total_ram_hook, &result);
return result;
}
/* Boot xnu. */
grub_err_t
grub_xnu_boot (void)
@ -973,6 +1016,7 @@ grub_xnu_boot (void)
{
bootparams_common = &bootparams->v2.common;
bootparams->v2.fsbfreq = fsbfreq;
bootparams->v2.ram_size = get_total_ram();
}
else
bootparams_common = &bootparams->v1.common;
@ -1080,7 +1124,7 @@ grub_xnu_boot (void)
bootparams_common->efi_mmap = memory_map_target;
bootparams_common->efi_mmap_size = memory_map_size;
bootparams_common->heap_start = grub_xnu_heap_target_start;
bootparams_common->heap_size = grub_xnu_heap_size;
bootparams_common->heap_size = curruntimepage * GRUB_XNU_PAGESIZE - grub_xnu_heap_target_start;
/* Parameters for asm helper. */
grub_xnu_stack = bootparams_common->heap_start

View file

@ -119,6 +119,48 @@ grub_multiboot_set_video_mode (void)
return err;
}
#ifdef GRUB_MACHINE_EFI
#ifdef __x86_64__
#define grub_relocator_efi_boot grub_relocator64_efi_boot
#define grub_relocator_efi_state grub_relocator64_efi_state
#endif
#endif
#ifdef grub_relocator_efi_boot
static void
efi_boot (struct grub_relocator *rel,
grub_uint32_t target)
{
struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE;
state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip;
state_efi.MULTIBOOT_EFI_MBI_REGISTER = target;
grub_relocator_efi_boot (rel, state_efi);
}
#else
#define grub_efi_is_finished 1
static void
efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
grub_uint32_t target __attribute__ ((unused)))
{
}
#endif
#if defined (__i386__) || defined (__x86_64__)
static void
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
{
grub_relocator32_boot (rel, state, 0);
}
#else
static void
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
{
grub_relocator32_boot (rel, state);
}
#endif
static grub_err_t
grub_multiboot_boot (void)
{
@ -132,11 +174,10 @@ grub_multiboot_boot (void)
if (err)
return err;
#if defined (__i386__) || defined (__x86_64__)
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
#else
grub_relocator32_boot (grub_multiboot_relocator, state);
#endif
if (grub_efi_is_finished)
normal_boot (grub_multiboot_relocator, state);
else
efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER);
/* Not reached. */
return GRUB_ERR_NONE;
@ -167,13 +208,12 @@ static grub_uint64_t highest_load;
/* Load ELF32 or ELF64. */
grub_err_t
grub_multiboot_load_elf (grub_file_t file, const char *filename,
void *buffer)
grub_multiboot_load_elf (mbi_load_data_t *mld)
{
if (grub_multiboot_is_elf32 (buffer))
return grub_multiboot_load_elf32 (file, filename, buffer);
else if (grub_multiboot_is_elf64 (buffer))
return grub_multiboot_load_elf64 (file, filename, buffer);
if (grub_multiboot_is_elf32 (mld->buffer))
return grub_multiboot_load_elf32 (mld);
else if (grub_multiboot_is_elf64 (mld->buffer))
return grub_multiboot_load_elf64 (mld);
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic"));
}

View file

@ -51,11 +51,15 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
}
static grub_err_t
CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, void *buffer)
CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
{
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer;
char *phdr_base;
grub_err_t err;
grub_relocator_chunk_t ch;
grub_uint32_t load_offset, load_size;
int i;
void *source;
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
@ -72,57 +76,89 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("this ELF file is not of the right type"));
/* FIXME: Should we support program headers at strange locations? */
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
phdr_base = (char *) buffer + ehdr->e_phoff;
phdr_base = (char *) mld->buffer + ehdr->e_phoff;
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
mld->link_base_addr = ~0;
/* Calculate lowest and highest load address. */
for (i = 0; i < ehdr->e_phnum; i++)
if (phdr(i)->p_type == PT_LOAD)
{
mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr);
highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz);
}
#ifdef MULTIBOOT_LOAD_ELF64
if (highest_load >= 0x100000000)
return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
#endif
load_size = highest_load - mld->link_base_addr;
if (mld->relocatable)
{
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
mld->min_addr, mld->max_addr - load_size,
load_size, mld->align ? mld->align : 1,
mld->preference, mld->avoid_efi_boot_services);
}
else
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch,
mld->link_base_addr, load_size);
if (err)
{
grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
return err;
}
mld->load_base_addr = get_physical_target_address (ch);
source = get_virtual_current_address (ch);
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
mld->load_base_addr, load_size, mld->relocatable);
if (mld->relocatable)
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
(long) mld->align, mld->preference, mld->avoid_efi_boot_services);
/* Load every loadable segment in memory. */
for (i = 0; i < ehdr->e_phnum; i++)
{
if (phdr(i)->p_type == PT_LOAD)
{
grub_err_t err;
void *source;
if (phdr(i)->p_paddr + phdr(i)->p_memsz > highest_load)
highest_load = phdr(i)->p_paddr + phdr(i)->p_memsz;
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&ch, phdr(i)->p_paddr,
phdr(i)->p_memsz);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
return err;
}
source = get_virtual_current_address (ch);
}
load_offset = phdr(i)->p_paddr - mld->link_base_addr;
if (phdr(i)->p_filesz != 0)
{
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset)
== (grub_off_t) -1)
return grub_errno;
if (grub_file_read (file, source, phdr(i)->p_filesz)
if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz)
!= (grub_ssize_t) phdr(i)->p_filesz)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
filename);
mld->filename);
return grub_errno;
}
}
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0,
phdr(i)->p_memsz - phdr(i)->p_filesz);
}
}
@ -164,22 +200,22 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
{
grub_uint8_t *shdr, *shdrptr;
shdr = grub_malloc (ehdr->e_shnum * ehdr->e_shentsize);
shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize);
if (!shdr)
return grub_errno;
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1)
{
grub_free (shdr);
return grub_errno;
}
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
filename);
mld->filename);
return grub_errno;
}
@ -189,7 +225,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
void *src;
grub_addr_t target;
grub_err_t err;
if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA))
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet");
/* This section is a loaded section,
so we don't care. */
@ -200,33 +238,28 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
if (sh->sh_size == 0)
continue;
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
&ch, 0,
(0xffffffff - sh->sh_size)
+ 1, sh->sh_size,
sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE,
0);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
return err;
}
src = get_virtual_current_address (ch);
target = get_physical_target_address (ch);
}
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0,
(0xffffffff - sh->sh_size) + 1,
sh->sh_size, sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE,
mld->avoid_efi_boot_services);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
return err;
}
src = get_virtual_current_address (ch);
target = get_physical_target_address (ch);
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1)
return grub_errno;
if (grub_file_read (file, src, sh->sh_size)
if (grub_file_read (mld->file, src, sh->sh_size)
!= (grub_ssize_t) sh->sh_size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
filename);
mld->filename);
return grub_errno;
}
sh->sh_addr = target;

View file

@ -69,6 +69,7 @@ static grub_size_t elf_sec_num, elf_sec_entsize;
static unsigned elf_sec_shstrndx;
static void *elf_sections;
static int keep_bs = 0;
static grub_uint32_t load_base_addr;
void
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
@ -102,39 +103,43 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
grub_err_t
grub_multiboot_load (grub_file_t file, const char *filename)
{
grub_properly_aligned_t *buffer;
grub_ssize_t len;
struct multiboot_header *header;
grub_err_t err;
struct multiboot_header_tag *tag;
struct multiboot_header_tag_address *addr_tag = NULL;
int entry_specified = 0;
grub_addr_t entry = 0;
struct multiboot_header_tag_relocatable *rel_tag;
int entry_specified = 0, efi_entry_specified = 0;
grub_addr_t entry = 0, efi_entry = 0;
grub_uint32_t console_required = 0;
struct multiboot_header_tag_framebuffer *fbtag = NULL;
int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
mbi_load_data_t mld;
buffer = grub_malloc (MULTIBOOT_SEARCH);
if (!buffer)
mld.mbi_ver = 2;
mld.relocatable = 0;
mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
if (!mld.buffer)
return grub_errno;
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
if (len < 32)
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
}
COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
grub_tpm_measure ((unsigned char *)buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
grub_tpm_measure ((unsigned char *)mld.buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
grub_print_error();
header = find_header (buffer, len);
header = find_header (mld.buffer, len);
if (header == 0)
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
}
@ -176,10 +181,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
case MULTIBOOT_TAG_TYPE_NETWORK:
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
case MULTIBOOT_TAG_TYPE_EFI_BS:
case MULTIBOOT_TAG_TYPE_EFI32_IH:
case MULTIBOOT_TAG_TYPE_EFI64_IH:
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
break;
default:
grub_free (buffer);
grub_free (mld.buffer);
return grub_error (GRUB_ERR_UNKNOWN_OS,
"unsupported information tag: 0x%x",
request_tag->requests[i]);
@ -196,6 +204,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
break;
case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
efi_entry_specified = 1;
efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
#endif
break;
case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
& MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
@ -210,27 +225,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
break;
case MULTIBOOT_HEADER_TAG_RELOCATABLE:
mld.relocatable = 1;
rel_tag = (struct multiboot_header_tag_relocatable *) tag;
mld.min_addr = rel_tag->min_addr;
mld.max_addr = rel_tag->max_addr;
mld.align = rel_tag->align;
switch (rel_tag->preference)
{
case MULTIBOOT_LOAD_PREFERENCE_LOW:
mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
break;
case MULTIBOOT_LOAD_PREFERENCE_HIGH:
mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
break;
default:
mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
}
break;
/* GRUB always page-aligns modules. */
case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
break;
case MULTIBOOT_HEADER_TAG_EFI_BS:
#ifdef GRUB_MACHINE_EFI
keep_bs = 1;
#endif
break;
default:
if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_error (GRUB_ERR_UNKNOWN_OS,
"unsupported tag: 0x%x", tag->type);
}
break;
}
if (addr_tag && !entry_specified)
if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_error (GRUB_ERR_UNKNOWN_OS,
"load address tag without entry address tag");
}
@ -239,8 +277,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
{
grub_uint64_t load_addr = (addr_tag->load_addr + 1)
? addr_tag->load_addr : (addr_tag->header_addr
- ((char *) header - (char *) buffer));
int offset = ((char *) header - (char *) buffer -
- ((char *) header - (char *) mld.buffer));
int offset = ((char *) header - (char *) mld.buffer -
(addr_tag->header_addr - load_addr));
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
addr_tag->load_end_addr - addr_tag->load_addr);
@ -253,27 +291,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
else
code_size = load_size;
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&ch, load_addr,
code_size);
if (mld.relocatable)
{
if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
{
grub_free (mld.buffer);
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
}
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
mld.min_addr, mld.max_addr - code_size,
code_size, mld.align ? mld.align : 1,
mld.preference, keep_bs);
}
else
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
&ch, load_addr, code_size);
if (err)
{
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
grub_free (buffer);
grub_free (mld.buffer);
return err;
}
mld.link_base_addr = load_addr;
mld.load_base_addr = get_physical_target_address (ch);
source = get_virtual_current_address (ch);
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
"load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
mld.load_base_addr, (long) code_size, mld.relocatable);
if (mld.relocatable)
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
(long) mld.align, mld.preference, keep_bs);
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_errno;
}
grub_file_read (file, source, load_size);
if (grub_errno)
{
grub_free (buffer);
grub_free (mld.buffer);
return grub_errno;
}
@ -283,17 +344,41 @@ grub_multiboot_load (grub_file_t file, const char *filename)
}
else
{
err = grub_multiboot_load_elf (file, filename, buffer);
mld.file = file;
mld.filename = filename;
mld.avoid_efi_boot_services = keep_bs;
err = grub_multiboot_load_elf (&mld);
if (err)
{
grub_free (buffer);
grub_free (mld.buffer);
return err;
}
}
if (entry_specified)
load_base_addr = mld.load_base_addr;
if (keep_bs && efi_entry_specified)
grub_multiboot_payload_eip = efi_entry;
else if (entry_specified)
grub_multiboot_payload_eip = entry;
if (mld.relocatable)
{
/*
* Both branches are mathematically equivalent. However, it looks
* that real life (C?) is more complicated. I am trying to avoid
* wrap around here if mld.load_base_addr < mld.link_base_addr.
* If you look at C operator precedence then everything should work.
* However, I am not 100% sure that a given compiler will not
* optimize/break this stuff. So, maybe we should use signed
* 64-bit int here.
*/
if (mld.load_base_addr >= mld.link_base_addr)
grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr;
else
grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr;
}
if (fbtag)
err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
accepted_consoles,
@ -381,7 +466,7 @@ static grub_size_t
grub_multiboot_get_mbi_size (void)
{
#ifdef GRUB_MACHINE_EFI
if (!efi_mmap_size)
if (!keep_bs && !efi_mmap_size)
find_efi_mmap_size ();
#endif
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
@ -400,13 +485,16 @@ grub_multiboot_get_mbi_size (void)
+ grub_get_multiboot_mmap_count ()
* sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
+ acpiv2_size ()
+ net_size ()
#ifdef GRUB_MACHINE_EFI
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
+ ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
#endif
@ -424,6 +512,7 @@ grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
(*mmap_entry)->addr = addr;
(*mmap_entry)->len = size;
(*mmap_entry)->type = type;
(*mmap_entry)->zero = 0;
(*mmap_entry)++;
return 0;
@ -681,6 +770,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
% sizeof (grub_properly_aligned_t) == 0);
ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
{
struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
tag->size = sizeof (struct multiboot_tag_load_base_addr);
tag->load_base_addr = load_base_addr;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
{
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
@ -743,12 +841,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
}
}
{
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
grub_fill_multiboot_mmap (tag);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
if (!keep_bs)
{
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
grub_fill_multiboot_mmap (tag);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
{
struct multiboot_tag_elf_sections *tag
@ -764,18 +863,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
/ sizeof (grub_properly_aligned_t);
}
{
struct multiboot_tag_basic_meminfo *tag
= (struct multiboot_tag_basic_meminfo *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
if (!keep_bs)
{
struct multiboot_tag_basic_meminfo *tag
= (struct multiboot_tag_basic_meminfo *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
/* Convert from bytes to kilobytes. */
tag->mem_lower = grub_mmap_get_lower () / 1024;
tag->mem_upper = grub_mmap_get_upper () / 1024;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
/* Convert from bytes to kilobytes. */
tag->mem_lower = grub_mmap_get_lower () / 1024;
tag->mem_upper = grub_mmap_get_upper () / 1024;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
{
struct grub_net_network_level_interface *net;
@ -874,36 +974,57 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
grub_efi_uintn_t efi_desc_size;
grub_efi_uint32_t efi_desc_version;
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
tag->size = sizeof (*tag) + efi_mmap_size;
if (!keep_bs)
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
&efi_desc_size, &efi_desc_version);
else
{
if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
NULL,
&efi_desc_size, &efi_desc_version) <= 0)
err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
}
if (err)
return err;
tag->descr_size = efi_desc_size;
tag->descr_vers = efi_desc_version;
tag->size = sizeof (*tag) + efi_mmap_size;
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
tag->size = sizeof (*tag) + efi_mmap_size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
&efi_desc_size, &efi_desc_version);
if (err)
return err;
tag->descr_size = efi_desc_size;
tag->descr_vers = efi_desc_version;
tag->size = sizeof (*tag) + efi_mmap_size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
}
if (keep_bs)
{
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
tag->size = sizeof (struct multiboot_tag);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
{
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
tag->size = sizeof (struct multiboot_tag);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
#ifdef __i386__
{
struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
tag->size = sizeof (struct multiboot_tag_efi32_ih);
tag->pointer = (grub_addr_t) grub_efi_image_handle;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
#endif
#ifdef __x86_64__
{
struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
tag->size = sizeof (struct multiboot_tag_efi64_ih);
tag->pointer = (grub_addr_t) grub_efi_image_handle;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
/ sizeof (grub_properly_aligned_t);
}
#endif
}
#endif

View file

@ -140,17 +140,17 @@ grub_linux_boot (void)
grub_dprintf ("loader", "Jumping to Linux...\n");
/* Boot the kernel. */
asm volatile ("sethi %hi(grub_ieee1275_entry_fn), %o1\n"
"ldx [%o1 + %lo(grub_ieee1275_entry_fn)], %o4\n"
"sethi %hi(grub_ieee1275_original_stack), %o1\n"
"ldx [%o1 + %lo(grub_ieee1275_original_stack)], %o6\n"
"sethi %hi(linux_addr), %o1\n"
"ldx [%o1 + %lo(linux_addr)], %o5\n"
"mov %g0, %o0\n"
"mov %g0, %o2\n"
"mov %g0, %o3\n"
"jmp %o5\n"
"mov %g0, %o1\n");
asm volatile ("ldx %0, %%o4\n"
"ldx %1, %%o6\n"
"ldx %2, %%o5\n"
"mov %%g0, %%o0\n"
"mov %%g0, %%o2\n"
"mov %%g0, %%o3\n"
"jmp %%o5\n"
"mov %%g0, %%o1\n": :
"m"(grub_ieee1275_entry_fn),
"m"(grub_ieee1275_original_stack),
"m"(linux_addr));
return GRUB_ERR_NONE;
}
@ -203,20 +203,20 @@ alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
if (addr + ctx->size >= end)
return 0;
if (addr >= grub_phys_start && addr < grub_phys_end)
{
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
if (addr + ctx->size >= end)
return 0;
}
if ((addr + ctx->size) >= grub_phys_start
&& (addr + ctx->size) < grub_phys_end)
/* OBP available region contains grub. Start at grub_phys_end. */
/* grub_phys_start does not start at the beginning of the memory region */
if ((grub_phys_start >= addr && grub_phys_end < end) ||
(addr > grub_phys_start && addr < grub_phys_end))
{
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
if (addr + ctx->size >= end)
return 0;
}
grub_dprintf("loader",
"addr = 0x%lx grub_phys_start = 0x%lx grub_phys_end = 0x%lx\n",
addr, grub_phys_start, grub_phys_end);
if (loaded)
{
grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);

View file

@ -100,7 +100,7 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
grub_memcpy (&gw.ipv4, ptr, sizeof (gw.ipv4));
rname = grub_xasprintf ("%s:default", name);
if (rname)
grub_net_add_route_gw (rname, target, gw);
grub_net_add_route_gw (rname, target, gw, NULL);
grub_free (rname);
}
break;
@ -160,6 +160,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
grub_net_link_level_address_t hwaddr;
struct grub_net_network_level_interface *inter;
int mask = -1;
char server_ip[sizeof ("xxx.xxx.xxx.xxx")];
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
addr.ipv4 = bp->your_ip;
@ -175,6 +176,9 @@ grub_net_configure_by_dhcp_ack (const char *name,
hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
if (!inter)
return 0;
#if 0
/* This is likely based on misunderstanding. gateway_ip refers to
address of BOOTP relay and should not be used after BOOTP transaction
@ -207,15 +211,22 @@ grub_net_configure_by_dhcp_ack (const char *name,
if (size > OFFSET_OF (boot_file, bp))
grub_env_set_net_property (name, "boot_file", bp->boot_file,
sizeof (bp->boot_file));
if (bp->server_ip)
{
grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d",
((grub_uint8_t *) &bp->server_ip)[0],
((grub_uint8_t *) &bp->server_ip)[1],
((grub_uint8_t *) &bp->server_ip)[2],
((grub_uint8_t *) &bp->server_ip)[3]);
grub_env_set_net_property (name, "next_server", server_ip, sizeof (server_ip));
grub_print_error ();
}
if (is_def)
grub_net_default_server = 0;
if (is_def && !grub_net_default_server && bp->server_ip)
{
grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d",
((grub_uint8_t *) &bp->server_ip)[0],
((grub_uint8_t *) &bp->server_ip)[1],
((grub_uint8_t *) &bp->server_ip)[2],
((grub_uint8_t *) &bp->server_ip)[3]);
grub_net_default_server = grub_strdup (server_ip);
grub_print_error ();
}
@ -227,11 +238,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
if (device && !*device && bp->server_ip)
{
*device = grub_xasprintf ("tftp,%d.%d.%d.%d",
((grub_uint8_t *) &bp->server_ip)[0],
((grub_uint8_t *) &bp->server_ip)[1],
((grub_uint8_t *) &bp->server_ip)[2],
((grub_uint8_t *) &bp->server_ip)[3]);
*device = grub_xasprintf ("tftp,%s", server_ip);
grub_print_error ();
}
if (size > OFFSET_OF (server_name, bp)
@ -386,6 +393,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (grub_strcmp (args[3], "string") == 0)
{
grub_err_t err = GRUB_ERR_NONE;
char *val = grub_malloc (taglength + 1);
if (!val)
return grub_errno;
@ -394,8 +402,9 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (args[0][0] == '-' && args[0][1] == 0)
grub_printf ("%s\n", val);
else
return grub_env_set (args[0], val);
return GRUB_ERR_NONE;
err = grub_env_set (args[0], val);
grub_free (val);
return err;
}
if (grub_strcmp (args[3], "number") == 0)
@ -417,6 +426,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (grub_strcmp (args[3], "hex") == 0)
{
grub_err_t err = GRUB_ERR_NONE;
char *val = grub_malloc (2 * taglength + 1);
int i;
if (!val)
@ -430,8 +440,9 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (args[0][0] == '-' && args[0][1] == 0)
grub_printf ("%s\n", val);
else
return grub_env_set (args[0], val);
return GRUB_ERR_NONE;
err = grub_env_set (args[0], val);
grub_free (val);
return err;
}
return grub_error (GRUB_ERR_BAD_ARGUMENT,

View file

@ -238,6 +238,15 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
char *redirect_save = NULL;
grub_uint32_t ttl_all = ~0U;
/* Code apparently assumed that only one packet is received as response.
We may get multiple responses due to network condition, so check here
and quit early. */
if (*data->addresses)
{
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
}
head = (struct dns_header *) nb->data;
ptr = (grub_uint8_t *) (head + 1);
if (ptr >= nb->tail)

View file

@ -85,24 +85,30 @@ get_card_packet (struct grub_net_card *dev)
grub_uint64_t start_time;
struct grub_net_buff *nb;
nb = grub_netbuff_alloc (dev->mtu + 64 + 2);
start_time = grub_get_time_ms ();
do
rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
if (actual <= 0)
return NULL;
nb = grub_netbuff_alloc (actual + 2);
if (!nb)
return NULL;
/* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible
by 4. So that IP header is aligned on 4 bytes. */
grub_netbuff_reserve (nb, 2);
start_time = grub_get_time_ms ();
do
rc = grub_ieee1275_read (data->handle, nb->data, dev->mtu + 64, &actual);
while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
if (actual > 0)
grub_memcpy (nb->data, dev->rcvbuf, actual);
if (grub_netbuff_put (nb, actual))
{
grub_netbuff_put (nb, actual);
return nb;
grub_netbuff_free (nb);
return NULL;
}
grub_netbuff_free (nb);
return NULL;
return nb;
}
static struct grub_net_card_driver ofdriver =
@ -151,7 +157,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath,
grub_net_network_level_address_t client_addr, gateway_addr, subnet_mask;
grub_net_link_level_address_t hw_addr;
grub_net_interface_flags_t flags = 0;
struct grub_net_network_level_interface *inter;
struct grub_net_network_level_interface *inter = NULL;
hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
@ -221,7 +227,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath,
target.ipv4.masksize = 0;
rname = grub_xasprintf ("%s:default", ((*card)->name));
if (rname)
grub_net_add_route_gw (rname, target, gateway_addr);
grub_net_add_route_gw (rname, target, gateway_addr, inter);
else
return grub_errno;
}
@ -294,6 +300,91 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path,
}
}
/* Allocate memory with alloc-mem */
static void *
grub_ieee1275_alloc_mem (grub_size_t len)
{
struct alloc_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t len;
grub_ieee1275_cell_t catch;
grub_ieee1275_cell_t result;
}
args;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
{
grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported"));
return NULL;
}
INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2);
args.len = len;
args.method = (grub_ieee1275_cell_t) "alloc-mem";
if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch)
{
grub_error (GRUB_ERR_INVALID_COMMAND, N_("alloc-mem failed"));
return NULL;
}
else
return (void *)args.result;
}
/* Free memory allocated by alloc-mem */
static grub_err_t
grub_ieee1275_free_mem (void *addr, grub_size_t len)
{
struct free_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t len;
grub_ieee1275_cell_t addr;
grub_ieee1275_cell_t catch;
}
args;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
{
grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported"));
return grub_errno;
}
INIT_IEEE1275_COMMON (&args.common, "interpret", 3, 1);
args.addr = (grub_ieee1275_cell_t)addr;
args.len = len;
args.method = (grub_ieee1275_cell_t) "free-mem";
if (IEEE1275_CALL_ENTRY_FN(&args) == -1 || args.catch)
{
grub_error (GRUB_ERR_INVALID_COMMAND, N_("free-mem failed"));
return grub_errno;
}
return GRUB_ERR_NONE;
}
static void *
ofnet_alloc_netbuf (grub_size_t len)
{
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
return grub_ieee1275_alloc_mem (len);
else
return grub_zalloc (len);
}
static void
ofnet_free_netbuf (void *addr, grub_size_t len)
{
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
grub_ieee1275_free_mem (addr, len);
else
grub_free (addr);
}
static int
search_net_devices (struct grub_ieee1275_devalias *alias)
{
@ -409,40 +500,19 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
card->default_address = lla;
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256;
card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
{
struct alloc_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t len;
grub_ieee1275_cell_t catch;
grub_ieee1275_cell_t result;
}
args;
INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2);
args.len = card->txbufsize;
args.method = (grub_ieee1275_cell_t) "alloc-mem";
if (IEEE1275_CALL_ENTRY_FN (&args) == -1
|| args.catch)
{
card->txbuf = 0;
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
}
else
card->txbuf = (void *) args.result;
}
else
card->txbuf = grub_zalloc (card->txbufsize);
card->txbuf = ofnet_alloc_netbuf (card->txbufsize);
if (!card->txbuf)
goto fail_netbuf;
card->rcvbuf = ofnet_alloc_netbuf (card->rcvbufsize);
if (!card->rcvbuf)
{
grub_free (ofdata->path);
grub_free (ofdata);
grub_free (card);
grub_print_error ();
return 0;
grub_error_push ();
ofnet_free_netbuf (card->txbuf, card->txbufsize);
grub_error_pop ();
goto fail_netbuf;
}
card->driver = NULL;
card->data = ofdata;
@ -455,6 +525,13 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
card->driver = &ofdriver;
grub_net_card_register (card);
return 0;
fail_netbuf:
grub_free (ofdata->path);
grub_free (ofdata);
grub_free (card);
grub_print_error ();
return 0;
}
static void

View file

@ -381,9 +381,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
ptr = nb->tail;
grub_snprintf ((char *) ptr,
sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX-"
"\r\n"
"\r\n"),
"Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n\r\n",
"Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n",
offset);
grub_netbuff_put (nb, grub_strlen ((char *) ptr));
}
@ -454,6 +453,7 @@ http_seek (struct grub_file *file, grub_off_t off)
}
file->device->net->stall = 0;
file->device->net->eof = 0;
file->device->net->offset = off;
data = grub_zalloc (sizeof (*data));

View file

@ -115,6 +115,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
grub_uint8_t ttl)
{
struct icmp_header *icmph;
struct grub_net_network_level_interface *orig_inf = inf;
grub_err_t err;
grub_uint16_t checksum;
@ -345,14 +346,31 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
{
grub_uint8_t *ptr;
struct option_header *ohdr;
struct router_adv *radv;
struct grub_net_network_level_interface *route_inf = NULL;
int default_route = 0;
if (icmph->code)
break;
radv = (struct router_adv *)nb->data;
err = grub_netbuff_pull (nb, sizeof (struct router_adv));
if (err)
{
grub_netbuff_free (nb);
return err;
}
if (grub_be_to_cpu16 (radv->router_lifetime) > 0)
{
struct grub_net_route *route;
FOR_NET_ROUTES (route)
{
if (!grub_memcmp (&route->gw, source, sizeof (route->gw)))
break;
}
if (route == NULL)
default_route = 1;
}
for (ptr = (grub_uint8_t *) nb->data; ptr < nb->tail;
ptr += ohdr->len * 8)
{
@ -413,7 +431,11 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
/* Update lease time if needed here once we have
lease times. */
if (inf)
continue;
{
if (!route_inf)
route_inf = inf;
continue;
}
grub_dprintf ("net", "creating slaac\n");
@ -429,12 +451,51 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
inf = grub_net_add_addr (name,
card, &addr,
&slaac->address, 0);
if (!route_inf)
route_inf = inf;
grub_net_add_route (name, netaddr, inf);
grub_free (name);
}
}
}
}
if (default_route)
{
char *name;
grub_net_network_level_netaddress_t netaddr;
name = grub_xasprintf ("%s:ra:default6", card->name);
if (!name)
{
grub_errno = GRUB_ERR_NONE;
goto next;
}
/* Default routes take alll of the traffic, so make the mask huge */
netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
netaddr.ipv6.masksize = 0;
netaddr.ipv6.base[0] = 0;
netaddr.ipv6.base[1] = 0;
/* May not have gotten slaac info, find a global address on this
card. */
if (route_inf == NULL)
{
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
{
if (inf->card == card && inf != orig_inf
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
&& grub_net_hwaddr_cmp(&inf->hwaddress,
&orig_inf->hwaddress) == 0)
{
route_inf = inf;
break;
}
}
}
if (route_inf != NULL)
grub_net_add_route_gw (name, netaddr, *source, route_inf);
grub_free (name);
}
next:
if (ptr != nb->tail)
break;
}

View file

@ -363,7 +363,9 @@ static void
free_old_fragments (void)
{
struct reassemble *rsm, **prev;
grub_uint64_t limit_time = grub_get_time_ms () - 90000;
grub_uint64_t limit_time = grub_get_time_ms ();
limit_time = (limit_time > 90000) ? limit_time - 90000 : 0;
for (prev = &reassembles, rsm = *prev; rsm; rsm = *prev)
if (rsm->last_time < limit_time)

View file

@ -37,21 +37,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
char *grub_net_default_server;
struct grub_net_route
{
struct grub_net_route *next;
struct grub_net_route **prev;
grub_net_network_level_netaddress_t target;
char *name;
struct grub_net_network_level_protocol *prot;
int is_gateway;
union
{
struct grub_net_network_level_interface *interface;
grub_net_network_level_address_t gw;
};
};
struct grub_net_route *grub_net_routes = NULL;
struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL;
struct grub_net_card *grub_net_cards = NULL;
@ -299,12 +284,6 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
char *ptr;
grub_net_network_level_address_t addr;
name = grub_malloc (grub_strlen (card->name)
+ GRUB_NET_MAX_STR_HWADDR_LEN
+ sizeof (":link"));
if (!name)
return NULL;
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48);
addr.ipv6[1] = grub_net_ipv6_get_id (hwaddr);
@ -317,6 +296,12 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
return inf;
}
name = grub_malloc (grub_strlen (card->name)
+ GRUB_NET_MAX_STR_HWADDR_LEN
+ sizeof (":link"));
if (!name)
return NULL;
ptr = grub_stpcpy (name, card->name);
if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0)
{
@ -410,14 +395,6 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)),
return err;
}
static inline void
grub_net_route_register (struct grub_net_route *route)
{
grub_list_push (GRUB_AS_LIST_P (&grub_net_routes),
GRUB_AS_LIST (route));
}
#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next)
static int
parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
@ -524,6 +501,8 @@ match_net (const grub_net_network_level_netaddress_t *net,
case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6:
{
grub_uint64_t mask[2];
if (net->ipv6.masksize == 0)
return 1;
if (net->ipv6.masksize <= 64)
{
mask[0] = 0xffffffffffffffffULL << (64 - net->ipv6.masksize);
@ -687,7 +666,14 @@ grub_net_route_address (grub_net_network_level_address_t addr,
return GRUB_ERR_NONE;
}
if (depth == 0)
*gateway = bestroute->gw;
{
*gateway = bestroute->gw;
if (bestroute->interface != NULL)
{
*interf = bestroute->interface;
return GRUB_ERR_NONE;
}
}
curtarget = bestroute->gw;
}
@ -1109,7 +1095,8 @@ grub_net_add_route (const char *name,
grub_err_t
grub_net_add_route_gw (const char *name,
grub_net_network_level_netaddress_t target,
grub_net_network_level_address_t gw)
grub_net_network_level_address_t gw,
struct grub_net_network_level_interface *inter)
{
struct grub_net_route *route;
@ -1127,6 +1114,7 @@ grub_net_add_route_gw (const char *name,
route->target = target;
route->is_gateway = 1;
route->gw = gw;
route->interface = inter;
grub_net_route_register (route);
@ -1152,7 +1140,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
err = grub_net_resolve_address (args[3], &gw);
if (err)
return err;
return grub_net_add_route_gw (args[0], target, gw);
return grub_net_add_route_gw (args[0], target, gw, NULL);
}
else
{
@ -1333,7 +1321,8 @@ grub_net_open_real (const char *name)
if (!ret)
return NULL;
ret->protocol = proto;
if (server)
ret->server = grub_strdup (server);
if (!ret->server)
{
ret->server = grub_strdup (server);
ret->port = port;
@ -1343,11 +1332,7 @@ grub_net_open_real (const char *name)
return NULL;
}
}
else
ret->server = NULL;
ret->fs = &grub_net_fs;
ret->offset = 0;
ret->eof = 0;
return ret;
}
}
@ -1377,6 +1362,15 @@ grub_net_open_real (const char *name)
continue;
}
if (grub_strncmp (prefdev, "pxe", sizeof ("pxe") - 1) == 0 &&
(!prefdev[sizeof ("pxe") - 1] || (prefdev[sizeof("pxe") - 1] == ':')))
{
grub_free (prefdev);
prefdev = grub_strdup ("tftp");
if (!prefdev)
continue;
}
comma = grub_strchr (prefdev, ',');
if (comma)
*comma = '\0';
@ -1440,7 +1434,10 @@ grub_net_fs_open (struct grub_file *file_out, const char *name)
file->device->net->packs.last = NULL;
file->device->net->name = grub_strdup (name);
if (!file->device->net->name)
return grub_errno;
{
grub_free (file);
return grub_errno;
}
err = file->device->net->protocol->open (file, name);
if (err)
@ -1700,6 +1697,7 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset)
file->device->net->packs.last = NULL;
file->device->net->offset = 0;
file->device->net->eof = 0;
file->device->net->stall = 0;
err = file->device->net->protocol->open (file, file->device->net->name);
if (err)
return err;

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