Merge branch 'master' into next

This commit is contained in:
Vladimir Serbinenko committed 2016-02-28 15:22:52 +01:00
commit b4fc7bc2fd
314 files changed
+14315 -4383

No files matched your search

+3
View File
@@ -104,6 +104,9 @@ The simplest way to compile this package is:
3. Type `./autogen.sh'. 3. Type `./autogen.sh'.
* autogen.sh uses python. By default invocation is "python" but can be
overriden by setting variable $PYTHON.
4. Type `./configure' to configure the package for your system. 4. Type `./configure' to configure the package for your system.
If you're using `csh' on an old version of System V, you might If you're using `csh' on an old version of System V, you might
need to type `sh ./configure' instead to prevent `csh' from trying need to type `sh ./configure' instead to prevent `csh' from trying
+43 -35
View File
@@ -89,16 +89,21 @@ CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT)
if COND_STARFIELD if COND_STARFIELD
starfield_DATA = dejavu_10.pf2 dejavu_12.pf2 dejavu_bold_14.pf2 dejavu_14.pf2 dejavu_16.pf2 $(starfield_theme_files) 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 dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont -s 10 -o $@ $(DJVU_FONT_SOURCE) ./build-grub-mkfont$(BUILD_EXEEXT) -s 10 -o $@ $(DJVU_FONT_SOURCE)
dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont CLEANFILES += dejavu_10.pf2
./build-grub-mkfont -s 12 -o $@ $(DJVU_FONT_SOURCE) dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont ./build-grub-mkfont$(BUILD_EXEEXT) -s 12 -o $@ $(DJVU_FONT_SOURCE)
./build-grub-mkfont -s 14 -o $@ $(DJVU_FONT_SOURCE) CLEANFILES += dejavu_12.pf2
dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont -b -s 14 -o $@ $(DJVU_FONT_SOURCE) ./build-grub-mkfont$(BUILD_EXEEXT) -s 14 -o $@ $(DJVU_FONT_SOURCE)
dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont CLEANFILES += dejavu_14.pf2
./build-grub-mkfont -s 16 -o $@ $(DJVU_FONT_SOURCE) 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 else
starfield_DATA = starfield_DATA =
endif endif
@@ -106,28 +111,28 @@ endif
EXTRA_DIST += $(starfield_theme_files) 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 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 unicode.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1) ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
CLEANFILES += unicode.pf2 CLEANFILES += unicode.pf2
# Arrows and lines are needed to draw the menu, so always include them # Arrows and lines are needed to draw the menu, so always include them
UNICODE_ARROWS=0x2190-0x2193 UNICODE_ARROWS=0x2190-0x2193
UNICODE_LINES=0x2501-0x251B UNICODE_LINES=0x2501-0x251B
ascii.pf2: $(FONT_SOURCE) build-grub-mkfont ascii.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += ascii.pf2 CLEANFILES += ascii.pf2
euro.pf2: $(FONT_SOURCE) build-grub-mkfont euro.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += euro.pf2 CLEANFILES += euro.pf2
ascii.h: $(FONT_SOURCE) build-grub-gen-asciih ascii.h: $(FONT_SOURCE) build-grub-gen-asciih$(BUILD_EXEEXT)
./build-grub-gen-asciih $(FONT_SOURCE) $@ || (rm -f $@; exit 1) ./build-grub-gen-asciih$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += ascii.h CLEANFILES += ascii.h
widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec$(BUILD_EXEEXT)
./build-grub-gen-widthspec $(FONT_SOURCE) $@ || (rm -f $@; exit 1) ./build-grub-gen-widthspec$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += widthspec.h CLEANFILES += widthspec.h
# Install config.h into platformdir # 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 ./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 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 endif
if COND_x86_64_efi 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 endif
if COND_i386_multiboot if COND_i386_multiboot
# FreeBSD requires ACPI # *BSD 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-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 endif
if COND_i386_coreboot 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 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
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
endif endif
if COND_i386_pc if COND_i386_pc
#pc chainloader by definition is only for i386-pc #pc chainloader by definition is only for i386-pc
#ntldr and bootmgr require BIOS. #ntldr and bootmgr require BIOS.
#legacy protocol makes early BIOS calls. #legacy protocol (linux16) makes early BIOS calls.
# NetBSD crashes early on non-BIOS # 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 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 endif
@@ -402,8 +409,9 @@ BOOTCHECK_TIMEOUT=180
bootcheck: $(BOOTCHECKS) bootcheck: $(BOOTCHECKS)
if COND_i386_coreboot if COND_i386_coreboot
default_payload.elf: grub-mkstandalone grub-mkimage default_payload.elf: grub-mkstandalone grub-mkimage FORCE
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 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
endif endif
+11 -2
View File
@@ -48,6 +48,7 @@ library = {
common = grub-core/partmap/gpt.c; common = grub-core/partmap/gpt.c;
common = grub-core/partmap/msdos.c; common = grub-core/partmap/msdos.c;
common = grub-core/fs/proc.c; common = grub-core/fs/proc.c;
common = grub-core/fs/archelp.c;
}; };
library = { library = {
@@ -91,7 +92,6 @@ library = {
common = grub-core/fs/bfs.c; common = grub-core/fs/bfs.c;
common = grub-core/fs/btrfs.c; common = grub-core/fs/btrfs.c;
common = grub-core/fs/cbfs.c; common = grub-core/fs/cbfs.c;
common = grub-core/fs/archelp.c;
common = grub-core/fs/cpio.c; common = grub-core/fs/cpio.c;
common = grub-core/fs/cpio_be.c; common = grub-core/fs/cpio_be.c;
common = grub-core/fs/odc.c; common = grub-core/fs/odc.c;
@@ -172,6 +172,8 @@ program = {
common = util/grub-mkimage.c; common = util/grub-mkimage.c;
common = util/mkimage.c; common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/resolve.c; common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c; common = grub-core/osdep/init.c;
@@ -510,6 +512,8 @@ program = {
common = util/render-label.c; common = util/render-label.c;
common = util/glue-efi.c; common = util/glue-efi.c;
common = util/mkimage.c; common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c; common = util/grub-install-common.c;
common = util/setup_bios.c; common = util/setup_bios.c;
common = util/setup_sparc.c; common = util/setup_sparc.c;
@@ -552,6 +556,8 @@ program = {
common = util/render-label.c; common = util/render-label.c;
common = util/glue-efi.c; common = util/glue-efi.c;
common = util/mkimage.c; common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c; common = util/grub-install-common.c;
common = util/setup_bios.c; common = util/setup_bios.c;
common = util/setup_sparc.c; common = util/setup_sparc.c;
@@ -595,6 +601,8 @@ program = {
common = util/grub-install.c; common = util/grub-install.c;
common = util/probe.c; common = util/probe.c;
common = util/mkimage.c; common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c; common = util/grub-install-common.c;
common = util/setup_bios.c; common = util/setup_bios.c;
common = util/setup_sparc.c; common = util/setup_sparc.c;
@@ -613,7 +621,6 @@ program = {
common = grub-core/disk/host.c; common = grub-core/disk/host.c;
common = util/resolve.c; common = util/resolve.c;
enable = noemu;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c; common = grub-core/osdep/init.c;
@@ -633,6 +640,8 @@ program = {
common = util/grub-mknetdir.c; common = util/grub-mknetdir.c;
common = util/mkimage.c; common = util/mkimage.c;
common = util/grub-mkimage32.c;
common = util/grub-mkimage64.c;
common = util/grub-install-common.c; common = util/grub-install-common.c;
common = util/setup_bios.c; common = util/setup_bios.c;
common = util/setup_sparc.c; common = util/setup_sparc.c;
+15
View File
@@ -17,6 +17,7 @@ New in 2.02:
files. files.
* ZFS features support. * ZFS features support.
* ZFS LZ4 support. * ZFS LZ4 support.
* XFS V5 format support.
* New/improved terminal and video support: * New/improved terminal and video support:
* Monochrome text (matching `hercules' in GRUB Legacy). * Monochrome text (matching `hercules' in GRUB Legacy).
@@ -58,6 +59,7 @@ New in 2.02:
* Command for inspecting coreboot tables (`lscoreboot'). * Command for inspecting coreboot tables (`lscoreboot').
* New target default_payload.elf. * New target default_payload.elf.
* Increased maximal core size. * Increased maximal core size.
* Prefer pmtimer for TSC calibration.
* New/improved platform support: * New/improved platform support:
* New `efifwsetup' and `lsefi' commands on EFI platforms. * New `efifwsetup' and `lsefi' commands on EFI platforms.
@@ -87,6 +89,13 @@ New in 2.02:
* Support *-emu on Windows. * Support *-emu on Windows.
* New platform `none' which builds only user level utilities. This is now * New platform `none' which builds only user level utilities. This is now
default if target CPU is not supported. default if target CPU is not supported.
* Support for booting little-endian Linux kernel on powerpc.
* Support network boot with Oracle sun4v vnet devices.
* Added SAS disks to the IEEE 1275 Open Firmware device list.
* Try multiple methods for TSC (timestamp counter) calibration - PIT, pmtimer,
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.
* Security: * Security:
* Add optional facility to enforce that all files read by the core image * Add optional facility to enforce that all files read by the core image
@@ -145,6 +154,12 @@ New in 2.02:
Python 2.6. Python 2.6.
* modinfo.sh contains build information now. * modinfo.sh contains build information now.
* Added many new tests to improve robustness. * Added many new tests to improve robustness.
* Target is built without libgcc now. Necessary builtins are reimplemented
directly. This removes requirement for target-specific runtime on build
system.
* emu libusb support removed (was broken and unmaintained).
* powerpc64le compile support.
* Use fixed timestamp when generating GRUB image for reproducible builds.
* Revision control moved to git. * Revision control moved to git.
-2
View File
@@ -12,8 +12,6 @@ The URL is <http://www.gnu.org/software/grub/grub.html>.
More extensive documentation is available in the Info manual, More extensive documentation is available in the Info manual,
accessible using 'info grub' after building and installing GRUB 2. accessible using 'info grub' after building and installing GRUB 2.
Please look at the GRUB Wiki <http://grub.enbug.org> for testing
procedures.
There are a number of important user-visible differences from the There are a number of important user-visible differences from the
first version of GRUB, now known as GRUB Legacy. For a summary, please first version of GRUB, now known as GRUB Legacy. For a summary, please
-4
View File
@@ -7,7 +7,3 @@ glance. So write to <grub-devel@gnu.org> first.
For bug tracking, refer to: For bug tracking, refer to:
http://savannah.gnu.org/bugs/?group=grub http://savannah.gnu.org/bugs/?group=grub
Our wiki also lists some areas that need work:
http://grub.enbug.org/
+1 -1
View File
@@ -93,7 +93,7 @@ else
fi fi
grub_cv_prog_objcopy_absolute=yes grub_cv_prog_objcopy_absolute=yes
for link_addr in 0x2000 0x8000 0x7C00; do for link_addr in 0x2000 0x8000 0x7C00; do
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then : if AC_TRY_COMMAND([${CC-cc} ${TARGET_CFLAGS} ${TARGET_LDFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then :
else else
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
fi fi
+5 -1
View File
@@ -5,6 +5,10 @@
.code16 .code16
jmp far jmp far
.org 4 .org 4
.space 300 jmp nearer
.org 6
.space 100
nearer:
.space 200
far: far:
.byte 0 .byte 0
+2 -2
View File
@@ -4,8 +4,8 @@
.set mips3 .set mips3
sync sync
ld $t2, 0($t6) ld $t2, 0($t1)
a: a:
addiu $t7, $s0, (b - a) addiu $t1, $s0, (b - a)
b: nop b: nop
+9 -6
View File
@@ -2,6 +2,9 @@
set -e set -e
# Set ${PYTHON} to plain 'python' if not set already
: ${PYTHON:=python}
export LC_COLLATE=C export LC_COLLATE=C
unset LC_ALL unset LC_ALL
@@ -9,10 +12,10 @@ find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './b
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
echo "Importing unicode..." echo "Importing unicode..."
python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt grub-core/unidata.c ${PYTHON} util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt grub-core/unidata.c
echo "Importing libgcrypt..." echo "Importing libgcrypt..."
python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core ${PYTHON} util/import_gcry.py grub-core/lib/libgcrypt/ grub-core
sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h
if [ -f include/grub/gcrypt/g10lib.h ]; then if [ -f include/grub/gcrypt/g10lib.h ]; then
rm include/grub/gcrypt/g10lib.h rm include/grub/gcrypt/g10lib.h
@@ -20,14 +23,14 @@ fi
if [ -d grub-core/lib/libgcrypt-grub/mpi/generic ]; then if [ -d grub-core/lib/libgcrypt-grub/mpi/generic ]; then
rm -rf grub-core/lib/libgcrypt-grub/mpi/generic rm -rf grub-core/lib/libgcrypt-grub/mpi/generic
fi fi
ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h cp grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h
cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic
for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do
if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ] || [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ] || [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then
rm grub-core/lib/libgcrypt-grub/mpi/"$x" rm grub-core/lib/libgcrypt-grub/mpi/"$x"
fi fi
ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" cp grub-core/lib/libgcrypt-grub/mpi/generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x"
done done
echo "Generating Automake input..." echo "Generating Automake input..."
@@ -54,8 +57,8 @@ for extra in contrib/*/Makefile.core.def; do
fi fi
done done
python gentpl.py $UTIL_DEFS > Makefile.util.am ${PYTHON} gentpl.py $UTIL_DEFS > Makefile.util.am
python gentpl.py $CORE_DEFS > grub-core/Makefile.core.am ${PYTHON} gentpl.py $CORE_DEFS > grub-core/Makefile.core.am
for extra in contrib/*/Makefile.common; do for extra in contrib/*/Makefile.common; do
if test -e "$extra"; then if test -e "$extra"; then
+5 -7
View File
@@ -17,9 +17,9 @@ endif
if COND_arm64 if COND_arm64
CFLAGS_PLATFORM += -mcmodel=large CFLAGS_PLATFORM += -mcmodel=large
endif endif
if COND_powerpc_ieee1275
#FIXME: discover and check XEN headers CFLAGS_PLATFORM += -mcpu=powerpc
CPPFLAGS_XEN = -I/usr/include endif
# Other options # Other options
@@ -34,13 +34,11 @@ CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src/
CCASFLAGS_DEFAULT = $(CPPFLAGS_DEFAULT) -DASM_FILE=1 CCASFLAGS_DEFAULT = $(CPPFLAGS_DEFAULT) -DASM_FILE=1
BUILD_CPPFLAGS += $(CPPFLAGS_DEFAULT) BUILD_CPPFLAGS += $(CPPFLAGS_DEFAULT)
LDADD_KERNEL = $(TARGET_LIBGCC)
CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) $(TARGET_LDFLAGS_STATIC_LIBGCC) LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC)
CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) 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 CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding
LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d
+6 -1
View File
@@ -5,6 +5,7 @@ EXTRA_DIST += gentpl.py
EXTRA_DIST += Makefile.util.def EXTRA_DIST += Makefile.util.def
EXTRA_DIST += Makefile.utilgcry.def EXTRA_DIST += Makefile.utilgcry.def
EXTRA_DIST += asm-tests
EXTRA_DIST += unicode EXTRA_DIST += unicode
EXTRA_DIST += util/import_gcry.py EXTRA_DIST += util/import_gcry.py
@@ -36,7 +37,6 @@ EXTRA_DIST += grub-core/lib/libgcrypt
EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic
EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h')
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h')
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h')
EXTRA_DIST += grub-core/efiemu/runtime/config.h EXTRA_DIST += grub-core/efiemu/runtime/config.h
EXTRA_DIST += grub-core/lib/LzmaDec.c EXTRA_DIST += grub-core/lib/LzmaDec.c
@@ -50,8 +50,13 @@ EXTRA_DIST += util/import_gcrypth.sed
EXTRA_DIST += util/bin2h.c EXTRA_DIST += util/bin2h.c
EXTRA_DIST += util/grub-gen-asciih.c EXTRA_DIST += util/grub-gen-asciih.c
EXTRA_DIST += util/grub-gen-widthspec.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 += util/grub-pe2elf.c
EXTRA_DIST += m4/gnulib-cache.m4 EXTRA_DIST += m4/gnulib-cache.m4
EXTRA_DIST += m4/glibc2.m4 EXTRA_DIST += m4/glibc2.m4
EXTRA_DIST += m4/gnulib-tool.m4 EXTRA_DIST += m4/gnulib-tool.m4
+1
View File
@@ -7,6 +7,7 @@
#endif #endif
#define GCRYPT_NO_DEPRECATED 1 #define GCRYPT_NO_DEPRECATED 1
#define HAVE_MEMMOVE 1
/* Define to 1 to enable disk cache statistics. */ /* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@ #define DISK_CACHE_STATS @DISK_CACHE_STATS@
+213 -138
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 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. 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]) AC_CONFIG_AUX_DIR([build-aux])
@@ -116,6 +116,7 @@ if test "x$with_platform" = x; then
x86_64-*) platform=pc ;; x86_64-*) platform=pc ;;
powerpc-*) platform=ieee1275 ;; powerpc-*) platform=ieee1275 ;;
powerpc64-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;;
powerpc64le-*) platform=ieee1275 ;;
sparc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;;
mipsel-*) platform=loongson ;; mipsel-*) platform=loongson ;;
mips-*) platform=arc ;; mips-*) platform=arc ;;
@@ -138,6 +139,7 @@ case "$target_cpu"-"$platform" in
x86_64-none) ;; x86_64-none) ;;
x86_64-*) target_cpu=i386 ;; x86_64-*) target_cpu=i386 ;;
powerpc64-ieee1275) target_cpu=powerpc ;; powerpc64-ieee1275) target_cpu=powerpc ;;
powerpc64le-ieee1275) target_cpu=powerpc ;;
esac esac
# Check if the platform is supported, make final adjustments. # Check if the platform is supported, make final adjustments.
@@ -313,7 +315,7 @@ AC_PROG_LN_S
if test "x$LEX" = "x:"; then if test "x$LEX" = "x:"; then
AC_MSG_ERROR([flex is not found]) AC_MSG_ERROR([flex is not found])
else else
version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` version=`$LEX --version | $AWK '{ split($2,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`
if test -n "$version" -a "$version" -ge 20535; then if test -n "$version" -a "$version" -ge 20535; then
: :
else else
@@ -560,6 +562,112 @@ AC_COMPILE_IFELSE(
]])], ]])],
[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])]) [grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])])
if test x$target_cpu = xpowerpc -o x$target_cpu = xmips; then
AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [
grub_cv_target_cc_big_endian=no
for cand in "-target $target_cpu -Wl,-EB" "-target $target_cpu" \
"-target $target_cpu-linux-gnu -Wl,-EB" "-target $target_cpu-linux-gnu" \
"-EB" "-mbig-endian"; do
if test x"$grub_cv_target_cc_big_endian" != xno ; then
break
fi
CFLAGS="$TARGET_CFLAGS $cand -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__)
#error still little endian
#endif
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
int main (void);
]], [[]])],
[grub_cv_target_cc_big_endian="$cand"], [])
done
])
if test x"$grub_cv_target_cc_big_endian" = xno ; then
AC_MSG_ERROR([could not force big-endian])
fi
skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')"
TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags"
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags"
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags"
TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian"
elif test x$target_cpu = xmipsel; then
AC_CACHE_CHECK([for options to get little-endian compilation], grub_cv_target_cc_little_endian, [
grub_cv_target_cc_little_endian=no
for cand in "-target $target_cpu -Wl,-EL" "-target $target_cpu" \
"-target $target_cpu-linux-gnu -Wl,-EL" "-target $target_cpu-linux-gnu" \
"-EL"; do
if test x"$grub_cv_target_cc_little_endian" != xno ; then
break
fi
CFLAGS="$TARGET_CFLAGS $cand -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ == __BYTE_ORDER__)
#error still big endian
#endif
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
int main (void);
]], [[]])],
[grub_cv_target_cc_little_endian="$cand"], [])
done
])
if test x"$grub_cv_target_cc_little_endian" = xno ; then
AC_MSG_ERROR([could not force little-endian])
fi
skip_linkflags="$(echo "$grub_cv_target_cc_little_endian"|sed 's@-Wl,-EL@@')"
TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags"
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags"
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags"
TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_little_endian"
fi
# GRUB code is N32-compliant but it's experimental and we would prefer to
# avoid having too much variety when it doesn't result in any real improvement.
# Moreover N64 isn't supported.
if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then
AC_CACHE_CHECK([for options to force MIPS o32 ABI], grub_cv_target_cc_mips_o32_abi, [
grub_cv_target_cc_mips_o32_abi=no
for arg in "" "-mabi=32" "-target $target_cpu -mabi=32" ; do
if test x"$grub_cv_target_cc_mips_o32_abi" != xno ; then
break
fi
CFLAGS="$TARGET_CFLAGS $arg -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if !defined(_ABIO32) || !defined(_MIPS_SIM) || (_MIPS_SIM != _ABIO32)
#error not o32 ABI
#endif
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
int main (void);
]], [[]])],
[grub_cv_target_cc_mips_o32_abi="$arg"], [])
done
])
if test x"$grub_cv_target_cc_mips_o32_abi" = xno ; then
AC_MSG_ERROR([could not force MIPS o32 ABI])
fi
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mips_o32_abi"
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mips_o32_abi"
fi
AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [ AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [
test_program= test_program=
case "x$target_cpu-$platform" in case "x$target_cpu-$platform" in
@@ -675,7 +783,7 @@ fi
if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then
# Some toolchains enable these features by default, but they need # Some toolchains enable these features by default, but they need
# registers that aren't set up properly in GRUB. # registers that aren't set up properly in GRUB.
TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow" TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow"
fi fi
# GRUB doesn't use float or doubles at all. Yet some toolchains may decide # GRUB doesn't use float or doubles at all. Yet some toolchains may decide
@@ -686,9 +794,9 @@ if test x"$platform" != xemu ; then
AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [
grub_cv_target_cc_soft_float=no grub_cv_target_cc_soft_float=no
if test "x$target_cpu" = xarm64; then if test "x$target_cpu" = xarm64; then
CFLAGS="$TARGET_CFLAGS -march=armv8-a+nofp+nosimd -Werror" CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_soft_float="-march=armv8-a+nofp+nosimd"], []) [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
fi fi
if test "x$target_cpu" = xia64; then if test "x$target_cpu" = xia64; then
CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror" CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
@@ -720,15 +828,7 @@ if test x"$platform" != xemu ; then
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float" TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float"
;; ;;
esac esac
case x"$grub_cv_target_cc_soft_float" in TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float"
x"-march=armv8-a+nofp+nosimd")
# +nosimd disables also the cache opcodes that we need in asm.
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -march=armv8-a+nofp"
;;
*)
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float"
;;
esac
fi fi
@@ -741,6 +841,7 @@ if test x"$target_cpu" = xsparc64 ; then
break break
fi fi
CFLAGS="$TARGET_CFLAGS $cand -Werror" CFLAGS="$TARGET_CFLAGS $cand -Werror"
CPPFLAGS="$TARGET_CPPFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_mno_app_regs="$cand"], []) [grub_cv_target_cc_mno_app_regs="$cand"], [])
done done
@@ -809,12 +910,24 @@ if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xy
TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions"
fi 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 # By default, GCC 4.6 generates .eh_frame sections containing unwind
# information in some cases where it previously did not. GRUB doesn't need # 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 # these and they just use up vital space. Restore the old compiler
# behaviour. # behaviour.
AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ 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([[]], [[]])], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_fno_asynchronous_unwind_tables=yes], [grub_cv_cc_fno_asynchronous_unwind_tables=yes],
[grub_cv_cc_fno_asynchronous_unwind_tables=no]) [grub_cv_cc_fno_asynchronous_unwind_tables=no])
@@ -824,66 +937,17 @@ if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
fi fi
AC_ARG_ENABLE([efiemu], AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [
[AS_HELP_STRING([--enable-efiemu], CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
[build and install the efiemu runtimes (default=guessed)])]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
if test x"$enable_efiemu" = xno ; then [grub_cv_cc_fno_unwind_tables=yes],
efiemu_excuse="explicitly disabled" [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 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" CFLAGS="$TARGET_CFLAGS"
@@ -977,6 +1041,73 @@ else
TARGET_IMG_CFLAGS= TARGET_IMG_CFLAGS=
fi 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) AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
@@ -1130,22 +1261,17 @@ fi
# Set them to their new values for the tests below. # Set them to their new values for the tests below.
CC="$TARGET_CC" CC="$TARGET_CC"
if test "x$TARGET_APPLE_LINKER" = x1 ; then if test x"$platform" = xemu ; then
CFLAGS="$TARGET_CFLAGS -Wno-error"
elif test "x$TARGET_APPLE_LINKER" = x1 ; then
CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error"
else else
CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error"
fi fi
CPPFLAGS="$TARGET_CPPFLAGS" CPPFLAGS="$TARGET_CPPFLAGS"
if test x$target_cpu = xi386 || test x$target_cpu = xx86_64 || test "x$grub_cv_cc_target_clang" = xyes ; then
TARGET_LIBGCC=
else
TARGET_LIBGCC=-lgcc
fi
LIBS="$TARGET_LIBGCC"
grub_ASM_USCORE grub_ASM_USCORE
if test "x$TARGET_APPLE_LINKER" = x0 ; then if test "x$TARGET_APPLE_LINKER" = x0 && test x"$platform" != xemu; then
if test x$grub_cv_asm_uscore = xyes; then if test x$grub_cv_asm_uscore = xyes; then
DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main" DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main"
else else
@@ -1155,7 +1281,9 @@ CFLAGS="$TARGET_CFLAGS -nostdlib $DEFSYM"
fi fi
# Check for libgcc symbols # Check for libgcc symbols
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x) if test x"$platform" = xemu; then
AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
fi
if test "x$TARGET_APPLE_LINKER" = x1 ; then if test "x$TARGET_APPLE_LINKER" = x1 ; then
CFLAGS="$TARGET_CFLAGS -nostdlib -static" CFLAGS="$TARGET_CFLAGS -nostdlib -static"
@@ -1257,10 +1385,6 @@ else
fi fi
AC_SUBST([BOOT_TIME_STATS]) AC_SUBST([BOOT_TIME_STATS])
AC_ARG_ENABLE([grub-emu-usb],
[AS_HELP_STRING([--enable-grub-emu-usb],
[build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
AC_ARG_ENABLE([grub-emu-sdl], AC_ARG_ENABLE([grub-emu-sdl],
[AS_HELP_STRING([--enable-grub-emu-sdl], [AS_HELP_STRING([--enable-grub-emu-sdl],
[build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])])
@@ -1271,34 +1395,6 @@ AC_ARG_ENABLE([grub-emu-pci],
if test "$platform" = emu; then if test "$platform" = emu; then
if test x"$enable_grub_emu_usb" != xyes ; then
grub_emu_usb_excuse="not enabled"
fi
if test x"$enable_grub_emu_pci" = xyes ; then
grub_emu_usb_excuse="conflicts with PCI support"
fi
[if [ x"$grub_emu_usb_excuse" = x ]; then
# Check for libusb libraries.]
AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
[grub_emu_usb_excuse=["need libusb library"]])
AC_SUBST([LIBUSB])
[fi]
[if [ x"$grub_emu_usb_excuse" = x ]; then
# Check for headers.]
AC_CHECK_HEADERS([usb.h], [],
[grub_emu_usb_excuse=["need libusb headers"]])
[fi]
if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled ($grub_emu_usb_excuse)])
fi
if test x"$grub_emu_usb_excuse" = x ; then
enable_grub_emu_usb=yes
else
enable_grub_emu_usb=no
fi
if test x"$enable_grub_emu_sdl" = xno ; then if test x"$enable_grub_emu_sdl" = xno ; then
grub_emu_sdl_excuse="explicitly disabled" grub_emu_sdl_excuse="explicitly disabled"
fi fi
@@ -1328,10 +1424,6 @@ if test x"$enable_grub_emu_pci" != xyes ; then
grub_emu_pci_excuse="not enabled" grub_emu_pci_excuse="not enabled"
fi fi
if test x"$enable_grub_emu_usb" = xyes ; then
grub_emu_pci_excuse="conflicts with USB support"
fi
[if [ x"$grub_emu_pci_excuse" = x ]; then [if [ x"$grub_emu_pci_excuse" = x ]; then
# Check for libpci libraries.] # Check for libpci libraries.]
AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"],
@@ -1340,7 +1432,7 @@ fi
[fi] [fi]
[if [ x"$grub_emu_pci_excuse" = x ]; then [if [ x"$grub_emu_pci_excuse" = x ]; then
# Check for headers.] # Check for headers.]
AC_CHECK_HEADERS([pci/pci.h], [], AC_CHECK_HEADERS([pciaccess.h], [],
[grub_emu_pci_excuse=["need libpciaccess headers"]]) [grub_emu_pci_excuse=["need libpciaccess headers"]])
[fi] [fi]
@@ -1352,14 +1444,12 @@ enable_grub_emu_pci=no
fi fi
AC_SUBST([enable_grub_emu_sdl]) AC_SUBST([enable_grub_emu_sdl])
AC_SUBST([enable_grub_emu_usb])
AC_SUBST([enable_grub_emu_pci]) AC_SUBST([enable_grub_emu_pci])
else else
# Ignore --enable-emu-* if platform is not emu # Ignore --enable-emu-* if platform is not emu
enable_grub_emu_sdl=no enable_grub_emu_sdl=no
enable_grub_emu_usb=no
enable_grub_emu_pci=no enable_grub_emu_pci=no
fi fi
@@ -1716,12 +1806,6 @@ if test x"$enable_werror" != xno ; then
HOST_CFLAGS="$HOST_CFLAGS -Werror" HOST_CFLAGS="$HOST_CFLAGS -Werror"
fi fi
if test "x$grub_cv_cc_target_clang" = xno; then
TARGET_LDFLAGS_STATIC_LIBGCC="-static-libgcc"
else
TARGET_LDFLAGS_STATIC_LIBGCC=
fi
TARGET_CPP="$TARGET_CC -E" TARGET_CPP="$TARGET_CC -E"
TARGET_CCAS=$TARGET_CC TARGET_CCAS=$TARGET_CC
@@ -1738,8 +1822,6 @@ AC_SUBST(GRUB_TARGET_CPU)
AC_SUBST(GRUB_PLATFORM) AC_SUBST(GRUB_PLATFORM)
AC_SUBST(TARGET_OBJCONV) AC_SUBST(TARGET_OBJCONV)
AC_SUBST(TARGET_LIBGCC)
AC_SUBST(TARGET_LDFLAGS_STATIC_LIBGCC)
AC_SUBST(TARGET_CPP) AC_SUBST(TARGET_CPP)
AC_SUBST(TARGET_CCAS) AC_SUBST(TARGET_CCAS)
AC_SUBST(TARGET_OBJ2ELF) AC_SUBST(TARGET_OBJ2ELF)
@@ -1769,7 +1851,6 @@ AC_SUBST(BUILD_LIBM)
AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone])
AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
AM_CONDITIONAL([COND_clang], [test x$grub_cv_cc_target_clang = xyes])
AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc]) AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi]) AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi]) AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi])
@@ -1804,7 +1885,6 @@ AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu])
AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos])
AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x])
AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes])
AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
@@ -1882,11 +1962,6 @@ echo "*******************************************************"
echo GRUB2 will be compiled with following components: echo GRUB2 will be compiled with following components:
echo Platform: "$target_cpu"-"$platform" echo Platform: "$target_cpu"-"$platform"
if [ x"$platform" = xemu ]; then if [ x"$platform" = xemu ]; then
if [ x"$grub_emu_usb_excuse" = x ]; then
echo USB support for grub-emu: Yes
else
echo USB support for grub-emu: No "($grub_emu_usb_excuse)"
fi
if [ x"$grub_emu_sdl_excuse" = x ]; then if [ x"$grub_emu_sdl_excuse" = x ]; then
echo SDL support for grub-emu: Yes echo SDL support for grub-emu: Yes
else else
+103 -22
View File
@@ -2538,6 +2538,8 @@ team are:
85:3 85:3
@item Asus EeePC 1005PE @item Asus EeePC 1005PE
84:1 (unconfirmed) 84:1 (unconfirmed)
@item LENOVO ThinkPad T410s (2912W1C)
101:3
@end table @end table
To take full advantage of this function, install GRUB into the MBR To take full advantage of this function, install GRUB into the MBR
@@ -3038,6 +3040,8 @@ These variables have special meaning to GRUB.
* cmdpath:: * cmdpath::
* color_highlight:: * color_highlight::
* color_normal:: * color_normal::
* config_directory::
* config_file::
* debug:: * debug::
* default:: * default::
* fallback:: * fallback::
@@ -3180,6 +3184,22 @@ matching colors of first half.
to support whole rgb24 palette but currently there is no compelling reason to support whole rgb24 palette but currently there is no compelling reason
to go beyond the current 16 colors. to go beyond the current 16 colors.
@node config_directory
@subsection config_directory
This variable is automatically set by GRUB to the directory part of
current configuration file name (@pxref{config_file}).
@node config_file
@subsection config_file
This variable is automatically set by GRUB to the name of configuration file that is being
processed by commands @command{configfile} (@pxref{configfile}) or @command{normal}
(@pxref{normal}). It is restored to the previous value when command completes.
@node debug @node debug
@subsection debug @subsection debug
@@ -3839,6 +3859,11 @@ you forget a command, you can run the command @command{help}
@comment * vbeinfo:: List available video modes @comment * vbeinfo:: List available video modes
* verify_detached:: Verify detached digital signature * verify_detached:: Verify detached digital signature
* videoinfo:: List available video modes * videoinfo:: List available video modes
@comment * xen_*:: Xen boot commands
* xen_hypervisor:: Load xen hypervisor binary
* xen_linux:: Load dom0 kernel for xen hypervisor
* xen_initrd:: Load dom0 initrd for dom0 kernel
* xen_xsm:: Load xen security module for xen hypervisor
@end menu @end menu
@@ -4050,12 +4075,15 @@ after @command{configfile} returns.
@node cpuid @node cpuid
@subsection cpuid @subsection cpuid
@deffn Command cpuid [-l] @deffn Command cpuid [-l] [-p]
Check for CPU features. This command is only available on x86 systems. 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 With the @option{-l} option, return true if the CPU supports long mode
(64-bit). (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 If invoked without options, this command currently behaves as if it had been
invoked with @option{-l}. This may change in the future. invoked with @option{-l}. This may change in the future.
@end deffn @end deffn
@@ -5019,6 +5047,8 @@ the length of @var{string} is zero
@var{expression} is false @var{expression} is false
@item @var{expression1} @code{-a} @var{expression2} @item @var{expression1} @code{-a} @var{expression2}
both @var{expression1} and @var{expression2} are true 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} @item @var{expression1} @code{-o} @var{expression2}
either @var{expression1} or @var{expression2} is true either @var{expression1} or @var{expression2} is true
@end table @end table
@@ -5102,6 +5132,39 @@ successfully. If validation fails, it is set to a non-zero value.
List available video modes. If resolution is given, show only matching modes. List available video modes. If resolution is given, show only matching modes.
@end deffn @end deffn
@node xen_hypervisor
@subsection xen_hypervisor
@deffn Command xen_hypervisor file [arguments] @dots{}
Load a Xen hypervisor binary from @var{file}. The rest of the line is passed
verbatim as the @dfn{kernel command-line}. Any other binaries must be
reloaded after using this command.
@end deffn
@node xen_linux
@subsection xen_linux
@deffn Command xen_linux file [arguments]
Load a dom0 kernel image for xen hypervisor at the booting process of xen.
The rest of the line is passed verbatim as the module command line.
@end deffn
@node xen_initrd
@subsection xen_initrd
@deffn Command xen_initrd file
Load a initrd image for dom0 kernel at the booting process of xen.
@end deffn
@node xen_xsm
@subsection xen_xsm
@deffn Command xen_xsm file
Load a xen security module for xen hypervisor at the booting process of xen.
See @uref{http://wiki.xen.org/wiki/XSM} for more detail.
@end deffn
@node Networking commands @node Networking commands
@section The list of networking commands @section The list of networking commands
@@ -5162,8 +5225,10 @@ by @var{shortname} which can be used to remove it (@pxref{net_del_route}).
Perform configuration of @var{card} using DHCP protocol. If no card name Perform configuration of @var{card} using DHCP protocol. If no card name
is specified, try to configure all existing cards. If configuration was is specified, try to configure all existing cards. If configuration was
successful, interface with name @var{card}@samp{:dhcp} and configured successful, interface with name @var{card}@samp{:dhcp} and configured
address is added to @var{card}. If server provided gateway information in address is added to @var{card}.
DHCP ACK packet, it is added as route entry with the name @var{card}@samp{:dhcp:gw}. Additionally the following DHCP options are recognized and processed: @comment If server provided gateway information in
@comment DHCP ACK packet, it is added as route entry with the name @var{card}@samp{:dhcp:gw}.
Additionally the following DHCP options are recognized and processed:
@table @samp @table @samp
@item 1 (Subnet Mask) @item 1 (Subnet Mask)
@@ -5426,10 +5491,12 @@ In order to enable authentication support, the @samp{superusers} environment
variable must be set to a list of usernames, separated by any of spaces, variable must be set to a list of usernames, separated by any of spaces,
commas, semicolons, pipes, or ampersands. Superusers are permitted to use commas, semicolons, pipes, or ampersands. Superusers are permitted to use
the GRUB command line, edit menu entries, and execute any menu entry. If the GRUB command line, edit menu entries, and execute any menu entry. If
@samp{superusers} is set, then use of the command line is automatically @samp{superusers} is set, then use of the command line and editing of menu
restricted to superusers. entries are automatically restricted to superusers. Setting @samp{superusers}
to empty string effectively disables both access to CLI and editing of menu
entries.
Other users may be given access to specific menu entries by giving a list of Other users may be allowed to execute specific menu entries by giving a list of
usernames (as above) using the @option{--users} option to the usernames (as above) using the @option{--users} option to the
@samp{menuentry} command (@pxref{menuentry}). If the @option{--unrestricted} @samp{menuentry} command (@pxref{menuentry}). If the @option{--unrestricted}
option is used for a menu entry, then that entry is unrestricted. option is used for a menu entry, then that entry is unrestricted.
@@ -5609,6 +5676,16 @@ BadRAM is the ability to mark some of the RAM as ``bad''. Note: due to protocol
limitations mips-loongson (with Linux protocol) limitations mips-loongson (with Linux protocol)
and mips-qemu_mips can use only memory up to first hole. and mips-qemu_mips can use only memory up to first hole.
Bootlocation is ability of GRUB to automatically detect where it boots from.
``disk'' means the detection is limited to detecting the disk with partition
being discovered on install time. ``partition'' means that disk and partiton
can be automatically discovered. ``file'' means that boot image file name as
well as disk and partition can be discovered. For consistency default install ignores
partition and relies solely on disk detection. If no bootlocation discovery is available
or boot and grub-root disks are different, UUID is used instead. On ARC if no device
to install to is specified, UUID is used instead as well.
@multitable @columnfractions .20 .20 .20 .20 .20 @multitable @columnfractions .20 .20 .20 .20 .20
@item @tab BIOS @tab Coreboot @tab Multiboot @tab Qemu @item @tab BIOS @tab Coreboot @tab Multiboot @tab Qemu
@item video @tab yes @tab yes @tab yes @tab yes @item video @tab yes @tab yes @tab yes @tab yes
@@ -5625,6 +5702,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item badram @tab yes @tab yes @tab yes @tab yes @item badram @tab yes @tab yes @tab yes @tab yes
@item compression @tab always @tab pointless @tab no @tab no @item compression @tab always @tab pointless @tab no @tab no
@item exit @tab yes @tab no @tab no @tab no @item exit @tab yes @tab no @tab no @tab no
@item bootlocation @tab disk @tab no @tab no @tab no
@end multitable @end multitable
@multitable @columnfractions .20 .20 .20 .20 .20 @multitable @columnfractions .20 .20 .20 .20 .20
@@ -5643,6 +5721,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item badram @tab yes @tab yes @tab no @tab yes @item badram @tab yes @tab yes @tab no @tab yes
@item compression @tab no @tab no @tab no @tab no @item compression @tab no @tab no @tab no @tab no
@item exit @tab yes @tab yes @tab yes @tab yes @item exit @tab yes @tab yes @tab yes @tab yes
@item bootlocation @tab file @tab file @tab file, ignored @tab file
@end multitable @end multitable
@multitable @columnfractions .20 .20 .20 .20 .20 @multitable @columnfractions .20 .20 .20 .20 .20
@@ -5661,24 +5740,26 @@ and mips-qemu_mips can use only memory up to first hole.
@item badram @tab yes (*) @tab no @tab no @tab no @item badram @tab yes (*) @tab no @tab no @tab no
@item compression @tab configurable @tab no @tab no @tab configurable @item compression @tab configurable @tab no @tab no @tab configurable
@item exit @tab no @tab yes @tab yes @tab yes @item exit @tab no @tab yes @tab yes @tab yes
@item bootlocation @tab no @tab partition @tab file @tab file (*)
@end multitable @end multitable
@multitable @columnfractions .20 .20 .20 .20 .20 @multitable @columnfractions .20 .20 .20 .20 .20
@item @tab MIPS qemu @tab emu @item @tab MIPS qemu @tab emu @tab xen
@item video @tab no @tab yes @item video @tab no @tab yes @tab no
@item console charset @tab CP437 @tab Unicode (*) @item console charset @tab CP437 @tab Unicode (*) @tab ASCII
@item network @tab no @tab yes @item network @tab no @tab yes @tab no
@item ATA/AHCI @tab yes @tab no @item ATA/AHCI @tab yes @tab no @tab no
@item AT keyboard @tab yes @tab no @item AT keyboard @tab yes @tab no @tab no
@item Speaker @tab no @tab no @item Speaker @tab no @tab no @tab no
@item USB @tab N/A @tab yes @item USB @tab N/A @tab yes @tab no
@item chainloader @tab yes @tab no @item chainloader @tab yes @tab no @tab yes
@item cpuid @tab no @tab no @item cpuid @tab no @tab no @tab yes
@item hints @tab guess @tab no @item hints @tab guess @tab no @tab no
@item PCI @tab no @tab no @item PCI @tab no @tab no @tab no
@item badram @tab yes (*) @tab no @item badram @tab yes (*) @tab no @tab no
@item compression @tab configurable @tab no @item compression @tab configurable @tab no @tab no
@item exit @tab no @tab yes @item exit @tab no @tab yes @tab no
@item bootlocation @tab no @tab file @tab no
@end multitable @end multitable
@node Platform-specific operations @node Platform-specific operations
@@ -5848,7 +5929,7 @@ Following variables must be defined:
@multitable @columnfractions .30 .65 @multitable @columnfractions .30 .65
@item GRUB_PAYLOADS_DIR @tab directory containing the required kernels @item GRUB_PAYLOADS_DIR @tab directory containing the required kernels
@item GRUB_CBFSTOOL @tab cbfstoll from Coreboot package (for coreboot platform only) @item GRUB_CBFSTOOL @tab cbfstool from Coreboot package (for coreboot platform only)
@item GRUB_COREBOOT_ROM @tab empty Coreboot ROM @item GRUB_COREBOOT_ROM @tab empty Coreboot ROM
@item GRUB_QEMU_OPTS @tab additional options to be supplied to QEMU @item GRUB_QEMU_OPTS @tab additional options to be supplied to QEMU
@end multitable @end multitable
+20 -3
View File
@@ -82,7 +82,7 @@ GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"]
GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
# Miscelaneous groups schedulded to disappear in future # Miscellaneous groups scheduled to disappear in future
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
@@ -606,7 +606,7 @@ def foreach_enabled_platform(defn, closure):
# enable = emu; # enable = emu;
# enable = i386; # enable = i386;
# enable = mips_loongson; # enable = mips_loongson;
# emu_condition = COND_GRUB_EMU_USB; # emu_condition = COND_GRUB_EMU_SDL;
# }; # };
# #
def under_platform_specific_conditionals(defn, platform, closure): def under_platform_specific_conditionals(defn, platform, closure):
@@ -729,9 +729,11 @@ def kernel(defn, platform):
"""if test x$(TARGET_APPLE_LINKER) = x1; then \ """if test x$(TARGET_APPLE_LINKER) = x1; then \
$(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \ $(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 $@; \ $(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 \ elif test ! -z '$(TARGET_OBJ2ELF)'; then \
""" + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \ """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \
$(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \ $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \
rm -f $@.bin; \
else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \ else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \
fi""")) fi"""))
@@ -759,7 +761,7 @@ def image(defn, platform):
if test x$(TARGET_APPLE_LINKER) = x1; then \ if test x$(TARGET_APPLE_LINKER) = x1; then \
$(MACHO2IMG) $< $@; \ $(MACHO2IMG) $< $@; \
else \ 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 fi
""") """)
@@ -834,6 +836,20 @@ def data(defn, platform):
var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform)) var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
gvar_add("dist_noinst_DATA", extra_dist(defn)) gvar_add("dist_noinst_DATA", extra_dist(defn))
def transform_data(defn, platform):
name = defn['name']
var_add(installdir(defn) + "_DATA", name)
rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
chmod a+x """ + name + """
""")
gvar_add("CLEANFILES", name)
gvar_add("EXTRA_DIST", extra_dist(defn))
gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
def script(defn, platform): def script(defn, platform):
name = defn['name'] name = defn['name']
@@ -881,6 +897,7 @@ rules("library", library)
rules("program", program) rules("program", program)
rules("script", script) rules("script", script)
rules("data", data) rules("data", data)
rules("transform_data", transform_data)
write_output(section='decl') write_output(section='decl')
write_output() write_output()
+19 -7
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) $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM)
CLEANFILES += gentrigtables$(BUILD_EXEEXT) 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
trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac
./gentrigtables$(BUILD_EXEEXT) > $@ ./gentrigtables$(BUILD_EXEEXT) > $@
@@ -76,6 +80,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
else
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h
endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
@@ -83,9 +92,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
if !COND_clang
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
if COND_i386_pc if COND_i386_pc
@@ -99,7 +105,9 @@ if COND_i386_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h 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/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/pci.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
endif endif
if COND_i386_coreboot if COND_i386_coreboot
@@ -110,10 +118,12 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif endif
if COND_i386_multiboot if COND_i386_multiboot
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif endif
if COND_i386_qemu if COND_i386_qemu
@@ -152,11 +162,14 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h 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/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.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 endif
if COND_ia64_efi if COND_ia64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif endif
if COND_mips if COND_mips
@@ -231,11 +244,13 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif endif
if COND_arm64_efi if COND_arm64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
endif endif
if COND_emu if COND_emu
@@ -248,9 +263,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
if COND_GRUB_EMU_SDL if COND_GRUB_EMU_SDL
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
endif endif
if COND_GRUB_EMU_USB
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libusb.h
endif
if COND_GRUB_EMU_PCI if COND_GRUB_EMU_PCI
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h
endif endif
@@ -384,7 +396,7 @@ moddep.lst: syminfo.lst genmoddep.awk video.lst
platform_DATA += moddep.lst platform_DATA += moddep.lst
CLEANFILES += config.log syminfo.lst moddep.lst CLEANFILES += config.log syminfo.lst moddep.lst
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) $(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT)
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
platform_DATA += $(MOD_FILES) platform_DATA += $(MOD_FILES)
platform_DATA += modinfo.sh platform_DATA += modinfo.sh
+98 -50
View File
@@ -1,43 +1,43 @@
AutoGen definitions Makefile.tpl; AutoGen definitions Makefile.tpl;
script = { transform_data = {
installdir = noinst; installdir = noinst;
name = gensyminfo.sh; name = gensyminfo.sh;
common = gensyminfo.sh.in; common = gensyminfo.sh.in;
}; };
script = { transform_data = {
installdir = noinst; installdir = noinst;
name = genmod.sh; name = genmod.sh;
common = genmod.sh.in; common = genmod.sh.in;
}; };
script = { transform_data = {
installdir = noinst; installdir = noinst;
name = modinfo.sh; name = modinfo.sh;
common = modinfo.sh.in; common = modinfo.sh.in;
}; };
script = { transform_data = {
installdir = platform; installdir = platform;
name = gmodule.pl; name = gmodule.pl;
common = gmodule.pl.in; common = gmodule.pl.in;
}; };
script = { transform_data = {
installdir = platform; installdir = platform;
name = gdb_grub; name = gdb_grub;
common = gdb_grub.in; common = gdb_grub.in;
}; };
script = { transform_data = {
installdir = platform; installdir = platform;
name = grub.chrp; name = grub.chrp;
common = boot/powerpc/grub.chrp.in; common = boot/powerpc/grub.chrp.in;
enable = powerpc_ieee1275; enable = powerpc_ieee1275;
}; };
script = { transform_data = {
installdir = platform; installdir = platform;
name = bootinfo.txt; name = bootinfo.txt;
common = boot/powerpc/bootinfo.txt.in; common = boot/powerpc/bootinfo.txt.in;
@@ -59,9 +59,6 @@ kernel = {
ia64_efi_ldflags = '-Wl,-r,-d'; ia64_efi_ldflags = '-Wl,-r,-d';
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
x86_64_xen_cppflags = '$(CPPFLAGS_XEN)';
i386_xen_cppflags = '$(CPPFLAGS_XEN)';
arm_efi_ldflags = '-Wl,-r,-d'; arm_efi_ldflags = '-Wl,-r,-d';
arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
@@ -83,8 +80,6 @@ kernel = {
x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
ldadd = '$(LDADD_KERNEL)';
mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
@@ -95,7 +90,7 @@ kernel = {
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
emu_cflags = '$(CFLAGS_GNULIB)'; emu_cflags = '$(CFLAGS_GNULIB)';
emu_cppflags = '$(CPPFLAGS_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'; arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_startup = kern/i386/pc/startup.S; i386_pc_startup = kern/i386/pc/startup.S;
@@ -132,6 +127,7 @@ kernel = {
common = kern/rescue_reader.c; common = kern/rescue_reader.c;
common = kern/term.c; common = kern/term.c;
noemu = kern/compiler-rt.c;
noemu = kern/mm.c; noemu = kern/mm.c;
noemu = kern/time.c; noemu = kern/time.c;
noemu = kern/generic/millisleep.c; noemu = kern/generic/millisleep.c;
@@ -175,8 +171,20 @@ kernel = {
efi = kern/efi/init.c; efi = kern/efi/init.c;
efi = kern/efi/mm.c; efi = kern/efi/mm.c;
efi = term/efi/console.c; efi = term/efi/console.c;
efi = kern/acpi.c;
efi = kern/efi/acpi.c;
i386_coreboot = kern/i386/pc/acpi.c;
i386_multiboot = kern/i386/pc/acpi.c;
i386_coreboot = kern/acpi.c;
i386_multiboot = kern/acpi.c;
x86 = kern/i386/tsc.c; x86 = kern/i386/tsc.c;
x86 = kern/i386/tsc_pit.c;
i386_efi = kern/i386/efi/tsc.c;
x86_64_efi = kern/i386/efi/tsc.c;
i386_efi = kern/i386/tsc_pmtimer.c;
i386_coreboot = kern/i386/tsc_pmtimer.c;
x86_64_efi = kern/i386/tsc_pmtimer.c;
i386_efi = kern/i386/efi/init.c; i386_efi = kern/i386/efi/init.c;
i386_efi = bus/pci.c; i386_efi = bus/pci.c;
@@ -188,6 +196,7 @@ kernel = {
x86_64_efi = bus/pci.c; x86_64_efi = bus/pci.c;
xen = kern/i386/tsc.c; xen = kern/i386/tsc.c;
xen = kern/i386/xen/tsc.c;
x86_64_xen = kern/x86_64/xen/hypercall.S; x86_64_xen = kern/x86_64/xen/hypercall.S;
i386_xen = kern/i386/xen/hypercall.S; i386_xen = kern/i386/xen/hypercall.S;
xen = kern/xen/init.c; xen = kern/xen/init.c;
@@ -204,7 +213,7 @@ kernel = {
arm_efi = kern/arm/efi/init.c; arm_efi = kern/arm/efi/init.c;
arm_efi = kern/arm/efi/misc.c; arm_efi = kern/arm/efi/misc.c;
arm64_efi = kern/arm/efi/init.c; arm64_efi = kern/arm64/efi/init.c;
i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c; i386_pc = kern/i386/pc/mmap.c;
@@ -254,6 +263,7 @@ kernel = {
powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c; powerpc_ieee1275 = kern/powerpc/dl.c;
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
sparc64_ieee1275 = kern/sparc64/cache.S; sparc64_ieee1275 = kern/sparc64/cache.S;
sparc64_ieee1275 = kern/sparc64/dl.c; sparc64_ieee1275 = kern/sparc64/dl.c;
@@ -265,7 +275,7 @@ kernel = {
arm = kern/arm/cache_armv7.S; arm = kern/arm/cache_armv7.S;
extra_dist = kern/arm/cache.S; extra_dist = kern/arm/cache.S;
arm = kern/arm/cache.c; arm = kern/arm/cache.c;
arm = kern/arm/misc.S; arm = kern/arm/compiler-rt.S;
arm64 = kern/arm64/cache.c; arm64 = kern/arm64/cache.c;
arm64 = kern/arm64/cache_flush.S; arm64 = kern/arm64/cache_flush.S;
@@ -443,13 +453,13 @@ image = {
common = lib/xzembed/xz_dec_bcj.c; common = lib/xzembed/xz_dec_bcj.c;
common = lib/xzembed/xz_dec_lzma2.c; common = lib/xzembed/xz_dec_lzma2.c;
common = lib/xzembed/xz_dec_stream.c; common = lib/xzembed/xz_dec_stream.c;
common = kern/compiler-rt.c;
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1'; cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary'; objcopyflags = '-O binary';
mips_ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) -Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
ldadd = '$(TARGET_LIBGCC)'; cflags = '-Wno-unreachable-code';
cflags = '-Wno-unreachable-code $(TARGET_LDFLAGS_STATIC_LIBGCC)';
enable = mips; enable = mips;
}; };
@@ -461,9 +471,7 @@ image = {
cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1'; cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary'; objcopyflags = '-O binary';
mips_ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) -Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
ldadd = '$(TARGET_LIBGCC)';
cflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC)';
enable = mips; enable = mips;
}; };
@@ -481,7 +489,7 @@ image = {
name = fwstart; name = fwstart;
mips_loongson = boot/mips/loongson/fwstart.S; mips_loongson = boot/mips/loongson/fwstart.S;
objcopyflags = '-O binary'; objcopyflags = '-O binary';
ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) $(TARGET_LIBGCC) -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_loongson; enable = mips_loongson;
}; };
@@ -489,7 +497,7 @@ image = {
name = fwstart_fuloong2f; name = fwstart_fuloong2f;
mips_loongson = boot/mips/loongson/fuloong2f.S; mips_loongson = boot/mips/loongson/fuloong2f.S;
objcopyflags = '-O binary'; objcopyflags = '-O binary';
ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) $(TARGET_LIBGCC) -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_loongson; enable = mips_loongson;
}; };
@@ -511,13 +519,6 @@ module = {
enable = x86; enable = x86;
}; };
module = {
name = libusb;
emu = bus/usb/emu/usb.c;
enable = emu;
condition = COND_GRUB_EMU_USB;
};
module = { module = {
name = lsspd; name = lsspd;
mips_loongson = commands/mips/loongson/lsspd.c; mips_loongson = commands/mips/loongson/lsspd.c;
@@ -532,13 +533,6 @@ module = {
enable = usb; enable = usb;
}; };
module = {
name = emuusb;
common = bus/usb/usb.c;
enable = emu;
condition = COND_GRUB_EMU_USB;
};
module = { module = {
name = usbserial_common; name = usbserial_common;
common = bus/usb/serial/common.c; common = bus/usb/serial/common.c;
@@ -620,7 +614,6 @@ module = {
module = { module = {
name = lsxen; name = lsxen;
common = commands/xen/lsxen.c; common = commands/xen/lsxen.c;
cppflags = '$(CPPFLAGS_XEN)';
enable = xen; enable = xen;
}; };
@@ -685,10 +678,8 @@ module = {
name = acpi; name = acpi;
common = commands/acpi.c; common = commands/acpi.c;
efi = commands/efi/acpi.c; i386_pc = kern/acpi.c;
i386_pc = commands/i386/pc/acpi.c; i386_pc = kern/i386/pc/acpi.c;
i386_coreboot = commands/i386/pc/acpi.c;
i386_multiboot = commands/i386/pc/acpi.c;
enable = efi; enable = efi;
enable = i386_pc; enable = i386_pc;
@@ -841,7 +832,6 @@ module = {
i386_coreboot = lib/i386/halt.c; i386_coreboot = lib/i386/halt.c;
i386_qemu = lib/i386/halt.c; i386_qemu = lib/i386/halt.c;
xen = lib/xen/halt.c; xen = lib/xen/halt.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
efi = lib/efi/halt.c; efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c; ieee1275 = lib/ieee1275/halt.c;
emu = lib/emu/halt.c; emu = lib/emu/halt.c;
@@ -862,7 +852,6 @@ module = {
mips_loongson = lib/mips/loongson/reboot.c; mips_loongson = lib/mips/loongson/reboot.c;
mips_qemu_mips = lib/mips/qemu_mips/reboot.c; mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
xen = lib/xen/reboot.c; xen = lib/xen/reboot.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
uboot = lib/uboot/reboot.c; uboot = lib/uboot/reboot.c;
common = commands/reboot.c; common = commands/reboot.c;
}; };
@@ -1464,7 +1453,6 @@ module = {
module = { module = {
name = gfxmenu; name = gfxmenu;
common = gfxmenu/gfxmenu.c; common = gfxmenu/gfxmenu.c;
common = gfxmenu/model.c;
common = gfxmenu/view.c; common = gfxmenu/view.c;
common = gfxmenu/font.c; common = gfxmenu/font.c;
common = gfxmenu/icon_manager.c; common = gfxmenu/icon_manager.c;
@@ -1543,7 +1531,6 @@ module = {
i386_xen = lib/i386/xen/relocator.S; i386_xen = lib/i386/xen/relocator.S;
x86_64_xen = lib/x86_64/xen/relocator.S; x86_64_xen = lib/x86_64/xen/relocator.S;
xen = lib/i386/relocator_common_c.c; xen = lib/i386/relocator_common_c.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
extra_dist = lib/i386/relocator_common.S; extra_dist = lib/i386/relocator_common.S;
extra_dist = kern/powerpc/cache_flush.S; extra_dist = kern/powerpc/cache_flush.S;
@@ -1564,7 +1551,6 @@ module = {
sparc64_ieee1275 = lib/ieee1275/cmos.c; sparc64_ieee1275 = lib/ieee1275/cmos.c;
powerpc_ieee1275 = lib/ieee1275/cmos.c; powerpc_ieee1275 = lib/ieee1275/cmos.c;
xen = lib/xen/datetime.c; xen = lib/xen/datetime.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
mips_arc = lib/arc/datetime.c; mips_arc = lib/arc/datetime.c;
enable = noemu; enable = noemu;
@@ -1663,11 +1649,17 @@ module = {
enable = x86; enable = x86;
}; };
module = {
name = xen_boot;
common = lib/cmdline.c;
arm64 = loader/arm64/xen_boot.c;
enable = arm64;
};
module = { module = {
name = linux; name = linux;
x86 = loader/i386/linux.c; x86 = loader/i386/linux.c;
xen = loader/i386/xen.c; xen = loader/i386/xen.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
i386_pc = lib/i386/pc/vesa_modes_table.c; i386_pc = lib/i386/pc/vesa_modes_table.c;
mips = loader/mips/linux.c; mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
@@ -1675,19 +1667,50 @@ module = {
ia64_efi = loader/ia64/efi/linux.c; ia64_efi = loader/ia64/efi/linux.c;
arm = loader/arm/linux.c; arm = loader/arm/linux.c;
arm64 = loader/arm64/linux.c; arm64 = loader/arm64/linux.c;
fdt = lib/fdt.c;
common = loader/linux.c; common = loader/linux.c;
common = lib/cmdline.c; common = lib/cmdline.c;
enable = noemu; enable = noemu;
}; };
module = {
name = fdt;
arm64 = loader/arm64/fdt.c;
common = lib/fdt.c;
enable = fdt;
};
module = { module = {
name = xnu; name = xnu;
x86 = loader/xnu_resume.c; x86 = loader/xnu_resume.c;
x86 = loader/i386/xnu.c; x86 = loader/i386/xnu.c;
x86 = loader/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 = { module = {
@@ -1982,6 +2005,31 @@ module = {
common = tests/div_test.c; common = tests/div_test.c;
}; };
module = {
name = mul_test;
common = tests/mul_test.c;
};
module = {
name = shift_test;
common = tests/shift_test.c;
};
module = {
name = cmp_test;
common = tests/cmp_test.c;
};
module = {
name = ctz_test;
common = tests/ctz_test.c;
};
module = {
name = bswap_test;
common = tests/bswap_test.c;
};
module = { module = {
name = videotest_checksum; name = videotest_checksum;
common = tests/videotest_checksum.c; common = tests/videotest_checksum.c;
+1 -10
View File
@@ -21,7 +21,7 @@
#include <grub/decompressor.h> #include <grub/decompressor.h>
void * void *
memset (void *s, int c, grub_size_t len) grub_memset (void *s, int c, grub_size_t len)
{ {
grub_uint8_t *ptr; grub_uint8_t *ptr;
for (ptr = s; len; ptr++, len--) for (ptr = s; len; ptr++, len--)
@@ -68,15 +68,6 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n)
return 0; return 0;
} }
int memcmp (const void *s1, const void *s2, grub_size_t n)
__attribute__ ((alias ("grub_memcmp")));
void *memmove (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
void *memcpy (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
void *grub_decompressor_scratch; void *grub_decompressor_scratch;
void void
+3 -3
View File
@@ -344,7 +344,7 @@ printhex:
nop nop
srl $t1, $a0, 28 srl $t1, $a0, 28
addiu $t1, $t1, -10 addiu $t1, $t1, -10
blt $t1, $zero, 2f bltz $t1, 2f
sll $a0, $a0, 4 sll $a0, $a0, 4
addiu $t1, $t1, 'A'-10-'0' addiu $t1, $t1, 'A'-10-'0'
2: addiu $t1, $t1, '0'+10 2: addiu $t1, $t1, '0'+10
@@ -398,7 +398,7 @@ read_spd:
move $t2, $a0 move $t2, $a0
move $t3, $ra move $t3, $ra
lui $a0, %hi(read_spd_fail) lui $a0, %hi(read_spd_fail)
addiu $a0, $a0, %hi(read_spd_fail) addiu $a0, $a0, %lo(read_spd_fail)
/* Send START. */ /* Send START. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F)
@@ -547,7 +547,7 @@ gpio_dump:
#endif #endif
gpio_dump_end: gpio_dump_end:
.p2align .p2align 3
write_dumpreg: write_dumpreg:
ld $t2, 0($t6) ld $t2, 0($t6)
+19 -20
View File
@@ -21,8 +21,8 @@
#include <grub/offsets.h> #include <grub/offsets.h>
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>
#include <grub/cpu/kernel.h>
#include <grub/offsets.h> #include <grub/offsets.h>
#include <grub/mips/asm.h>
#define BASE_ADDR 8 #define BASE_ADDR 8
@@ -33,7 +33,6 @@
.globl __start, _start, start .globl __start, _start, start
.set noreorder .set noreorder
.set nomacro .set nomacro
mips_attributes
__start: __start:
_start: _start:
start: start:
@@ -120,32 +119,32 @@ parsestr:
move $v0, $zero move $v0, $zero
move $t3, $t1 move $t3, $t1
3: 3:
lb $t4, 0($t2) lb GRUB_ASM_T4, 0($t2)
lb $t5, 0($t3) lb GRUB_ASM_T5, 0($t3)
addiu $t2, $t2, 1 addiu $t2, $t2, 1
addiu $t3, $t3, 1 addiu $t3, $t3, 1
beq $t5, $zero, 1f beq GRUB_ASM_T5, $zero, 1f
nop nop
beq $t5, $t4, 3b beq GRUB_ASM_T5, GRUB_ASM_T4, 3b
nop nop
bne $t4, $zero, 1f bne GRUB_ASM_T4, $zero, 1f
nop nop
addiu $t3, $t3, 0xffff addiu $t3, $t3, 0xffff
digcont: digcont:
lb $t5, 0($t3) lb GRUB_ASM_T5, 0($t3)
/* Substract '0' from digit. */ /* Substract '0' from digit. */
addiu $t5, $t5, 0xffd0 addiu GRUB_ASM_T5, GRUB_ASM_T5, 0xffd0
bltz $t5, 1f bltz GRUB_ASM_T5, 1f
nop nop
addiu $t4, $t5, 0xfff7 addiu GRUB_ASM_T4, GRUB_ASM_T5, 0xfff7
bgtz $t4, 1f bgtz GRUB_ASM_T4, 1f
nop nop
/* Multiply $v0 by 10 with bitshifts. */ /* Multiply $v0 by 10 with bitshifts. */
sll $v0, $v0, 1 sll $v0, $v0, 1
sll $t4, $v0, 2 sll GRUB_ASM_T4, $v0, 2
addu $v0, $v0, $t4 addu $v0, $v0, GRUB_ASM_T4
addu $v0, $v0, $t5 addu $v0, $v0, GRUB_ASM_T5
addiu $t3, $t3, 1 addiu $t3, $t3, 1
b digcont b digcont
nop nop
@@ -184,10 +183,10 @@ argdone:
b argdone b argdone
addiu $a1, $a1, 4 addiu $a1, $a1, 4
do_check: do_check:
lb $t4, 0($t7) lb GRUB_ASM_T4, 0($t7)
beq $t4, $zero, 1f beq GRUB_ASM_T4, $zero, 1f
lb $t3, 0($t6) lb $t3, 0($t6)
bne $t3, $t4, 2f bne $t3, GRUB_ASM_T4, 2f
addiu $t6, $t6, 1 addiu $t6, $t6, 1
b do_check b do_check
addiu $t7, $t7, 1 addiu $t7, $t7, 1
@@ -224,8 +223,8 @@ cmdlinedone:
1: 1:
beq $t1, $t3, 2f beq $t1, $t3, 2f
lb $t4, 0($t2) lb GRUB_ASM_T4, 0($t2)
sb $t4, 0($t1) sb GRUB_ASM_T4, 0($t1)
addiu $t1, $t1, 1 addiu $t1, $t1, 1
b 1b b 1b
addiu $t2, $t2, 1 addiu $t2, $t2, 1
+4 -3
View File
@@ -55,7 +55,8 @@ grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
int err; int err;
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr); err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
if (err) if (err)
grub_util_error ("mapping 0x%x failed (error %d)\n", base, err); grub_util_error ("mapping 0x%llx failed (error %d)",
(unsigned long long) base, err);
return addr; return addr;
} }
@@ -66,12 +67,12 @@ grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
pci_device_unmap_range (dev, mem, size); pci_device_unmap_range (dev, mem, size);
} }
GRUB_MOD_INIT (pci) GRUB_MOD_INIT (emupci)
{ {
pci_system_init (); pci_system_init ();
} }
GRUB_MOD_FINI (pci) GRUB_MOD_FINI (emupci)
{ {
pci_system_cleanup (); pci_system_cleanup ();
} }
+60 -11
View File
@@ -29,6 +29,7 @@
#include <grub/loader.h> #include <grub/loader.h>
#include <grub/cs5536.h> #include <grub/cs5536.h>
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/cache.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -337,6 +338,21 @@ struct grub_ehci
static struct grub_ehci *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 */ /* EHCC registers access functions */
static inline grub_uint32_t static inline grub_uint32_t
grub_ehci_ehcc_read32 (struct grub_ehci *e, grub_uint32_t addr) 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; grub_uint64_t maxtime;
sync_all_caches (e);
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
GRUB_EHCI_CMD_HC_RESET GRUB_EHCI_CMD_HC_RESET
| grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); | 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; e->next = ehci;
ehci = e; ehci = e;
sync_all_caches (e);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n"); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n");
grub_dprintf ("ehci", 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 */ /* Found proper existing (and linked) QH, do setup of QH */
grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter); grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter);
grub_ehci_setup_qh (qh_iter, transfer); grub_ehci_setup_qh (qh_iter, transfer);
sync_all_caches (e);
return qh_iter; 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); token = grub_le_to_cpu32 (td->token);
to_transfer = (token & GRUB_EHCI_TOTAL_MASK) >> GRUB_EHCI_TOTAL_OFF; 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 * whole data then set last_trans - it should be last executed TD
* in case when something went wrong. */ * in case when something went wrong. */
if (transfer && (td->size != to_transfer)) 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; grub_ehci_td_t td_prev = NULL;
int i; int i;
struct grub_ehci_transfer_controller_data *cdata; struct grub_ehci_transfer_controller_data *cdata;
grub_uint32_t status;
sync_all_caches (e);
/* Check if EHCI is running and AL is enabled */ /* Check if EHCI is running and AL is enabled */
if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
& GRUB_EHCI_ST_HC_HALTED) != 0) if ((status & GRUB_EHCI_ST_HC_HALTED) != 0)
/* XXX: Fix it: Currently we don't do anything to restart EHCI */ /* 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) & (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)
/* XXX: Fix it: Currently we don't do anything to restart EHCI */ /* 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. */ /* Allocate memory for controller transfer data. */
cdata = grub_malloc (sizeof (*cdata)); 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); cdata->qh_virt = grub_ehci_find_qh (e, transfer);
if (!cdata->qh_virt) if (!cdata->qh_virt)
{ {
grub_dprintf ("ehci", "setup_transfer: no QH\n");
grub_free (cdata); grub_free (cdata);
return GRUB_USB_ERR_INTERNAL; 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); cdata->td_alt_virt = grub_ehci_alloc_td (e);
if (!cdata->td_alt_virt) if (!cdata->td_alt_virt)
{ {
grub_dprintf ("ehci", "setup_transfer: no TDs\n");
grub_free (cdata); grub_free (cdata);
return GRUB_USB_ERR_INTERNAL; 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_ehci_free_tds (e, cdata->td_first_virt, NULL, &actual);
grub_free (cdata); grub_free (cdata);
grub_dprintf ("ehci", "setup_transfer: no TD\n");
return GRUB_USB_ERR_INTERNAL; return GRUB_USB_ERR_INTERNAL;
} }
@@ -1386,6 +1422,8 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
* i.e. reset token */ * i.e. reset token */
cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0); cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0);
sync_all_caches (e);
/* Finito */ /* Finito */
transfer->controller_data = cdata; 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_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata); grub_free (cdata);
sync_all_caches (e);
/* Additionally, do something with EHCI to make it running (what?) */ /* Additionally, do something with EHCI to make it running (what?) */
/* Try enable EHCI and AL */ /* Try enable EHCI and AL */
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, 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_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata); grub_free (cdata);
sync_all_caches (e);
/* Evaluation of error code - currently we don't have GRUB USB error /* 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. * codes for some EHCI states, GRUB_USB_ERR_DATA is used for them.
* Order of evaluation is critical, specially bubble/stall. */ * 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_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata); grub_free (cdata);
sync_all_caches (e);
return GRUB_USB_ERR_NONE; return GRUB_USB_ERR_NONE;
} }
@@ -1515,6 +1559,8 @@ grub_ehci_check_transfer (grub_usb_controller_t dev,
transfer->controller_data; transfer->controller_data;
grub_uint32_t token, token_ftd; grub_uint32_t token, token_ftd;
sync_all_caches (e);
grub_dprintf ("ehci", grub_dprintf ("ehci",
"check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n", "check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS), grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS),
@@ -1581,6 +1627,9 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
int i; int i;
grub_uint64_t maxtime; grub_uint64_t maxtime;
grub_uint32_t qh_phys; grub_uint32_t qh_phys;
sync_all_caches (e);
grub_uint32_t interrupt = grub_uint32_t interrupt =
cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK; 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_tds (e, cdata->td_first_virt, transfer, &actual);
grub_ehci_free_td (e, cdata->td_alt_virt); grub_ehci_free_td (e, cdata->td_alt_virt);
grub_free (cdata); grub_free (cdata);
sync_all_caches (e);
grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n"); grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n");
return GRUB_USB_ERR_NONE; return GRUB_USB_ERR_NONE;
} }
@@ -1622,6 +1672,8 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
/* Unlink QH from AL */ /* Unlink QH from AL */
e->qh_virt[i].qh_hptr = cdata->qh_virt->qh_hptr; 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 /* If this is an interrupt transfer, we just wait for the periodic
* schedule to advance a few times and then assume that the EHCI * schedule to advance a few times and then assume that the EHCI
* controller has read the updated QH. */ * 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"); grub_dprintf ("ehci", "cancel_transfer: end\n");
sync_all_caches (e);
return GRUB_USB_ERR_NONE; 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); 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 */ /* Connect Status Change bit - it detects change of connection */
if (status & GRUB_EHCI_PORT_CONNECT_CH) if (status & GRUB_EHCI_PORT_CONNECT_CH)
{ {
-203
View File
@@ -1,203 +0,0 @@
/* usb.c -- libusb USB support for GRUB. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <usb.h>
#include <grub/usb.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
static struct grub_usb_controller_dev usb_controller =
{
.name = "libusb"
};
static struct grub_usb_device *grub_usb_devs[128];
struct usb_bus *busses;
static grub_err_t
grub_libusb_devices (void)
{
struct usb_bus *bus;
int last = 0;
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next)
{
struct usb_device *usbdev;
struct grub_usb_device *dev;
for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
{
struct usb_device_descriptor *desc = &usbdev->descriptor;
grub_err_t err;
if (! desc->bcdUSB)
continue;
dev = grub_malloc (sizeof (*dev));
if (! dev)
return grub_errno;
dev->data = usbdev;
/* Fill in all descriptors. */
err = grub_usb_device_initialize (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
/* Register the device. */
grub_usb_devs[last++] = dev;
}
}
return GRUB_USB_ERR_NONE;
}
void
grub_usb_poll_devices (void)
{
/* TODO: recheck grub_usb_devs */
}
int
grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data)
{
int i;
for (i = 0; i < 128; i++)
{
if (grub_usb_devs[i])
{
if (hook (grub_usb_devs[i], hook_data))
return 1;
}
}
return 0;
}
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
{
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
grub_uint8_t request, grub_uint16_t value,
grub_uint16_t idx, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_control_msg (devh, reqtype, request,
value, idx, data, size, 20) < 0)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_release_interface (devh, 0);
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_write (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 0)
goto fail;
if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
goto fail;
if (usb_release_interface (devh, 0) < 0)
goto fail;
usb_close (devh);
return GRUB_USB_ERR_NONE;
fail:
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
GRUB_MOD_INIT (libusb)
{
usb_init();
usb_find_busses();
usb_find_devices();
if (grub_libusb_devices ())
return;
grub_usb_controller_dev_register (&usb_controller);
return;
}
GRUB_MOD_FINI (libusb)
{
return;
}
+4 -1
View File
@@ -750,7 +750,10 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev,
{ {
cdata->td_head_virt = grub_ohci_alloc_td (o); cdata->td_head_virt = grub_ohci_alloc_td (o);
if (!cdata->td_head_virt) if (!cdata->td_head_virt)
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */ {
grub_free (cdata);
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */
}
/* We can set td_head only when ED is not active, i.e. /* We can set td_head only when ED is not active, i.e.
* when it is newly allocated. */ * when it is newly allocated. */
cdata->ed_virt->td_head cdata->ed_virt->td_head
+20 -6
View File
@@ -24,6 +24,7 @@
#include <grub/usb.h> #include <grub/usb.h>
#include <grub/usbtrans.h> #include <grub/usbtrans.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/cache.h>
static inline unsigned int 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); data_addr = grub_dma_get_phys (data_chunk);
grub_memcpy ((char *) data, data_in, size); grub_memcpy ((char *) data, data_in, size);
grub_arch_sync_dma_caches (data, size);
grub_dprintf ("usb", grub_dprintf ("usb",
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n", "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n",
reqtype, request, value, index, (unsigned long)size); reqtype, request, value, index, (unsigned long)size);
@@ -161,6 +164,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
setupdata->value = value; setupdata->value = value;
setupdata->index = index; setupdata->index = index;
setupdata->length = size; setupdata->length = size;
grub_arch_sync_dma_caches (setupdata, sizeof (*setupdata));
transfer->transactions[0].size = sizeof (*setupdata); transfer->transactions[0].size = sizeof (*setupdata);
transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
transfer->transactions[0].data = setupdata_addr; 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->transactions);
grub_free (transfer); grub_free (transfer);
grub_dma_free (data_chunk);
grub_dma_free (setupdata_chunk); grub_dma_free (setupdata_chunk);
grub_arch_sync_dma_caches (data, size0);
grub_memcpy (data_in, (char *) data, size0); grub_memcpy (data_in, (char *) data, size0);
grub_dma_free (data_chunk);
return err; return err;
} }
@@ -236,7 +243,10 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
data = grub_dma_get_virt (data_chunk); data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk); data_addr = grub_dma_get_phys (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_OUT) 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. */ /* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer)); transfer = grub_malloc (sizeof (struct grub_usb_transfer));
@@ -306,13 +316,17 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
dev->toggle[transfer->endpoint] = toggle; dev->toggle[transfer->endpoint] = toggle;
if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN) if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN)
grub_memcpy (transfer->data, (void *) {
grub_dma_get_virt (transfer->data_chunk), grub_arch_sync_dma_caches (grub_dma_get_virt (transfer->data_chunk),
transfer->size + 1); transfer->size + 1);
grub_memcpy (transfer->data, (void *)
grub_dma_get_virt (transfer->data_chunk),
transfer->size + 1);
}
grub_free (transfer->transactions); grub_free (transfer->transactions);
grub_free (transfer);
grub_dma_free (transfer->data_chunk); grub_dma_free (transfer->data_chunk);
grub_free (transfer);
} }
static grub_usb_err_t static grub_usb_err_t
+7 -12
View File
@@ -61,18 +61,6 @@ static const struct grub_arg_option options[] = {
{0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0}
}; };
/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
grub_uint8_t
grub_byte_checksum (void *base, grub_size_t size)
{
grub_uint8_t *ptr;
grub_uint8_t ret = 0;
for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
ptr++)
ret += *ptr;
return ret;
}
/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise. /* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
rev2 contains the revision of ACPIv2+ to generate or 0 if none. */ rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
static int rev1, rev2; static int rev1, rev2;
@@ -180,8 +168,10 @@ grub_acpi_create_ebda (void)
struct grub_acpi_rsdp_v20 *v2; struct grub_acpi_rsdp_v20 *v2;
ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4); ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
grub_dprintf ("acpi", "EBDA @%p\n", ebda);
if (ebda) if (ebda)
ebda_kb_len = *(grub_uint16_t *) ebda; ebda_kb_len = *(grub_uint16_t *) ebda;
grub_dprintf ("acpi", "EBDA length 0x%x\n", ebda_kb_len);
if (ebda_kb_len > 16) if (ebda_kb_len > 16)
ebda_kb_len = 0; ebda_kb_len = 0;
ctx.ebda_len = (ebda_kb_len + 1) << 10; ctx.ebda_len = (ebda_kb_len + 1) << 10;
@@ -495,6 +485,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
if (! rsdp) if (! rsdp)
rsdp = grub_machine_acpi_get_rsdpv1 (); rsdp = grub_machine_acpi_get_rsdpv1 ();
grub_dprintf ("acpi", "RSDP @%p\n", rsdp);
if (rsdp) if (rsdp)
{ {
grub_uint32_t *entry_ptr; grub_uint32_t *entry_ptr;
@@ -601,6 +593,9 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
if (! table->addr) if (! table->addr)
{ {
free_tables (); free_tables ();
grub_free (exclude);
grub_free (load_only);
grub_free (table);
return grub_errno; return grub_errno;
} }
table->next = acpi_tables; table->next = acpi_tables;
+3
View File
@@ -26,6 +26,8 @@
#define grub_dprintf(cond, args...) printf ( args ) #define grub_dprintf(cond, args...) printf ( args )
#define grub_printf printf #define grub_printf printf
#define grub_util_fopen fopen
#define grub_memcmp memcmp
typedef uint64_t grub_uint64_t; typedef uint64_t grub_uint64_t;
typedef uint32_t grub_uint32_t; typedef uint32_t grub_uint32_t;
typedef uint16_t grub_uint16_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) if (!add)
return -1; return -1;
break; break;
case GRUB_ACPI_OPCODE_CREATE_DWORD_FIELD:
case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD: case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD: case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
{ {
+2
View File
@@ -23,6 +23,8 @@
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/disk.h> #include <grub/disk.h>
GRUB_MOD_LICENSE ("GPLv3+");
static grub_err_t static grub_err_t
grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)), int argc __attribute__ ((unused)),
+7 -4
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_STANDARD);
} }
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); if (utcount)
for (j = 0; j < utcount; j++) {
grub_printf ("<%x>", (unsigned int) utbuf[j]); grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); for (j = 0; j < utcount; j++)
grub_printf ("<%x>", (unsigned int) utbuf[j]);
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
}
grub_xputs ("\n"); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
+31 -16
View File
@@ -51,7 +51,7 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)),
grub_printf grub_printf
("Type Physical start - end #Pages " ("Type Physical start - end #Pages "
" Size Attributes\n"); " Size Attributes\n");
memory_map_end = ADD_MEMORY_DESCRIPTOR (memory_map, map_size); memory_map_end = ADD_MEMORY_DESCRIPTOR (memory_map, map_size);
for (desc = memory_map; for (desc = memory_map;
desc < memory_map_end; desc < memory_map_end;
@@ -74,7 +74,8 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)),
"ACPI-nvs", "ACPI-nvs",
"MMIO ", "MMIO ",
"IO-ports", "IO-ports",
"PAL-code" "PAL-code",
"persist ",
}; };
if (desc->type < ARRAY_SIZE (types_str)) if (desc->type < ARRAY_SIZE (types_str))
grub_printf ("%s ", types_str[desc->type]); grub_printf ("%s ", types_str[desc->type]);
@@ -87,21 +88,29 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)),
desc->physical_start + (desc->num_pages << 12) - 1, desc->physical_start + (desc->num_pages << 12) - 1,
desc->num_pages); desc->num_pages);
size = desc->num_pages; size = desc->num_pages << 12; /* 4 KiB page size */
size <<= (12 - 10); /*
if (size < 1024) * Since size is a multiple of 4 KiB, no need to handle units
grub_printf (" %4" PRIuGRUB_UINT64_T "KB", size); * of just Bytes (which would use a mask of 0x3ff).
*
* 14 characters would support the largest possible number of 4 KiB
* pages that are not a multiple of larger units (e.g., MiB):
* 17592186044415 (0xffffff_fffff000), but that uses a lot of
* whitespace for a rare case. 6 characters usually suffices;
* columns will be off if not, but this is preferable to rounding.
*/
if (size & 0xfffff)
grub_printf (" %6" PRIuGRUB_UINT64_T "KiB", size >> 10);
else if (size & 0x3fffffff)
grub_printf (" %6" PRIuGRUB_UINT64_T "MiB", size >> 20);
else if (size & 0xffffffffff)
grub_printf (" %6" PRIuGRUB_UINT64_T "GiB", size >> 30);
else if (size & 0x3ffffffffffff)
grub_printf (" %6" PRIuGRUB_UINT64_T "TiB", size >> 40);
else if (size & 0xfffffffffffffff)
grub_printf (" %6" PRIuGRUB_UINT64_T "PiB", size >> 50);
else else
{ grub_printf (" %6" PRIuGRUB_UINT64_T "EiB", size >> 60);
size /= 1024;
if (size < 1024)
grub_printf (" %4" PRIuGRUB_UINT64_T "MB", size);
else
{
size /= 1024;
grub_printf (" %4" PRIuGRUB_UINT64_T "GB", size);
}
}
attr = desc->attribute; attr = desc->attribute;
if (attr & GRUB_EFI_MEMORY_RUNTIME) if (attr & GRUB_EFI_MEMORY_RUNTIME)
@@ -122,6 +131,12 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)),
grub_printf (" RP"); grub_printf (" RP");
if (attr & GRUB_EFI_MEMORY_XP) if (attr & GRUB_EFI_MEMORY_XP)
grub_printf (" XP"); grub_printf (" XP");
if (attr & GRUB_EFI_MEMORY_NV)
grub_printf (" NV");
if (attr & GRUB_EFI_MEMORY_MORE_RELIABLE)
grub_printf (" MR");
if (attr & GRUB_EFI_MEMORY_RO)
grub_printf (" RO");
grub_printf ("\n"); grub_printf ("\n");
} }
+12 -2
View File
@@ -37,10 +37,20 @@ static const struct guid_mapping guid_mappings[] =
{ {
{ GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"}, { GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"},
{ GRUB_EFI_ACPI_TABLE_GUID, "ACPI-1.0"}, { GRUB_EFI_ACPI_TABLE_GUID, "ACPI-1.0"},
{ GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID,
"CRC32 GUIDED SECTION EXTRACTION"},
{ GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID, "DEBUG IMAGE INFO"},
{ GRUB_EFI_DXE_SERVICES_TABLE_GUID, "DXE SERVICES"},
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"},
{ GRUB_EFI_HOB_LIST_GUID, "HOB LIST"},
{ GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID, "LZMA CUSTOM DECOMPRESS"},
{ GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID, "MEMORY TYPE INFO"},
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"}, { GRUB_EFI_SAL_TABLE_GUID, "SAL"},
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"}, { GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"}, { GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"} { GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
{ GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},
}; };
static grub_err_t static grub_err_t
+3 -3
View File
@@ -45,7 +45,7 @@ static grub_err_t
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
int byte, bit; int byte = 0, bit = 0;
grub_err_t err; grub_err_t err;
grub_uint8_t value; grub_uint8_t value;
@@ -67,7 +67,7 @@ static grub_err_t
grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)), grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
int byte, bit; int byte = 0, bit = 0;
grub_err_t err; grub_err_t err;
grub_uint8_t value; grub_uint8_t value;
@@ -85,7 +85,7 @@ static grub_err_t
grub_cmd_cmosset (struct grub_command *cmd __attribute__ ((unused)), grub_cmd_cmosset (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
int byte, bit; int byte = 0, bit = 0;
grub_err_t err; grub_err_t err;
grub_uint8_t value; grub_uint8_t value;
@@ -39,9 +39,17 @@ static const char *descs[] = {
[2] = "before RAM init", [2] = "before RAM init",
[3] = "after RAM init", [3] = "after RAM init",
[4] = "end of romstage", [4] = "end of romstage",
[5] = "start of verified boot",
[6] = "end of verified boot",
[8] = "start of RAM copy", [8] = "start of RAM copy",
[9] = "end of RAM copy", [9] = "end of RAM copy",
[10] = "start of ramstage", [10] = "start of ramstage",
[11] = "start of bootblock",
[12] = "end of bootblock",
[13] = "starting to load romstage",
[14] = "finished loading romstage",
[15] = "starting LZMA decompress (ignore for x86)",
[16] = "finished LZMA decompress (ignore for x86)",
[30] = "device enumerate", [30] = "device enumerate",
[40] = "device configure", [40] = "device configure",
[50] = "device enable", [50] = "device enable",
+32 -11
View File
@@ -253,6 +253,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
struct grub_command *cmd; struct grub_command *cmd;
char **cutargs; char **cutargs;
int cutargc; int cutargc;
grub_err_t err = GRUB_ERR_NONE;
for (i = 0; i < 2; i++) 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")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
if (!cutargs)
return grub_errno;
cutargc = argc - 1; cutargc = argc - 1;
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2)); grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
cutargs[0] = args[0]; cutargs[0] = args[0];
@@ -333,7 +336,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, cutargc, cutargs)) if (!(cmd->func) (cmd, cutargc, cutargs))
{ {
kernel_type = LINUX; kernel_type = LINUX;
return GRUB_ERR_NONE; goto out;
} }
} }
grub_errno = GRUB_ERR_NONE; 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)) if (!(cmd->func) (cmd, argc, args))
{ {
kernel_type = MULTIBOOT; kernel_type = MULTIBOOT;
return GRUB_ERR_NONE; goto out;
} }
} }
grub_errno = GRUB_ERR_NONE; 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)) if (!(cmd->func) (cmd, cutargc, cutargs))
{ {
kernel_type = KFREEBSD; kernel_type = KFREEBSD;
return GRUB_ERR_NONE; goto out;
} }
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
@@ -422,6 +425,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
char **bsdargs; char **bsdargs;
int bsdargc; int bsdargc;
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")]; char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
int found = 0;
if (bsd_device == -1) if (bsd_device == -1)
{ {
bsdargs = cutargs; bsdargs = cutargs;
@@ -432,6 +437,11 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
char rbuf[3] = "-r"; char rbuf[3] = "-r";
bsdargc = cutargc + 2; bsdargc = cutargc + 2;
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
if (!bsdargs)
{
err = grub_errno;
goto out;
}
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0])); grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
bsdargs[argc] = rbuf; bsdargs[argc] = rbuf;
bsdargs[argc + 1] = bsddevname; bsdargs[argc + 1] = bsddevname;
@@ -447,7 +457,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (!(cmd->func) (cmd, bsdargc, bsdargs)) if (!(cmd->func) (cmd, bsdargc, bsdargs))
{ {
kernel_type = KNETBSD; kernel_type = KNETBSD;
return GRUB_ERR_NONE; found = 1;
goto free_bsdargs;
} }
} }
grub_errno = GRUB_ERR_NONE; 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)) if (!(cmd->func) (cmd, bsdargc, bsdargs))
{ {
kernel_type = KOPENBSD; kernel_type = KOPENBSD;
return GRUB_ERR_NONE; found = 1;
goto free_bsdargs;
} }
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
free_bsdargs:
if (bsdargs != cutargs) if (bsdargs != cutargs)
grub_free (bsdargs); grub_free (bsdargs);
if (found)
goto out;
} }
} }
} }
while (0); while (0);
return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s", err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
args[0]); args[0]);
out:
grub_free (cutargs);
return err;
} }
static grub_err_t static grub_err_t
@@ -534,15 +553,17 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
char **newargs; char **newargs;
grub_err_t err; grub_err_t err;
char nounzipbuf[10] = "--nounzip"; 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])); newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
if (!newargs) if (!newargs)
return grub_errno; return grub_errno;
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
newargs[0] = nounzipbuf; 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); err = cmd->func (cmd, argc + 1, newargs);
grub_free (newargs); grub_free (newargs);
+2
View File
@@ -37,6 +37,8 @@ static const char *names[] =
is required to save accross hibernations. */ is required to save accross hibernations. */
[GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage RAM"), [GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage RAM"),
[GRUB_MEMORY_BADRAM] = N_("faulty RAM (BadRAM)"), [GRUB_MEMORY_BADRAM] = N_("faulty RAM (BadRAM)"),
[GRUB_MEMORY_PERSISTENT] = N_("persistent RAM"),
[GRUB_MEMORY_PERSISTENT_LEGACY] = N_("persistent RAM (legacy)"),
[GRUB_MEMORY_COREBOOT_TABLES] = N_("RAM holding coreboot tables"), [GRUB_MEMORY_COREBOOT_TABLES] = N_("RAM holding coreboot tables"),
[GRUB_MEMORY_CODE] = N_("RAM holding firmware code") [GRUB_MEMORY_CODE] = N_("RAM holding firmware code")
}; };
+11 -1
View File
@@ -198,7 +198,10 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
return grub_errno; return grub_errno;
if (get_uuid (NULL, &uuid_root, 0)) if (get_uuid (NULL, &uuid_root, 0))
return grub_errno; {
grub_free (mods);
return grub_errno;
}
prefdev = grub_file_get_device_name (prefix); prefdev = grub_file_get_device_name (prefix);
if (grub_errno) if (grub_errno)
@@ -210,6 +213,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
if (get_uuid (prefdev, &uuid_prefix, 0)) if (get_uuid (prefdev, &uuid_prefix, 0))
{ {
grub_free (uuid_root); grub_free (uuid_root);
grub_free (prefdev);
grub_free (mods);
return grub_errno; return grub_errno;
} }
@@ -289,12 +294,15 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
} }
grub_free (uuid_root); grub_free (uuid_root);
grub_free (uuid_prefix); grub_free (uuid_prefix);
grub_free (prefdev);
grub_free (mods);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
fail: fail:
grub_free (uuid_root); grub_free (uuid_root);
grub_free (uuid_prefix); grub_free (uuid_prefix);
grub_free (prefdev);
for (i = 0; i < mods_loaded; i++) for (i = 0; i < mods_loaded; i++)
if (mods[i]) if (mods[i])
@@ -302,6 +310,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
mods[i]->fini = 0; mods[i]->fini = 0;
grub_dl_unload (mods[i]); grub_dl_unload (mods[i]);
} }
grub_free (mods);
return grub_errno; return grub_errno;
} }
+1
View File
@@ -283,6 +283,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
} }
if (! cur) if (! cur)
{ {
grub_free (parsed);
grub_device_close (dev); grub_device_close (dev);
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"), return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"),
args[i]); args[i]);
+13 -9
View File
@@ -45,6 +45,7 @@ check_password (const char *user, const char *entered, void *pin)
grub_uint8_t *buf; grub_uint8_t *buf;
struct pbkdf2_password *pass = pin; struct pbkdf2_password *pass = pin;
gcry_err_code_t err; gcry_err_code_t err;
grub_err_t ret;
buf = grub_malloc (pass->buflen); buf = grub_malloc (pass->buflen);
if (!buf) if (!buf)
@@ -55,17 +56,17 @@ check_password (const char *user, const char *entered, void *pin)
pass->salt, pass->saltlen, pass->c, pass->salt, pass->saltlen, pass->c,
buf, pass->buflen); buf, pass->buflen);
if (err) 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); grub_auth_authenticate (user);
return grub_crypto_gcry_error (err); ret = GRUB_ERR_NONE;
} }
if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0) grub_free (buf);
return GRUB_ACCESS_DENIED; return ret;
grub_auth_authenticate (user);
return GRUB_ERR_NONE;
} }
static inline int static inline int
@@ -104,7 +105,10 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
pass->c = grub_strtoul (ptr, &ptr, 0); pass->c = grub_strtoul (ptr, &ptr, 0);
if (grub_errno) if (grub_errno)
return grub_errno; {
grub_free (pass);
return grub_errno;
}
if (*ptr != '.') if (*ptr != '.')
{ {
grub_free (pass); grub_free (pass);
+2 -2
View File
@@ -64,7 +64,7 @@ iterate_device (const char *name, void *data)
/* Skip floppy drives when requested. */ /* Skip floppy drives when requested. */
if (ctx->no_floppy && if (ctx->no_floppy &&
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
return 0; return 1;
#ifdef DO_SEARCH_FS_UUID #ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp #define compare_fn grub_strcasecmp
@@ -210,10 +210,10 @@ try (struct search_ctx *ctx)
/* Cache entry was outdated. Remove it. */ /* Cache entry was outdated. Remove it. */
if (!ctx->count) if (!ctx->count)
{ {
*prev = cache_ent->next;
grub_free (cache_ent->key); grub_free (cache_ent->key);
grub_free (cache_ent->value); grub_free (cache_ent->value);
grub_free (cache_ent); grub_free (cache_ent);
*prev = cache_ent->next;
} }
} }
+7 -2
View File
@@ -175,7 +175,10 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
var = "root"; var = "root";
} }
else else
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); {
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
goto out;
}
if (state[SEARCH_LABEL].set) if (state[SEARCH_LABEL].set)
grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set, grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set,
@@ -187,8 +190,10 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set, grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints); hints, nhints);
else else
return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
out:
grub_free (hints);
return grub_errno; return grub_errno;
} }
+11 -5
View File
@@ -324,19 +324,19 @@ grub_load_public_key (grub_file_t f)
if (grub_file_read (f, &l, sizeof (l)) != sizeof (l)) if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
{ {
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); 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; lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
{ {
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); 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) if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
{ {
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
goto fail; break;
} }
grub_memcpy (buffer, &l, sizeof (l)); grub_memcpy (buffer, &l, sizeof (l));
@@ -346,10 +346,16 @@ grub_load_public_key (grub_file_t f)
buffer, lb + sizeof (grub_uint16_t), 0)) buffer, lb + sizeof (grub_uint16_t), 0))
{ {
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); 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_MD_SHA1->final (fingerprint_context);
grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20); grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);
@@ -454,7 +460,7 @@ grub_verify_signature_real (char *buf, grub_size_t size,
grub_err_t err; grub_err_t err;
grub_size_t i; grub_size_t i;
gcry_mpi_t mpis[10]; gcry_mpi_t mpis[10];
grub_uint8_t type; grub_uint8_t type = 0;
err = read_packet_header (sig, &type, &len); err = read_packet_header (sig, &type, &len);
if (err) if (err)
+21 -19
View File
@@ -32,7 +32,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
struct grub_ahci_cmd_head struct grub_ahci_cmd_head
{ {
grub_uint32_t config; grub_uint32_t config;
grub_uint32_t transfered; grub_uint32_t transferred;
grub_uint64_t command_table_base; grub_uint64_t command_table_base;
grub_uint32_t unused[4]; grub_uint32_t unused[4];
}; };
@@ -195,7 +195,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word (addr, grub_pci_read_word (addr) grub_pci_write_word (addr, grub_pci_read_word (addr)
| GRUB_PCI_COMMAND_MEM_ENABLED); | GRUB_PCI_COMMAND_MEM_ENABLED | GRUB_PCI_COMMAND_BUS_MASTER);
hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK,
sizeof (*hba)); sizeof (*hba));
@@ -355,7 +355,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
if (adevs[i]) if (adevs[i])
{ {
adevs[i]->hba->ports[adevs[i]->port].sata_error = adevs[i]->hba->ports[adevs[i]->port].sata_error; adevs[i]->hba->ports[adevs[i]->port].sata_error = adevs[i]->hba->ports[adevs[i]->port].sata_error;
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
adevs[i]->command_list_chunk = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head) * 32); adevs[i]->command_list_chunk = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head) * 32);
@@ -440,7 +440,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
adevs[i]->hba->ports[adevs[i]->port].intstatus = ~0; adevs[i]->hba->ports[adevs[i]->port].intstatus = ~0;
// adevs[i]->hba->ports[adevs[i]->port].fbs = 0; // adevs[i]->hba->ports[adevs[i]->port].fbs = 0;
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
adevs[i]->rfis = grub_memalign_dma32 (4096, adevs[i]->rfis = grub_memalign_dma32 (4096,
@@ -480,7 +480,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
for (i = 0; i < nports; i++) for (i = 0; i < nports; i++)
if (adevs[i]) if (adevs[i])
{ {
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
fr_running |= (1 << i); fr_running |= (1 << i);
@@ -488,7 +488,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON; adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
adevs[i]->hba->ports[adevs[i]->port].command |= 1 << 28; adevs[i]->hba->ports[adevs[i]->port].command |= 1 << 28;
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
} }
@@ -515,26 +515,26 @@ grub_ahci_pciinit (grub_pci_device_t dev,
for (i = 0; i < nports; i++) for (i = 0; i < nports; i++)
if (adevs[i]) if (adevs[i])
{ {
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON; adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP; adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP;
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
adevs[i]->hba->ports[adevs[i]->port].sata_error = ~0; adevs[i]->hba->ports[adevs[i]->port].sata_error = ~0;
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
grub_dprintf ("ahci", "offset: %x, tfd:%x, CMD: %x\n", grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port,
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data - (int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
(char *) adevs[i]->hba), (char *) adevs[i]->hba),
adevs[i]->hba->ports[adevs[i]->port].task_file_data, adevs[i]->hba->ports[adevs[i]->port].task_file_data,
adevs[i]->hba->ports[adevs[i]->port].command); adevs[i]->hba->ports[adevs[i]->port].command);
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
} }
@@ -542,17 +542,19 @@ grub_ahci_pciinit (grub_pci_device_t dev,
for (i = 0; i < nports; i++) for (i = 0; i < nports; i++)
if (adevs[i]) if (adevs[i])
{ {
grub_dprintf ("ahci", "offset: %x, tfd:%x, CMD: %x\n", grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port,
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data - (int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
(char *) adevs[i]->hba), (char *) adevs[i]->hba),
adevs[i]->hba->ports[adevs[i]->port].task_file_data, adevs[i]->hba->ports[adevs[i]->port].task_file_data,
adevs[i]->hba->ports[adevs[i]->port].command); adevs[i]->hba->ports[adevs[i]->port].command);
grub_dprintf ("ahci", "err: %x\n", grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
adevs[i]->hba->ports[adevs[i]->port].sata_error); adevs[i]->hba->ports[adevs[i]->port].sata_error);
adevs[i]->hba->ports[adevs[i]->port].command adevs[i]->hba->ports[adevs[i]->port].command
= (adevs[i]->hba->ports[adevs[i]->port].command & 0x0fffffff) | (1 << 28) | 2 | 4; = (adevs[i]->hba->ports[adevs[i]->port].command & 0x0fffffff) | (1 << 28)
| GRUB_AHCI_HBA_PORT_CMD_SPIN_UP
| GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
/* struct grub_disk_ata_pass_through_parms parms2; /* struct grub_disk_ata_pass_through_parms parms2;
grub_memset (&parms2, 0, sizeof (parms2)); grub_memset (&parms2, 0, sizeof (parms2));
@@ -565,14 +567,14 @@ grub_ahci_pciinit (grub_pci_device_t dev,
while (grub_get_time_ms () < endtime) while (grub_get_time_ms () < endtime)
{ {
for (i = 0; i < nports; i++) for (i = 0; i < nports; i++)
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & 0x88)) if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ)))
break; break;
if (i == nports) if (i == nports)
break; break;
} }
for (i = 0; i < nports; i++) for (i = 0; i < nports; i++)
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & 0x88)) if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ)))
{ {
grub_dprintf ("ahci", "port %d is busy\n", i); grub_dprintf ("ahci", "port %d is busy\n", i);
failed_adevs[i] = adevs[i]; failed_adevs[i] = adevs[i];
@@ -952,7 +954,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
grub_dprintf ("ahci", "AHCI tfd = %x\n", grub_dprintf ("ahci", "AHCI tfd = %x\n",
dev->hba->ports[dev->port].task_file_data); 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 dev->command_list[0].command_table_base
= grub_dma_get_phys (dev->command_table_chunk); = grub_dma_get_phys (dev->command_table_chunk);
@@ -1002,7 +1004,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
if (parms->write) if (parms->write)
grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size); grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size);
grub_dprintf ("ahci", "AHCI command schedulded\n"); grub_dprintf ("ahci", "AHCI command scheduled\n");
grub_dprintf ("ahci", "AHCI tfd = %x\n", grub_dprintf ("ahci", "AHCI tfd = %x\n",
dev->hba->ports[dev->port].task_file_data); dev->hba->ports[dev->port].task_file_data);
grub_dprintf ("ahci", "AHCI inten = %x\n", grub_dprintf ("ahci", "AHCI inten = %x\n",
@@ -1042,7 +1044,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
dev->hba->ports[dev->port].command_issue, dev->hba->ports[dev->port].command_issue,
dev->hba->ports[dev->port].intstatus, dev->hba->ports[dev->port].intstatus,
dev->hba->ports[dev->port].task_file_data, 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, 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))[0x00],
((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]); ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]);
+24 -9
View File
@@ -25,6 +25,7 @@
#include <grub/fs.h> #include <grub/fs.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/procfs.h> #include <grub/procfs.h>
#include <grub/partition.h>
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
#include <grub/emu/hostdisk.h> #include <grub/emu/hostdisk.h>
@@ -718,6 +719,7 @@ grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name,
newdev->id = last_cryptodisk_id++; newdev->id = last_cryptodisk_id++;
newdev->source_id = source->id; newdev->source_id = source->id;
newdev->source_dev_id = source->dev->id; newdev->source_dev_id = source->dev->id;
newdev->partition_start = grub_partition_get_start (source->partition);
newdev->next = cryptodisk_list; newdev->next = cryptodisk_list;
cryptodisk_list = newdev; cryptodisk_list = newdev;
@@ -740,7 +742,9 @@ grub_cryptodisk_get_by_source_disk (grub_disk_t disk)
grub_cryptodisk_t dev; grub_cryptodisk_t dev;
for (dev = cryptodisk_list; dev != NULL; dev = dev->next) for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id)
return dev; if ((disk->partition && grub_partition_get_start (disk->partition) == dev->partition_start) ||
(!disk->partition && dev->partition_start == 0))
return dev;
return NULL; return NULL;
} }
@@ -761,6 +765,7 @@ grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name,
newdev->cheat_fd = GRUB_UTIL_FD_INVALID; newdev->cheat_fd = GRUB_UTIL_FD_INVALID;
newdev->source_id = source->id; newdev->source_id = source->id;
newdev->source_dev_id = source->dev->id; newdev->source_dev_id = source->dev->id;
newdev->partition_start = grub_partition_get_start (source->partition);
newdev->id = last_cryptodisk_id++; newdev->id = last_cryptodisk_id++;
newdev->next = cryptodisk_list; newdev->next = cryptodisk_list;
cryptodisk_list = newdev; cryptodisk_list = newdev;
@@ -964,33 +969,43 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
grub_disk_t disk; grub_disk_t disk;
grub_cryptodisk_t dev; grub_cryptodisk_t dev;
char *diskname; char *diskname;
char *disklast; char *disklast = NULL;
grub_size_t len;
search_uuid = NULL; search_uuid = NULL;
check_boot = state[2].set; check_boot = state[2].set;
diskname = args[0]; diskname = args[0];
if (diskname[0] == '(' && *(disklast = &diskname[grub_strlen (diskname) - 1]) == ')') len = grub_strlen (diskname);
if (len && diskname[0] == '(' && diskname[len - 1] == ')')
{ {
disklast = &diskname[len - 1];
*disklast = '\0'; *disklast = '\0';
disk = grub_disk_open (diskname + 1); diskname++;
*disklast = ')';
} }
else
disk = grub_disk_open (diskname); disk = grub_disk_open (diskname);
if (!disk) if (!disk)
return grub_errno; {
if (disklast)
*disklast = ')';
return grub_errno;
}
dev = grub_cryptodisk_get_by_source_disk (disk); dev = grub_cryptodisk_get_by_source_disk (disk);
if (dev) if (dev)
{ {
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
grub_disk_close (disk); grub_disk_close (disk);
if (disklast)
*disklast = ')';
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
err = grub_cryptodisk_scan_device_real (args[0], disk); err = grub_cryptodisk_scan_device_real (diskname, disk);
grub_disk_close (disk); grub_disk_close (disk);
if (disklast)
*disklast = ')';
return err; return err;
} }
+1 -1
View File
@@ -1007,7 +1007,7 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
struct grub_diskfilter_vg * struct grub_diskfilter_vg *
grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
char *name, grub_uint64_t disk_size, const char *name, grub_uint64_t disk_size,
grub_uint64_t stripe_size, grub_uint64_t stripe_size,
int layout, int level) int layout, int level)
{ {
+1 -1
View File
@@ -172,7 +172,7 @@ grub_dmraid_nv_detect (grub_disk_t disk,
return grub_diskfilter_make_raid (sizeof (sb.array.signature), return grub_diskfilter_make_raid (sizeof (sb.array.signature),
uuid, sb.array.total_volumes, uuid, sb.array.total_volumes,
NULL, disk_size, "nv", disk_size,
sb.array.stripe_block_size, sb.array.stripe_block_size,
GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC, GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC,
level); level);
+63 -60
View File
@@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devices;
static struct grub_efidisk_data *hd_devices; static struct grub_efidisk_data *hd_devices;
static struct grub_efidisk_data *cd_devices; static struct grub_efidisk_data *cd_devices;
/* Duplicate a device path. */
static grub_efi_device_path_t *
duplicate_device_path (const grub_efi_device_path_t *dp)
{
grub_efi_device_path_t *p;
grub_size_t total_size = 0;
for (p = (grub_efi_device_path_t *) dp;
;
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
{
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
break;
}
p = grub_malloc (total_size);
if (! p)
return 0;
grub_memcpy (p, dp, total_size);
return p;
}
/* Return the device path node right before the end node. */
static grub_efi_device_path_t *
find_last_device_path (const grub_efi_device_path_t *dp)
{
grub_efi_device_path_t *next, *p;
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
return 0;
for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
;
return p;
}
static struct grub_efidisk_data * static struct grub_efidisk_data *
make_devices (void) make_devices (void)
{ {
@@ -110,7 +69,7 @@ make_devices (void)
if (! dp) if (! dp)
continue; continue;
ldp = find_last_device_path (dp); ldp = grub_efi_find_last_device_path (dp);
if (! ldp) if (! ldp)
/* This is empty. Why? */ /* This is empty. Why? */
continue; continue;
@@ -126,6 +85,12 @@ make_devices (void)
{ {
/* Uggh. */ /* Uggh. */
grub_free (handles); grub_free (handles);
while (devices)
{
d = devices->next;
grub_free (devices);
devices = d;
}
return 0; return 0;
} }
@@ -150,11 +115,11 @@ find_parent_device (struct grub_efidisk_data *devices,
grub_efi_device_path_t *dp, *ldp; grub_efi_device_path_t *dp, *ldp;
struct grub_efidisk_data *parent; struct grub_efidisk_data *parent;
dp = duplicate_device_path (d->device_path); dp = grub_efi_duplicate_device_path (d->device_path);
if (! dp) if (! dp)
return 0; return 0;
ldp = find_last_device_path (dp); ldp = grub_efi_find_last_device_path (dp);
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
ldp->length = sizeof (*ldp); ldp->length = sizeof (*ldp);
@@ -180,11 +145,11 @@ is_child (struct grub_efidisk_data *child,
grub_efi_device_path_t *dp, *ldp; grub_efi_device_path_t *dp, *ldp;
int ret; int ret;
dp = duplicate_device_path (child->device_path); dp = grub_efi_duplicate_device_path (child->device_path);
if (! dp) if (! dp)
return 0; return 0;
ldp = find_last_device_path (dp); ldp = grub_efi_find_last_device_path (dp);
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
ldp->length = sizeof (*ldp); ldp->length = sizeof (*ldp);
@@ -207,8 +172,8 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
{ {
int ret; int ret;
ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path), ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path),
find_last_device_path (d->device_path)); grub_efi_find_last_device_path (d->device_path));
if (ret == 0) if (ret == 0)
ret = grub_efi_compare_device_paths ((*p)->device_path, ret = grub_efi_compare_device_paths ((*p)->device_path,
d->device_path); d->device_path);
@@ -528,8 +493,15 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
m = d->block_io->media; m = d->block_io->media;
/* FIXME: Probably it is better to store the block size in the disk, /* FIXME: Probably it is better to store the block size in the disk,
and total sectors should be replaced with total blocks. */ and total sectors should be replaced with total blocks. */
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n", grub_dprintf ("efidisk",
m, (unsigned long long) m->last_block, m->block_size); "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; disk->total_sectors = m->last_block + 1;
/* Don't increase this value due to bug in some EFI. */ /* Don't increase this value due to bug in some EFI. */
disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
@@ -559,15 +531,42 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector,
{ {
struct grub_efidisk_data *d; struct grub_efidisk_data *d;
grub_efi_block_io_t *bio; grub_efi_block_io_t *bio;
grub_efi_status_t status;
grub_size_t io_align, num_bytes;
char *aligned_buf;
d = disk->data; d = disk->data;
bio = d->block_io; bio = d->block_io;
return efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio, /* Set alignment to 1 if 0 specified */
bio->media->media_id, io_align = bio->media->io_align ? bio->media->io_align : 1;
(grub_efi_uint64_t) sector, num_bytes = size << disk->log_sector_size;
(grub_efi_uintn_t) size << disk->log_sector_size,
buf); 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 static grub_err_t
@@ -582,7 +581,9 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
status = grub_efidisk_readwrite (disk, sector, size, buf, 0); 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, return grub_error (GRUB_ERR_READ_ERROR,
N_("failure reading sector 0x%llx from `%s'"), N_("failure reading sector 0x%llx from `%s'"),
(unsigned long long) sector, (unsigned long long) sector,
@@ -603,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); 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, return grub_error (GRUB_ERR_WRITE_ERROR,
N_("failure writing sector 0x%llx to `%s'"), N_("failure writing sector 0x%llx to `%s'"),
(unsigned long long) sector, disk->name); (unsigned long long) sector, disk->name);
@@ -795,7 +798,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
if (! dp) if (! dp)
return 0; return 0;
ldp = find_last_device_path (dp); ldp = grub_efi_find_last_device_path (dp);
if (! ldp) if (! ldp)
return 0; return 0;
@@ -810,14 +813,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
/* It is necessary to duplicate the device path so that GRUB /* It is necessary to duplicate the device path so that GRUB
can overwrite it. */ can overwrite it. */
dup_dp = duplicate_device_path (dp); dup_dp = grub_efi_duplicate_device_path (dp);
if (! dup_dp) if (! dup_dp)
return 0; return 0;
while (1) while (1)
{ {
grub_efi_device_path_t *dup_ldp; grub_efi_device_path_t *dup_ldp;
dup_ldp = find_last_device_path (dup_dp); dup_ldp = grub_efi_find_last_device_path (dup_dp);
if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))) || GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
+131 -21
View File
@@ -35,6 +35,7 @@ struct ofdisk_hash_ent
char *grub_devpath; char *grub_devpath;
int is_boot; int is_boot;
int is_removable; int is_removable;
int block_size_fails;
/* Pointer to shortest available name on nodes representing canonical names, /* Pointer to shortest available name on nodes representing canonical names,
otherwise NULL. */ otherwise NULL. */
const char *shortest; const char *shortest;
@@ -42,6 +43,10 @@ struct ofdisk_hash_ent
struct ofdisk_hash_ent *next; struct ofdisk_hash_ent *next;
}; };
static grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
struct ofdisk_hash_ent *op);
#define OFDISK_HASH_SZ 8 #define OFDISK_HASH_SZ 8
static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ]; static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
@@ -223,6 +228,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
if (grub_ieee1275_open (alias->path, &ihandle)) if (grub_ieee1275_open (alias->path, &ihandle))
return; return;
/* This method doesn't need memory allocation for the table. Open
firmware takes care of all memory management and the result table
stays in memory and is never freed. */
INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
args.method = (grub_ieee1275_cell_t) "vscsi-report-luns"; args.method = (grub_ieee1275_cell_t) "vscsi-report-luns";
args.ihandle = ihandle; args.ihandle = ihandle;
@@ -255,6 +263,82 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
grub_free (buf); grub_free (buf);
return; return;
} }
else if (grub_strcmp (alias->type, "sas_ioa") == 0)
{
/* The method returns the number of disks and a table where
* each ID is 64-bit long. Example of sas paths:
* /pci@80000002000001f/pci1014,034A@0/sas/disk@c05db70800
* /pci@80000002000001f/pci1014,034A@0/sas/disk@a05db70800
* /pci@80000002000001f/pci1014,034A@0/sas/disk@805db70800 */
struct sas_children
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t max;
grub_ieee1275_cell_t table;
grub_ieee1275_cell_t catch_result;
grub_ieee1275_cell_t nentries;
}
args;
char *buf, *bufptr;
unsigned i;
grub_uint64_t *table;
grub_uint16_t table_size;
grub_ieee1275_ihandle_t ihandle;
buf = grub_malloc (grub_strlen (alias->path) +
sizeof ("/disk@7766554433221100"));
if (!buf)
return;
bufptr = grub_stpcpy (buf, alias->path);
/* Power machines documentation specify 672 as maximum SAS disks in
one system. Using a slightly larger value to be safe. */
table_size = 768;
table = grub_malloc (table_size * sizeof (grub_uint64_t));
if (!table)
{
grub_free (buf);
return;
}
if (grub_ieee1275_open (alias->path, &ihandle))
{
grub_free (buf);
grub_free (table);
return;
}
INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2);
args.method = (grub_ieee1275_cell_t) "get-sas-children";
args.ihandle = ihandle;
args.max = table_size;
args.table = (grub_ieee1275_cell_t) table;
args.catch_result = 0;
args.nentries = 0;
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
{
grub_ieee1275_close (ihandle);
grub_free (table);
grub_free (buf);
return;
}
for (i = 0; i < args.nentries; i++)
{
grub_snprintf (bufptr, sizeof ("/disk@7766554433221100"),
"/disk@%" PRIxGRUB_UINT64_T, table[i]);
dev_iterate_real (buf, buf);
}
grub_ieee1275_close (ihandle);
grub_free (table);
grub_free (buf);
}
if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS) if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS)
&& grub_strcmp (alias->type, "block") == 0) && grub_strcmp (alias->type, "block") == 0)
@@ -375,6 +459,8 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
/* XXX: This should be large enough for any possible case. */ /* XXX: This should be large enough for any possible case. */
char prop[64]; char prop[64];
grub_ssize_t actual; grub_ssize_t actual;
grub_uint32_t block_size = 0;
grub_err_t err;
if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0) if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
@@ -405,14 +491,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
} }
grub_uint32_t block_size = 0;
if (grub_ofdisk_get_block_size (devpath, &block_size) == 0)
{
for (disk->log_sector_size = 0;
(1U << disk->log_sector_size) < block_size;
disk->log_sector_size++);
}
/* XXX: There is no property to read the number of blocks. There /* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */ is possible to use seek for this. */
@@ -423,14 +501,31 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
op = ofdisk_hash_find (devpath); op = ofdisk_hash_find (devpath);
if (!op) if (!op)
op = ofdisk_hash_add (devpath, NULL); op = ofdisk_hash_add (devpath, NULL);
else
grub_free (devpath);
if (!op) if (!op)
return grub_errno; {
grub_free (devpath);
return grub_errno;
}
disk->id = (unsigned long) op; disk->id = (unsigned long) op;
disk->data = op->open_path; disk->data = op->open_path;
err = grub_ofdisk_get_block_size (devpath, &block_size, op);
if (err)
{
grub_free (devpath);
return err;
}
if (block_size != 0)
{
for (disk->log_sector_size = 0;
(1U << disk->log_sector_size) < block_size;
disk->log_sector_size++);
}
else
disk->log_sector_size = 9;
} }
grub_free (devpath);
return 0; return 0;
} }
@@ -589,8 +684,9 @@ grub_ofdisk_init (void)
grub_disk_dev_register (&grub_ofdisk_dev); grub_disk_dev_register (&grub_ofdisk_dev);
} }
grub_err_t static grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size) grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
struct ofdisk_hash_ent *op)
{ {
struct size_args_ieee1275 struct size_args_ieee1275
{ {
@@ -612,20 +708,34 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
if (! last_ihandle) if (! last_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
*block_size = 0;
if (op->block_size_fails >= 2)
return GRUB_ERR_NONE;
INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2); INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2);
args_ieee1275.method = (grub_ieee1275_cell_t) "block-size"; args_ieee1275.method = (grub_ieee1275_cell_t) "block-size";
args_ieee1275.ihandle = last_ihandle; args_ieee1275.ihandle = last_ihandle;
args_ieee1275.result = 1; args_ieee1275.result = 1;
*block_size = GRUB_DISK_SECTOR_SIZE; if (IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1)
{
if ((IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) || (args_ieee1275.result)) grub_dprintf ("disk", "can't get block size: failed call-method\n");
grub_dprintf ("disk", "can't get block size\n"); op->block_size_fails++;
else }
if (args_ieee1275.size1 else if (args_ieee1275.result)
&& !(args_ieee1275.size1 & (args_ieee1275.size1 - 1)) {
&& args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384) grub_dprintf ("disk", "can't get block size: %lld\n",
(long long) args_ieee1275.result);
op->block_size_fails++;
}
else if (args_ieee1275.size1
&& !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
&& args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
{
op->block_size_fails = 0;
*block_size = args_ieee1275.size1; *block_size = args_ieee1275.size1;
}
return 0; return 0;
} }
+1 -1
View File
@@ -963,7 +963,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
if (embed_type != GRUB_EMBED_PCBIOS) if (embed_type != GRUB_EMBED_PCBIOS)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"LDM curently supports only PC-BIOS embedding"); "LDM currently supports only PC-BIOS embedding");
if (disk->partition) if (disk->partition)
return grub_error (GRUB_ERR_BUG, "disk isn't LDM"); return grub_error (GRUB_ERR_BUG, "disk isn't LDM");
pv = grub_diskfilter_get_pv_from_disk (disk, &vg); pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
+33 -27
View File
@@ -160,7 +160,7 @@ grub_lvm_detect (grub_disk_t disk,
"we don't support multiple LVM data areas"); "we don't support multiple LVM data areas");
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("we don't support multiple LVM data areas\n"); grub_util_info ("we don't support multiple LVM data areas");
#endif #endif
goto fail; goto fail;
} }
@@ -189,7 +189,7 @@ grub_lvm_detect (grub_disk_t disk,
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unknown LVM metadata header"); "unknown LVM metadata header");
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown LVM metadata header\n"); grub_util_info ("unknown LVM metadata header");
#endif #endif
goto fail2; goto fail2;
} }
@@ -213,7 +213,7 @@ grub_lvm_detect (grub_disk_t disk,
if (q == metadatabuf + mda_size) if (q == metadatabuf + mda_size)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("error parsing metadata\n"); grub_util_info ("error parsing metadata");
#endif #endif
goto fail2; goto fail2;
} }
@@ -230,7 +230,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("couldn't find ID\n"); grub_util_info ("couldn't find ID");
#endif #endif
goto fail3; goto fail3;
} }
@@ -258,7 +258,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown extent size\n"); grub_util_info ("unknown extent size");
#endif #endif
goto fail4; goto fail4;
} }
@@ -306,7 +306,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown pe_start\n"); grub_util_info ("unknown pe_start");
#endif #endif
goto pvs_fail; goto pvs_fail;
} }
@@ -315,7 +315,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("error parsing pe_start\n"); grub_util_info ("error parsing pe_start");
#endif #endif
goto pvs_fail; goto pvs_fail;
} }
@@ -402,7 +402,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("couldn't find ID\n"); grub_util_info ("couldn't find ID");
#endif #endif
goto lvs_fail; goto lvs_fail;
} }
@@ -422,7 +422,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown segment_count\n"); grub_util_info ("unknown segment_count");
#endif #endif
goto lvs_fail; goto lvs_fail;
} }
@@ -436,7 +436,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown segment\n"); grub_util_info ("unknown segment");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
@@ -445,7 +445,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown start_extent\n"); grub_util_info ("unknown start_extent");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
@@ -453,7 +453,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown extent_count\n"); grub_util_info ("unknown extent_count");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
@@ -475,7 +475,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown stripe_count\n"); grub_util_info ("unknown stripe_count");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
@@ -491,7 +491,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown stripes\n"); grub_util_info ("unknown stripes");
#endif #endif
goto lvs_segment_fail2; goto lvs_segment_fail2;
} }
@@ -533,7 +533,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown mirror_count\n"); grub_util_info ("unknown mirror_count");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
@@ -545,7 +545,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown mirrors\n"); grub_util_info ("unknown mirrors");
#endif #endif
goto lvs_segment_fail2; goto lvs_segment_fail2;
} }
@@ -577,13 +577,17 @@ grub_lvm_detect (grub_disk_t disk,
if (is_pvmove) if (is_pvmove)
seg->node_count = 1; seg->node_count = 1;
} }
else if (grub_memcmp (p, "raid", sizeof ("raid") - 1) else if (grub_memcmp (p, "raid", sizeof ("raid") - 1) == 0
== 0 && (p[sizeof ("raid") - 1] >= '4' && ((p[sizeof ("raid") - 1] >= '4'
&& p[sizeof ("raid") - 1] <= '6') && p[sizeof ("raid") - 1] <= '6')
|| p[sizeof ("raid") - 1] == '1')
&& p[sizeof ("raidX") - 1] == '"') && p[sizeof ("raidX") - 1] == '"')
{ {
switch (p[sizeof ("raid") - 1]) switch (p[sizeof ("raid") - 1])
{ {
case '1':
seg->type = GRUB_DISKFILTER_MIRROR;
break;
case '4': case '4':
seg->type = GRUB_DISKFILTER_RAID4; seg->type = GRUB_DISKFILTER_RAID4;
seg->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC; seg->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
@@ -603,21 +607,23 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown device_count\n"); grub_util_info ("unknown device_count");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
} }
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); if (seg->type != GRUB_DISKFILTER_MIRROR)
if (p == NULL)
{ {
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
if (p == NULL)
{
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown stripe_size\n"); grub_util_info ("unknown stripe_size");
#endif #endif
goto lvs_segment_fail; goto lvs_segment_fail;
}
} }
seg->nodes = grub_zalloc (sizeof (seg->nodes[0]) seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
* seg->node_count); * seg->node_count);
@@ -625,7 +631,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL) if (p == NULL)
{ {
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
grub_util_info ("unknown mirrors\n"); grub_util_info ("unknown raids");
#endif #endif
goto lvs_segment_fail2; goto lvs_segment_fail2;
} }
@@ -672,7 +678,7 @@ grub_lvm_detect (grub_disk_t disk,
p2 = grub_strchr (p, '"'); p2 = grub_strchr (p, '"');
if (p2) if (p2)
*p2 = 0; *p2 = 0;
grub_util_info ("unknown LVM type %s\n", p); grub_util_info ("unknown LVM type %s", p);
if (p2) if (p2)
*p2 ='"'; *p2 ='"';
#endif #endif
+3 -2
View File
@@ -615,9 +615,10 @@ grub_scsi_open (const char *name, grub_disk_t disk)
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize) if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
{ {
grub_error (GRUB_ERR_IO, "invalid sector size %d",
scsi->blocksize);
grub_free (scsi); grub_free (scsi);
return grub_error (GRUB_ERR_IO, "invalid sector size %d", return grub_errno;
scsi->blocksize);
} }
for (disk->log_sector_size = 0; for (disk->log_sector_size = 0;
(1U << disk->log_sector_size) < scsi->blocksize; (1U << disk->log_sector_size) < scsi->blocksize;
+5 -2
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 s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
: GRUB_EFI_RUNTIME_SERVICES_DATA); : GRUB_EFI_RUNTIME_SERVICES_DATA);
if (seg->handle < 0) if (seg->handle < 0)
return grub_errno; {
grub_free (seg);
return grub_errno;
}
seg->off = 0; 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")); 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. */ /* 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"), return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
filename); filename);
+1 -1
View File
@@ -196,7 +196,7 @@ grub_efiemu_load_file (const char *filename)
{ {
grub_file_close (file); grub_file_close (file);
grub_efiemu_unload (); grub_efiemu_unload ();
return grub_errno; return err;
} }
grub_dprintf ("efiemu", "mm initialized\n"); grub_dprintf ("efiemu", "mm initialized\n");
+22 -3
View File
@@ -99,7 +99,8 @@ grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
grub_size_t align_overhead; grub_size_t align_overhead;
struct grub_efiemu_memrequest *ret, *cur, *prev; struct grub_efiemu_memrequest *ret, *cur, *prev;
/* Check that the request is correct */ /* 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; return -2;
/* Add new size to requested size */ /* Add new size to requested size */
@@ -166,6 +167,13 @@ efiemu_alloc_requests (void)
GRUB_EFI_MEMORY_MAPPED_IO, GRUB_EFI_MEMORY_MAPPED_IO,
GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
GRUB_EFI_PAL_CODE 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 */ /* 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, return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_ACPI_MEMORY_NVS); 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: default:
grub_dprintf ("efiemu", grub_dprintf ("efiemu",
"Unknown memory type %d. Assuming unusable\n", type); "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:
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case GRUB_EFI_PAL_CODE: case GRUB_EFI_PAL_CODE:
case GRUB_EFI_MAX_MEMORY_TYPE: default:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_MEMORY_RESERVED, hook_data); GRUB_MEMORY_RESERVED, hook_data);
break; 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, hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_MEMORY_NVS, hook_data); GRUB_MEMORY_NVS, hook_data);
break; 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; return 0;
@@ -503,7 +521,8 @@ grub_efiemu_mmap_sort_and_uniq (void)
[GRUB_EFI_ACPI_MEMORY_NVS] = 3, [GRUB_EFI_ACPI_MEMORY_NVS] = 3,
[GRUB_EFI_MEMORY_MAPPED_IO] = 4, [GRUB_EFI_MEMORY_MAPPED_IO] = 4,
[GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 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; int i, j, k, done;
+10 -4
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); ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
/* Put pointer to the list of configuration tables in system table */ /* Put pointer to the list of configuration tables in system table */
grub_efiemu_write_value err = grub_efiemu_write_value
(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0, (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
conftable_handle, 0, 1, conftable_handle, 0, 1,
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table)); sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
if (err)
{
grub_efiemu_unload ();
return err;
}
SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables; SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
/* Fill the list of configuration tables */ /* Fill the list of configuration tables */
+4 -3
View File
@@ -34,12 +34,12 @@ canonicalize (char *name)
iptr++; iptr++;
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0)) if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
{ {
iptr += 2; iptr++;
continue; continue;
} }
if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0)) if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
{ {
iptr += 3; iptr += 2;
if (optr == name) if (optr == name)
continue; continue;
for (optr -= 2; optr >= name && *optr != '/'; optr--); for (optr -= 2; optr >= name && *optr != '/'; optr--);
@@ -249,9 +249,10 @@ grub_archelp_open (struct grub_archelp_data *data,
while (1) while (1)
{ {
grub_uint32_t mode; grub_uint32_t mode;
grub_int32_t mtime;
int restart; int restart;
if (arcops->find_file (data, &fn, NULL, &mode)) if (arcops->find_file (data, &fn, &mtime, &mode))
goto fail; goto fail;
if (mode == GRUB_ARCHELP_ATTR_END) if (mode == GRUB_ARCHELP_ATTR_END)
+104 -117
View File
@@ -29,6 +29,7 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/fshelp.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -561,10 +562,10 @@ iterate_in_b_tree (grub_disk_t disk,
} }
static int static int
bfs_strcmp (const char *a, const char *b, grub_size_t alen, grub_size_t blen) bfs_strcmp (const char *a, const char *b, grub_size_t alen)
{ {
char ac, bc; char ac, bc;
while (blen && alen) while (*b && alen)
{ {
if (*a != *b) if (*a != *b)
break; break;
@@ -572,11 +573,10 @@ bfs_strcmp (const char *a, const char *b, grub_size_t alen, grub_size_t blen)
a++; a++;
b++; b++;
alen--; alen--;
blen--;
} }
ac = alen ? *a : 0; ac = alen ? *a : 0;
bc = blen ? *b : 0; bc = *b;
#ifdef MODE_AFS #ifdef MODE_AFS
return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc; return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc;
@@ -589,7 +589,6 @@ static grub_err_t
find_in_b_tree (grub_disk_t disk, find_in_b_tree (grub_disk_t disk,
const struct grub_bfs_superblock *sb, const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino, const char *name, const struct grub_bfs_inode *ino, const char *name,
grub_size_t name_len,
grub_uint64_t * res) grub_uint64_t * res)
{ {
struct grub_bfs_btree_header head; struct grub_bfs_btree_header head;
@@ -637,7 +636,7 @@ find_in_b_tree (grub_disk_t disk,
end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]); end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]);
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end) if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node->total_key_len); end = grub_bfs_to_cpu_treehead (node->total_key_len);
cmp = bfs_strcmp (key_data + start, name, end - start, name_len); cmp = bfs_strcmp (key_data + start, name, end - start);
if (cmp == 0 && level == 0) if (cmp == 0 && level == 0)
{ {
*res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val); *res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val);
@@ -658,7 +657,7 @@ find_in_b_tree (grub_disk_t disk,
end = grub_bfs_to_cpu16 (keylen_idx[0]); end = grub_bfs_to_cpu16 (keylen_idx[0]);
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end) if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node->total_key_len); end = grub_bfs_to_cpu_treehead (node->total_key_len);
cmp = bfs_strcmp (key_data, name, end, name_len); cmp = bfs_strcmp (key_data, name, end);
if (cmp == 0 && level == 0) if (cmp == 0 && level == 0)
{ {
*res = grub_bfs_to_cpu64 (key_values[0].val); *res = grub_bfs_to_cpu64 (key_values[0].val);
@@ -707,127 +706,119 @@ find_in_b_tree (grub_disk_t disk,
} }
} }
struct grub_fshelp_node
{
grub_disk_t disk;
const struct grub_bfs_superblock *sb;
struct grub_bfs_inode ino;
};
static grub_err_t static grub_err_t
hop_level (grub_disk_t disk, lookup_file (grub_fshelp_node_t dir,
const struct grub_bfs_superblock *sb, const char *name,
struct grub_bfs_inode *ino, const char *name, grub_fshelp_node_t *foundnode,
const char *name_end) enum grub_fshelp_filetype *foundtype)
{ {
grub_err_t err; grub_err_t err;
struct grub_bfs_inode *new_ino;
grub_uint64_t res = 0; grub_uint64_t res = 0;
if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) != ATTR_DIR)) err = find_in_b_tree (dir->disk, dir->sb, &dir->ino, name, &res);
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
err = find_in_b_tree (disk, sb, ino, name, name_end - name, &res);
if (err) if (err)
return err; return err;
return grub_disk_read (disk, res *foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
<< (grub_bfs_to_cpu32 (sb->log2_bsize) if (!*foundnode)
- GRUB_DISK_SECTOR_BITS), 0, return grub_errno;
sizeof (*ino), (char *) ino);
(*foundnode)->disk = dir->disk;
(*foundnode)->sb = dir->sb;
new_ino = &(*foundnode)->ino;
if (grub_disk_read (dir->disk, res
<< (grub_bfs_to_cpu32 (dir->sb->log2_bsize)
- GRUB_DISK_SECTOR_BITS), 0,
sizeof (*new_ino), (char *) new_ino))
{
grub_free (*foundnode);
return grub_errno;
}
switch (grub_bfs_to_cpu32 (new_ino->mode) & ATTR_TYPE)
{
default:
case ATTR_REG:
*foundtype = GRUB_FSHELP_REG;
break;
case ATTR_DIR:
*foundtype = GRUB_FSHELP_DIR;
break;
case ATTR_LNK:
*foundtype = GRUB_FSHELP_SYMLINK;
break;
}
return GRUB_ERR_NONE;
}
static char *
read_symlink (grub_fshelp_node_t node)
{
char *alloc = NULL;
grub_err_t err;
#ifndef MODE_AFS
if (!(grub_bfs_to_cpu32 (node->ino.flags) & LONG_SYMLINK))
{
alloc = grub_malloc (sizeof (node->ino.inplace_link) + 1);
if (!alloc)
{
return NULL;
}
grub_memcpy (alloc, node->ino.inplace_link,
sizeof (node->ino.inplace_link));
alloc[sizeof (node->ino.inplace_link)] = 0;
}
else
#endif
{
grub_size_t symsize = grub_bfs_to_cpu64 (node->ino.size);
alloc = grub_malloc (symsize + 1);
if (!alloc)
return NULL;
err = read_bfs_file (node->disk, node->sb, &node->ino, 0, alloc, symsize, 0, 0);
if (err)
{
grub_free (alloc);
return NULL;
}
alloc[symsize] = 0;
}
return alloc;
} }
static grub_err_t static grub_err_t
find_file (const char *path, grub_disk_t disk, find_file (const char *path, grub_disk_t disk,
const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino) const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino,
enum grub_fshelp_filetype exptype)
{ {
const char *ptr, *next = path;
char *alloc = NULL;
char *wptr;
grub_err_t err; grub_err_t err;
struct grub_bfs_inode old_ino; struct grub_fshelp_node root = {
unsigned symlinks_max = 32; .disk = disk,
.sb = sb,
};
struct grub_fshelp_node *found;
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino,
sizeof (*ino)); sizeof (root.ino));
if (err) if (err)
return err; return err;
err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, read_symlink, exptype);
if (!err)
grub_memcpy (ino, &found->ino, sizeof (*ino));
while (1) if (&root != found)
{ grub_free (found);
ptr = next; return err;
while (*ptr == '/')
ptr++;
if (*ptr == 0)
{
grub_free (alloc);
return GRUB_ERR_NONE;
}
for (next = ptr; *next && *next != '/'; next++);
grub_memcpy (&old_ino, ino, sizeof (old_ino));
err = hop_level (disk, sb, ino, ptr, next);
if (err)
return err;
if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) == ATTR_LNK))
{
char *old_alloc = alloc;
if (--symlinks_max == 0)
{
grub_free (alloc);
return grub_error (GRUB_ERR_SYMLINK_LOOP,
N_("too deep nesting of symlinks"));
}
#ifndef MODE_AFS
if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK)
#endif
{
grub_size_t symsize = grub_bfs_to_cpu64 (ino->size);
alloc = grub_malloc (grub_strlen (next)
+ symsize + 1);
if (!alloc)
{
grub_free (alloc);
return grub_errno;
}
grub_free (old_alloc);
err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0, 0);
if (err)
{
grub_free (alloc);
return err;
}
alloc[symsize] = 0;
}
#ifndef MODE_AFS
else
{
alloc = grub_malloc (grub_strlen (next)
+ sizeof (ino->inplace_link) + 1);
if (!alloc)
{
grub_free (alloc);
return grub_errno;
}
grub_free (old_alloc);
grub_memcpy (alloc, ino->inplace_link,
sizeof (ino->inplace_link));
alloc[sizeof (ino->inplace_link)] = 0;
}
#endif
if (alloc[0] == '/')
{
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino,
sizeof (*ino));
if (err)
{
grub_free (alloc);
return err;
}
}
else
grub_memcpy (ino, &old_ino, sizeof (old_ino));
wptr = alloc + grub_strlen (alloc);
if (next)
wptr = grub_stpcpy (wptr, next);
*wptr = 0;
next = alloc;
continue;
}
}
} }
static grub_err_t static grub_err_t
@@ -909,11 +900,9 @@ grub_bfs_dir (grub_device_t device, const char *path,
{ {
struct grub_bfs_inode ino; struct grub_bfs_inode ino;
err = find_file (path, device->disk, &ctx.sb, &ino); err = find_file (path, device->disk, &ctx.sb, &ino, GRUB_FSHELP_DIR);
if (err) if (err)
return err; return err;
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_DIR))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter, iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter,
&ctx); &ctx);
} }
@@ -934,11 +923,9 @@ grub_bfs_open (struct grub_file *file, const char *name)
{ {
struct grub_bfs_inode ino; struct grub_bfs_inode ino;
struct grub_bfs_data *data; struct grub_bfs_data *data;
err = find_file (name, file->device->disk, &sb, &ino); err = find_file (name, file->device->disk, &sb, &ino, GRUB_FSHELP_REG);
if (err) if (err)
return err; return err;
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_REG))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
data = grub_zalloc (sizeof (struct grub_bfs_data)); data = grub_zalloc (sizeof (struct grub_bfs_data));
if (!data) if (!data)
@@ -1034,7 +1021,7 @@ read_bfs_attr (grub_disk_t disk,
if (err) if (err)
return -1; return -1;
err = find_in_b_tree (disk, sb, ino, name, grub_strlen (name), &res); err = find_in_b_tree (disk, sb, ino, name, &res);
if (err) if (err)
return -1; return -1;
grub_disk_read (disk, res grub_disk_read (disk, res
+9 -1
View File
@@ -344,8 +344,16 @@ init_cbfsdisk (void)
ptr = *(grub_uint32_t *) 0xfffffffc; ptr = *(grub_uint32_t *) 0xfffffffc;
head = (struct cbfs_header *) (grub_addr_t) ptr; head = (struct cbfs_header *) (grub_addr_t) ptr;
grub_dprintf ("cbfs", "head=%p\n", head);
if (!validate_head (head)) /* coreboot current supports only ROMs <= 16 MiB. Bigger ROMs will
have problems as RCBA is 18 MiB below end of 32-bit typically,
so either memory map would have to be rearranged or we'd need to support
reading ROMs through controller directly.
*/
if (ptr < 0xff000000
|| 0xffffffff - ptr < (grub_uint32_t) sizeof (*head) + 0xf
|| !validate_head (head))
return; return;
cbfsdisk_size = ALIGN_UP (grub_be_to_cpu32 (head->romsize), cbfsdisk_size = ALIGN_UP (grub_be_to_cpu32 (head->romsize),
+4 -3
View File
@@ -538,8 +538,9 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
shift = 2; shift = 2;
goto indirect; goto indirect;
} }
return grub_error (GRUB_ERR_BAD_FS, grub_error (GRUB_ERR_BAD_FS,
"ext2fs doesn't support quadruple indirect blocks"); "ext2fs doesn't support quadruple indirect blocks");
return -1;
indirect: indirect:
do { do {
@@ -554,7 +555,7 @@ indirect:
& ((1 << log_perblock) - 1)) & ((1 << log_perblock) - 1))
* sizeof (indir), * sizeof (indir),
sizeof (indir), &indir)) sizeof (indir), &indir))
return grub_errno; return -1;
} while (shift--); } while (shift--);
return grub_le_to_cpu32 (indir); return grub_le_to_cpu32 (indir);
+175 -171
View File
@@ -31,6 +31,7 @@
#else #else
#include <grub/exfat.h> #include <grub/exfat.h>
#endif #endif
#include <grub/fshelp.h>
#include <grub/i18n.h> #include <grub/i18n.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -173,8 +174,6 @@ struct grub_fat_data
#ifndef MODE_EXFAT #ifndef MODE_EXFAT
grub_uint32_t root_sector; grub_uint32_t root_sector;
grub_uint32_t num_root_sectors; grub_uint32_t num_root_sectors;
#else
int is_contiguous;
#endif #endif
int cluster_bits; int cluster_bits;
@@ -182,13 +181,22 @@ struct grub_fat_data
grub_uint32_t cluster_sector; grub_uint32_t cluster_sector;
grub_uint32_t num_clusters; grub_uint32_t num_clusters;
grub_uint32_t uuid;
};
struct grub_fshelp_node {
grub_disk_t disk;
struct grub_fat_data *data;
grub_uint8_t attr; grub_uint8_t attr;
grub_ssize_t file_size; grub_ssize_t file_size;
grub_uint32_t file_cluster; grub_uint32_t file_cluster;
grub_uint32_t cur_cluster_num; grub_uint32_t cur_cluster_num;
grub_uint32_t cur_cluster; grub_uint32_t cur_cluster;
grub_uint32_t uuid; #ifdef MODE_EXFAT
int is_contiguous;
#endif
}; };
static grub_dl_t my_mod; static grub_dl_t my_mod;
@@ -427,13 +435,6 @@ grub_fat_mount (grub_disk_t disk)
(void) magic; (void) magic;
#endif #endif
/* Start from the root directory. */
data->file_cluster = data->root_cluster;
data->cur_cluster_num = ~0U;
data->attr = GRUB_FAT_ATTR_DIRECTORY;
#ifdef MODE_EXFAT
data->is_contiguous = 0;
#endif
return data; return data;
fail: fail:
@@ -444,7 +445,7 @@ grub_fat_mount (grub_disk_t disk)
} }
static grub_ssize_t static grub_ssize_t
grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, grub_fat_read_data (grub_disk_t disk, grub_fshelp_node_t node,
grub_disk_read_hook_t read_hook, void *read_hook_data, grub_disk_read_hook_t read_hook, void *read_hook_data,
grub_off_t offset, grub_size_t len, char *buf) grub_off_t offset, grub_size_t len, char *buf)
{ {
@@ -457,13 +458,13 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
#ifndef MODE_EXFAT #ifndef MODE_EXFAT
/* This is a special case. FAT12 and FAT16 doesn't have the root directory /* This is a special case. FAT12 and FAT16 doesn't have the root directory
in clusters. */ in clusters. */
if (data->file_cluster == ~0U) if (node->file_cluster == ~0U)
{ {
size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; size = (node->data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
if (size > len) if (size > len)
size = len; size = len;
if (grub_disk_read (disk, data->root_sector, offset, size, buf)) if (grub_disk_read (disk, node->data->root_sector, offset, size, buf))
return -1; return -1;
return size; return size;
@@ -471,12 +472,12 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
#endif #endif
#ifdef MODE_EXFAT #ifdef MODE_EXFAT
if (data->is_contiguous) if (node->is_contiguous)
{ {
/* Read the data here. */ /* Read the data here. */
sector = (data->cluster_sector sector = (node->data->cluster_sector
+ ((data->file_cluster - 2) + ((node->file_cluster - 2)
<< data->cluster_bits)); << node->data->cluster_bits));
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data; disk->read_hook_data = read_hook_data;
@@ -491,53 +492,53 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
#endif #endif
/* Calculate the logical cluster number and offset. */ /* Calculate the logical cluster number and offset. */
logical_cluster_bits = (data->cluster_bits logical_cluster_bits = (node->data->cluster_bits
+ GRUB_DISK_SECTOR_BITS); + GRUB_DISK_SECTOR_BITS);
logical_cluster = offset >> logical_cluster_bits; logical_cluster = offset >> logical_cluster_bits;
offset &= (1ULL << logical_cluster_bits) - 1; offset &= (1ULL << logical_cluster_bits) - 1;
if (logical_cluster < data->cur_cluster_num) if (logical_cluster < node->cur_cluster_num)
{ {
data->cur_cluster_num = 0; node->cur_cluster_num = 0;
data->cur_cluster = data->file_cluster; node->cur_cluster = node->file_cluster;
} }
while (len) while (len)
{ {
while (logical_cluster > data->cur_cluster_num) while (logical_cluster > node->cur_cluster_num)
{ {
/* Find next cluster. */ /* Find next cluster. */
grub_uint32_t next_cluster; grub_uint32_t next_cluster;
grub_uint32_t fat_offset; grub_uint32_t fat_offset;
switch (data->fat_size) switch (node->data->fat_size)
{ {
case 32: case 32:
fat_offset = data->cur_cluster << 2; fat_offset = node->cur_cluster << 2;
break; break;
case 16: case 16:
fat_offset = data->cur_cluster << 1; fat_offset = node->cur_cluster << 1;
break; break;
default: default:
/* case 12: */ /* case 12: */
fat_offset = data->cur_cluster + (data->cur_cluster >> 1); fat_offset = node->cur_cluster + (node->cur_cluster >> 1);
break; break;
} }
/* Read the FAT. */ /* Read the FAT. */
if (grub_disk_read (disk, data->fat_sector, fat_offset, if (grub_disk_read (disk, node->data->fat_sector, fat_offset,
(data->fat_size + 7) >> 3, (node->data->fat_size + 7) >> 3,
(char *) &next_cluster)) (char *) &next_cluster))
return -1; return -1;
next_cluster = grub_le_to_cpu32 (next_cluster); next_cluster = grub_le_to_cpu32 (next_cluster);
switch (data->fat_size) switch (node->data->fat_size)
{ {
case 16: case 16:
next_cluster &= 0xFFFF; next_cluster &= 0xFFFF;
break; break;
case 12: case 12:
if (data->cur_cluster & 1) if (node->cur_cluster & 1)
next_cluster >>= 4; next_cluster >>= 4;
next_cluster &= 0x0FFF; next_cluster &= 0x0FFF;
@@ -545,27 +546,27 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
} }
grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n", grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
data->fat_size, next_cluster); node->data->fat_size, next_cluster);
/* Check the end. */ /* Check the end. */
if (next_cluster >= data->cluster_eof_mark) if (next_cluster >= node->data->cluster_eof_mark)
return ret; return ret;
if (next_cluster < 2 || next_cluster >= data->num_clusters) if (next_cluster < 2 || next_cluster >= node->data->num_clusters)
{ {
grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u", grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
next_cluster); next_cluster);
return -1; return -1;
} }
data->cur_cluster = next_cluster; node->cur_cluster = next_cluster;
data->cur_cluster_num++; node->cur_cluster_num++;
} }
/* Read the data here. */ /* Read the data here. */
sector = (data->cluster_sector sector = (node->data->cluster_sector
+ ((data->cur_cluster - 2) + ((node->cur_cluster - 2)
<< data->cluster_bits)); << node->data->cluster_bits));
size = (1 << logical_cluster_bits) - offset; size = (1 << logical_cluster_bits) - offset;
if (size > len) if (size > len)
size = len; size = len;
@@ -631,7 +632,7 @@ grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt)
#ifdef MODE_EXFAT #ifdef MODE_EXFAT
static grub_err_t static grub_err_t
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, grub_fat_iterate_dir_next (grub_fshelp_node_t node,
struct grub_fat_iterate_context *ctxt) struct grub_fat_iterate_context *ctxt)
{ {
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir)); grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
@@ -641,7 +642,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
ctxt->offset += sizeof (dir); ctxt->offset += sizeof (dir);
if (grub_fat_read_data (disk, data, 0, 0, ctxt->offset, sizeof (dir), if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir),
(char *) &dir) (char *) &dir)
!= sizeof (dir)) != sizeof (dir))
break; break;
@@ -663,7 +664,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
{ {
struct grub_fat_dir_entry sec; struct grub_fat_dir_entry sec;
ctxt->offset += sizeof (sec); ctxt->offset += sizeof (sec);
if (grub_fat_read_data (disk, data, 0, 0, if (grub_fat_read_data (node->disk, node, 0, 0,
ctxt->offset, sizeof (sec), (char *) &sec) ctxt->offset, sizeof (sec), (char *) &sec)
!= sizeof (sec)) != sizeof (sec))
break; break;
@@ -680,7 +681,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
ctxt->dir.file_size ctxt->dir.file_size
= grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size); = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
ctxt->dir.have_stream = 1; 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)); & grub_cpu_to_le16_compile_time (FLAG_CONTIGUOUS));
break; break;
case 0xc1: case 0xc1:
@@ -727,7 +728,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
#else #else
static grub_err_t static grub_err_t
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, grub_fat_iterate_dir_next (grub_fshelp_node_t node,
struct grub_fat_iterate_context *ctxt) struct grub_fat_iterate_context *ctxt)
{ {
char *filep = 0; char *filep = 0;
@@ -742,7 +743,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
ctxt->offset += sizeof (ctxt->dir); ctxt->offset += sizeof (ctxt->dir);
/* Read a directory entry. */ /* Read a directory entry. */
if (grub_fat_read_data (disk, data, 0, 0, if (grub_fat_read_data (node->disk, node, 0, 0,
ctxt->offset, sizeof (ctxt->dir), ctxt->offset, sizeof (ctxt->dir),
(char *) &ctxt->dir) (char *) &ctxt->dir)
!= sizeof (ctxt->dir) || ctxt->dir.name[0] == 0) != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
@@ -829,7 +830,9 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
i--; i--;
} }
*filep++ = '.'; /* XXX should we check that dir position is 0 or 1? */
if (i > 2 || filep[0] != '.' || (i == 2 && filep[1] != '.'))
*filep++ = '.';
for (i = 8; i < 11 && ctxt->dir.name[i]; i++) for (i = 8; i < 11 && ctxt->dir.name[i]; i++)
*filep++ = grub_tolower (ctxt->dir.name[i]); *filep++ = grub_tolower (ctxt->dir.name[i]);
@@ -851,62 +854,20 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
#endif #endif
/* Find the underlying directory or file in PATH and return the static grub_err_t lookup_file (grub_fshelp_node_t node,
next path. If there is no next path or an error occurs, return NULL. const char *name,
If HOOK is specified, call it with each file name. */ grub_fshelp_node_t *foundnode,
static char * enum grub_fshelp_filetype *foundtype)
grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
const char *path, const char *origpath,
grub_fs_dir_hook_t hook, void *hook_data)
{ {
char *dirname, *dirp;
int call_hook;
int found = 0;
struct grub_fat_iterate_context ctxt;
grub_err_t err; grub_err_t err;
struct grub_fat_iterate_context ctxt;
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
return 0;
}
/* Extract a directory name. */
while (*path == '/')
path++;
dirp = grub_strchr (path, '/');
if (dirp)
{
unsigned len = dirp - path;
dirname = grub_malloc (len + 1);
if (! dirname)
goto fail;
grub_memcpy (dirname, path, len);
dirname[len] = '\0';
}
else
/* This is actually a file. */
dirname = grub_strdup (path);
call_hook = (! dirp && hook);
err = grub_fat_iterate_init (&ctxt); err = grub_fat_iterate_init (&ctxt);
if (err) if (err)
{ return err;
grub_free (dirname);
return 0;
}
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt))) while (!(err = grub_fat_iterate_dir_next (node, &ctxt)))
{ {
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
info.case_insensitive = 1;
#ifdef MODE_EXFAT #ifdef MODE_EXFAT
if (!ctxt.dir.have_stream) if (!ctxt.dir.have_stream)
@@ -915,33 +876,33 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID) if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
continue; continue;
#endif #endif
if (*dirname == '\0' && call_hook)
{
if (hook (ctxt.filename, &info, hook_data))
break;
else
continue;
}
if (grub_strcasecmp (dirname, ctxt.filename) == 0) if (grub_strcasecmp (name, ctxt.filename) == 0)
{ {
found = 1; *foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
data->attr = ctxt.dir.attr; if (!*foundnode)
return grub_errno;
(*foundnode)->attr = ctxt.dir.attr;
#ifdef MODE_EXFAT #ifdef MODE_EXFAT
data->file_size = ctxt.dir.file_size; (*foundnode)->file_size = ctxt.dir.file_size;
data->file_cluster = ctxt.dir.first_cluster; (*foundnode)->file_cluster = ctxt.dir.first_cluster;
data->is_contiguous = ctxt.dir.is_contiguous; (*foundnode)->is_contiguous = ctxt.dir.is_contiguous;
#else #else
data->file_size = grub_le_to_cpu32 (ctxt.dir.file_size); (*foundnode)->file_size = grub_le_to_cpu32 (ctxt.dir.file_size);
data->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16) (*foundnode)->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16)
| grub_le_to_cpu16 (ctxt.dir.first_cluster_low)); | grub_le_to_cpu16 (ctxt.dir.first_cluster_low));
/* If directory points to root, starting cluster is 0 */
if (!(*foundnode)->file_cluster)
(*foundnode)->file_cluster = node->data->root_cluster;
#endif #endif
data->cur_cluster_num = ~0U; (*foundnode)->cur_cluster_num = ~0U;
(*foundnode)->data = node->data;
(*foundnode)->disk = node->disk;
if (call_hook) *foundtype = ((*foundnode)->attr & GRUB_FAT_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
hook (ctxt.filename, &info, hook_data);
break; grub_fat_iterate_fini (&ctxt);
return GRUB_ERR_NONE;
} }
} }
@@ -949,13 +910,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
if (err == GRUB_ERR_EOF) if (err == GRUB_ERR_EOF)
err = 0; err = 0;
if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook) return err;
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
fail:
grub_free (dirname);
return found ? dirp : 0;
} }
static grub_err_t static grub_err_t
@@ -964,9 +920,9 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
{ {
struct grub_fat_data *data = 0; struct grub_fat_data *data = 0;
grub_disk_t disk = device->disk; grub_disk_t disk = device->disk;
grub_size_t len; grub_fshelp_node_t found = NULL;
char *dirname = 0; grub_err_t err;
char *p; struct grub_fat_iterate_context ctxt;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@@ -974,27 +930,53 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
if (! data) if (! data)
goto fail; goto fail;
/* Make sure that DIRNAME terminates with '/'. */ struct grub_fshelp_node root = {
len = grub_strlen (path); .data = data,
dirname = grub_malloc (len + 1 + 1); .disk = disk,
if (! dirname) .attr = GRUB_FAT_ATTR_DIRECTORY,
goto fail; .file_size = 0,
grub_memcpy (dirname, path, len); .file_cluster = data->root_cluster,
p = dirname + len; .cur_cluster_num = ~0U,
if (path[len - 1] != '/') .cur_cluster = 0,
*p++ = '/'; #ifdef MODE_EXFAT
*p = '\0'; .is_contiguous = 0,
p = dirname; #endif
};
do err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, NULL, GRUB_FSHELP_DIR);
if (err)
goto fail;
err = grub_fat_iterate_init (&ctxt);
if (err)
goto fail;
while (!(err = grub_fat_iterate_dir_next (found, &ctxt)))
{ {
p = grub_fat_find_dir (disk, data, p, path, hook, hook_data); struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
info.case_insensitive = 1;
#ifdef MODE_EXFAT
if (!ctxt.dir.have_stream)
continue;
#else
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
continue;
#endif
if (hook (ctxt.filename, &info, hook_data))
break;
} }
while (p && grub_errno == GRUB_ERR_NONE); grub_fat_iterate_fini (&ctxt);
if (err == GRUB_ERR_EOF)
err = 0;
fail: fail:
if (found != &root)
grub_free (found);
grub_free (dirname);
grub_free (data); grub_free (data);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
@@ -1006,35 +988,43 @@ static grub_err_t
grub_fat_open (grub_file_t file, const char *name) grub_fat_open (grub_file_t file, const char *name)
{ {
struct grub_fat_data *data = 0; struct grub_fat_data *data = 0;
char *p = (char *) name; grub_fshelp_node_t found = NULL;
grub_err_t err;
grub_disk_t disk = file->device->disk;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
data = grub_fat_mount (file->device->disk); data = grub_fat_mount (disk);
if (! data) if (! data)
goto fail; goto fail;
do struct grub_fshelp_node root = {
{ .data = data,
p = grub_fat_find_dir (file->device->disk, data, p, name, 0, 0); .disk = disk,
if (grub_errno != GRUB_ERR_NONE) .attr = GRUB_FAT_ATTR_DIRECTORY,
goto fail; .file_size = 0,
} .file_cluster = data->root_cluster,
while (p); .cur_cluster_num = ~0U,
.cur_cluster = 0,
#ifdef MODE_EXFAT
.is_contiguous = 0,
#endif
};
if (data->attr & GRUB_FAT_ATTR_DIRECTORY) err = grub_fshelp_find_file_lookup (name, &root, &found, lookup_file, NULL, GRUB_FSHELP_REG);
{ if (err)
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); goto fail;
goto fail;
}
file->data = data; file->data = found;
file->size = data->file_size; file->size = found->file_size;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
fail: fail:
if (found != &root)
grub_free (found);
grub_free (data); grub_free (data);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
@@ -1053,7 +1043,10 @@ grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
static grub_err_t static grub_err_t
grub_fat_close (grub_file_t file) grub_fat_close (grub_file_t file)
{ {
grub_free (file->data); grub_fshelp_node_t node = file->data;
grub_free (node->data);
grub_free (node);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
@@ -1066,20 +1059,29 @@ grub_fat_label (grub_device_t device, char **label)
{ {
struct grub_fat_dir_entry dir; struct grub_fat_dir_entry dir;
grub_ssize_t offset = -sizeof(dir); grub_ssize_t offset = -sizeof(dir);
struct grub_fat_data *data;
grub_disk_t disk = device->disk; grub_disk_t disk = device->disk;
struct grub_fshelp_node root = {
.disk = disk,
.attr = GRUB_FAT_ATTR_DIRECTORY,
.file_size = 0,
.cur_cluster_num = ~0U,
.cur_cluster = 0,
.is_contiguous = 0,
};
data = grub_fat_mount (disk); root.data = grub_fat_mount (disk);
if (! data) if (! root.data)
return grub_errno; return grub_errno;
root.file_cluster = root.data->root_cluster;
*label = NULL; *label = NULL;
while (1) while (1)
{ {
offset += sizeof (dir); offset += sizeof (dir);
if (grub_fat_read_data (disk, data, 0, 0, if (grub_fat_read_data (disk, &root, 0, 0,
offset, sizeof (dir), (char *) &dir) offset, sizeof (dir), (char *) &dir)
!= sizeof (dir)) != sizeof (dir))
break; break;
@@ -1099,7 +1101,7 @@ grub_fat_label (grub_device_t device, char **label)
* GRUB_MAX_UTF8_PER_UTF16 + 1); * GRUB_MAX_UTF8_PER_UTF16 + 1);
if (!*label) if (!*label)
{ {
grub_free (data); grub_free (root.data);
return grub_errno; return grub_errno;
} }
chc = dir.type_specific.volume_label.character_count; chc = dir.type_specific.volume_label.character_count;
@@ -1111,7 +1113,7 @@ grub_fat_label (grub_device_t device, char **label)
} }
} }
grub_free (data); grub_free (root.data);
return grub_errno; return grub_errno;
} }
@@ -1120,30 +1122,32 @@ grub_fat_label (grub_device_t device, char **label)
static grub_err_t static grub_err_t
grub_fat_label (grub_device_t device, char **label) grub_fat_label (grub_device_t device, char **label)
{ {
struct grub_fat_data *data;
grub_disk_t disk = device->disk; grub_disk_t disk = device->disk;
grub_err_t err; grub_err_t err;
struct grub_fat_iterate_context ctxt; struct grub_fat_iterate_context ctxt;
struct grub_fshelp_node root = {
.disk = disk,
.attr = GRUB_FAT_ATTR_DIRECTORY,
.file_size = 0,
.cur_cluster_num = ~0U,
.cur_cluster = 0,
};
*label = 0; *label = 0;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
data = grub_fat_mount (disk); root.data = grub_fat_mount (disk);
if (! data) if (! root.data)
goto fail; goto fail;
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) root.file_cluster = root.data->root_cluster;
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
goto fail;
}
err = grub_fat_iterate_init (&ctxt); err = grub_fat_iterate_init (&ctxt);
if (err) if (err)
goto fail; goto fail;
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt))) while (!(err = grub_fat_iterate_dir_next (&root, &ctxt)))
if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID) if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID)
{ {
*label = grub_strdup (ctxt.filename); *label = grub_strdup (ctxt.filename);
@@ -1156,7 +1160,7 @@ grub_fat_label (grub_device_t device, char **label)
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
grub_free (data); grub_free (root.data);
return grub_errno; return grub_errno;
} }
+217 -107
View File
@@ -30,169 +30,287 @@ GRUB_MOD_LICENSE ("GPLv3+");
typedef int (*iterate_dir_func) (grub_fshelp_node_t dir, typedef int (*iterate_dir_func) (grub_fshelp_node_t dir,
grub_fshelp_iterate_dir_hook_t hook, grub_fshelp_iterate_dir_hook_t hook,
void *data); void *data);
typedef grub_err_t (*lookup_file_func) (grub_fshelp_node_t dir,
const char *name,
grub_fshelp_node_t *foundnode,
enum grub_fshelp_filetype *foundtype);
typedef char *(*read_symlink_func) (grub_fshelp_node_t node); typedef char *(*read_symlink_func) (grub_fshelp_node_t node);
struct stack_element {
struct stack_element *parent;
grub_fshelp_node_t node;
enum grub_fshelp_filetype type;
};
/* Context for grub_fshelp_find_file. */ /* Context for grub_fshelp_find_file. */
struct grub_fshelp_find_file_ctx struct grub_fshelp_find_file_ctx
{ {
/* Inputs. */
const char *path; const char *path;
grub_fshelp_node_t rootnode, currroot, currnode, oldnode; grub_fshelp_node_t rootnode;
enum grub_fshelp_filetype foundtype;
/* Global options. */
int symlinknest; int symlinknest;
const char *name;
const char *next; /* Current file being traversed and its parents. */
enum grub_fshelp_filetype type; struct stack_element *currnode;
}; };
/* Helper for find_file_iter. */ /* Helper for find_file_iter. */
static void static void
free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx) free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx)
{ {
if (node != ctx->rootnode && node != ctx->currroot) if (node != ctx->rootnode)
grub_free (node); grub_free (node);
} }
static void
pop_element (struct grub_fshelp_find_file_ctx *ctx)
{
struct stack_element *el;
el = ctx->currnode;
ctx->currnode = el->parent;
free_node (el->node, ctx);
grub_free (el);
}
static void
free_stack (struct grub_fshelp_find_file_ctx *ctx)
{
while (ctx->currnode)
pop_element (ctx);
}
static void
go_up_a_level (struct grub_fshelp_find_file_ctx *ctx)
{
if (!ctx->currnode->parent)
return;
pop_element (ctx);
}
static grub_err_t
push_node (struct grub_fshelp_find_file_ctx *ctx, grub_fshelp_node_t node, enum grub_fshelp_filetype filetype)
{
struct stack_element *nst;
nst = grub_malloc (sizeof (*nst));
if (!nst)
return grub_errno;
nst->node = node;
nst->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
nst->parent = ctx->currnode;
ctx->currnode = nst;
return GRUB_ERR_NONE;
}
static grub_err_t
go_to_root (struct grub_fshelp_find_file_ctx *ctx)
{
free_stack (ctx);
return push_node (ctx, ctx->rootnode, GRUB_FSHELP_DIR);
}
struct grub_fshelp_find_file_iter_ctx
{
const char *name;
grub_fshelp_node_t *foundnode;
enum grub_fshelp_filetype *foundtype;
};
/* Helper for grub_fshelp_find_file. */ /* Helper for grub_fshelp_find_file. */
static int static int
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node, void *data) grub_fshelp_node_t node, void *data)
{ {
struct grub_fshelp_find_file_ctx *ctx = data; struct grub_fshelp_find_file_iter_ctx *ctx = data;
if (filetype == GRUB_FSHELP_UNKNOWN || if (filetype == GRUB_FSHELP_UNKNOWN ||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE) ((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
? grub_strncasecmp (ctx->name, filename, ctx->next - ctx->name) ? grub_strcasecmp (ctx->name, filename)
: grub_strncmp (ctx->name, filename, ctx->next - ctx->name)) : grub_strcmp (ctx->name, filename)))
|| filename[ctx->next - ctx->name])
{ {
grub_free (node); grub_free (node);
return 0; return 0;
} }
/* The node is found, stop iterating over the nodes. */ /* The node is found, stop iterating over the nodes. */
ctx->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; *ctx->foundnode = node;
ctx->oldnode = ctx->currnode; *ctx->foundtype = filetype;
ctx->currnode = node;
return 1; return 1;
} }
static grub_err_t static grub_err_t
find_file (const char *currpath, grub_fshelp_node_t currroot, directory_find_file (grub_fshelp_node_t node, const char *name, grub_fshelp_node_t *foundnode,
grub_fshelp_node_t *currfound, enum grub_fshelp_filetype *foundtype, iterate_dir_func iterate_dir)
iterate_dir_func iterate_dir, read_symlink_func read_symlink, {
int found;
struct grub_fshelp_find_file_iter_ctx ctx = {
.foundnode = foundnode,
.foundtype = foundtype,
.name = name
};
found = iterate_dir (node, find_file_iter, &ctx);
if (! found)
{
if (grub_errno)
return grub_errno;
}
return GRUB_ERR_NONE;
}
static grub_err_t
find_file (char *currpath,
iterate_dir_func iterate_dir, lookup_file_func lookup_file,
read_symlink_func read_symlink,
struct grub_fshelp_find_file_ctx *ctx) struct grub_fshelp_find_file_ctx *ctx)
{ {
ctx->currroot = currroot; char *name, *next;
ctx->name = currpath; grub_err_t err;
ctx->type = GRUB_FSHELP_DIR; for (name = currpath; ; name = next)
ctx->currnode = currroot;
ctx->oldnode = currroot;
for (;;)
{ {
int found; char c;
grub_fshelp_node_t foundnode = NULL;
enum grub_fshelp_filetype foundtype = 0;
/* Remove all leading slashes. */ /* Remove all leading slashes. */
while (*ctx->name == '/') while (*name == '/')
ctx->name++; name++;
/* Found the node! */ /* Found the node! */
if (! *ctx->name) if (! *name)
{ return 0;
*currfound = ctx->currnode;
ctx->foundtype = ctx->type;
return 0;
}
/* Extract the actual part from the pathname. */ /* Extract the actual part from the pathname. */
for (ctx->next = ctx->name; *ctx->next && *ctx->next != '/'; ctx->next++); for (next = name; *next && *next != '/'; next++);
/* At this point it is expected that the current node is a /* At this point it is expected that the current node is a
directory, check if this is true. */ directory, check if this is true. */
if (ctx->type != GRUB_FSHELP_DIR) if (ctx->currnode->type != GRUB_FSHELP_DIR)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
/* Don't rely on fs providing actual . in the listing. */
if (next - name == 1 && name[0] == '.')
continue;
/* Don't rely on fs providing actual .. in the listing. */
if (next - name == 2 && name[0] == '.' && name[1] == '.')
{ {
free_node (ctx->currnode, ctx); go_up_a_level (ctx);
ctx->currnode = 0; continue;
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
} }
/* Iterate over the directory. */ /* Iterate over the directory. */
found = iterate_dir (ctx->currnode, find_file_iter, ctx); c = *next;
if (! found) *next = '\0';
{ if (lookup_file)
free_node (ctx->currnode, ctx); err = lookup_file (ctx->currnode->node, name, &foundnode, &foundtype);
ctx->currnode = 0; else
if (grub_errno) err = directory_find_file (ctx->currnode->node, name, &foundnode, &foundtype, iterate_dir);
return grub_errno; *next = c;
break; if (err)
} return err;
if (!foundnode)
break;
push_node (ctx, foundnode, foundtype);
/* Read in the symlink and follow it. */ /* Read in the symlink and follow it. */
if (ctx->type == GRUB_FSHELP_SYMLINK) if (ctx->currnode->type == GRUB_FSHELP_SYMLINK)
{ {
char *symlink; char *symlink;
const char *next;
/* Test if the symlink does not loop. */ /* Test if the symlink does not loop. */
if (++ctx->symlinknest == 8) if (++ctx->symlinknest == 8)
{ return grub_error (GRUB_ERR_SYMLINK_LOOP,
free_node (ctx->currnode, ctx); N_("too deep nesting of symlinks"));
free_node (ctx->oldnode, ctx);
ctx->currnode = 0;
ctx->oldnode = 0;
return grub_error (GRUB_ERR_SYMLINK_LOOP,
N_("too deep nesting of symlinks"));
}
symlink = read_symlink (ctx->currnode); symlink = read_symlink (ctx->currnode->node);
free_node (ctx->currnode, ctx);
ctx->currnode = 0;
if (!symlink) if (!symlink)
{ return grub_errno;
free_node (ctx->oldnode, ctx);
ctx->oldnode = 0;
return grub_errno;
}
/* The symlink is an absolute path, go back to the root inode. */ /* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/') if (symlink[0] == '/')
{ {
free_node (ctx->oldnode, ctx); err = go_to_root (ctx);
ctx->oldnode = ctx->rootnode; if (err)
return err;
}
else
{
/* Get from symlink to containing directory. */
go_up_a_level (ctx);
} }
/* Lookup the node the symlink points to. */ /* Lookup the node the symlink points to. */
next = ctx->next; find_file (symlink, iterate_dir, lookup_file, read_symlink, ctx);
find_file (symlink, ctx->oldnode, &ctx->currnode,
iterate_dir, read_symlink, ctx);
ctx->next = next;
ctx->type = ctx->foundtype;
grub_free (symlink); grub_free (symlink);
if (grub_errno) if (grub_errno)
{ return grub_errno;
free_node (ctx->oldnode, ctx);
ctx->oldnode = 0;
return grub_errno;
}
} }
if (ctx->oldnode != ctx->currnode)
{
free_node (ctx->oldnode, ctx);
ctx->oldnode = 0;
}
ctx->name = ctx->next;
} }
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
ctx->path); ctx->path);
} }
static grub_err_t
grub_fshelp_find_file_real (const char *path, grub_fshelp_node_t rootnode,
grub_fshelp_node_t *foundnode,
iterate_dir_func iterate_dir,
lookup_file_func lookup_file,
read_symlink_func read_symlink,
enum grub_fshelp_filetype expecttype)
{
struct grub_fshelp_find_file_ctx ctx = {
.path = path,
.rootnode = rootnode,
.symlinknest = 0,
.currnode = 0
};
grub_err_t err;
enum grub_fshelp_filetype foundtype;
char *duppath;
if (!path || path[0] != '/')
{
return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
}
err = go_to_root (&ctx);
if (err)
return err;
duppath = grub_strdup (path);
if (!duppath)
return grub_errno;
err = find_file (duppath, iterate_dir, lookup_file, read_symlink, &ctx);
grub_free (duppath);
if (err)
{
free_stack (&ctx);
return err;
}
*foundnode = ctx.currnode->node;
foundtype = ctx.currnode->type;
/* Avoid the node being freed. */
ctx.currnode->node = 0;
free_stack (&ctx);
/* Check if the node that was found was of the expected type. */
if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
return 0;
}
/* Lookup the node PATH. The node ROOTNODE describes the root of the /* Lookup the node PATH. The node ROOTNODE describes the root of the
directory tree. The node found is returned in FOUNDNODE, which is directory tree. The node found is returned in FOUNDNODE, which is
either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
@@ -207,31 +325,23 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
read_symlink_func read_symlink, read_symlink_func read_symlink,
enum grub_fshelp_filetype expecttype) enum grub_fshelp_filetype expecttype)
{ {
struct grub_fshelp_find_file_ctx ctx = { return grub_fshelp_find_file_real (path, rootnode, foundnode,
.path = path, iterate_dir, NULL,
.rootnode = rootnode, read_symlink, expecttype);
.foundtype = GRUB_FSHELP_DIR,
.symlinknest = 0
};
grub_err_t err;
if (!path || path[0] != '/') }
{
grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
return grub_errno;
}
err = find_file (path, rootnode, foundnode, iterate_dir, read_symlink, &ctx); grub_err_t
if (err) grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode,
return err; grub_fshelp_node_t *foundnode,
lookup_file_func lookup_file,
read_symlink_func read_symlink,
enum grub_fshelp_filetype expecttype)
{
return grub_fshelp_find_file_real (path, rootnode, foundnode,
NULL, lookup_file,
read_symlink, expecttype);
/* Check if the node that was found was of the expected type. */
if (expecttype == GRUB_FSHELP_REG && ctx.foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
else if (expecttype == GRUB_FSHELP_DIR && ctx.foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
return 0;
} }
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
+77 -97
View File
@@ -29,6 +29,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/hfs.h> #include <grub/hfs.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/fshelp.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -1125,90 +1126,81 @@ utf8_to_macroman (grub_uint8_t *to, const char *from)
return optr - to; return optr - to;
} }
union grub_hfs_anyrec {
struct grub_hfs_filerec frec;
struct grub_hfs_dirrec dir;
};
struct grub_fshelp_node
{
struct grub_hfs_data *data;
union grub_hfs_anyrec fdrec;
grub_uint32_t inode;
};
static grub_err_t
lookup_file (grub_fshelp_node_t dir,
const char *name,
grub_fshelp_node_t *foundnode,
enum grub_fshelp_filetype *foundtype)
{
struct grub_hfs_catalog_key key;
grub_ssize_t slen;
union grub_hfs_anyrec fdrec;
key.parent_dir = grub_cpu_to_be32 (dir->inode);
slen = utf8_to_macroman (key.str, name);
if (slen < 0)
/* Not found */
return GRUB_ERR_NONE;
key.strlen = slen;
/* Lookup this node. */
if (! grub_hfs_find_node (dir->data, (char *) &key, dir->data->cat_root,
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
/* Not found */
return GRUB_ERR_NONE;
*foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
if (!*foundnode)
return grub_errno;
(*foundnode)->inode = grub_be_to_cpu32 (fdrec.dir.dirid);
(*foundnode)->fdrec = fdrec;
(*foundnode)->data = dir->data;
*foundtype = (fdrec.frec.type == GRUB_HFS_FILETYPE_DIR) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
return GRUB_ERR_NONE;
}
/* Find a file or directory with the pathname PATH in the filesystem /* Find a file or directory with the pathname PATH in the filesystem
DATA. Return the file record in RETDATA when it is non-zero. DATA. Return the file record in RETDATA when it is non-zero.
Return the directory number in RETINODE when it is non-zero. */ Return the directory number in RETINODE when it is non-zero. */
static grub_err_t static grub_err_t
grub_hfs_find_dir (struct grub_hfs_data *data, const char *path, grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
struct grub_hfs_filerec *retdata, int *retinode) grub_fshelp_node_t *found,
enum grub_fshelp_filetype exptype)
{ {
int inode = data->rootdir; struct grub_fshelp_node root = {
char *next; .data = data,
char *origpath; .inode = data->rootdir,
union { .fdrec = {
struct grub_hfs_filerec frec; .frec = {
struct grub_hfs_dirrec dir; .type = GRUB_HFS_FILETYPE_DIR
} fdrec; }
fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
if (path[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
return 0;
} }
};
grub_err_t err;
origpath = grub_strdup (path); err = grub_fshelp_find_file_lookup (path, &root, found, lookup_file, NULL, exptype);
if (!origpath)
return grub_errno;
path = origpath; if (&root == *found)
while (*path == '/')
path++;
while (path && grub_strlen (path))
{ {
grub_ssize_t slen; *found = grub_malloc (sizeof (root));
if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR) if (!*found)
{ return grub_errno;
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); grub_memcpy (*found, &root, sizeof (root));
goto fail;
}
/* Isolate a part of the path. */
next = grub_strchr (path, '/');
if (next)
{
while (*next == '/')
*(next++) = '\0';
}
struct grub_hfs_catalog_key key;
key.parent_dir = grub_cpu_to_be32 (inode);
slen = utf8_to_macroman (key.str, path);
if (slen < 0)
{
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
goto fail;
}
key.strlen = slen;
/* Lookup this node. */
if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
{
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
goto fail;
}
if (grub_errno)
goto fail;
inode = grub_be_to_cpu32 (fdrec.dir.dirid);
path = next;
} }
return err;
if (retdata)
grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
if (retinode)
*retinode = inode;
fail:
grub_free (origpath);
return grub_errno;
} }
struct grub_hfs_dir_hook_ctx struct grub_hfs_dir_hook_ctx
@@ -1266,15 +1258,13 @@ static grub_err_t
grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
void *hook_data) void *hook_data)
{ {
int inode;
struct grub_hfs_data *data; struct grub_hfs_data *data;
struct grub_hfs_filerec frec;
struct grub_hfs_dir_hook_ctx ctx = struct grub_hfs_dir_hook_ctx ctx =
{ {
.hook = hook, .hook = hook,
.hook_data = hook_data .hook_data = hook_data
}; };
grub_fshelp_node_t found = NULL;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@@ -1283,18 +1273,13 @@ grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
goto fail; goto fail;
/* First the directory ID for the directory. */ /* First the directory ID for the directory. */
if (grub_hfs_find_dir (data, path, &frec, &inode)) if (grub_hfs_find_dir (data, path, &found, GRUB_FSHELP_DIR))
goto fail; goto fail;
if (frec.type != GRUB_HFS_FILETYPE_DIR) grub_hfs_iterate_dir (data, data->cat_root, found->inode, grub_hfs_dir_hook, &ctx);
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
goto fail;
}
grub_hfs_iterate_dir (data, data->cat_root, inode, grub_hfs_dir_hook, &ctx);
fail: fail:
grub_free (found);
grub_free (data); grub_free (data);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
@@ -1308,7 +1293,7 @@ static grub_err_t
grub_hfs_open (struct grub_file *file, const char *name) grub_hfs_open (struct grub_file *file, const char *name)
{ {
struct grub_hfs_data *data; struct grub_hfs_data *data;
struct grub_hfs_filerec frec; grub_fshelp_node_t found = NULL;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@@ -1320,29 +1305,24 @@ grub_hfs_open (struct grub_file *file, const char *name)
return grub_errno; return grub_errno;
} }
if (grub_hfs_find_dir (data, name, &frec, 0)) if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG))
{ {
grub_free (data); grub_free (data);
grub_free (found);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
return grub_errno; return grub_errno;
} }
if (frec.type != GRUB_HFS_FILETYPE_FILE) grub_memcpy (data->extents, found->fdrec.frec.extents, sizeof (grub_hfs_datarecord_t));
{ file->size = grub_be_to_cpu32 (found->fdrec.frec.size);
grub_free (data); data->size = grub_be_to_cpu32 (found->fdrec.frec.size);
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); data->fileid = grub_be_to_cpu32 (found->fdrec.frec.fileid);
grub_dl_unref (my_mod);
return grub_errno;
}
grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
file->size = grub_be_to_cpu32 (frec.size);
data->size = grub_be_to_cpu32 (frec.size);
data->fileid = grub_be_to_cpu32 (frec.fileid);
file->offset = 0; file->offset = 0;
file->data = data; file->data = data;
grub_free (found);
return 0; return 0;
} }
+10 -4
View File
@@ -336,6 +336,9 @@ grub_hfsplus_mount (grub_disk_t disk)
data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) && data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
(header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE)); (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
if (data->catalog_tree.nodesize < 2)
goto fail;
if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode), sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0) sizeof (header), (char *) &header) <= 0)
@@ -350,6 +353,9 @@ grub_hfsplus_mount (grub_disk_t disk)
data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize); data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
if (data->extoverflow_tree.nodesize < 2)
goto fail;
if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0, if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode), sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0) sizeof (header), (char *) &header) <= 0)
@@ -786,8 +792,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
}; };
struct grub_hfsplus_key_internal intern; struct grub_hfsplus_key_internal intern;
struct grub_hfsplus_btnode *node; struct grub_hfsplus_btnode *node = NULL;
grub_disk_addr_t ptr; grub_disk_addr_t ptr = 0;
{ {
struct grub_fshelp_node *fsnode; struct grub_fshelp_node *fsnode;
@@ -970,8 +976,8 @@ grub_hfsplus_label (grub_device_t device, char **label)
struct grub_hfsplus_catkey *catkey; struct grub_hfsplus_catkey *catkey;
int i, label_len; int i, label_len;
struct grub_hfsplus_key_internal intern; struct grub_hfsplus_key_internal intern;
struct grub_hfsplus_btnode *node; struct grub_hfsplus_btnode *node = NULL;
grub_disk_addr_t ptr; grub_disk_addr_t ptr = 0;
*label = 0; *label = 0;
+1 -1
View File
@@ -104,7 +104,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest)
if (tag & 1) if (tag & 1)
{ {
grub_uint32_t i, len, delta, code, lmask, dshift; grub_uint32_t i, len, delta, code, lmask, dshift;
grub_uint16_t word; grub_uint16_t word = 0;
if (decomp_get16 (cc, &word)) if (decomp_get16 (cc, &word))
return grub_errno; return grub_errno;
+57 -27
View File
@@ -22,6 +22,7 @@
#include <grub/file.h> #include <grub/file.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/archelp.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -74,6 +75,44 @@ grub_procdev_write (grub_disk_t disk __attribute ((unused)),
return GRUB_ERR_OUT_OF_RANGE; return GRUB_ERR_OUT_OF_RANGE;
} }
struct grub_archelp_data
{
struct grub_procfs_entry *entry, *next_entry;
};
static void
grub_procfs_rewind (struct grub_archelp_data *data)
{
data->entry = NULL;
data->next_entry = grub_procfs_entries;
}
static grub_err_t
grub_procfs_find_file (struct grub_archelp_data *data, char **name,
grub_int32_t *mtime,
grub_uint32_t *mode)
{
data->entry = data->next_entry;
if (!data->entry)
{
*mode = GRUB_ARCHELP_ATTR_END;
return GRUB_ERR_NONE;
}
data->next_entry = data->entry->next;
*mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;
*name = grub_strdup (data->entry->name);
*mtime = 0;
if (!*name)
return grub_errno;
return GRUB_ERR_NONE;
}
static struct grub_archelp_ops arcops =
{
.find_file = grub_procfs_find_file,
.rewind = grub_procfs_rewind
};
static grub_ssize_t static grub_ssize_t
grub_procfs_read (grub_file_t file, char *buf, grub_size_t len) grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
{ {
@@ -99,44 +138,35 @@ static grub_err_t
grub_procfs_dir (grub_device_t device, const char *path, grub_procfs_dir (grub_device_t device, const char *path,
grub_fs_dir_hook_t hook, void *hook_data) grub_fs_dir_hook_t hook, void *hook_data)
{ {
const char *ptr; struct grub_archelp_data data;
struct grub_dirhook_info info;
struct grub_procfs_entry *entry;
grub_memset (&info, 0, sizeof (info));
/* Check if the disk is our dummy disk. */ /* Check if the disk is our dummy disk. */
if (grub_strcmp (device->disk->name, "proc")) if (grub_strcmp (device->disk->name, "proc"))
return grub_error (GRUB_ERR_BAD_FS, "not a procfs"); return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
for (ptr = path; *ptr == '/'; ptr++);
if (*ptr) grub_procfs_rewind (&data);
return 0;
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries)) return grub_archelp_dir (&data, &arcops,
if (hook (entry->name, &info, hook_data)) path, hook, hook_data);
return 0;
return 0;
} }
static grub_err_t static grub_err_t
grub_procfs_open (struct grub_file *file, const char *path) grub_procfs_open (struct grub_file *file, const char *path)
{ {
const char *pathptr; grub_err_t err;
struct grub_procfs_entry *entry; struct grub_archelp_data data;
grub_size_t sz;
for (pathptr = path; *pathptr == '/'; pathptr++); grub_procfs_rewind (&data);
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries)) err = grub_archelp_open (&data, &arcops, path);
if (grub_strcmp (pathptr, entry->name) == 0) if (err)
{ return err;
grub_size_t sz; file->data = data.entry->get_contents (&sz);
file->data = entry->get_contents (&sz); if (!file->data)
if (!file->data) return grub_errno;
return grub_errno; file->size = sz;
file->size = sz; return GRUB_ERR_NONE;
return GRUB_ERR_NONE;
}
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
} }
static struct grub_disk_dev grub_procfs_dev = { static struct grub_disk_dev grub_procfs_dev = {
+25 -4
View File
@@ -783,12 +783,30 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
struct grub_reiserfs_key entry_key; struct grub_reiserfs_key entry_key;
enum grub_fshelp_filetype entry_type; enum grub_fshelp_filetype entry_type;
char *entry_name; char *entry_name;
char *entry_name_end = 0;
char c;
if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK)) if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK))
continue; continue;
entry_name = (((char *) directory_headers) entry_name = (((char *) directory_headers)
+ grub_le_to_cpu16 (directory_header->location)); + grub_le_to_cpu16 (directory_header->location));
if (entry_number == 0)
{
entry_name_end = (char *) block_header
+ grub_le_to_cpu16 (item_headers[block_position].item_location)
+ grub_le_to_cpu16 (item_headers[block_position].item_size);
}
else
{
entry_name_end = (((char *) directory_headers)
+ grub_le_to_cpu16 (directory_headers[entry_number - 1].location));
}
if (entry_name_end < entry_name || entry_name_end > (char *) block_header + block_size)
{
entry_name_end = (char *) block_header + block_size;
}
entry_key.directory_id = directory_header->directory_id; entry_key.directory_id = directory_header->directory_id;
entry_key.object_id = directory_header->object_id; entry_key.object_id = directory_header->object_id;
entry_key.u.v2.offset_type = 0; entry_key.u.v2.offset_type = 0;
@@ -935,7 +953,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
else else
{ {
/* Pseudo file ".." never has stat block. */ /* Pseudo file ".." never has stat block. */
if (grub_strcmp (entry_name, "..")) if (entry_name_end == entry_name + 2 && grub_memcmp (entry_name, "..", 2) != 0)
grub_dprintf ("reiserfs", grub_dprintf ("reiserfs",
"Warning : %s has no stat block !\n", "Warning : %s has no stat block !\n",
entry_name); entry_name);
@@ -943,18 +961,21 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
goto next; goto next;
} }
} }
c = *entry_name_end;
*entry_name_end = 0;
if (hook (entry_name, entry_type, entry_item, hook_data)) if (hook (entry_name, entry_type, entry_item, hook_data))
{ {
*entry_name_end = c;
grub_dprintf ("reiserfs", "Found : %s, type=%d\n", grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
entry_name, entry_type); entry_name, entry_type);
ret = 1; ret = 1;
goto found; goto found;
} }
*entry_name_end = c;
next: next:
*entry_name = 0; /* Make sure next entry name (which is just ;
before this one in disk order) stops before
the current one. */
} }
if (next_offset == 0) if (next_offset == 0)
+1 -1
View File
@@ -394,7 +394,7 @@ grub_ufs_read_file (struct grub_ufs_data *data,
return -1; return -1;
} }
else else
grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0); grub_memset (buf, 0, blockend);
buf += UFS_BLKSZ (sblock) - skipfirst; buf += UFS_BLKSZ (sblock) - skipfirst;
} }
+340 -124
View File
@@ -34,6 +34,50 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_INODE_FORMAT_EXT 2 #define XFS_INODE_FORMAT_EXT 2
#define XFS_INODE_FORMAT_BTREE 3 #define XFS_INODE_FORMAT_BTREE 3
/* Superblock version field flags */
#define XFS_SB_VERSION_NUMBITS 0x000f
#define XFS_SB_VERSION_ATTRBIT 0x0010
#define XFS_SB_VERSION_NLINKBIT 0x0020
#define XFS_SB_VERSION_QUOTABIT 0x0040
#define XFS_SB_VERSION_ALIGNBIT 0x0080
#define XFS_SB_VERSION_DALIGNBIT 0x0100
#define XFS_SB_VERSION_LOGV2BIT 0x0400
#define XFS_SB_VERSION_SECTORBIT 0x0800
#define XFS_SB_VERSION_EXTFLGBIT 0x1000
#define XFS_SB_VERSION_DIRV2BIT 0x2000
#define XFS_SB_VERSION_MOREBITSBIT 0x8000
#define XFS_SB_VERSION_BITS_SUPPORTED \
(XFS_SB_VERSION_NUMBITS | \
XFS_SB_VERSION_ATTRBIT | \
XFS_SB_VERSION_NLINKBIT | \
XFS_SB_VERSION_QUOTABIT | \
XFS_SB_VERSION_ALIGNBIT | \
XFS_SB_VERSION_DALIGNBIT | \
XFS_SB_VERSION_LOGV2BIT | \
XFS_SB_VERSION_SECTORBIT | \
XFS_SB_VERSION_EXTFLGBIT | \
XFS_SB_VERSION_DIRV2BIT | \
XFS_SB_VERSION_MOREBITSBIT)
/* Recognized xfs format versions */
#define XFS_SB_VERSION_4 4 /* Good old XFS filesystem */
#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */
/* features2 field flags */
#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */
#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
#define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32-bit project ids */
#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */
#define XFS_SB_VERSION2_BITS_SUPPORTED \
(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
XFS_SB_VERSION2_ATTR2BIT | \
XFS_SB_VERSION2_PROJID32BIT | \
XFS_SB_VERSION2_FTYPE)
/* incompat feature flags */
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
(XFS_SB_FEAT_INCOMPAT_FTYPE)
struct grub_xfs_sblock struct grub_xfs_sblock
{ {
@@ -45,7 +89,9 @@ struct grub_xfs_sblock
grub_uint64_t rootino; grub_uint64_t rootino;
grub_uint8_t unused3[20]; grub_uint8_t unused3[20];
grub_uint32_t agsize; grub_uint32_t agsize;
grub_uint8_t unused4[20]; grub_uint8_t unused4[12];
grub_uint16_t version;
grub_uint8_t unused5[6];
grub_uint8_t label[12]; grub_uint8_t label[12];
grub_uint8_t log2_bsize; grub_uint8_t log2_bsize;
grub_uint8_t log2_sect; grub_uint8_t log2_sect;
@@ -54,12 +100,19 @@ struct grub_xfs_sblock
grub_uint8_t log2_agblk; grub_uint8_t log2_agblk;
grub_uint8_t unused6[67]; grub_uint8_t unused6[67];
grub_uint8_t log2_dirblk; grub_uint8_t log2_dirblk;
grub_uint8_t unused7[7];
grub_uint32_t features2;
grub_uint8_t unused8[4];
grub_uint32_t sb_features_compat;
grub_uint32_t sb_features_ro_compat;
grub_uint32_t sb_features_incompat;
grub_uint32_t sb_features_log_incompat;
} GRUB_PACKED; } GRUB_PACKED;
struct grub_xfs_dir_header struct grub_xfs_dir_header
{ {
grub_uint8_t count; grub_uint8_t count;
grub_uint8_t smallino; grub_uint8_t largeino;
union union
{ {
grub_uint32_t i4; grub_uint32_t i4;
@@ -67,21 +120,29 @@ struct grub_xfs_dir_header
} GRUB_PACKED parent; } GRUB_PACKED parent;
} GRUB_PACKED; } GRUB_PACKED;
/* Structure for directory entry inlined in the inode */
struct grub_xfs_dir_entry struct grub_xfs_dir_entry
{ {
grub_uint8_t len; grub_uint8_t len;
grub_uint16_t offset; grub_uint16_t offset;
char name[1]; char name[1];
/* Inode number follows, 32 bits. */ /* Inode number follows, 32 / 64 bits. */
} GRUB_PACKED; } GRUB_PACKED;
/* Structure for directory entry in a block */
struct grub_xfs_dir2_entry struct grub_xfs_dir2_entry
{ {
grub_uint64_t inode; grub_uint64_t inode;
grub_uint8_t len; grub_uint8_t len;
} GRUB_PACKED; } GRUB_PACKED;
typedef grub_uint32_t grub_xfs_extent[4]; struct grub_xfs_extent
{
/* This should be a bitfield but bietfields are unportable, so just have
a raw array and functions extracting useful info from it.
*/
grub_uint32_t raw[4];
} GRUB_PACKED;
struct grub_xfs_btree_node struct grub_xfs_btree_node
{ {
@@ -90,21 +151,22 @@ struct grub_xfs_btree_node
grub_uint16_t numrecs; grub_uint16_t numrecs;
grub_uint64_t left; grub_uint64_t left;
grub_uint64_t right; grub_uint64_t right;
grub_uint64_t keys[1]; /* In V5 here follow crc, uuid, etc. */
} GRUB_PACKED; /* Then follow keys and block pointers */
} GRUB_PACKED;
struct grub_xfs_btree_root struct grub_xfs_btree_root
{ {
grub_uint16_t level; grub_uint16_t level;
grub_uint16_t numrecs; grub_uint16_t numrecs;
grub_uint64_t keys[1]; grub_uint64_t keys[1];
} GRUB_PACKED; } GRUB_PACKED;
struct grub_xfs_time struct grub_xfs_time
{ {
grub_uint32_t sec; grub_uint32_t sec;
grub_uint32_t nanosec; grub_uint32_t nanosec;
} GRUB_PACKED; } GRUB_PACKED;
struct grub_xfs_inode struct grub_xfs_inode
{ {
@@ -123,19 +185,11 @@ struct grub_xfs_inode
grub_uint16_t unused3; grub_uint16_t unused3;
grub_uint8_t fork_offset; grub_uint8_t fork_offset;
grub_uint8_t unused4[17]; grub_uint8_t unused4[17];
union
{
char raw[156];
struct dir
{
struct grub_xfs_dir_header dirhead;
struct grub_xfs_dir_entry direntry[1];
} dir;
grub_xfs_extent extents[XFS_INODE_EXTENTS];
struct grub_xfs_btree_root btree;
} GRUB_PACKED data;
} GRUB_PACKED; } GRUB_PACKED;
#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)
struct grub_xfs_dirblock_tail struct grub_xfs_dirblock_tail
{ {
grub_uint32_t leaf_count; grub_uint32_t leaf_count;
@@ -157,6 +211,8 @@ struct grub_xfs_data
int pos; int pos;
int bsize; int bsize;
grub_uint32_t agsize; grub_uint32_t agsize;
unsigned int hasftype:1;
unsigned int hascrc:1;
struct grub_fshelp_node diropen; struct grub_fshelp_node diropen;
}; };
@@ -164,6 +220,71 @@ static grub_dl_t my_mod;
static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
{
return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5);
}
static int grub_xfs_sb_hasftype(struct grub_xfs_data *data)
{
if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) &&
data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE))
return 1;
if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE))
return 1;
return 0;
}
static int grub_xfs_sb_valid(struct grub_xfs_data *data)
{
grub_dprintf("xfs", "Validating superblock\n");
if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
|| data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
|| ((int) data->sblock.log2_bsize
+ (int) data->sblock.log2_dirblk) >= 27)
{
grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
return 0;
}
if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5))
{
grub_dprintf("xfs", "XFS v5 superblock detected\n");
if (data->sblock.sb_features_incompat &
grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED))
{
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported "
"incompatible features");
return 0;
}
return 1;
}
else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4))
{
grub_dprintf("xfs", "XFS v4 superblock detected\n");
if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT)))
{
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories "
"is unsupported");
return 0;
}
if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) ||
(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED)))
{
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version "
"bits");
return 0;
}
return 1;
}
return 0;
}
/* Filetype information as used in inodes. */ /* Filetype information as used in inodes. */
#define FILETYPE_INO_MASK 0170000 #define FILETYPE_INO_MASK 0170000
#define FILETYPE_INO_REG 0100000 #define FILETYPE_INO_REG 0100000
@@ -180,14 +301,14 @@ static inline grub_uint64_t
GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
grub_uint64_t ino) grub_uint64_t ino)
{ {
return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
} }
static inline grub_uint64_t static inline grub_uint64_t
GRUB_XFS_INO_AG (struct grub_xfs_data *data, GRUB_XFS_INO_AG (struct grub_xfs_data *data,
grub_uint64_t ino) grub_uint64_t ino)
{ {
return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)); return (ino >> GRUB_XFS_INO_AGBITS (data));
} }
static inline grub_disk_addr_t static inline grub_disk_addr_t
@@ -198,37 +319,25 @@ GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb)
} }
static inline grub_uint64_t static inline grub_uint64_t
GRUB_XFS_EXTENT_OFFSET (grub_xfs_extent *exts, int ex) GRUB_XFS_EXTENT_OFFSET (struct grub_xfs_extent *exts, int ex)
{ {
return ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 return ((grub_be_to_cpu32 (exts[ex].raw[0]) & ~(1 << 31)) << 23
| grub_be_to_cpu32 (exts[ex][1]) >> 9); | grub_be_to_cpu32 (exts[ex].raw[1]) >> 9);
} }
static inline grub_uint64_t static inline grub_uint64_t
GRUB_XFS_EXTENT_BLOCK (grub_xfs_extent *exts, int ex) GRUB_XFS_EXTENT_BLOCK (struct grub_xfs_extent *exts, int ex)
{ {
return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex].raw[1])
& (0x1ff)) << 43 & (0x1ff)) << 43
| (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 | (grub_uint64_t) grub_be_to_cpu32 (exts[ex].raw[2]) << 11
| grub_be_to_cpu32 (exts[ex][3]) >> 21); | grub_be_to_cpu32 (exts[ex].raw[3]) >> 21);
} }
static inline grub_uint64_t static inline grub_uint64_t
GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex) GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex)
{ {
return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 21) - 1)); return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1));
}
static inline int
GRUB_XFS_ROUND_TO_DIRENT (int pos)
{
return ((((pos) + 8 - 1) / 8) * 8);
}
static inline int
GRUB_XFS_NEXT_DIRENT (int pos, int len)
{
return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2);
} }
@@ -255,6 +364,109 @@ grub_xfs_inode_offset (struct grub_xfs_data *data,
data->sblock.log2_inode); data->sblock.log2_inode);
} }
static inline grub_size_t
grub_xfs_inode_size(struct grub_xfs_data *data)
{
return (grub_size_t)1 << data->sblock.log2_inode;
}
/*
* Returns size occupied by XFS inode stored in memory - we store struct
* grub_fshelp_node there but on disk inode size may be actually larger than
* struct grub_xfs_inode so we need to account for that so that we can read
* from disk directly into in-memory structure.
*/
static inline grub_size_t
grub_xfs_fshelp_size(struct grub_xfs_data *data)
{
return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode)
+ grub_xfs_inode_size(data);
}
/* This should return void * but XFS code is error-prone with alignment, so
return char to retain cast-align.
*/
static char *
grub_xfs_inode_data(struct grub_xfs_inode *inode)
{
if (inode->version <= 2)
return ((char *)inode) + XFS_V2_INODE_SIZE;
return ((char *)inode) + XFS_V3_INODE_SIZE;
}
static struct grub_xfs_dir_entry *
grub_xfs_inline_de(struct grub_xfs_dir_header *head)
{
/*
With small inode numbers the header is 4 bytes smaller because of
smaller parent pointer
*/
return (struct grub_xfs_dir_entry *)
(((char *) head) + sizeof(struct grub_xfs_dir_header) -
(head->largeino ? 0 : sizeof(grub_uint32_t)));
}
static grub_uint8_t *
grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
struct grub_xfs_dir_entry *de)
{
return ((grub_uint8_t *)(de + 1)) + de->len - 1 + (data->hasftype ? 1 : 0);
}
static struct grub_xfs_dir_entry *
grub_xfs_inline_next_de(struct grub_xfs_data *data,
struct grub_xfs_dir_header *head,
struct grub_xfs_dir_entry *de)
{
char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;
p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
if (data->hasftype)
p++;
return (struct grub_xfs_dir_entry *)p;
}
static struct grub_xfs_dirblock_tail *
grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
{
int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk);
return (struct grub_xfs_dirblock_tail *)
((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail));
}
static struct grub_xfs_dir2_entry *
grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
{
if (data->hascrc)
return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
}
static struct grub_xfs_dir2_entry *
grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de)
{
int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;
if (data->hasftype)
size++; /* File type */
return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8));
}
/* This should return void * but XFS code is error-prone with alignment, so
return char to retain cast-align.
*/
static char *
grub_xfs_btree_keys(struct grub_xfs_data *data,
struct grub_xfs_btree_node *leaf)
{
char *keys = (char *)(leaf + 1);
if (data->hascrc)
keys += 48; /* skip crc, uuid, ... */
return keys;
}
static grub_err_t static grub_err_t
grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
@@ -263,9 +475,11 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
grub_uint64_t block = grub_xfs_inode_block (data, ino); grub_uint64_t block = grub_xfs_inode_block (data, ino);
int offset = grub_xfs_inode_offset (data, ino); int offset = grub_xfs_inode_offset (data, ino);
grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n",
ino, block, offset);
/* Read the inode. */ /* Read the inode. */
if (grub_disk_read (data->disk, block, offset, if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
1 << data->sblock.log2_inode, inode)) inode))
return grub_errno; return grub_errno;
if (grub_strncmp ((char *) inode->magic, "IN", 2)) if (grub_strncmp ((char *) inode->magic, "IN", 2))
@@ -274,40 +488,47 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
return 0; return 0;
} }
static grub_uint64_t
get_fsb (const void *keys, int idx)
{
const char *p = (const char *) keys + sizeof(grub_uint64_t) * idx;
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
}
static grub_disk_addr_t static grub_disk_addr_t
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{ {
struct grub_xfs_btree_node *leaf = 0; struct grub_xfs_btree_node *leaf = 0;
int ex, nrec; int ex, nrec;
grub_xfs_extent *exts; struct grub_xfs_extent *exts;
grub_uint64_t ret = 0; grub_uint64_t ret = 0;
if (node->inode.format == XFS_INODE_FORMAT_BTREE) if (node->inode.format == XFS_INODE_FORMAT_BTREE)
{ {
const grub_uint64_t *keys; struct grub_xfs_btree_root *root;
const char *keys;
int recoffset; int recoffset;
leaf = grub_malloc (node->data->bsize); leaf = grub_malloc (node->data->bsize);
if (leaf == 0) if (leaf == 0)
return 0; return 0;
nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); root = (struct grub_xfs_btree_root *) grub_xfs_inode_data(&node->inode);
keys = &node->inode.data.btree.keys[0]; nrec = grub_be_to_cpu16 (root->numrecs);
keys = (char *) &root->keys[0];
if (node->inode.fork_offset) if (node->inode.fork_offset)
recoffset = (node->inode.fork_offset - 1) / 2; recoffset = (node->inode.fork_offset - 1) / 2;
else else
recoffset = ((1 << node->data->sblock.log2_inode) recoffset = (grub_xfs_inode_size(node->data)
- ((char *) &node->inode.data.btree.keys - ((char *) keys - (char *) &node->inode))
- (char *) &node->inode)) / (2 * sizeof (grub_uint64_t));
/ (2 * sizeof (grub_uint64_t));
do do
{ {
int i; int i;
for (i = 0; i < nrec; i++) for (i = 0; i < nrec; i++)
{ {
if (fileblock < grub_be_to_cpu64 (keys[i])) if (fileblock < get_fsb(keys, i))
break; break;
} }
@@ -317,12 +538,16 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
grub_free (leaf); grub_free (leaf);
return 0; return 0;
} }
if (grub_disk_read (node->data->disk, if (grub_disk_read (node->data->disk,
GRUB_XFS_FSB_TO_BLOCK (node->data, grub_be_to_cpu64 (keys[i - 1 + recoffset])) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
0, node->data->bsize, leaf)) 0, node->data->bsize, leaf))
return 0; return 0;
if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) if ((!node->data->hascrc &&
grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
(node->data->hascrc &&
grub_strncmp ((char *) leaf->magic, "BMA3", 4)))
{ {
grub_free (leaf); grub_free (leaf);
grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
@@ -330,18 +555,18 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
} }
nrec = grub_be_to_cpu16 (leaf->numrecs); nrec = grub_be_to_cpu16 (leaf->numrecs);
keys = &leaf->keys[0]; keys = grub_xfs_btree_keys(node->data, leaf);
recoffset = ((node->data->bsize - ((char *) &leaf->keys recoffset = ((node->data->bsize - ((char *) keys
- (char *) leaf)) - (char *) leaf))
/ (2 * sizeof (grub_uint64_t))); / (2 * sizeof (grub_uint64_t)));
} }
while (leaf->level); while (leaf->level);
exts = (grub_xfs_extent *) keys; exts = (struct grub_xfs_extent *) keys;
} }
else if (node->inode.format == XFS_INODE_FORMAT_EXT) else if (node->inode.format == XFS_INODE_FORMAT_EXT)
{ {
nrec = grub_be_to_cpu32 (node->inode.nextents); nrec = grub_be_to_cpu32 (node->inode.nextents);
exts = &node->inode.data.extents[0]; exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
} }
else else
{ {
@@ -379,13 +604,13 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_xfs_read_file (grub_fshelp_node_t node, grub_xfs_read_file (grub_fshelp_node_t node,
grub_disk_read_hook_t read_hook, void *read_hook_data, grub_disk_read_hook_t read_hook, void *read_hook_data,
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf, grub_uint32_t header_size)
{ {
return grub_fshelp_read_file (node->data->disk, node, return grub_fshelp_read_file (node->data->disk, node,
read_hook, read_hook_data, read_hook, read_hook_data,
pos, len, buf, grub_xfs_read_block, pos, len, buf, grub_xfs_read_block,
grub_be_to_cpu64 (node->inode.size), grub_be_to_cpu64 (node->inode.size) + header_size,
node->data->sblock.log2_bsize node->data->sblock.log2_bsize
- GRUB_DISK_SECTOR_BITS, 0); - GRUB_DISK_SECTOR_BITS, 0);
} }
@@ -394,23 +619,34 @@ grub_xfs_read_file (grub_fshelp_node_t node,
static char * static char *
grub_xfs_read_symlink (grub_fshelp_node_t node) grub_xfs_read_symlink (grub_fshelp_node_t node)
{ {
int size = grub_be_to_cpu64 (node->inode.size); grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
if (size < 0)
{
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
return 0;
}
switch (node->inode.format) switch (node->inode.format)
{ {
case XFS_INODE_FORMAT_INO: case XFS_INODE_FORMAT_INO:
return grub_strndup (node->inode.data.raw, size); return grub_strndup (grub_xfs_inode_data(&node->inode), size);
case XFS_INODE_FORMAT_EXT: case XFS_INODE_FORMAT_EXT:
{ {
char *symlink; char *symlink;
grub_ssize_t numread; grub_ssize_t numread;
int off = 0;
if (node->data->hascrc)
off = 56;
symlink = grub_malloc (size + 1); symlink = grub_malloc (size + 1);
if (!symlink) if (!symlink)
return 0; return 0;
numread = grub_xfs_read_file (node, 0, 0, 0, size, symlink); node->inode.size = grub_be_to_cpu64 (size + off);
numread = grub_xfs_read_file (node, 0, 0, off, size, symlink, off);
if (numread != size) if (numread != size)
{ {
grub_free (symlink); grub_free (symlink);
@@ -456,9 +692,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
struct grub_fshelp_node *fdiro; struct grub_fshelp_node *fdiro;
grub_err_t err; grub_err_t err;
fdiro = grub_malloc (sizeof (struct grub_fshelp_node) fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
- sizeof (struct grub_xfs_inode)
+ (1 << ctx->diro->data->sblock.log2_inode) + 1);
if (!fdiro) if (!fdiro)
{ {
grub_print_error (); grub_print_error ();
@@ -496,24 +730,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
{ {
case XFS_INODE_FORMAT_INO: case XFS_INODE_FORMAT_INO:
{ {
struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0]; struct grub_xfs_dir_header *head = (struct grub_xfs_dir_header *) grub_xfs_inode_data(&diro->inode);
int smallino = !diro->inode.data.dir.dirhead.smallino; struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head);
int smallino = !head->largeino;
int i; int i;
grub_uint64_t parent; grub_uint64_t parent;
/* If small inode numbers are used to pack the direntry, the /* If small inode numbers are used to pack the direntry, the
parent inode number is small too. */ parent inode number is small too. */
if (smallino) if (smallino)
{ parent = grub_be_to_cpu32 (head->parent.i4);
parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
parent = grub_cpu_to_be64 (parent);
/* The header is a bit smaller than usual. */
de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
}
else else
{ parent = grub_be_to_cpu64 (head->parent.i8);
parent = diro->inode.data.dir.dirhead.parent.i8;
}
/* Synthesize the direntries for `.' and `..'. */ /* Synthesize the direntries for `.' and `..'. */
if (iterate_dir_call_hook (diro->ino, ".", &ctx)) if (iterate_dir_call_hook (diro->ino, ".", &ctx))
@@ -522,12 +750,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
if (iterate_dir_call_hook (parent, "..", &ctx)) if (iterate_dir_call_hook (parent, "..", &ctx))
return 1; return 1;
for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) for (i = 0; i < head->count; i++)
{ {
grub_uint64_t ino; grub_uint64_t ino;
grub_uint8_t *inopos = (((grub_uint8_t *) de) grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
+ sizeof (struct grub_xfs_dir_entry)
+ de->len - 1);
grub_uint8_t c; grub_uint8_t c;
/* inopos might be unaligned. */ /* inopos might be unaligned. */
@@ -545,18 +771,17 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
| (((grub_uint64_t) inopos[5]) << 16) | (((grub_uint64_t) inopos[5]) << 16)
| (((grub_uint64_t) inopos[6]) << 8) | (((grub_uint64_t) inopos[6]) << 8)
| (((grub_uint64_t) inopos[7]) << 0); | (((grub_uint64_t) inopos[7]) << 0);
ino = grub_cpu_to_be64 (ino);
c = de->name[de->len]; c = de->name[de->len];
de->name[de->len] = '\0'; de->name[de->len] = '\0';
if (iterate_dir_call_hook (ino, de->name, &ctx)) if (iterate_dir_call_hook (ino, de->name, &ctx))
return 1; {
de->name[de->len] = c;
return 1;
}
de->name[de->len] = c; de->name[de->len] = c;
de = ((struct grub_xfs_dir_entry *) de = grub_xfs_inline_next_de(dir->data, head, de);
(((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+ ((smallino ? sizeof (grub_uint32_t)
: sizeof (grub_uint64_t))) - 1));
} }
break; break;
} }
@@ -583,19 +808,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
>> dirblk_log2); >> dirblk_log2);
blk++) blk++)
{ {
/* The header is skipped, the first direntry is stored struct grub_xfs_dir2_entry *direntry =
from byte 16. */ grub_xfs_first_de(dir->data, dirblock);
int pos = 16;
int entries; int entries;
int tail_start = (dirblk_size struct grub_xfs_dirblock_tail *tail =
- sizeof (struct grub_xfs_dirblock_tail)); grub_xfs_dir_tail(dir->data, dirblock);
struct grub_xfs_dirblock_tail *tail;
tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
numread = grub_xfs_read_file (dir, 0, 0, numread = grub_xfs_read_file (dir, 0, 0,
blk << dirblk_log2, blk << dirblk_log2,
dirblk_size, dirblock); dirblk_size, dirblock, 0);
if (numread != dirblk_size) if (numread != dirblk_size)
return 0; return 0;
@@ -603,14 +824,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
- grub_be_to_cpu32 (tail->leaf_stale)); - grub_be_to_cpu32 (tail->leaf_stale));
/* Iterate over all entries within this block. */ /* Iterate over all entries within this block. */
while (pos < (dirblk_size while ((char *)direntry < (char *)tail)
- (int) sizeof (struct grub_xfs_dir2_entry)))
{ {
struct grub_xfs_dir2_entry *direntry;
grub_uint8_t *freetag; grub_uint8_t *freetag;
char *filename; char *filename;
direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
freetag = (grub_uint8_t *) direntry; freetag = (grub_uint8_t *) direntry;
if (grub_get_unaligned16 (freetag) == 0XFFFF) if (grub_get_unaligned16 (freetag) == 0XFFFF)
@@ -618,17 +836,20 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t)); grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));
/* This entry is not used, go to the next one. */ /* This entry is not used, go to the next one. */
pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip)); direntry = (struct grub_xfs_dir2_entry *)
(((char *)direntry) +
grub_be_to_cpu16 (grub_get_unaligned16 (skip)));
continue; continue;
} }
filename = &dirblock[pos + sizeof (*direntry)]; filename = (char *)(direntry + 1);
/* The byte after the filename is for the tag, which /* The byte after the filename is for the filetype, padding, or
is not used by GRUB. So it can be overwritten. */ tag, which is not used by GRUB. So it can be overwritten. */
filename[direntry->len] = '\0'; filename[direntry->len] = '\0';
if (iterate_dir_call_hook (direntry->inode, filename, &ctx)) if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
filename, &ctx))
{ {
grub_free (dirblock); grub_free (dirblock);
return 1; return 1;
@@ -641,8 +862,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
break; break;
/* Select the next directory entry. */ /* Select the next directory entry. */
pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len); direntry = grub_xfs_next_de(dir->data, direntry);
pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
} }
} }
grub_free (dirblock); grub_free (dirblock);
@@ -667,36 +887,35 @@ grub_xfs_mount (grub_disk_t disk)
if (!data) if (!data)
return 0; return 0;
grub_dprintf("xfs", "Reading sb\n");
/* Read the superblock. */ /* Read the superblock. */
if (grub_disk_read (disk, 0, 0, if (grub_disk_read (disk, 0, 0,
sizeof (struct grub_xfs_sblock), &data->sblock)) sizeof (struct grub_xfs_sblock), &data->sblock))
goto fail; goto fail;
if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) if (!grub_xfs_sb_valid(data))
|| data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS goto fail;
|| ((int) data->sblock.log2_bsize
+ (int) data->sblock.log2_dirblk) >= 27)
{
grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
goto fail;
}
data = grub_realloc (data, data = grub_realloc (data,
sizeof (struct grub_xfs_data) sizeof (struct grub_xfs_data)
- sizeof (struct grub_xfs_inode) - sizeof (struct grub_xfs_inode)
+ (1 << data->sblock.log2_inode) + 1); + grub_xfs_inode_size(data) + 1);
if (! data) if (! data)
goto fail; goto fail;
data->diropen.data = data; data->diropen.data = data;
data->diropen.ino = data->sblock.rootino; data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
data->diropen.inode_read = 1; data->diropen.inode_read = 1;
data->bsize = grub_be_to_cpu32 (data->sblock.bsize); data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
data->agsize = grub_be_to_cpu32 (data->sblock.agsize); data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
data->hasftype = grub_xfs_sb_hasftype(data);
data->hascrc = grub_xfs_sb_hascrc(data);
data->disk = disk; data->disk = disk;
data->pos = 0; data->pos = 0;
grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n",
grub_cpu_to_be64(data->sblock.rootino));
grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
@@ -799,10 +1018,7 @@ grub_xfs_open (struct grub_file *file, const char *name)
if (fdiro != &data->diropen) if (fdiro != &data->diropen)
{ {
grub_memcpy (&data->diropen, fdiro, grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data));
sizeof (struct grub_fshelp_node)
- sizeof (struct grub_xfs_inode)
+ (1 << data->sblock.log2_inode));
grub_free (fdiro); grub_free (fdiro);
} }
@@ -832,7 +1048,7 @@ grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
return grub_xfs_read_file (&data->diropen, return grub_xfs_read_file (&data->diropen,
file->read_hook, file->read_hook_data, file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf, 0);
} }
+101 -34
View File
@@ -280,7 +280,12 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key
*/ */
#define MAX_SUPPORTED_FEATURE_STRLEN 50 #define MAX_SUPPORTED_FEATURE_STRLEN 50
static const char *spa_feature_names[] = { static const char *spa_feature_names[] = {
"org.illumos:lz4_compress",NULL "org.illumos:lz4_compress",
"com.delphix:hole_birth",
"com.delphix:embedded_data",
"com.delphix:extensible_dataset",
"org.open-zfs:large_blocks",
NULL
}; };
static int static int
@@ -1751,7 +1756,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf,
for (i = 0; i < SPA_GBH_NBLKPTRS; i++) for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
{ {
if (zio_gb->zg_blkptr[i].blk_birth == 0) if (BP_IS_HOLE(&zio_gb->zg_blkptr[i]))
continue; continue;
err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data); err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
@@ -1800,6 +1805,39 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf,
return err; return err;
} }
/*
* buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
* more than BPE_PAYLOAD_SIZE bytes).
*/
static grub_err_t
decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
{
grub_size_t psize, i;
grub_uint8_t *buf8 = buf;
grub_uint64_t w = 0;
const grub_uint64_t *bp64 = (const grub_uint64_t *)bp;
psize = BPE_GET_PSIZE(bp);
/*
* Decode the words of the block pointer into the byte array.
* Low bits of first word are the first byte (little endian).
*/
for (i = 0; i < psize; i++)
{
if (i % sizeof (w) == 0)
{
/* beginning of a word */
w = *bp64;
bp64++;
if (!BPE_IS_PAYLOADWORD(bp, bp64))
bp64++;
}
buf8[i] = BF64_GET(w, (i % sizeof (w)) * 8, 8);
}
return GRUB_ERR_NONE;
}
/* /*
* Read in a block of data, verify its checksum, decompress if needed, * Read in a block of data, verify its checksum, decompress if needed,
* and put the uncompressed data in buf. * and put the uncompressed data in buf.
@@ -1818,12 +1856,26 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
*buf = NULL; *buf = NULL;
checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3); encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
lsize = (BP_IS_HOLE(bp) ? 0 : if (BP_IS_EMBEDDED(bp))
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) {
<< SPA_MINBLOCKSHIFT)); if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA)
psize = get_psize (bp, endian); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported embedded BP (type=%u)\n",
BPE_GET_ETYPE(bp));
lsize = BPE_GET_LSIZE(bp);
psize = BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), 25, 7, 0, 1);
}
else
{
lsize = (BP_IS_HOLE(bp) ? 0 :
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
<< SPA_MINBLOCKSHIFT));
psize = get_psize (bp, endian);
}
grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%"
PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize);
if (size) if (size)
*size = lsize; *size = lsize;
@@ -1837,33 +1889,41 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
"compression algorithm %s not supported\n", decomp_table[comp].name); "compression algorithm %s not supported\n", decomp_table[comp].name);
if (comp != ZIO_COMPRESS_OFF) if (comp != ZIO_COMPRESS_OFF)
{ /* It's not really necessary to align to 16, just for safety. */
/* It's not really necessary to align to 16, just for safety. */ compbuf = grub_malloc (ALIGN_UP (psize, 16));
compbuf = grub_malloc (ALIGN_UP (psize, 16));
if (! compbuf)
return grub_errno;
}
else else
compbuf = *buf = grub_malloc (lsize); compbuf = *buf = grub_malloc (lsize);
if (! compbuf)
return grub_errno;
grub_dprintf ("zfs", "endian = %d\n", endian); grub_dprintf ("zfs", "endian = %d\n", endian);
err = zio_read_data (bp, endian, compbuf, data); if (BP_IS_EMBEDDED(bp))
err = decode_embedded_bp_compressed(bp, compbuf);
else
{
err = zio_read_data (bp, endian, compbuf, data);
/* FIXME is it really necessary? */
if (comp != ZIO_COMPRESS_OFF)
grub_memset (compbuf + psize, 0, ALIGN_UP (psize, 16) - psize);
}
if (err) if (err)
{ {
grub_free (compbuf); grub_free (compbuf);
*buf = NULL; *buf = NULL;
return err; return err;
} }
grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
err = zio_checksum_verify (zc, checksum, endian, if (!BP_IS_EMBEDDED(bp))
compbuf, psize);
if (err)
{ {
grub_dprintf ("zfs", "incorrect checksum\n"); err = zio_checksum_verify (zc, checksum, endian,
grub_free (compbuf); compbuf, psize);
*buf = NULL; if (err)
return err; {
grub_dprintf ("zfs", "incorrect checksum\n");
grub_free (compbuf);
*buf = NULL;
return err;
}
} }
if (encrypted) if (encrypted)
@@ -2013,10 +2073,10 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
*/ */
static grub_err_t static grub_err_t
mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
grub_uint16_t objsize, const char *name, grub_uint64_t * value, grub_uint32_t objsize, const char *name, grub_uint64_t * value,
int case_insensitive) int case_insensitive)
{ {
grub_uint16_t i, chunks; grub_uint32_t i, chunks;
mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
if (objsize < MZAP_ENT_LEN) if (objsize < MZAP_ENT_LEN)
@@ -2428,7 +2488,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
struct grub_zfs_data *data, int case_insensitive) struct grub_zfs_data *data, int case_insensitive)
{ {
grub_uint64_t block_type; grub_uint64_t block_type;
grub_uint16_t size; grub_uint32_t size;
void *zapbuf; void *zapbuf;
grub_err_t err; grub_err_t err;
grub_zfs_endian_t endian; grub_zfs_endian_t endian;
@@ -2436,7 +2496,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
grub_dprintf ("zfs", "looking for '%s'\n", name); grub_dprintf ("zfs", "looking for '%s'\n", name);
/* Read in the first block of the zap object data. */ /* Read in the first block of the zap object data. */
size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, size = (grub_uint32_t) grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
zap_dnode->endian) << SPA_MINBLOCKSHIFT; zap_dnode->endian) << SPA_MINBLOCKSHIFT;
err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
if (err) if (err)
@@ -2822,7 +2882,10 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
err = dmu_read (&(dnode_path->dn), block, &t, 0, data); err = dmu_read (&(dnode_path->dn), block, &t, 0, data);
if (err) if (err)
return err; {
grub_free (sym_value);
return err;
}
movesize = sym_sz - block * blksz; movesize = sym_sz - block * blksz;
if (movesize > blksz) if (movesize > blksz)
@@ -3022,7 +3085,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
grub_dprintf ("zfs", "alive\n"); grub_dprintf ("zfs", "alive\n");
err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); err = dnode_get (mosmdn, objnum, 0, mdn, data);
if (err) if (err)
return err; return err;
@@ -3055,7 +3118,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
if (err) if (err)
return err; return err;
err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); err = dnode_get (mosmdn, objnum, 0, mdn, data);
if (err) if (err)
return err; return err;
@@ -3069,7 +3132,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
{ {
void *osp; void *osp;
blkptr_t *bp; blkptr_t *bp;
grub_size_t ospsize; grub_size_t ospsize = 0;
grub_err_t err; grub_err_t err;
grub_dprintf ("zfs", "endian = %d\n", mdn->endian); grub_dprintf ("zfs", "endian = %d\n", mdn->endian);
@@ -3210,8 +3273,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &subvol->mdn, err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data);
data);
if (err) if (err)
{ {
grub_free (fsname); grub_free (fsname);
@@ -3607,7 +3669,12 @@ zfs_mount (grub_device_t dev)
if (ub->ub_version >= SPA_VERSION_FEATURES && if (ub->ub_version >= SPA_VERSION_FEATURES &&
check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian, check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian,
data) != 0) data) != 0)
return NULL; {
grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool");
grub_free (osp);
zfs_unmount (data);
return NULL;
}
/* Got the MOS. Save it at the memory addr MOS. */ /* Got the MOS. Save it at the memory addr MOS. */
grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode, grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode,
@@ -3905,7 +3972,7 @@ fill_fs_info (struct grub_dirhook_info *info,
{ {
headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian); headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian);
err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &mdn, data); err = dnode_get (&(data->mos), headobj, 0, &mdn, data);
if (err) if (err)
{ {
grub_dprintf ("zfs", "failed here\n"); grub_dprintf ("zfs", "failed here\n");
+2
View File
@@ -184,6 +184,8 @@ LZ4_uncompress_unknownOutputSize(const char *source,
} }
} }
/* copy literals */ /* copy literals */
if ((grub_addr_t) length > ~(grub_addr_t)op)
goto _output_error;
cpy = op + length; cpy = op + length;
if ((cpy > oend - COPYLENGTH) || if ((cpy > oend - COPYLENGTH) ||
(ip + length > iend - COPYLENGTH)) { (ip + length > iend - COPYLENGTH)) {
+7 -4
View File
@@ -15,12 +15,12 @@ set -e
# #
# Example: # Example:
# #
# genmod.sh moddep.lst normal.module normal.mod # genmod.sh moddep.lst normal.module build-grub-module-verifier normal.mod
# #
moddep=$1 moddep=$1
infile=$2 infile=$2
outfile=$3 outfile=$4
tmpfile=${outfile}.tmp tmpfile=${outfile}.tmp
modname=`echo $infile | sed -e 's@\.module.*$@@'` 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 \
-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.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 fi
if ! test -z "${TARGET_OBJ2ELF}"; then if ! test -z "${TARGET_OBJ2ELF}"; then
"${TARGET_OBJ2ELF}" $tmpfile || exit 1 "${TARGET_OBJ2ELF}" $tmpfile || exit 1
@@ -91,6 +91,9 @@ else
-nr:_grub_mod_init:grub_mod_init \ -nr:_grub_mod_init:grub_mod_init \
-nr:_grub_mod_fini:grub_mod_fini \ -nr:_grub_mod_fini:grub_mod_fini \
-wd1106 -nu -nd $tmpfile.bin $tmpfile || exit 1 -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 fi
mv $tmpfile $outfile mv $tmpfile $outfile
+31 -1
View File
@@ -29,7 +29,7 @@ BEGIN {
} }
} }
else { else {
printf "error: %u: unrecognized input format\n", NR; printf "error: %u: unrecognized input format\n", NR >"/dev/stderr";
error++; error++;
} }
} }
@@ -39,6 +39,8 @@ END {
if (error >= 1) if (error >= 1)
exit 1; exit 1;
total_depcount = 0
for (mod in modtab) { for (mod in modtab) {
# Remove duplications. # Remove duplications.
split(modtab[mod], depmods, " "); split(modtab[mod], depmods, " ");
@@ -52,14 +54,42 @@ END {
uniqmods[depmod] = 1; uniqmods[depmod] = 1;
} }
modlist = "" modlist = ""
depcount[mod] = 0
for (depmod in uniqmods) { for (depmod in uniqmods) {
modlist = modlist " " depmod; modlist = modlist " " depmod;
inverse_dependencies[depmod] = inverse_dependencies[depmod] " " mod
depcount[mod]++
total_depcount++
} }
if (mod == "all_video") { if (mod == "all_video") {
continue; continue;
} }
printf "%s:%s\n", mod, modlist; printf "%s:%s\n", mod, modlist;
} }
# Check that we have no dependency circles
while (total_depcount != 0) {
something_done = 0
for (mod in depcount) {
if (depcount[mod] == 0) {
delete depcount[mod]
split(inverse_dependencies[mod], inv_depmods, " ");
for (ctr in inv_depmods) {
depcount[inv_depmods[ctr]]--
total_depcount--
}
delete inverse_dependencies[mod]
something_done = 1
}
}
if (something_done == 0) {
for (mod in depcount) {
circle = circle " " mod
}
printf "error: modules %s form a dependency circle\n", circle >"/dev/stderr";
exit 1
}
}
modlist = "" modlist = ""
while (getline <"video.lst") { while (getline <"video.lst") {
modlist = modlist " " $1; modlist = modlist " " $1;
+10 -5
View File
@@ -45,6 +45,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
grub_uint32_t *logical; grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len; grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr; struct grub_unicode_glyph *visual, *ptr;
grub_err_t err;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0) if (logical_len < 0)
@@ -56,24 +57,28 @@ grub_font_draw_string (const char *str, grub_font_t font,
if (visual_len < 0) if (visual_len < 0)
return grub_errno; return grub_errno;
err = GRUB_ERR_NONE;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{ {
grub_err_t err;
struct grub_font_glyph *glyph; struct grub_font_glyph *glyph;
glyph = grub_font_construct_glyph (font, ptr); glyph = grub_font_construct_glyph (font, ptr);
if (!glyph) if (!glyph)
return grub_errno; {
err = grub_errno;
goto out;
}
err = grub_font_draw_glyph (glyph, color, x, baseline_y); err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width;
if (err) if (err)
return err; goto out;
x += glyph->device_width;
} }
out:
for (ptr = visual; ptr < visual + visual_len; ptr++) for (ptr = visual; ptr < visual + visual_len; ptr++)
grub_unicode_destroy_glyph (ptr); grub_unicode_destroy_glyph (ptr);
grub_free (visual); grub_free (visual);
return GRUB_ERR_NONE; return err;
} }
/* Get the width in pixels of the specified UTF-8 string, when rendered in /* Get the width in pixels of the specified UTF-8 string, when rendered in
+4 -4
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"), return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"),
"theme"); "theme");
instance = grub_zalloc (sizeof (*instance));
if (!instance)
return grub_errno;
err = grub_video_get_info (&mode_info); err = grub_video_get_info (&mode_info);
if (err) if (err)
return err; return err;
instance = grub_zalloc (sizeof (*instance));
if (!instance)
return grub_errno;
if (theme_path[0] != '/' && theme_path[0] != '(') if (theme_path[0] != '/' && theme_path[0] != '(')
{ {
const char *prefix; const char *prefix;
View File
Whitespace-only changes.
+2 -2
View File
@@ -255,7 +255,7 @@ theme_set_string (grub_gfxmenu_view_t view,
{ {
unsigned int tmp; unsigned int tmp;
int err = theme_get_unsigned_int_from_proportional (value, int err = theme_get_unsigned_int_from_proportional (value,
view->screen.width, view->screen.height,
&tmp); &tmp);
if (err != GRUB_ERR_NONE) if (err != GRUB_ERR_NONE)
return err; return err;
@@ -275,7 +275,7 @@ theme_set_string (grub_gfxmenu_view_t view,
{ {
unsigned int tmp; unsigned int tmp;
int err = theme_get_unsigned_int_from_proportional (value, int err = theme_get_unsigned_int_from_proportional (value,
view->screen.width, view->screen.height,
&tmp); &tmp);
if (err != GRUB_ERR_NONE) if (err != GRUB_ERR_NONE)
return err; return err;
+8 -4
View File
@@ -1,5 +1,5 @@
/* Hierarchical argument parsing help output /* Hierarchical argument parsing help output
Copyright (C) 1995-2005, 2007, 2009-2013 Free Software Foundation, Inc. Copyright (C) 1995-2005, 2007, 2009-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>. Written by Miles Bader <miles@gnu.ai.mit.edu>.
@@ -650,7 +650,7 @@ hol_find_entry (struct hol *hol, const char *name)
return 0; return 0;
} }
/* If an entry with the long option NAME occurs in HOL, set it's special /* If an entry with the long option NAME occurs in HOL, set its special
sort position to GROUP. */ sort position to GROUP. */
static void static void
hol_set_group (struct hol *hol, const char *name, int group) hol_set_group (struct hol *hol, const char *name, int group)
@@ -1507,11 +1507,15 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
if (vt) if (vt)
{ {
if (post) if (post)
inp_text = vt + 1; {
inp_text = vt + 1;
if (! *inp_text)
inp_text = 0;
}
else else
{ {
inp_text_len = vt - argp->doc; inp_text_len = vt - argp->doc;
inp_text = __strndup (argp->doc, inp_text_len); inp_text = inp_text_len ? __strndup (argp->doc, inp_text_len) : 0;
} }
} }
else else
+119
View File
@@ -0,0 +1,119 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2012 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/types.h>
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/acpi.h>
/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
grub_uint8_t
grub_byte_checksum (void *base, grub_size_t size)
{
grub_uint8_t *ptr;
grub_uint8_t ret = 0;
for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
ptr++)
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;
}
File renamed without changes.
+34 -44
View File
@@ -26,14 +26,14 @@
#include <grub/arm/reloc.h> #include <grub/arm/reloc.h>
static inline grub_uint32_t static inline grub_uint32_t
thumb_get_instruction_word(grub_uint16_t *target) thumb_get_instruction_word (grub_uint16_t *target)
{ {
/* Extract instruction word in alignment-safe manner */ /* Extract instruction word in alignment-safe manner */
return grub_le_to_cpu16 ((*target)) << 16 | grub_le_to_cpu16 (*(target + 1)); return grub_le_to_cpu16 ((*target)) << 16 | grub_le_to_cpu16 (*(target + 1));
} }
static inline void static inline void
thumb_set_instruction_word(grub_uint16_t *target, grub_uint32_t insword) thumb_set_instruction_word (grub_uint16_t *target, grub_uint32_t insword)
{ {
*target = grub_cpu_to_le16 (insword >> 16); *target = grub_cpu_to_le16 (insword >> 16);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff); *(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
@@ -70,9 +70,7 @@ grub_arm_thm_call_get_offset (grub_uint16_t *target)
grub_uint32_t insword; grub_uint32_t insword;
grub_int32_t offset; grub_int32_t offset;
/* Extract instruction word in alignment-safe manner */ insword = thumb_get_instruction_word (target);
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
/* Extract bitfields from instruction words */ /* Extract bitfields from instruction words */
sign = (insword >> 26) & 1; sign = (insword >> 26) & 1;
@@ -97,9 +95,7 @@ grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset)
grub_uint32_t insword; grub_uint32_t insword;
int is_blx; int is_blx;
/* Extract instruction word in alignment-safe manner */ insword = thumb_get_instruction_word (target);
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
if (((insword >> 12) & 0xd) == 0xc) if (((insword >> 12) & 0xd) == 0xc)
is_blx = 1; is_blx = 1;
@@ -122,9 +118,7 @@ grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset)
(((offset >> 12) & 0x03ff) << 16) | (((offset >> 12) & 0x03ff) << 16) |
(j1 << 13) | (j2 << 11) | ((offset >> 1) & 0x07ff); (j1 << 13) | (j2 << 11) | ((offset >> 1) & 0x07ff);
/* Write instruction word back in alignment-safe manner */ thumb_set_instruction_word (target, insword);
*target = grub_cpu_to_le16 ((insword >> 16) & 0xffff);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
grub_dprintf ("dl", " *insword = 0x%08x", insword); grub_dprintf ("dl", " *insword = 0x%08x", insword);
@@ -137,9 +131,7 @@ grub_arm_thm_jump19_get_offset (grub_uint16_t *target)
grub_int32_t offset; grub_int32_t offset;
grub_uint32_t insword; grub_uint32_t insword;
/* Extract instruction word in alignment-safe manner */ insword = thumb_get_instruction_word (target);
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
/* Extract and sign extend offset */ /* Extract and sign extend offset */
offset = ((insword >> 26) & 1) << 19 offset = ((insword >> 26) & 1) << 19
@@ -163,9 +155,7 @@ grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset)
offset >>= 1; offset >>= 1;
offset &= 0xfffff; offset &= 0xfffff;
/* Extract instruction word in alignment-safe manner */ insword = thumb_get_instruction_word (target);
insword = grub_le_to_cpu16 ((*target)) << 16
| grub_le_to_cpu16 (*(target + 1));
/* Reassemble instruction word and write back */ /* Reassemble instruction word and write back */
insword &= insmask; insword &= insmask;
@@ -174,8 +164,7 @@ grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset)
| ((offset >> 17) & 1) << 13 | ((offset >> 17) & 1) << 13
| ((offset >> 11) & 0x3f) << 16 | ((offset >> 11) & 0x3f) << 16
| (offset & 0x7ff); | (offset & 0x7ff);
*target = grub_cpu_to_le16 (insword >> 16); thumb_set_instruction_word (target, insword);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
} }
int int
@@ -186,6 +175,32 @@ grub_arm_thm_jump19_check_offset (grub_int32_t offset)
return 1; return 1;
} }
grub_uint16_t
grub_arm_thm_movw_movt_get_value (grub_uint16_t *target)
{
grub_uint32_t insword;
insword = thumb_get_instruction_word (target);
return ((insword & 0xf0000) >> 4) | ((insword & 0x04000000) >> 15) | \
((insword & 0x7000) >> 4) | (insword & 0xff);
}
void
grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value)
{
grub_uint32_t insword;
const grub_uint32_t insmask = 0xfbf08f00;
insword = thumb_get_instruction_word (target);
insword &= insmask;
insword |= ((value & 0xf000) << 4) | ((value & 0x0800) << 15) | \
((value & 0x0700) << 4) | (value & 0xff);
thumb_set_instruction_word (target, insword);
}
/*********************************************************** /***********************************************************
* ARM (A32) relocations: * * ARM (A32) relocations: *
@@ -228,28 +243,3 @@ grub_arm_jump24_set_offset (grub_uint32_t *target,
*target = grub_cpu_to_le32 (insword); *target = grub_cpu_to_le32 (insword);
} }
grub_uint16_t
grub_arm_thm_movw_movt_get_value (grub_uint16_t *target)
{
grub_uint32_t insword;
insword = thumb_get_instruction_word (target);
return ((insword & 0xf0000) >> 4) | ((insword & 0x04000000) >> 15) | \
((insword & 0x7000) >> 4) | (insword & 0xff);
}
void
grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value)
{
grub_uint32_t insword;
insword = thumb_get_instruction_word (target);
insword &= 0xfbf08f00;
insword |= ((value & 0xf000) << 4) | ((value & 0x0800) << 15) | \
((value & 0x0700) << 4) | (value & 0xff);
thumb_set_instruction_word (target, insword);
}
+3 -3
View File
@@ -38,7 +38,7 @@ static void
increment_timer (grub_efi_event_t event __attribute__ ((unused)), increment_timer (grub_efi_event_t event __attribute__ ((unused)),
void *context __attribute__ ((unused))) void *context __attribute__ ((unused)))
{ {
tmr++; tmr += 10;
} }
void void
@@ -52,7 +52,7 @@ grub_machine_init (void)
efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL,
GRUB_EFI_TPL_CALLBACK, increment_timer, NULL, &tmr_evt); 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); grub_install_get_time_ms (grub_efi_get_time_ms);
} }
@@ -67,7 +67,7 @@ grub_machine_fini (int flags)
b = grub_efi_system_table->boot_services; b = grub_efi_system_table->boot_services;
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 0); efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0);
efi_call_1 (b->close_event, tmr_evt); efi_call_1 (b->close_event, tmr_evt);
grub_efi_fini (); grub_efi_fini ();
+49 -11
View File
@@ -55,10 +55,6 @@ FUNCTION(_start)
VARIABLE(grub_total_module_size) VARIABLE(grub_total_module_size)
.long 0 .long 0
VARIABLE(grub_uboot_machine_type)
.long 0
VARIABLE(grub_uboot_boot_data)
.long 0
VARIABLE(grub_modbase) VARIABLE(grub_modbase)
.long 0 .long 0
bss_start_ptr: bss_start_ptr:
@@ -66,29 +62,66 @@ bss_start_ptr:
end_ptr: end_ptr:
.long EXT_C(_end) .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) FUNCTION(codestart)
@ Store context: Machine ID, atags/dtb, ... @ Store context: Machine ID, atags/dtb, ...
@ U-Boot API signature is stored on the U-Boot heap @ U-Boot API signature is stored on the U-Boot heap
@ Stack pointer used as start address for signature probing @ Stack pointer used as start address for signature probing
mov r12, sp mov r12, sp
adr sp, entry_state 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) adr r1, _start
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
ldr r0, bss_start_ptr @ src 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) add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
mvn r1, #(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 r1, end_ptr @ dst = End of BSS
ldr r2, grub_total_module_size @ blob size ldr r2, grub_total_module_size @ blob size
add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE
and r1, r1, #~0x7 @ Ensure 8-byte alignment and r1, r1, #~0x7 @ Ensure 8-byte alignment
sub sp, r1, #8 sub sp, r1, #8
add r1, r1, #1024 add r1, r1, #1024
@@ -157,6 +190,11 @@ FUNCTION(grub_uboot_return)
.align 3 .align 3
@ U-boot context stack space @ U-boot context stack space
entry_state_end: 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 @ r4
.long 0 @ r5 .long 0 @ r5
.long 0 @ r6 .long 0 @ r6
+18
View File
@@ -132,6 +132,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
*abs_place = (grub_uint64_t) sym_addr; *abs_place = (grub_uint64_t) sym_addr;
} }
break; 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_CALL26:
case R_AARCH64_JUMP26: 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); grub_arm64_set_xxxx26_offset (place, offset);
} }
break; 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: default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"), N_("relocation 0x%x is not implemented yet"),
+40
View File
@@ -53,3 +53,43 @@ grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset)
*place &= insmask; *place &= insmask;
*place |= grub_cpu_to_le32 (offset >> 2) & ~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;
}
+60
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 ();
}
+419
View File
@@ -0,0 +1,419 @@
/* compiler-rt.c - compiler helpers. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010-2014 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/misc.h>
#include <grub/compiler-rt.h>
#ifndef GRUB_EMBED_DECOMPRESSOR
void * GRUB_BUILTIN_ATTR
memcpy (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
void * GRUB_BUILTIN_ATTR
memmove (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
int GRUB_BUILTIN_ATTR
memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
void * GRUB_BUILTIN_ATTR
memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
#ifdef __APPLE__
void GRUB_BUILTIN_ATTR
__bzero (void *s, grub_size_t n)
{
grub_memset (s, 0, n);
}
#endif
#if GRUB_DIVISION_IN_SOFTWARE
grub_uint32_t
__udivsi3 (grub_uint32_t a, grub_uint32_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_int32_t
__divsi3 (grub_int32_t a, grub_int32_t b)
{
return grub_divmod64s (a, b, 0);
}
grub_uint32_t
__umodsi3 (grub_uint32_t a, grub_uint32_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
grub_int32_t
__modsi3 (grub_int32_t a, grub_int32_t b)
{
grub_int64_t ret;
grub_divmod64s (a, b, &ret);
return ret;
}
grub_uint64_t
__udivdi3 (grub_uint64_t a, grub_uint64_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_uint64_t
__umoddi3 (grub_uint64_t a, grub_uint64_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
grub_int64_t
__divdi3 (grub_int64_t a, grub_int64_t b)
{
return grub_divmod64s (a, b, 0);
}
grub_int64_t
__moddi3 (grub_int64_t a, grub_int64_t b)
{
grub_int64_t ret;
grub_divmod64s (a, b, &ret);
return ret;
}
#endif
#endif
#ifdef NEED_CTZDI2
unsigned
__ctzdi2 (grub_uint64_t x)
{
unsigned ret = 0;
if (!x)
return 64;
if (!(x & 0xffffffff))
{
x >>= 32;
ret |= 32;
}
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#ifdef NEED_CTZSI2
unsigned
__ctzsi2 (grub_uint32_t x)
{
unsigned ret = 0;
if (!x)
return 32;
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#if defined (__clang__) && !defined(GRUB_EMBED_DECOMPRESSOR)
/* clang emits references to abort(). */
void __attribute__ ((noreturn))
abort (void)
{
grub_fatal ("compiler abort");
}
#endif
#if (defined (__MINGW32__) || defined (__CYGWIN__))
void __register_frame_info (void)
{
}
void __deregister_frame_info (void)
{
}
void ___chkstk_ms (void)
{
}
void __chkstk_ms (void)
{
}
#endif
union component64
{
grub_uint64_t full;
struct
{
#ifdef GRUB_CPU_WORDS_BIGENDIAN
grub_uint32_t high;
grub_uint32_t low;
#else
grub_uint32_t low;
grub_uint32_t high;
#endif
};
};
#if defined (__powerpc__) || defined (__arm__) || defined(__mips__)
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__lshrdi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
w.high = 0;
w.low = (grub_uint32_t) uu.high >> -bm;
}
else
{
const grub_uint32_t carries = (grub_uint32_t) uu.high << bm;
w.high = (grub_uint32_t) uu.high >> b;
w.low = ((grub_uint32_t) uu.low >> b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__ashrdi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
/* w.high = 1..1 or 0..0 */
w.high = ((grub_int32_t) uu.high) >> (32 - 1);
w.low = ((grub_int32_t) uu.high) >> -bm;
}
else
{
const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm;
w.high = ((grub_int32_t) uu.high) >> b;
w.low = ((grub_uint32_t) uu.low >> b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__ashldi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
w.low = 0;
w.high = (grub_uint32_t) uu.low << -bm;
}
else
{
const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm;
w.low = (grub_uint32_t) uu.low << b;
w.high = ((grub_uint32_t) uu.high << b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
int
__ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
{
union component64 ac, bc;
ac.full = a;
bc.full = b;
if (ac.high < bc.high)
return 0;
else if (ac.high > bc.high)
return 2;
if (ac.low < bc.low)
return 0;
else if (ac.low > bc.low)
return 2;
return 1;
}
#endif
#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined(__arm__)
/* Based on libgcc2.c from gcc suite. */
grub_uint32_t
__bswapsi2 (grub_uint32_t u)
{
return ((((u) & 0xff000000) >> 24)
| (((u) & 0x00ff0000) >> 8)
| (((u) & 0x0000ff00) << 8)
| (((u) & 0x000000ff) << 24));
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__bswapdi2 (grub_uint64_t u)
{
return ((((u) & 0xff00000000000000ull) >> 56)
| (((u) & 0x00ff000000000000ull) >> 40)
| (((u) & 0x0000ff0000000000ull) >> 24)
| (((u) & 0x000000ff00000000ull) >> 8)
| (((u) & 0x00000000ff000000ull) << 8)
| (((u) & 0x0000000000ff0000ull) << 24)
| (((u) & 0x000000000000ff00ull) << 40)
| (((u) & 0x00000000000000ffull) << 56));
}
#endif
#ifdef __arm__
grub_uint32_t
__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
__attribute__ ((alias ("__udivsi3")));
grub_int32_t
__aeabi_idiv (grub_int32_t a, grub_int32_t b)
__attribute__ ((alias ("__divsi3")));
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memcpy")));
void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memcpy")));
void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memcpy")));
void *__aeabi_memset (void *s, int c, grub_size_t n)
__attribute__ ((alias ("memset")));
void
__aeabi_memclr (void *s, grub_size_t n)
{
grub_memset (s, 0, n);
}
void __aeabi_memclr4 (void *s, grub_size_t n)
__attribute__ ((alias ("__aeabi_memclr")));
void __aeabi_memclr8 (void *s, grub_size_t n)
__attribute__ ((alias ("__aeabi_memclr")));
int
__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
{
return __ucmpdi2 (a, b) - 1;
}
grub_uint64_t
__aeabi_lasr (grub_uint64_t u, int b)
__attribute__ ((alias ("__ashrdi3")));
grub_uint64_t
__aeabi_llsr (grub_uint64_t u, int b)
__attribute__ ((alias ("__lshrdi3")));
grub_uint64_t
__aeabi_llsl (grub_uint64_t u, int b)
__attribute__ ((alias ("__ashldi3")));
#endif
+8 -2
View File
@@ -333,8 +333,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
if (s->sh_type == SHT_SYMTAB) if (s->sh_type == SHT_SYMTAB)
break; 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) 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 #ifdef GRUB_MODULES_MACHINE_READONLY
mod->symtab = grub_malloc (s->sh_size); mod->symtab = grub_malloc (s->sh_size);
@@ -576,6 +579,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (seg) 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); err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
if (err) if (err)
return err; return err;
@@ -605,7 +611,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
} }
/* Make sure that every section is within the core. */ /* 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"); grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
return 0; return 0;
File renamed without changes.
+49 -3
View File
@@ -27,6 +27,7 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/kernel.h> #include <grub/kernel.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/loader.h>
/* The handle of GRUB itself. Filled in by the startup code. */ /* The handle of GRUB itself. Filled in by the startup code. */
grub_efi_handle_t grub_efi_image_handle; grub_efi_handle_t grub_efi_image_handle;
@@ -156,7 +157,7 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
void void
grub_exit (void) grub_exit (void)
{ {
grub_efi_fini (); grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
efi_call_4 (grub_efi_system_table->boot_services->exit, efi_call_4 (grub_efi_system_table->boot_services->exit,
grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
for (;;) ; for (;;) ;
@@ -205,6 +206,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
| GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
| GRUB_EFI_VARIABLE_RUNTIME_ACCESS), | GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
datasize, data); datasize, data);
grub_free (var16);
if (status == GRUB_EFI_SUCCESS) if (status == GRUB_EFI_SUCCESS)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@@ -236,8 +238,11 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL); status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL);
if (!datasize) if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
return NULL; {
grub_free (var16);
return NULL;
}
data = grub_malloc (datasize); data = grub_malloc (datasize);
if (!data) if (!data)
@@ -394,6 +399,47 @@ grub_efi_get_device_path (grub_efi_handle_t handle)
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
} }
/* Return the device path node right before the end node. */
grub_efi_device_path_t *
grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
{
grub_efi_device_path_t *next, *p;
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
return 0;
for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
;
return p;
}
/* Duplicate a device path. */
grub_efi_device_path_t *
grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
{
grub_efi_device_path_t *p;
grub_size_t total_size = 0;
for (p = (grub_efi_device_path_t *) dp;
;
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
{
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
break;
}
p = grub_malloc (total_size);
if (! p)
return 0;
grub_memcpy (p, dp, total_size);
return p;
}
static void static void
dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
{ {
+56 -2
View File
@@ -28,6 +28,25 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
#pragma GCC diagnostic ignored "-Wcast-align"
#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
#define GRUB_ELF_ENABLE_BI_ENDIAN 1
#else
#define GRUB_ELF_ENABLE_BI_ENDIAN 0
#endif
#if defined(GRUB_CPU_WORDS_BIGENDIAN)
#define GRUB_ELF_NATIVE_ENDIANNESS ELFDATA2MSB
#define GRUB_ELF_OPPOSITE_ENDIANNESS ELFDATA2LSB
#else
#define GRUB_ELF_NATIVE_ENDIANNESS ELFDATA2LSB
#define GRUB_ELF_OPPOSITE_ENDIANNESS ELFDATA2MSB
#endif
static int grub_elf32_check_endianess_and_bswap_ehdr (grub_elf_t elf);
static int grub_elf64_check_endianess_and_bswap_ehdr (grub_elf_t elf);
/* Check if EHDR is a valid ELF header. */ /* Check if EHDR is a valid ELF header. */
static grub_err_t static grub_err_t
grub_elf_check_header (grub_elf_t elf) grub_elf_check_header (grub_elf_t elf)
@@ -38,8 +57,25 @@ grub_elf_check_header (grub_elf_t elf)
|| e->e_ident[EI_MAG1] != ELFMAG1 || e->e_ident[EI_MAG1] != ELFMAG1
|| e->e_ident[EI_MAG2] != ELFMAG2 || e->e_ident[EI_MAG2] != ELFMAG2
|| e->e_ident[EI_MAG3] != ELFMAG3 || e->e_ident[EI_MAG3] != ELFMAG3
|| e->e_ident[EI_VERSION] != EV_CURRENT || e->e_ident[EI_VERSION] != EV_CURRENT)
|| e->e_version != EV_CURRENT) return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic"));
if (grub_elf_is_elf32 (elf))
{
if (!grub_elf32_check_endianess_and_bswap_ehdr (elf)) {
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF endianness magic");
}
}
else if (grub_elf_is_elf64 (elf))
{
if (!grub_elf64_check_endianess_and_bswap_ehdr (elf)) {
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF endianness magic");
}
}
else
return grub_error (GRUB_ERR_BAD_OS, "unknown ELF class");
if (e->e_version != EV_CURRENT)
return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic")); return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic"));
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@@ -117,6 +153,9 @@ grub_elf_open (const char *name)
} }
#define grub_swap_bytes_halfXX grub_swap_bytes16
#define grub_swap_bytes_wordXX grub_swap_bytes32
/* 32-bit */ /* 32-bit */
#define ehdrXX ehdr32 #define ehdrXX ehdr32
#define ELFCLASSXX ELFCLASS32 #define ELFCLASSXX ELFCLASS32
@@ -127,7 +166,12 @@ grub_elf_open (const char *name)
#define grub_elf_is_elfXX grub_elf_is_elf32 #define grub_elf_is_elfXX grub_elf_is_elf32
#define grub_elfXX_load_phdrs grub_elf32_load_phdrs #define grub_elfXX_load_phdrs grub_elf32_load_phdrs
#define ElfXX_Phdr Elf32_Phdr #define ElfXX_Phdr Elf32_Phdr
#define ElfXX_Ehdr Elf32_Ehdr
#define grub_uintXX_t grub_uint32_t #define grub_uintXX_t grub_uint32_t
#define grub_swap_bytes_addrXX grub_swap_bytes32
#define grub_swap_bytes_offXX grub_swap_bytes32
#define grub_swap_bytes_XwordXX grub_swap_bytes32
#define grub_elfXX_check_endianess_and_bswap_ehdr grub_elf32_check_endianess_and_bswap_ehdr
#include "elfXX.c" #include "elfXX.c"
@@ -140,7 +184,12 @@ grub_elf_open (const char *name)
#undef grub_elf_is_elfXX #undef grub_elf_is_elfXX
#undef grub_elfXX_load_phdrs #undef grub_elfXX_load_phdrs
#undef ElfXX_Phdr #undef ElfXX_Phdr
#undef ElfXX_Ehdr
#undef grub_uintXX_t #undef grub_uintXX_t
#undef grub_swap_bytes_addrXX
#undef grub_swap_bytes_offXX
#undef grub_swap_bytes_XwordXX
#undef grub_elfXX_check_endianess_and_bswap_ehdr
/* 64-bit */ /* 64-bit */
@@ -153,6 +202,11 @@ grub_elf_open (const char *name)
#define grub_elf_is_elfXX grub_elf_is_elf64 #define grub_elf_is_elfXX grub_elf_is_elf64
#define grub_elfXX_load_phdrs grub_elf64_load_phdrs #define grub_elfXX_load_phdrs grub_elf64_load_phdrs
#define ElfXX_Phdr Elf64_Phdr #define ElfXX_Phdr Elf64_Phdr
#define ElfXX_Ehdr Elf64_Ehdr
#define grub_uintXX_t grub_uint64_t #define grub_uintXX_t grub_uint64_t
#define grub_swap_bytes_addrXX grub_swap_bytes64
#define grub_swap_bytes_offXX grub_swap_bytes64
#define grub_swap_bytes_XwordXX grub_swap_bytes64
#define grub_elfXX_check_endianess_and_bswap_ehdr grub_elf64_check_endianess_and_bswap_ehdr
#include "elfXX.c" #include "elfXX.c"
+52 -1
View File
@@ -12,7 +12,7 @@ grub_elfXX_load_phdrs (grub_elf_t elf)
if (elf->phdrs) if (elf->phdrs)
return GRUB_ERR_NONE; 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", grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
(unsigned long long) elf->ehdr.ehdrXX.e_phoff, (unsigned long long) elf->ehdr.ehdrXX.e_phoff,
@@ -31,6 +31,25 @@ grub_elfXX_load_phdrs (grub_elf_t elf)
return grub_errno; return grub_errno;
} }
#if GRUB_ELF_ENABLE_BI_ENDIAN
if (elf->ehdr.ehdrXX.e_ident[EI_DATA] == GRUB_ELF_OPPOSITE_ENDIANNESS)
{
ElfXX_Phdr *phdr;
for (phdr = elf->phdrs; (char *) phdr < (char *) elf->phdrs + phdrs_size;
phdr = (ElfXX_Phdr *) ((char *) phdr + elf->ehdr.ehdrXX.e_phentsize))
{
phdr->p_type = grub_swap_bytes_wordXX (phdr->p_type);
phdr->p_flags = grub_swap_bytes_wordXX (phdr->p_flags);
phdr->p_offset = grub_swap_bytes_offXX (phdr->p_offset);
phdr->p_vaddr = grub_swap_bytes_addrXX (phdr->p_vaddr);
phdr->p_paddr = grub_swap_bytes_addrXX (phdr->p_paddr);
phdr->p_filesz = grub_swap_bytes_XwordXX (phdr->p_filesz);
phdr->p_memsz = grub_swap_bytes_XwordXX (phdr->p_memsz);
phdr->p_align = grub_swap_bytes_XwordXX (phdr->p_align);
}
}
#endif /* GRUB_ELF_ENABLE_BI_ENDIAN */
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -154,3 +173,35 @@ grub_elfXX_load (grub_elf_t elf, const char *filename,
return grub_errno; return grub_errno;
} }
static int
grub_elfXX_check_endianess_and_bswap_ehdr (grub_elf_t elf)
{
ElfXX_Ehdr *e = &(elf->ehdr.ehdrXX);
if (e->e_ident[EI_DATA] == GRUB_ELF_NATIVE_ENDIANNESS)
{
return 1;
}
#if GRUB_ELF_ENABLE_BI_ENDIAN
if (e->e_ident[EI_DATA] == GRUB_ELF_OPPOSITE_ENDIANNESS)
{
e->e_type = grub_swap_bytes_halfXX (e->e_type);
e->e_machine = grub_swap_bytes_halfXX (e->e_machine);
e->e_version = grub_swap_bytes_wordXX (e->e_version);
e->e_entry = grub_swap_bytes_addrXX (e->e_entry);
e->e_phoff = grub_swap_bytes_offXX (e->e_phoff);
e->e_shoff = grub_swap_bytes_offXX (e->e_shoff);
e->e_flags = grub_swap_bytes_wordXX (e->e_flags);
e->e_ehsize = grub_swap_bytes_halfXX (e->e_ehsize);
e->e_phentsize = grub_swap_bytes_halfXX (e->e_phentsize);
e->e_phnum = grub_swap_bytes_halfXX (e->e_phnum);
e->e_shentsize = grub_swap_bytes_halfXX (e->e_shentsize);
e->e_shnum = grub_swap_bytes_halfXX (e->e_shnum);
e->e_shstrndx = grub_swap_bytes_halfXX (e->e_shstrndx);
return 1;
}
#endif /* GRUB_ELF_ENABLE_BI_ENDIAN */
return 0;
}
+5 -5
View File
@@ -161,9 +161,9 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
{ {
struct stat st; struct stat st;
# if GRUB_DISK_DEVS_ARE_CHAR # 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 # else
if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) if (fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode))
# endif # endif
data->is_disk = 1; data->is_disk = 1;
} }
@@ -184,7 +184,7 @@ grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add)
unsigned int i; unsigned int i;
char *canon; char *canon;
canon = canonicalize_file_name (os_disk); canon = grub_canonicalize_file_name (os_disk);
if (!canon) if (!canon)
canon = xstrdup (os_disk); canon = xstrdup (os_disk);
@@ -422,7 +422,7 @@ read_device_map (const char *dev_map)
char buf[1024]; /* XXX */ char buf[1024]; /* XXX */
int lineno = 0; int lineno = 0;
if (dev_map[0] == '\0') if (!dev_map || dev_map[0] == '\0')
{ {
grub_util_info ("no device.map"); grub_util_info ("no device.map");
return; return;
@@ -535,7 +535,7 @@ read_device_map (const char *dev_map)
/* On Linux, the devfs uses symbolic links horribly, and that /* On Linux, the devfs uses symbolic links horribly, and that
confuses the interface very much, so use realpath to expand confuses the interface very much, so use realpath to expand
symbolic links. */ symbolic links. */
map[drive].device = canonicalize_file_name (p); map[drive].device = grub_canonicalize_file_name (p);
if (! map[drive].device) if (! map[drive].device)
map[drive].device = xstrdup (p); map[drive].device = xstrdup (p);
-5
View File
@@ -19,11 +19,6 @@
#include <config-util.h> #include <config-util.h>
/* Legacy feature macro.*/
#define _BSD_SOURCE
/* New feature macro that provides everything _BSD_SOURCE and
* _SVID_SOURCE provided and possibly more. */
#define _DEFAULT_SOURCE
#include <grub/fs.h> #include <grub/fs.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/disk.h> #include <grub/disk.h>
+47 -1
View File
@@ -65,6 +65,12 @@ grub_reboot (void)
longjmp (main_env, 1); longjmp (main_env, 1);
} }
void
grub_exit (void)
{
grub_reboot ();
}
void void
grub_machine_init (void) grub_machine_init (void)
{ {
@@ -86,11 +92,16 @@ grub_machine_fini (int flags)
#define OPT_MEMDISK 257
static struct argp_option options[] = { static struct argp_option options[] = {
{"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2},
{"device-map", 'm', N_("FILE"), 0, {"device-map", 'm', N_("FILE"), 0,
/* TRANSLATORS: There are many devices in device map. */ /* TRANSLATORS: There are many devices in device map. */
N_("use FILE as the device map [default=%s]"), 0}, 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, {"directory", 'd', N_("DIR"), 0,
N_("use GRUB files in the directory DIR [default=%s]"), 0}, N_("use GRUB files in the directory DIR [default=%s]"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 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 struct arguments
{ {
const char *dev_map; const char *dev_map;
const char *mem_disk;
int hold; int hold;
}; };
@@ -131,6 +143,9 @@ argp_parser (int key, char *arg, struct argp_state *state)
switch (key) switch (key)
{ {
case OPT_MEMDISK:
arguments->mem_disk = arg;
break;
case 'r': case 'r':
free (root_dev); free (root_dev);
root_dev = xstrdup (arg); root_dev = xstrdup (arg);
@@ -180,9 +195,13 @@ main (int argc, char *argv[])
struct arguments arguments = struct arguments arguments =
{ {
.dev_map = DEFAULT_DEVICE_MAP, .dev_map = DEFAULT_DEVICE_MAP,
.hold = 0 .hold = 0,
.mem_disk = 0,
}; };
volatile int hold = 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); grub_util_host_init (&argc, &argv);
@@ -194,6 +213,33 @@ main (int argc, char *argv[])
exit(1); 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; hold = arguments.hold;
/* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
if (hold && verbosity > 0) if (hold && verbosity > 0)
+50
View File
@@ -134,11 +134,13 @@ xasprintf (const char *fmt, ...)
} }
#endif #endif
#if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
void void
grub_exit (void) grub_exit (void)
{ {
exit (1); exit (1);
} }
#endif
grub_uint64_t grub_uint64_t
grub_get_time_ms (void) grub_get_time_ms (void)
@@ -149,3 +151,51 @@ grub_get_time_ms (void)
return (tv.tv_sec * 1000 + tv.tv_usec / 1000); 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);
}
+10 -1
View File
@@ -89,7 +89,16 @@ grub_file_open (const char *name)
file->device = device; file->device = device;
if (device->disk && file_name[0] != '/') /* In case of relative pathnames and non-Unix systems (like Windows)
* name of host files may not start with `/'. Blocklists for host files
* are meaningless as well (for a start, host disk does not allow any direct
* access - it is just a marker). So skip host disk in this case.
*/
if (device->disk && file_name[0] != '/'
#if defined(GRUB_UTIL) || defined(GRUB_MACHINE_EMU)
&& grub_strcmp (device->disk->name, "host")
#endif
)
/* This is a block list. */ /* This is a block list. */
file->fs = &grub_fs_blocklist; file->fs = &grub_fs_blocklist;
else else
+40
View File
@@ -0,0 +1,40 @@
/* kern/i386/tsc.c - x86 TSC time source implementation
* Requires Pentium or better x86 CPU that supports the RDTSC instruction.
* This module uses the PIT to calibrate the TSC to
* real time.
*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/i386/tsc.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
int
grub_tsc_calibrate_from_efi (void)
{
grub_uint64_t start_tsc, end_tsc;
/* Use EFI Time Service to calibrate TSC */
start_tsc = grub_get_tsc ();
efi_call_1 (grub_efi_system_table->boot_services->stall, 1000);
end_tsc = grub_get_tsc ();
grub_tsc_rate = grub_divmod64 ((1ULL << 32), end_tsc - start_tsc, 0);
return 1;
}
+11
View File
@@ -44,6 +44,13 @@ FUNCTION(grub_bios_interrupt)
movl 24(%edx), %esi movl 24(%edx), %esi
movl 28(%edx), %edx 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 PROT_TO_REAL
.code16 .code16
pushf pushf
@@ -92,6 +99,10 @@ intno:
movw %ax, LOCAL(bios_register_es) movw %ax, LOCAL(bios_register_es)
popf popf
VARIABLE(grub_bios_via_workaround2)
.byte 0x90, 0x90
REAL_TO_PROT REAL_TO_PROT
.code32 .code32
@@ -29,14 +29,15 @@ grub_machine_acpi_get_rsdpv1 (void)
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
ebda_len = * (grub_uint16_t *) ebda; ebda_len = * (grub_uint16_t *) ebda;
if (! ebda_len) if (! ebda_len) /* FIXME do we really need this check? */
return 0; goto scan_bios;
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0) && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
return (struct grub_acpi_rsdp_v10 *) ptr; return (struct grub_acpi_rsdp_v10 *) ptr;
scan_bios:
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16) ptr += 16)
@@ -56,8 +57,8 @@ grub_machine_acpi_get_rsdpv2 (void)
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
ebda_len = * (grub_uint16_t *) ebda; ebda_len = * (grub_uint16_t *) ebda;
if (! ebda_len) if (! ebda_len) /* FIXME do we really need this check? */
return 0; goto scan_bios;
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
@@ -67,6 +68,7 @@ grub_machine_acpi_get_rsdpv2 (void)
== 0) == 0)
return (struct grub_acpi_rsdp_v20 *) ptr; return (struct grub_acpi_rsdp_v20 *) ptr;
scan_bios:
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16) ptr += 16)
+24
View File
@@ -32,6 +32,7 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/cache.h> #include <grub/cache.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/cpu/cpuid.h>
#include <grub/cpu/tsc.h> #include <grub/cpu/tsc.h>
#include <grub/machine/time.h> #include <grub/machine/time.h>
@@ -184,6 +185,26 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
return 0; 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 void
grub_machine_init (void) grub_machine_init (void)
{ {
@@ -193,6 +214,9 @@ grub_machine_init (void)
#endif #endif
grub_addr_t modend; 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); grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
/* Initialize the console as early as possible. */ /* Initialize the console as early as possible. */
Loaded 100 of 314 files, more files were not shown because too many files have changed in this diff. Show more