merge mainline into net
This commit is contained in:
commit
bd67ad0f70
335 changed files with 22289 additions and 5940 deletions
|
@ -48,6 +48,7 @@ grub-kbdcomp
|
||||||
grub-macho2img
|
grub-macho2img
|
||||||
grub-menulst2cfg
|
grub-menulst2cfg
|
||||||
grub-mk*
|
grub-mk*
|
||||||
|
grub-mount
|
||||||
grub-pe2elf
|
grub-pe2elf
|
||||||
grub-probe
|
grub-probe
|
||||||
grub_probe_init.c
|
grub_probe_init.c
|
||||||
|
|
|
@ -33,6 +33,8 @@ library = {
|
||||||
|
|
||||||
library = {
|
library = {
|
||||||
name = libgrubmods.a;
|
name = libgrubmods.a;
|
||||||
|
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||||
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(top_srcdir)/grub-core/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
|
||||||
|
|
||||||
common_nodist = grub_script.tab.c;
|
common_nodist = grub_script.tab.c;
|
||||||
common_nodist = grub_script.yy.c;
|
common_nodist = grub_script.yy.c;
|
||||||
|
@ -41,6 +43,7 @@ library = {
|
||||||
common_nodist = grub_script.tab.h;
|
common_nodist = grub_script.tab.h;
|
||||||
|
|
||||||
common = grub-core/commands/blocklist.c;
|
common = grub-core/commands/blocklist.c;
|
||||||
|
common = grub-core/commands/xnu_uuid.c;
|
||||||
common = grub-core/commands/testload.c;
|
common = grub-core/commands/testload.c;
|
||||||
common = grub-core/commands/ls.c;
|
common = grub-core/commands/ls.c;
|
||||||
common = grub-core/disk/dmraid_nvidia.c;
|
common = grub-core/disk/dmraid_nvidia.c;
|
||||||
|
@ -52,14 +55,13 @@ library = {
|
||||||
common = grub-core/disk/raid6_recover.c;
|
common = grub-core/disk/raid6_recover.c;
|
||||||
common = grub-core/disk/raid.c;
|
common = grub-core/disk/raid.c;
|
||||||
common = grub-core/fs/affs.c;
|
common = grub-core/fs/affs.c;
|
||||||
common = grub-core/fs/afs_be.c;
|
|
||||||
common = grub-core/fs/afs.c;
|
common = grub-core/fs/afs.c;
|
||||||
common = grub-core/fs/befs_be.c;
|
common = grub-core/fs/bfs.c;
|
||||||
common = grub-core/fs/befs.c;
|
|
||||||
common = grub-core/fs/btrfs.c;
|
common = grub-core/fs/btrfs.c;
|
||||||
common = grub-core/fs/cpio.c;
|
common = grub-core/fs/cpio.c;
|
||||||
common = grub-core/fs/ext2.c;
|
common = grub-core/fs/ext2.c;
|
||||||
common = grub-core/fs/fat.c;
|
common = grub-core/fs/fat.c;
|
||||||
|
common = grub-core/fs/exfat.c;
|
||||||
common = grub-core/fs/fshelp.c;
|
common = grub-core/fs/fshelp.c;
|
||||||
common = grub-core/fs/hfs.c;
|
common = grub-core/fs/hfs.c;
|
||||||
common = grub-core/fs/hfsplus.c;
|
common = grub-core/fs/hfsplus.c;
|
||||||
|
@ -80,7 +82,9 @@ library = {
|
||||||
common = grub-core/fs/ufs2.c;
|
common = grub-core/fs/ufs2.c;
|
||||||
common = grub-core/fs/ufs.c;
|
common = grub-core/fs/ufs.c;
|
||||||
common = grub-core/fs/xfs.c;
|
common = grub-core/fs/xfs.c;
|
||||||
|
common = grub-core/fs/zfs/zfscrypt.c;
|
||||||
common = grub-core/fs/zfs/zfs.c;
|
common = grub-core/fs/zfs/zfs.c;
|
||||||
|
common = grub-core/fs/zfs/zfsinfo.c;
|
||||||
common = grub-core/fs/zfs/zfs_lzjb.c;
|
common = grub-core/fs/zfs/zfs_lzjb.c;
|
||||||
common = grub-core/fs/zfs/zfs_sha256.c;
|
common = grub-core/fs/zfs/zfs_sha256.c;
|
||||||
common = grub-core/fs/zfs/zfs_fletcher.c;
|
common = grub-core/fs/zfs/zfs_fletcher.c;
|
||||||
|
@ -89,6 +93,8 @@ library = {
|
||||||
common = grub-core/lib/LzFind.c;
|
common = grub-core/lib/LzFind.c;
|
||||||
common = grub-core/lib/LzmaEnc.c;
|
common = grub-core/lib/LzmaEnc.c;
|
||||||
common = grub-core/lib/crc.c;
|
common = grub-core/lib/crc.c;
|
||||||
|
common = grub-core/lib/adler32.c;
|
||||||
|
common = grub-core/lib/crc64.c;
|
||||||
common = grub-core/normal/datetime.c;
|
common = grub-core/normal/datetime.c;
|
||||||
common = grub-core/normal/misc.c;
|
common = grub-core/normal/misc.c;
|
||||||
common = grub-core/partmap/acorn.c;
|
common = grub-core/partmap/acorn.c;
|
||||||
|
@ -97,6 +103,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/partmap/sun.c;
|
common = grub-core/partmap/sun.c;
|
||||||
|
common = grub-core/partmap/plan.c;
|
||||||
common = grub-core/partmap/dvh.c;
|
common = grub-core/partmap/dvh.c;
|
||||||
common = grub-core/partmap/sunpc.c;
|
common = grub-core/partmap/sunpc.c;
|
||||||
common = grub-core/partmap/bsdlabel.c;
|
common = grub-core/partmap/bsdlabel.c;
|
||||||
|
@ -106,7 +113,9 @@ library = {
|
||||||
common = grub-core/script/script.c;
|
common = grub-core/script/script.c;
|
||||||
common = grub-core/script/argv.c;
|
common = grub-core/script/argv.c;
|
||||||
common = grub-core/io/gzio.c;
|
common = grub-core/io/gzio.c;
|
||||||
|
common = grub-core/io/lzopio.c;
|
||||||
common = grub-core/kern/ia64/dl_helper.c;
|
common = grub-core/kern/ia64/dl_helper.c;
|
||||||
|
common = grub-core/lib/minilzo/minilzo.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -229,6 +238,22 @@ program = {
|
||||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
program = {
|
||||||
|
name = grub-mount;
|
||||||
|
mansection = 1;
|
||||||
|
common_nodist = grub_fstest_init.c;
|
||||||
|
common = util/grub-mount.c;
|
||||||
|
common = grub-core/kern/emu/hostfs.c;
|
||||||
|
common = grub-core/disk/host.c;
|
||||||
|
|
||||||
|
ldadd = libgrubmods.a;
|
||||||
|
ldadd = libgrubgcry.a;
|
||||||
|
ldadd = libgrubkern.a;
|
||||||
|
ldadd = grub-core/gnulib/libgnu.a;
|
||||||
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse';
|
||||||
|
condition = COND_GRUB_MOUNT;
|
||||||
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
name = grub-mkfont;
|
name = grub-mkfont;
|
||||||
mansection = 1;
|
mansection = 1;
|
||||||
|
@ -359,6 +384,13 @@ script = {
|
||||||
condition = COND_HOST_KFREEBSD;
|
condition = COND_HOST_KFREEBSD;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script = {
|
||||||
|
name = '10_illumos';
|
||||||
|
common = util/grub.d/10_illumos.in;
|
||||||
|
installdir = grubconf;
|
||||||
|
condition = COND_HOST_ILLUMOS;
|
||||||
|
};
|
||||||
|
|
||||||
script = {
|
script = {
|
||||||
name = '10_netbsd';
|
name = '10_netbsd';
|
||||||
common = util/grub.d/10_netbsd.in;
|
common = util/grub.d/10_netbsd.in;
|
||||||
|
@ -645,6 +677,21 @@ program = {
|
||||||
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
program = {
|
||||||
|
testcase;
|
||||||
|
name = printf_test;
|
||||||
|
common = tests/printf_unit_test.c;
|
||||||
|
common = tests/lib/unit_test.c;
|
||||||
|
common = grub-core/kern/list.c;
|
||||||
|
common = grub-core/kern/misc.c;
|
||||||
|
common = grub-core/tests/lib/test.c;
|
||||||
|
ldadd = libgrubmods.a;
|
||||||
|
ldadd = libgrubgcry.a;
|
||||||
|
ldadd = libgrubkern.a;
|
||||||
|
ldadd = grub-core/gnulib/libgnu.a;
|
||||||
|
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
name = grub-menulst2cfg;
|
name = grub-menulst2cfg;
|
||||||
mansection = 1;
|
mansection = 1;
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
/* 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@
|
||||||
|
|
||||||
|
#define RE_ENABLE_I18N 1
|
||||||
|
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
|
#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
|
||||||
#else
|
#else
|
||||||
|
|
60
configure.ac
60
configure.ac
|
@ -154,6 +154,7 @@ case "$host_os" in
|
||||||
linux*) host_kernel=linux ;;
|
linux*) host_kernel=linux ;;
|
||||||
freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;;
|
freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;;
|
||||||
netbsd*) host_kernel=netbsd ;;
|
netbsd*) host_kernel=netbsd ;;
|
||||||
|
solaris*) host_kernel=illumos ;;
|
||||||
cygwin) host_kernel=windows ;;
|
cygwin) host_kernel=windows ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -412,6 +413,23 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# By default, GCC 4.6 generates .eh_frame sections containing unwind
|
||||||
|
# information in some cases where it previously did not. GRUB doesn't need
|
||||||
|
# these and they just use up vital space. Restore the old compiler
|
||||||
|
# behaviour.
|
||||||
|
AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [
|
||||||
|
SAVE_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||||
|
[grub_cv_cc_fno_asynchronous_unwind_tables=yes],
|
||||||
|
[grub_cv_cc_fno_asynchronous_unwind_tables=no])
|
||||||
|
CFLAGS="$SAVE_CFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
|
||||||
|
fi
|
||||||
|
|
||||||
grub_apple_target_cc
|
grub_apple_target_cc
|
||||||
if test x$grub_cv_apple_target_cc = xyes ; then
|
if test x$grub_cv_apple_target_cc = xyes ; then
|
||||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1"
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1"
|
||||||
|
@ -463,6 +481,7 @@ if test "x$target_m32" = x1; then
|
||||||
# Force 32-bit mode.
|
# Force 32-bit mode.
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -m32"
|
TARGET_CFLAGS="$TARGET_CFLAGS -m32"
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
|
||||||
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32"
|
||||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
|
TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
|
||||||
TARGET_MODULE_FORMAT="elf32"
|
TARGET_MODULE_FORMAT="elf32"
|
||||||
fi
|
fi
|
||||||
|
@ -471,6 +490,7 @@ if test "x$target_m64" = x1; then
|
||||||
# Force 64-bit mode.
|
# Force 64-bit mode.
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -m64"
|
TARGET_CFLAGS="$TARGET_CFLAGS -m64"
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
|
||||||
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64"
|
||||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
|
TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
|
||||||
TARGET_MODULE_FORMAT="elf64"
|
TARGET_MODULE_FORMAT="elf64"
|
||||||
fi
|
fi
|
||||||
|
@ -587,7 +607,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for libgcc symbols
|
# Check for libgcc symbols
|
||||||
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3)
|
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2)
|
||||||
|
|
||||||
if test "x$TARGET_APPLE_CC" = x1 ; then
|
if test "x$TARGET_APPLE_CC" = x1 ; then
|
||||||
CFLAGS="$TARGET_CFLAGS -nostdlib"
|
CFLAGS="$TARGET_CFLAGS -nostdlib"
|
||||||
|
@ -867,6 +887,37 @@ AC_SUBST([enable_grub_mkfont])
|
||||||
AC_SUBST([freetype_cflags])
|
AC_SUBST([freetype_cflags])
|
||||||
AC_SUBST([freetype_libs])
|
AC_SUBST([freetype_libs])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([grub-mount],
|
||||||
|
[AS_HELP_STRING([--enable-grub-mount],
|
||||||
|
[build and install the `grub-mount' utility (default=guessed)])])
|
||||||
|
if test x"$enable_grub_mount" = xno ; then
|
||||||
|
grub_mount_excuse="explicitly disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$grub_mount_excuse" = x ; then
|
||||||
|
AC_CHECK_LIB([fuse], [fuse_main_real], [],
|
||||||
|
[grub_mount_excuse="need FUSE library"])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$grub_mount_excuse" = x ; then
|
||||||
|
# Check for fuse headers.
|
||||||
|
SAVED_CPPFLAGS="$CPPFLAGS"
|
||||||
|
CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26"
|
||||||
|
AC_CHECK_HEADERS([fuse/fuse.h], [],
|
||||||
|
[grub_mount_excuse=["need FUSE headers"]])
|
||||||
|
CPPFLAGS="$SAVED_CPPFLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then
|
||||||
|
AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled])
|
||||||
|
fi
|
||||||
|
if test x"$grub_mount_excuse" = x ; then
|
||||||
|
enable_grub_mount=yes
|
||||||
|
else
|
||||||
|
enable_grub_mount=no
|
||||||
|
fi
|
||||||
|
AC_SUBST([enable_grub_mount])
|
||||||
|
|
||||||
AC_ARG_ENABLE([device-mapper],
|
AC_ARG_ENABLE([device-mapper],
|
||||||
[AS_HELP_STRING([--enable-device-mapper],
|
[AS_HELP_STRING([--enable-device-mapper],
|
||||||
[enable Linux device-mapper support (default=guessed)])])
|
[enable Linux device-mapper support (default=guessed)])])
|
||||||
|
@ -974,12 +1025,14 @@ AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
|
||||||
AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd])
|
AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd])
|
||||||
AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows])
|
AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows])
|
||||||
AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd])
|
AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd])
|
||||||
|
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_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])
|
||||||
|
AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
|
||||||
AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
|
AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
|
||||||
AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x])
|
AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x])
|
||||||
AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
|
AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
|
||||||
|
@ -1066,5 +1119,10 @@ echo grub-mkfont: Yes
|
||||||
else
|
else
|
||||||
echo grub-mkfont: No "($grub_mkfont_excuse)"
|
echo grub-mkfont: No "($grub_mkfont_excuse)"
|
||||||
fi
|
fi
|
||||||
|
if [ x"$grub_mount_excuse" = x ]; then
|
||||||
|
echo grub-mount: Yes
|
||||||
|
else
|
||||||
|
echo grub-mount: No "($grub_mount_excuse)"
|
||||||
|
fi
|
||||||
echo "*******************************************************"
|
echo "*******************************************************"
|
||||||
]
|
]
|
||||||
|
|
|
@ -3943,6 +3943,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab BIOS @tab Coreboot
|
@item @tab BIOS @tab Coreboot
|
||||||
@item BIOS chainloading @tab yes @tab no (1)
|
@item BIOS chainloading @tab yes @tab no (1)
|
||||||
@item NTLDR @tab yes @tab no (1)
|
@item NTLDR @tab yes @tab no (1)
|
||||||
|
@item Plan9 @tab yes @tab no (1)
|
||||||
@item Freedos @tab yes @tab no (1)
|
@item Freedos @tab yes @tab no (1)
|
||||||
@item FreeBSD bootloader @tab yes @tab crashes (1)
|
@item FreeBSD bootloader @tab yes @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
|
@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
|
||||||
|
@ -3968,6 +3969,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab Multiboot @tab Qemu
|
@item @tab Multiboot @tab Qemu
|
||||||
@item BIOS chainloading @tab no (1) @tab no (1)
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
@item NTLDR @tab no (1) @tab no (1)
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item Plan9 @tab no (1) @tab no (1)
|
||||||
@item FreeDOS @tab no (1) @tab no (1)
|
@item FreeDOS @tab no (1) @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
||||||
|
@ -3993,6 +3995,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab 32-bit EFI @tab 64-bit EFI
|
@item @tab 32-bit EFI @tab 64-bit EFI
|
||||||
@item BIOS chainloading @tab no (1) @tab no (1)
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
@item NTLDR @tab no (1) @tab no (1)
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item Plan9 @tab no (1) @tab no (1)
|
||||||
@item FreeDOS @tab no (1) @tab no (1)
|
@item FreeDOS @tab no (1) @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab headless @tab headless
|
@item 32-bit kFreeBSD @tab headless @tab headless
|
||||||
|
@ -4018,6 +4021,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab IEEE1275
|
@item @tab IEEE1275
|
||||||
@item BIOS chainloading @tab no (1)
|
@item BIOS chainloading @tab no (1)
|
||||||
@item NTLDR @tab no (1)
|
@item NTLDR @tab no (1)
|
||||||
|
@item Plan9 @tab no (1)
|
||||||
@item FreeDOS @tab no (1)
|
@item FreeDOS @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab crashes (6)
|
@item 32-bit kFreeBSD @tab crashes (6)
|
||||||
|
|
2
docs/man/grub-mount.h2m
Normal file
2
docs/man/grub-mount.h2m
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[NAME]
|
||||||
|
grub-mount \- export GRUB filesystem with FUSE
|
40
gentpl.py
40
gentpl.py
|
@ -568,28 +568,28 @@ f = script_rules()
|
||||||
g = data_rules()
|
g = data_rules()
|
||||||
z = global_variable_initializers()
|
z = global_variable_initializers()
|
||||||
|
|
||||||
print "[+ AutoGen5 template +]\n"
|
print ("[+ AutoGen5 template +]\n")
|
||||||
for p in GRUB_PLATFORMS:
|
for p in GRUB_PLATFORMS:
|
||||||
print define_macro_for_platform_sources(p)
|
print (define_macro_for_platform_sources(p))
|
||||||
print define_macro_for_platform_nodist_sources(p)
|
print (define_macro_for_platform_nodist_sources(p))
|
||||||
# print define_macro_for_platform_dependencies(p)
|
# print define_macro_for_platform_dependencies(p)
|
||||||
|
|
||||||
print define_macro_for_platform_startup(p)
|
print (define_macro_for_platform_startup(p))
|
||||||
print define_macro_for_platform_cflags(p)
|
print (define_macro_for_platform_cflags(p))
|
||||||
print define_macro_for_platform_ldadd(p)
|
print (define_macro_for_platform_ldadd(p))
|
||||||
print define_macro_for_platform_ldflags(p)
|
print (define_macro_for_platform_ldflags(p))
|
||||||
print define_macro_for_platform_cppflags(p)
|
print (define_macro_for_platform_cppflags(p))
|
||||||
print define_macro_for_platform_ccasflags(p)
|
print (define_macro_for_platform_ccasflags(p))
|
||||||
print define_macro_for_platform_stripflags(p)
|
print (define_macro_for_platform_stripflags(p))
|
||||||
print define_macro_for_platform_objcopyflags(p)
|
print (define_macro_for_platform_objcopyflags(p))
|
||||||
|
|
||||||
print define_macro_for_platform_conditionals_if_statement(p)
|
print (define_macro_for_platform_conditionals_if_statement(p))
|
||||||
print define_macro_for_platform_conditionals_endif_statement(p)
|
print (define_macro_for_platform_conditionals_endif_statement(p))
|
||||||
# print z # initializer for all vars
|
# print z # initializer for all vars
|
||||||
print a
|
print (a)
|
||||||
print b
|
print (b)
|
||||||
print c
|
print (c)
|
||||||
print d
|
print (d)
|
||||||
print e
|
print (e)
|
||||||
print f
|
print (f)
|
||||||
print g
|
print (g)
|
||||||
|
|
|
@ -78,13 +78,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
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/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||||
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
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
||||||
|
|
|
@ -18,6 +18,18 @@ script = {
|
||||||
common = modinfo.sh.in;
|
common = modinfo.sh.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script = {
|
||||||
|
installdir = noinst;
|
||||||
|
name = gmodule.pl;
|
||||||
|
common = gmodule.pl.in;
|
||||||
|
};
|
||||||
|
|
||||||
|
script = {
|
||||||
|
installdir = noinst;
|
||||||
|
name = gdb_grub;
|
||||||
|
common = gdb_grub.in;
|
||||||
|
};
|
||||||
|
|
||||||
kernel = {
|
kernel = {
|
||||||
name = kernel;
|
name = kernel;
|
||||||
|
|
||||||
|
@ -34,7 +46,7 @@ kernel = {
|
||||||
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
||||||
|
|
||||||
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
||||||
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
|
||||||
|
|
||||||
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
||||||
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
||||||
|
@ -356,6 +368,15 @@ image = {
|
||||||
enable = mips;
|
enable = mips;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
image = {
|
||||||
|
name = lzma_decompress;
|
||||||
|
i386_pc = boot/i386/pc/startup_raw.S;
|
||||||
|
|
||||||
|
objcopyflags = '-O binary';
|
||||||
|
ldflags = '-Wl,-Ttext,0x8200';
|
||||||
|
enable = i386_pc;
|
||||||
|
};
|
||||||
|
|
||||||
image = {
|
image = {
|
||||||
name = fwstart;
|
name = fwstart;
|
||||||
mips_loongson = boot/mips/loongson/fwstart.S;
|
mips_loongson = boot/mips/loongson/fwstart.S;
|
||||||
|
@ -633,6 +654,20 @@ module = {
|
||||||
emu = lib/emu/halt.c;
|
emu = lib/emu/halt.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = reboot;
|
||||||
|
i386 = lib/i386/reboot.c;
|
||||||
|
i386 = lib/i386/reboot_trampoline.S;
|
||||||
|
ia64_efi = lib/efi/reboot.c;
|
||||||
|
x86_64_efi = lib/efi/reboot.c;
|
||||||
|
powerpc_ieee1275 = lib/ieee1275/reboot.c;
|
||||||
|
sparc64_ieee1275 = lib/ieee1275/reboot.c;
|
||||||
|
mips_arc = lib/mips/arc/reboot.c;
|
||||||
|
mips_loongson = lib/mips/loongson/reboot.c;
|
||||||
|
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
|
||||||
|
common = commands/reboot.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = hashsum;
|
name = hashsum;
|
||||||
common = commands/hashsum.c;
|
common = commands/hashsum.c;
|
||||||
|
@ -733,11 +768,6 @@ module = {
|
||||||
common = commands/read.c;
|
common = commands/read.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
|
||||||
name = reboot;
|
|
||||||
common = commands/reboot.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = search;
|
name = search;
|
||||||
common = commands/search_wrap.c;
|
common = commands/search_wrap.c;
|
||||||
|
@ -967,24 +997,16 @@ module = {
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = afs_be;
|
name = bfs;
|
||||||
common = fs/afs_be.c;
|
common = fs/bfs.c;
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = befs;
|
|
||||||
common = fs/befs.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = befs_be;
|
|
||||||
common = fs/befs_be.c;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = btrfs;
|
name = btrfs;
|
||||||
common = fs/btrfs.c;
|
common = fs/btrfs.c;
|
||||||
common = lib/crc.c;
|
common = lib/crc.c;
|
||||||
|
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||||
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1002,6 +1024,11 @@ module = {
|
||||||
common = fs/fat.c;
|
common = fs/fat.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = exfat;
|
||||||
|
common = fs/exfat.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = fshelp;
|
name = fshelp;
|
||||||
common = fs/fshelp.c;
|
common = fs/fshelp.c;
|
||||||
|
@ -1110,6 +1137,11 @@ module = {
|
||||||
common = fs/zfs/zfs_fletcher.c;
|
common = fs/zfs/zfs_fletcher.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = zfscrypt;
|
||||||
|
common = fs/zfs/zfscrypt.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = zfsinfo;
|
name = zfsinfo;
|
||||||
common = fs/zfs/zfsinfo.c;
|
common = fs/zfs/zfsinfo.c;
|
||||||
|
@ -1245,6 +1277,13 @@ module = {
|
||||||
enable = x86;
|
enable = x86;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = plan9;
|
||||||
|
i386_pc = loader/i386/pc/plan9.c;
|
||||||
|
enable = i386_pc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = linux16;
|
name = linux16;
|
||||||
i386_pc = loader/i386/pc/linux.c;
|
i386_pc = loader/i386/pc/linux.c;
|
||||||
|
@ -1379,7 +1418,7 @@ module = {
|
||||||
extra_dist = script/yylex.l;
|
extra_dist = script/yylex.l;
|
||||||
extra_dist = script/parser.y;
|
extra_dist = script/parser.y;
|
||||||
|
|
||||||
cflags = '$(CFLAGS_POSIX) -Wno-error';
|
cflags = '$(CFLAGS_POSIX)';
|
||||||
cppflags = '$(CPPFLAGS_POSIX)';
|
cppflags = '$(CPPFLAGS_POSIX)';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1413,6 +1452,11 @@ module = {
|
||||||
common = partmap/sun.c;
|
common = partmap/sun.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = part_plan;
|
||||||
|
common = partmap/plan.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = part_dvh;
|
name = part_dvh;
|
||||||
common = partmap/dvh.c;
|
common = partmap/dvh.c;
|
||||||
|
@ -1661,6 +1705,14 @@ module = {
|
||||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = lzopio;
|
||||||
|
common = io/lzopio.c;
|
||||||
|
common = lib/minilzo/minilzo.c;
|
||||||
|
cflags = '$(CFLAGS_POSIX) -Wno-undef';
|
||||||
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H';
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = testload;
|
name = testload;
|
||||||
common = commands/testload.c;
|
common = commands/testload.c;
|
||||||
|
@ -1693,3 +1745,13 @@ module = {
|
||||||
common = commands/cacheinfo.c;
|
common = commands/cacheinfo.c;
|
||||||
condition = COND_ENABLE_CACHE_STATS;
|
condition = COND_ENABLE_CACHE_STATS;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = adler32;
|
||||||
|
common = lib/adler32.c;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = crc64;
|
||||||
|
common = lib/crc64.c;
|
||||||
|
};
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/boot.h>
|
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/boot.h>
|
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/boot.h>
|
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
@ -200,21 +199,12 @@ real_code_2:
|
||||||
|
|
||||||
1:
|
1:
|
||||||
|
|
||||||
movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
|
movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx
|
||||||
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
|
addl $((0x9000 - 0x8200) - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
|
||||||
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
|
|
||||||
#else
|
|
||||||
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
2:
|
2:
|
||||||
call LOCAL(move_memory)
|
call LOCAL(move_memory)
|
||||||
|
|
||||||
movsbl %dh, %eax
|
|
||||||
movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
|
|
||||||
movsbl (reg_edx + 2 - start), %eax
|
|
||||||
movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
|
|
||||||
|
|
||||||
movb $0xFF, %dh
|
movb $0xFF, %dh
|
||||||
|
|
||||||
ljmp $(DATA_ADDR >> 4), $0
|
ljmp $(DATA_ADDR >> 4), $0
|
||||||
|
|
348
grub-core/boot/i386/pc/startup_raw.S
Normal file
348
grub-core/boot/i386/pc/startup_raw.S
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 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/symbol.h>
|
||||||
|
#include <grub/offsets.h>
|
||||||
|
#include <grub/machine/boot.h>
|
||||||
|
#include <grub/machine/memory.h>
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
|
|
||||||
|
#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
|
||||||
|
|
||||||
|
.file "startup_raw.S"
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/* Tell GAS to generate 16-bit instructions so that this code works
|
||||||
|
in real mode. */
|
||||||
|
.code16
|
||||||
|
|
||||||
|
.globl start, _start
|
||||||
|
start:
|
||||||
|
_start:
|
||||||
|
LOCAL (base):
|
||||||
|
/*
|
||||||
|
* Guarantee that "main" is loaded at 0x0:0x8200.
|
||||||
|
*/
|
||||||
|
#ifdef __APPLE__
|
||||||
|
ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
|
||||||
|
#else
|
||||||
|
ljmp $0, $ABS(LOCAL (codestart))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a special data area.
|
||||||
|
*/
|
||||||
|
|
||||||
|
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||||
|
LOCAL(compressed_size):
|
||||||
|
.long 0
|
||||||
|
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||||
|
LOCAL(uncompressed_size):
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
. = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
|
||||||
|
reed_solomon_redundancy:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the area for all of the special variables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LOCAL(boot_dev):
|
||||||
|
.byte 0xFF, 0xFF, 0xFF
|
||||||
|
LOCAL(boot_drive):
|
||||||
|
.byte 0x00
|
||||||
|
|
||||||
|
/* the real mode code continues... */
|
||||||
|
LOCAL (codestart):
|
||||||
|
cli /* we're not safe here! */
|
||||||
|
|
||||||
|
/* set up %ds, %ss, and %es */
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %ss
|
||||||
|
movw %ax, %es
|
||||||
|
|
||||||
|
/* set up the real mode/BIOS stack */
|
||||||
|
movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
|
||||||
|
movl %ebp, %esp
|
||||||
|
|
||||||
|
sti /* we're safe again */
|
||||||
|
|
||||||
|
/* save the boot drive */
|
||||||
|
ADDR32 movb %dl, LOCAL(boot_drive)
|
||||||
|
|
||||||
|
/* reset disk system (%ah = 0) */
|
||||||
|
int $0x13
|
||||||
|
|
||||||
|
/* transition to protected mode */
|
||||||
|
DATA32 call real_to_prot
|
||||||
|
|
||||||
|
/* The ".code32" directive takes GAS out of 16-bit mode. */
|
||||||
|
.code32
|
||||||
|
|
||||||
|
incl %eax
|
||||||
|
cld
|
||||||
|
call grub_gate_a20
|
||||||
|
|
||||||
|
movl LOCAL(compressed_size), %edx
|
||||||
|
addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - _start), %edx
|
||||||
|
movl reed_solomon_redundancy, %ecx
|
||||||
|
leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
|
||||||
|
cld
|
||||||
|
call EXT_C (grub_reed_solomon_recover)
|
||||||
|
jmp post_reed_solomon
|
||||||
|
|
||||||
|
#include "../../../kern/i386/realmode.S"
|
||||||
|
|
||||||
|
#include <rs_decoder.S>
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
. = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART
|
||||||
|
/*
|
||||||
|
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
|
||||||
|
* This uses the a.out kludge to load raw binary to the area starting at 1MB,
|
||||||
|
* and relocates itself after loaded.
|
||||||
|
*/
|
||||||
|
.p2align 2 /* force 4-byte alignment */
|
||||||
|
multiboot_header:
|
||||||
|
/* magic */
|
||||||
|
.long 0x1BADB002
|
||||||
|
/* flags */
|
||||||
|
.long (1 << 16)
|
||||||
|
/* checksum */
|
||||||
|
.long -0x1BADB002 - (1 << 16)
|
||||||
|
/* header addr */
|
||||||
|
.long multiboot_header - _start + 0x100000 + 0x200
|
||||||
|
/* load addr */
|
||||||
|
.long 0x100000
|
||||||
|
/* load end addr */
|
||||||
|
.long 0
|
||||||
|
/* bss end addr */
|
||||||
|
.long 0
|
||||||
|
/* entry addr */
|
||||||
|
.long multiboot_entry - _start + 0x100000 + 0x200
|
||||||
|
|
||||||
|
multiboot_entry:
|
||||||
|
.code32
|
||||||
|
/* obtain the boot device */
|
||||||
|
movl 12(%ebx), %edx
|
||||||
|
|
||||||
|
movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
|
||||||
|
movl %ebp, %esp
|
||||||
|
|
||||||
|
/* relocate the code */
|
||||||
|
movl $(LOCAL(decompressor_end) + 0x200), %ecx
|
||||||
|
addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx
|
||||||
|
movl $0x100000, %esi
|
||||||
|
movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
/* jump to the real address */
|
||||||
|
movl $multiboot_trampoline, %eax
|
||||||
|
jmp *%eax
|
||||||
|
|
||||||
|
multiboot_trampoline:
|
||||||
|
/* fill the boot information */
|
||||||
|
movl %edx, LOCAL(boot_dev)
|
||||||
|
shrl $24, %edx
|
||||||
|
/* enter the usual booting */
|
||||||
|
call prot_to_real
|
||||||
|
.code16
|
||||||
|
jmp LOCAL (codestart)
|
||||||
|
.code32
|
||||||
|
|
||||||
|
post_reed_solomon:
|
||||||
|
|
||||||
|
#ifdef ENABLE_LZMA
|
||||||
|
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
|
||||||
|
movl $LOCAL(decompressor_end), %esi
|
||||||
|
pushl %edi
|
||||||
|
movl LOCAL (uncompressed_size), %ecx
|
||||||
|
leal (%edi, %ecx), %ebx
|
||||||
|
call _LzmaDecodeA
|
||||||
|
/* _LzmaDecodeA clears DF, so no need to run cld */
|
||||||
|
popl %esi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
movl LOCAL(boot_dev), %edx
|
||||||
|
movl $prot_to_real, %edi
|
||||||
|
movl $real_to_prot, %ecx
|
||||||
|
jmp *%esi
|
||||||
|
|
||||||
|
/*
|
||||||
|
* grub_gate_a20(int on)
|
||||||
|
*
|
||||||
|
* Gate address-line 20 for high memory.
|
||||||
|
*
|
||||||
|
* This routine is probably overconservative in what it does, but so what?
|
||||||
|
*
|
||||||
|
* It also eats any keystrokes in the keyboard buffer. :-(
|
||||||
|
*/
|
||||||
|
|
||||||
|
grub_gate_a20:
|
||||||
|
movl %eax, %edx
|
||||||
|
|
||||||
|
gate_a20_test_current_state:
|
||||||
|
/* first of all, test if already in a good state */
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
jnz gate_a20_try_bios
|
||||||
|
ret
|
||||||
|
|
||||||
|
gate_a20_try_bios:
|
||||||
|
/* second, try a BIOS call */
|
||||||
|
pushl %ebp
|
||||||
|
call prot_to_real
|
||||||
|
|
||||||
|
.code16
|
||||||
|
movw $0x2400, %ax
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 1f
|
||||||
|
incw %ax
|
||||||
|
1: int $0x15
|
||||||
|
|
||||||
|
DATA32 call real_to_prot
|
||||||
|
.code32
|
||||||
|
|
||||||
|
popl %ebp
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
jnz gate_a20_try_system_control_port_a
|
||||||
|
ret
|
||||||
|
|
||||||
|
gate_a20_try_system_control_port_a:
|
||||||
|
/*
|
||||||
|
* In macbook, the keyboard test would hang the machine, so we move
|
||||||
|
* this forward.
|
||||||
|
*/
|
||||||
|
/* fourth, try the system control port A */
|
||||||
|
inb $0x92
|
||||||
|
andb $(~0x03), %al
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 6f
|
||||||
|
orb $0x02, %al
|
||||||
|
6: outb $0x92
|
||||||
|
|
||||||
|
/* When turning off Gate A20, do not check the state strictly,
|
||||||
|
because a failure is not fatal usually, and Gate A20 is always
|
||||||
|
on some modern machines. */
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 7f
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
jnz gate_a20_try_keyboard_controller
|
||||||
|
7: ret
|
||||||
|
|
||||||
|
gate_a20_flush_keyboard_buffer:
|
||||||
|
inb $0x64
|
||||||
|
andb $0x02, %al
|
||||||
|
jnz gate_a20_flush_keyboard_buffer
|
||||||
|
2:
|
||||||
|
inb $0x64
|
||||||
|
andb $0x01, %al
|
||||||
|
jz 3f
|
||||||
|
inb $0x60
|
||||||
|
jmp 2b
|
||||||
|
3:
|
||||||
|
ret
|
||||||
|
|
||||||
|
gate_a20_try_keyboard_controller:
|
||||||
|
/* third, try the keyboard controller */
|
||||||
|
call gate_a20_flush_keyboard_buffer
|
||||||
|
|
||||||
|
movb $0xd1, %al
|
||||||
|
outb $0x64
|
||||||
|
4:
|
||||||
|
inb $0x64
|
||||||
|
andb $0x02, %al
|
||||||
|
jnz 4b
|
||||||
|
|
||||||
|
movb $0xdd, %al
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 5f
|
||||||
|
orb $0x02, %al
|
||||||
|
5: outb $0x60
|
||||||
|
call gate_a20_flush_keyboard_buffer
|
||||||
|
|
||||||
|
/* output a dummy command (USB keyboard hack) */
|
||||||
|
movb $0xff, %al
|
||||||
|
outb $0x64
|
||||||
|
call gate_a20_flush_keyboard_buffer
|
||||||
|
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
/* everything failed, so restart from the beginning */
|
||||||
|
jnz gate_a20_try_bios
|
||||||
|
ret
|
||||||
|
|
||||||
|
gate_a20_check_state:
|
||||||
|
/* iterate the checking for a while */
|
||||||
|
movl $100, %ecx
|
||||||
|
1:
|
||||||
|
call 3f
|
||||||
|
cmpb %al, %dl
|
||||||
|
jz 2f
|
||||||
|
loop 1b
|
||||||
|
2:
|
||||||
|
ret
|
||||||
|
3:
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
xorl %eax, %eax
|
||||||
|
/* compare the byte at 0x8000 with that at 0x108000 */
|
||||||
|
movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
|
||||||
|
pushl %ebx
|
||||||
|
/* save the original byte in CL */
|
||||||
|
movb (%ebx), %cl
|
||||||
|
/* store the value at 0x108000 in AL */
|
||||||
|
addl $0x100000, %ebx
|
||||||
|
movb (%ebx), %al
|
||||||
|
/* try to set one less value at 0x8000 */
|
||||||
|
popl %ebx
|
||||||
|
movb %al, %ch
|
||||||
|
decb %ch
|
||||||
|
movb %ch, (%ebx)
|
||||||
|
/* serialize */
|
||||||
|
outb %al, $0x80
|
||||||
|
outb %al, $0x80
|
||||||
|
/* obtain the value at 0x108000 in CH */
|
||||||
|
pushl %ebx
|
||||||
|
addl $0x100000, %ebx
|
||||||
|
movb (%ebx), %ch
|
||||||
|
/* this result is 1 if A20 is on or 0 if it is off */
|
||||||
|
subb %ch, %al
|
||||||
|
xorb $1, %al
|
||||||
|
/* restore the original */
|
||||||
|
popl %ebx
|
||||||
|
movb %cl, (%ebx)
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
#ifdef ENABLE_LZMA
|
||||||
|
#include "lzma_decode.S"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
|
||||||
|
LOCAL(decompressor_end):
|
|
@ -38,13 +38,13 @@ start:
|
||||||
bal codestart
|
bal codestart
|
||||||
nop
|
nop
|
||||||
base:
|
base:
|
||||||
. = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
|
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||||
compressed_size:
|
compressed_size:
|
||||||
.long 0
|
.long 0
|
||||||
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
|
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||||
uncompressed_size:
|
uncompressed_size:
|
||||||
.long 0
|
.long 0
|
||||||
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR
|
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
|
||||||
uncompressed_addr:
|
uncompressed_addr:
|
||||||
.long 0
|
.long 0
|
||||||
codestart:
|
codestart:
|
||||||
|
@ -240,9 +240,9 @@ cmdlinedone:
|
||||||
subu $a0, $a0, $t0
|
subu $a0, $a0, $t0
|
||||||
addu $a0, $a0, $s0
|
addu $a0, $a0, $s0
|
||||||
|
|
||||||
lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
|
lw $a1, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
|
||||||
lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
|
lw $a2, (GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||||
lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
|
lw $a3, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||||
move $s1, $a1
|
move $s1, $a1
|
||||||
|
|
||||||
/* $a0 contains source compressed address, $a1 is destination,
|
/* $a0 contains source compressed address, $a1 is destination,
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/boot.h>
|
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
@ -29,9 +28,6 @@ pic_base:
|
||||||
call boot_continue
|
call boot_continue
|
||||||
mov %o4, CIF_REG
|
mov %o4, CIF_REG
|
||||||
|
|
||||||
. = _start + GRUB_BOOT_MACHINE_VER_MAJ
|
|
||||||
boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
|
|
||||||
|
|
||||||
/* The offsets to these locations are defined by the
|
/* The offsets to these locations are defined by the
|
||||||
* GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
|
* GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
|
||||||
* and grub-setup uses this to patch these next three values as needed.
|
* and grub-setup uses this to patch these next three values as needed.
|
||||||
|
@ -44,6 +40,7 @@ boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
|
||||||
* After loading in that block we will execute it by jumping to the
|
* After loading in that block we will execute it by jumping to the
|
||||||
* load address plus the size of the prepended A.OUT header (32 bytes).
|
* load address plus the size of the prepended A.OUT header (32 bytes).
|
||||||
*/
|
*/
|
||||||
|
. = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH
|
||||||
boot_path:
|
boot_path:
|
||||||
. = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
|
. = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
|
||||||
boot_path_end:
|
boot_path_end:
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/boot.h>
|
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
|
|
|
@ -97,8 +97,6 @@ grub_cs5536_smbus_wait (grub_port_t smbbase)
|
||||||
if (grub_get_time_ms () > start + 40)
|
if (grub_get_time_ms () > start + 40)
|
||||||
return grub_error (GRUB_ERR_IO, "SM stalled");
|
return grub_error (GRUB_ERR_IO, "SM stalled");
|
||||||
}
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
|
|
|
@ -1152,8 +1152,8 @@ grub_ohci_check_transfer (grub_usb_controller_t dev,
|
||||||
return parse_halt (dev, transfer, actual);
|
return parse_halt (dev, transfer, actual);
|
||||||
|
|
||||||
/* Finished ED detection */
|
/* Finished ED detection */
|
||||||
if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) ==
|
if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xfU) ==
|
||||||
(grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */
|
(grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xfU) ) /* Empty ED */
|
||||||
{
|
{
|
||||||
/* Check the HALT bit */
|
/* Check the HALT bit */
|
||||||
/* It looks like nonsense - it was tested previously...
|
/* It looks like nonsense - it was tested previously...
|
||||||
|
@ -1426,7 +1426,7 @@ static struct grub_usb_controller_dev usb_controller =
|
||||||
.detect_dev = grub_ohci_detect_dev
|
.detect_dev = grub_ohci_detect_dev
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *fini_hnd;
|
static struct grub_preboot *fini_hnd;
|
||||||
|
|
||||||
GRUB_MOD_INIT(ohci)
|
GRUB_MOD_INIT(ohci)
|
||||||
{
|
{
|
||||||
|
|
|
@ -544,8 +544,11 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev,
|
||||||
{
|
{
|
||||||
grub_size_t actual = 0;
|
grub_size_t actual = 0;
|
||||||
/* Terminate and free. */
|
/* Terminate and free. */
|
||||||
td_prev->linkptr2 = 0;
|
if (td_prev)
|
||||||
td_prev->linkptr = 1;
|
{
|
||||||
|
td_prev->linkptr2 = 0;
|
||||||
|
td_prev->linkptr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (cdata->td_first)
|
if (cdata->td_first)
|
||||||
grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual);
|
grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual);
|
||||||
|
|
|
@ -138,6 +138,7 @@ iszero (grub_uint8_t *reg, int size)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_acpi_create_ebda (void)
|
grub_acpi_create_ebda (void)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +166,7 @@ grub_acpi_create_ebda (void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4);
|
ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
|
||||||
ebda_kb_len = *(grub_uint16_t *) ebda;
|
ebda_kb_len = *(grub_uint16_t *) ebda;
|
||||||
if (! ebda || ebda_kb_len > 16)
|
if (! ebda || ebda_kb_len > 16)
|
||||||
ebda_kb_len = 0;
|
ebda_kb_len = 0;
|
||||||
|
@ -173,14 +174,14 @@ grub_acpi_create_ebda (void)
|
||||||
|
|
||||||
/* FIXME: use low-memory mm allocation once it's available. */
|
/* FIXME: use low-memory mm allocation once it's available. */
|
||||||
grub_mmap_iterate (find_hook);
|
grub_mmap_iterate (find_hook);
|
||||||
targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow);
|
targetebda = (grub_uint8_t *) (grub_addr_t) highestlow;
|
||||||
grub_dprintf ("acpi", "creating ebda @%llx\n",
|
grub_dprintf ("acpi", "creating ebda @%llx\n",
|
||||||
(unsigned long long) highestlow);
|
(unsigned long long) highestlow);
|
||||||
if (! highestlow)
|
if (! highestlow)
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||||
"couldn't find space for the new EBDA");
|
"couldn't find space for the new EBDA");
|
||||||
|
|
||||||
mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
|
mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ebda_len,
|
||||||
GRUB_MEMORY_RESERVED);
|
GRUB_MEMORY_RESERVED);
|
||||||
if (! mmapregion)
|
if (! mmapregion)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -297,6 +298,7 @@ grub_acpi_create_ebda (void)
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create tables common to ACPIv1 and ACPIv2+ */
|
/* Create tables common to ACPIv1 and ACPIv2+ */
|
||||||
static void
|
static void
|
||||||
|
@ -328,13 +330,13 @@ setup_common_tables (void)
|
||||||
if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
|
if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
|
||||||
sizeof (fadt->hdr.signature)) == 0)
|
sizeof (fadt->hdr.signature)) == 0)
|
||||||
{
|
{
|
||||||
fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
|
fadt->dsdt_addr = (grub_addr_t) table_dsdt;
|
||||||
fadt->facs_addr = facs_addr;
|
fadt->facs_addr = facs_addr;
|
||||||
|
|
||||||
/* Does a revision 2 exist at all? */
|
/* Does a revision 2 exist at all? */
|
||||||
if (fadt->hdr.revision >= 3)
|
if (fadt->hdr.revision >= 3)
|
||||||
{
|
{
|
||||||
fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt);
|
fadt->dsdt_xaddr = (grub_addr_t) table_dsdt;
|
||||||
fadt->facs_xaddr = facs_addr;
|
fadt->facs_xaddr = facs_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +367,7 @@ setup_common_tables (void)
|
||||||
rsdt->creator_rev = root_creator_rev;
|
rsdt->creator_rev = root_creator_rev;
|
||||||
|
|
||||||
for (cur = acpi_tables; cur; cur = cur->next)
|
for (cur = acpi_tables; cur; cur = cur->next)
|
||||||
*(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
|
*(rsdt_entry++) = (grub_addr_t) cur->addr;
|
||||||
|
|
||||||
/* Recompute checksum. */
|
/* Recompute checksum. */
|
||||||
rsdt->checksum = 0;
|
rsdt->checksum = 0;
|
||||||
|
@ -383,7 +385,7 @@ setv1table (void)
|
||||||
sizeof (rsdpv1_new->signature));
|
sizeof (rsdpv1_new->signature));
|
||||||
grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid));
|
grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid));
|
||||||
rsdpv1_new->revision = 0;
|
rsdpv1_new->revision = 0;
|
||||||
rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
|
rsdpv1_new->rsdt_addr = (grub_addr_t) rsdt_addr;
|
||||||
rsdpv1_new->checksum = 0;
|
rsdpv1_new->checksum = 0;
|
||||||
rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
|
rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
|
||||||
sizeof (*rsdpv1_new));
|
sizeof (*rsdpv1_new));
|
||||||
|
@ -408,7 +410,7 @@ setv2table (void)
|
||||||
|
|
||||||
xsdt_entry = (grub_uint64_t *)(xsdt + 1);
|
xsdt_entry = (grub_uint64_t *)(xsdt + 1);
|
||||||
for (cur = acpi_tables; cur; cur = cur->next)
|
for (cur = acpi_tables; cur; cur = cur->next)
|
||||||
*(xsdt_entry++) = PTR_TO_UINT64 (cur->addr);
|
*(xsdt_entry++) = (grub_addr_t) cur->addr;
|
||||||
grub_memcpy (&(xsdt->signature), "XSDT", 4);
|
grub_memcpy (&(xsdt->signature), "XSDT", 4);
|
||||||
xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
|
xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
|
||||||
xsdt->revision = 1;
|
xsdt->revision = 1;
|
||||||
|
@ -428,12 +430,12 @@ setv2table (void)
|
||||||
grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
|
grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
|
||||||
sizeof (rsdpv2_new->rsdpv1.oemid));
|
sizeof (rsdpv2_new->rsdpv1.oemid));
|
||||||
rsdpv2_new->rsdpv1.revision = rev2;
|
rsdpv2_new->rsdpv1.revision = rev2;
|
||||||
rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
|
rsdpv2_new->rsdpv1.rsdt_addr = (grub_addr_t) rsdt_addr;
|
||||||
rsdpv2_new->rsdpv1.checksum = 0;
|
rsdpv2_new->rsdpv1.checksum = 0;
|
||||||
rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
|
rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
|
||||||
(&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
|
(&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
|
||||||
rsdpv2_new->length = sizeof (*rsdpv2_new);
|
rsdpv2_new->length = sizeof (*rsdpv2_new);
|
||||||
rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt);
|
rsdpv2_new->xsdt_addr = (grub_addr_t) xsdt;
|
||||||
rsdpv2_new->checksum = 0;
|
rsdpv2_new->checksum = 0;
|
||||||
rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
|
rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
|
||||||
rsdpv2_new->length);
|
rsdpv2_new->length);
|
||||||
|
@ -463,7 +465,6 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
struct grub_arg_list *state = ctxt->state;
|
struct grub_arg_list *state = ctxt->state;
|
||||||
struct grub_acpi_rsdp_v10 *rsdp;
|
struct grub_acpi_rsdp_v10 *rsdp;
|
||||||
struct efiemu_acpi_table *cur, *t;
|
struct efiemu_acpi_table *cur, *t;
|
||||||
grub_err_t err;
|
|
||||||
int i, mmapregion;
|
int i, mmapregion;
|
||||||
int numoftables;
|
int numoftables;
|
||||||
|
|
||||||
|
@ -506,7 +507,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
/* Set revision variables to replicate the same version as host. */
|
/* Set revision variables to replicate the same version as host. */
|
||||||
rev1 = ! rsdp->revision;
|
rev1 = ! rsdp->revision;
|
||||||
rev2 = rsdp->revision;
|
rev2 = rsdp->revision;
|
||||||
rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr);
|
rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr;
|
||||||
/* Load host tables. */
|
/* Load host tables. */
|
||||||
for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
|
for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
|
||||||
entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
|
entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
|
||||||
|
@ -516,7 +517,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
char signature[5];
|
char signature[5];
|
||||||
struct efiemu_acpi_table *table;
|
struct efiemu_acpi_table *table;
|
||||||
struct grub_acpi_table_header *curtable
|
struct grub_acpi_table_header *curtable
|
||||||
= (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr);
|
= (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr;
|
||||||
signature[4] = 0;
|
signature[4] = 0;
|
||||||
for (i = 0; i < 4;i++)
|
for (i = 0; i < 4;i++)
|
||||||
signature[i] = grub_tolower (curtable->signature[i]);
|
signature[i] = grub_tolower (curtable->signature[i]);
|
||||||
|
@ -540,7 +541,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
|
|
||||||
/* Load DSDT if not excluded. */
|
/* Load DSDT if not excluded. */
|
||||||
dsdt = (struct grub_acpi_table_header *)
|
dsdt = (struct grub_acpi_table_header *)
|
||||||
UINT_TO_PTR (fadt->dsdt_addr);
|
(grub_addr_t) fadt->dsdt_addr;
|
||||||
if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
|
if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
|
||||||
&& (! load_only || grub_strword (load_only, "dsdt"))
|
&& (! load_only || grub_strword (load_only, "dsdt"))
|
||||||
&& dsdt->length >= sizeof (*dsdt))
|
&& dsdt->length >= sizeof (*dsdt))
|
||||||
|
@ -732,13 +733,20 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
}
|
}
|
||||||
acpi_tables = 0;
|
acpi_tables = 0;
|
||||||
|
|
||||||
if (! state[9].set && (err = grub_acpi_create_ebda ()))
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
if (! state[9].set)
|
||||||
{
|
{
|
||||||
rsdpv1_new = 0;
|
grub_err_t err;
|
||||||
rsdpv2_new = 0;
|
err = grub_acpi_create_ebda ();
|
||||||
grub_mmap_free_and_unregister (mmapregion);
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
rsdpv1_new = 0;
|
||||||
|
rsdpv2_new = 0;
|
||||||
|
grub_mmap_free_and_unregister (mmapregion);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
#ifdef GRUB_MACHINE_EFI
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef uint8_t grub_uint8_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <grub/acpi.h>
|
#include <grub/acpi.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
#ifndef GRUB_DSDT_TEST
|
#ifndef GRUB_DSDT_TEST
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
@ -327,6 +328,6 @@ grub_acpi_halt (void)
|
||||||
|
|
||||||
grub_millisleep (1500);
|
grub_millisleep (1500);
|
||||||
|
|
||||||
grub_printf ("ACPI shutdown failed\n");
|
grub_puts_ (N_("ACPI shutdown failed"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,17 +31,17 @@ static grub_err_t (*grub_loader_boot_func) (void);
|
||||||
static grub_err_t (*grub_loader_unload_func) (void);
|
static grub_err_t (*grub_loader_unload_func) (void);
|
||||||
static int grub_loader_noreturn;
|
static int grub_loader_noreturn;
|
||||||
|
|
||||||
struct grub_preboot_t
|
struct grub_preboot
|
||||||
{
|
{
|
||||||
grub_err_t (*preboot_func) (int);
|
grub_err_t (*preboot_func) (int);
|
||||||
grub_err_t (*preboot_rest_func) (void);
|
grub_err_t (*preboot_rest_func) (void);
|
||||||
grub_loader_preboot_hook_prio_t prio;
|
grub_loader_preboot_hook_prio_t prio;
|
||||||
struct grub_preboot_t *next;
|
struct grub_preboot *next;
|
||||||
struct grub_preboot_t *prev;
|
struct grub_preboot *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int grub_loader_loaded;
|
static int grub_loader_loaded;
|
||||||
static struct grub_preboot_t *preboots_head = 0,
|
static struct grub_preboot *preboots_head = 0,
|
||||||
*preboots_tail = 0;
|
*preboots_tail = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -51,18 +51,18 @@ grub_loader_is_loaded (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register a preboot hook. */
|
/* Register a preboot hook. */
|
||||||
void *
|
struct grub_preboot *
|
||||||
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
|
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
|
||||||
grub_err_t (*preboot_rest_func) (void),
|
grub_err_t (*preboot_rest_func) (void),
|
||||||
grub_loader_preboot_hook_prio_t prio)
|
grub_loader_preboot_hook_prio_t prio)
|
||||||
{
|
{
|
||||||
struct grub_preboot_t *cur, *new_preboot;
|
struct grub_preboot *cur, *new_preboot;
|
||||||
|
|
||||||
if (! preboot_func && ! preboot_rest_func)
|
if (! preboot_func && ! preboot_rest_func)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
new_preboot = (struct grub_preboot_t *)
|
new_preboot = (struct grub_preboot *)
|
||||||
grub_malloc (sizeof (struct grub_preboot_t));
|
grub_malloc (sizeof (struct grub_preboot));
|
||||||
if (! new_preboot)
|
if (! new_preboot)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
|
||||||
|
@ -96,9 +96,9 @@ grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_loader_unregister_preboot_hook (void *hnd)
|
grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
|
||||||
{
|
{
|
||||||
struct grub_preboot_t *preb = hnd;
|
struct grub_preboot *preb = hnd;
|
||||||
|
|
||||||
if (preb->next)
|
if (preb->next)
|
||||||
preb->next->prev = preb->prev;
|
preb->next->prev = preb->prev;
|
||||||
|
@ -143,7 +143,7 @@ grub_err_t
|
||||||
grub_loader_boot (void)
|
grub_loader_boot (void)
|
||||||
{
|
{
|
||||||
grub_err_t err = GRUB_ERR_NONE;
|
grub_err_t err = GRUB_ERR_NONE;
|
||||||
struct grub_preboot_t *cur;
|
struct grub_preboot *cur;
|
||||||
|
|
||||||
if (! grub_loader_loaded)
|
if (! grub_loader_loaded)
|
||||||
return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
|
return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
|
||||||
|
|
|
@ -31,14 +31,14 @@ grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
unsigned long hits, misses;
|
unsigned long hits, misses;
|
||||||
|
|
||||||
grub_disk_cache_get_performance (&hits, &misses);
|
grub_disk_cache_get_performance (&hits, &misses);
|
||||||
grub_printf ("Disk cache: hits = %lu, misses = %lu ", hits, misses);
|
grub_printf_ (N_("Disk cache: hits = %lu, misses = %lu "), hits, misses);
|
||||||
if (hits + misses)
|
if (hits + misses)
|
||||||
{
|
{
|
||||||
unsigned long ratio = hits * 10000 / (hits + misses);
|
unsigned long ratio = hits * 10000 / (hits + misses);
|
||||||
grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100);
|
grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
grub_printf ("(N/A)\n");
|
grub_puts_ (N_("(N/A)"));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
|
||||||
|
|
||||||
grub_printf ("Compare file `%s' with `%s':\n", args[0],
|
grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0],
|
||||||
args[1]);
|
args[1]);
|
||||||
|
|
||||||
file1 = grub_file_open (args[0]);
|
file1 = grub_file_open (args[0]);
|
||||||
file2 = grub_file_open (args[1]);
|
file2 = grub_file_open (args[1]);
|
||||||
|
@ -51,9 +51,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (grub_file_size (file1) != grub_file_size (file2))
|
if (grub_file_size (file1) != grub_file_size (file2))
|
||||||
grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n",
|
grub_printf_ (N_("Files differ in size: %llu [%s], %llu [%s]\n"),
|
||||||
(unsigned long long) grub_file_size (file1), args[0],
|
(unsigned long long) grub_file_size (file1), args[0],
|
||||||
(unsigned long long) grub_file_size (file2), args[1]);
|
(unsigned long long) grub_file_size (file2), args[1]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
@ -78,9 +78,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
if (buf1[i] != buf2[i])
|
if (buf1[i] != buf2[i])
|
||||||
{
|
{
|
||||||
grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n",
|
grub_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"),
|
||||||
(unsigned long long) (i + pos), buf1[i], args[0],
|
(unsigned long long) (i + pos), buf1[i],
|
||||||
buf2[i], args[1]);
|
args[0], buf2[i], args[1]);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
while (rd2);
|
while (rd2);
|
||||||
|
|
||||||
grub_printf ("The files are identical.\n");
|
/* TRANSLATORS: it's always exactly 2 files. */
|
||||||
|
grub_printf_ (N_("The files are identical.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
|
@ -56,24 +56,24 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid)
|
||||||
{
|
{
|
||||||
grub_target_addr_t base;
|
grub_target_addr_t base;
|
||||||
|
|
||||||
grub_printf ("Found graphic card: %s\n", p->name);
|
grub_dprintf ("fixvideo", "Found graphic card: %s\n", p->name);
|
||||||
addr += 8 + p->mmio_bar * 4;
|
addr += 8 + p->mmio_bar * 4;
|
||||||
base = grub_pci_read (addr);
|
base = grub_pci_read (addr);
|
||||||
if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) ||
|
if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) ||
|
||||||
(base & GRUB_PCI_ADDR_MEM_PREFETCH))
|
(base & GRUB_PCI_ADDR_MEM_PREFETCH))
|
||||||
grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar);
|
grub_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
base &= GRUB_PCI_ADDR_MEM_MASK;
|
base &= GRUB_PCI_ADDR_MEM_MASK;
|
||||||
base += p->mmio_reg;
|
base += p->mmio_reg;
|
||||||
|
|
||||||
if (*((volatile grub_uint32_t *) base) != p->mmio_old)
|
if (*((volatile grub_uint32_t *) base) != p->mmio_old)
|
||||||
grub_printf ("Old value don't match\n");
|
grub_dprintf ("fixvideo", "Old value doesn't match\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*((volatile grub_uint32_t *) base) = 0;
|
*((volatile grub_uint32_t *) base) = 0;
|
||||||
if (*((volatile grub_uint32_t *) base))
|
if (*((volatile grub_uint32_t *) base))
|
||||||
grub_printf ("Set MMIO fails\n");
|
grub_dprintf ("fixvideo", "Setting MMIO fails\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid)
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_printf ("Unknown graphic card: %x\n", pciid);
|
grub_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -49,7 +49,7 @@ enable_rom_area (void)
|
||||||
rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
|
rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
|
||||||
if (*rom_ptr != BLANK_MEM)
|
if (*rom_ptr != BLANK_MEM)
|
||||||
{
|
{
|
||||||
grub_printf ("ROM image is present.\n");
|
grub_puts_ (N_("ROM image is present."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ enable_rom_area (void)
|
||||||
*rom_ptr = 0;
|
*rom_ptr = 0;
|
||||||
if (*rom_ptr != 0)
|
if (*rom_ptr != 0)
|
||||||
{
|
{
|
||||||
grub_printf ("Can\'t enable ROM area.\n");
|
grub_puts_ (N_("Can\'t enable ROM area."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ GRUB_MOD_INIT(loadbios)
|
||||||
0, N_("Fake BIOS."));
|
0, N_("Fake BIOS."));
|
||||||
|
|
||||||
cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
|
cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
|
||||||
"BIOS_DUMP [INT10_DUMP]",
|
N_("BIOS_DUMP [INT10_DUMP]"),
|
||||||
N_("Load BIOS dump."));
|
N_("Load BIOS dump."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_printf ("New MBR is written to '%s'\n", args[0]);
|
grub_printf_ (N_("New MBR is written to '%s'\n"), args[0]);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,12 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t __attribute__ ((noreturn))
|
||||||
grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
char **args __attribute__ ((unused)))
|
char **args __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
grub_halt ();
|
grub_halt ();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd;
|
static grub_command_t cmd;
|
||||||
|
|
|
@ -141,7 +141,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_printf ("%s: READ ERROR\n", p);
|
grub_printf_ (N_("%s: READ ERROR\n"), p);
|
||||||
if (!keep)
|
if (!keep)
|
||||||
{
|
{
|
||||||
grub_file_close (hashlist);
|
grub_file_close (hashlist);
|
||||||
|
@ -155,7 +155,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||||
}
|
}
|
||||||
if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
|
if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
|
||||||
{
|
{
|
||||||
grub_printf ("%s: HASH MISMATCH\n", p);
|
grub_printf_ (N_("%s: HASH MISMATCH\n"), p);
|
||||||
if (!keep)
|
if (!keep)
|
||||||
{
|
{
|
||||||
grub_file_close (hashlist);
|
grub_file_close (hashlist);
|
||||||
|
@ -166,7 +166,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||||
mismatch++;
|
mismatch++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
grub_printf ("%s: OK\n", p);
|
grub_printf_ (N_("%s: OK\n"), p);
|
||||||
}
|
}
|
||||||
if (mismatch || unread)
|
if (mismatch || unread)
|
||||||
return grub_error (GRUB_ERR_TEST_FAILURE,
|
return grub_error (GRUB_ERR_TEST_FAILURE,
|
||||||
|
@ -257,8 +257,8 @@ static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc;
|
||||||
GRUB_MOD_INIT(hashsum)
|
GRUB_MOD_INIT(hashsum)
|
||||||
{
|
{
|
||||||
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0,
|
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0,
|
||||||
"hashsum -h HASH [-c FILE [-p PREFIX]] "
|
N_("-h HASH [-c FILE [-p PREFIX]] "
|
||||||
"[FILE1 [FILE2 ...]]",
|
"[FILE1 [FILE2 ...]]"),
|
||||||
N_("Compute or check hash checksum."),
|
N_("Compute or check hash checksum."),
|
||||||
options);
|
options);
|
||||||
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0,
|
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0,
|
||||||
|
|
|
@ -165,22 +165,20 @@ grub_hdparm_set_val_cmd (const char * msg, int val,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes)
|
le16_to_char (grub_uint16_t *dest, const grub_uint16_t * src16, unsigned bytes)
|
||||||
{
|
{
|
||||||
grub_uint16_t * dest16 = (grub_uint16_t *) dest;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < bytes / 2; i++)
|
for (i = 0; i < bytes / 2; i++)
|
||||||
dest16[i] = grub_be_to_cpu16 (src16[i]);
|
dest[i] = grub_be_to_cpu16 (src16[i]);
|
||||||
return dest;
|
dest[i] = 0;
|
||||||
|
return (char *) dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_hdparm_print_identify (const char * idbuf)
|
grub_hdparm_print_identify (const grub_uint16_t * idw)
|
||||||
{
|
{
|
||||||
const grub_uint16_t * idw = (const grub_uint16_t *) idbuf;
|
|
||||||
|
|
||||||
/* Print identity strings. */
|
/* Print identity strings. */
|
||||||
char tmp[40];
|
grub_uint16_t tmp[21];
|
||||||
grub_printf ("Model: \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
|
grub_printf ("Model: \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
|
||||||
grub_printf ("Firmware: \"%.8s\"\n", le16_to_char (tmp, &idw[23], 8));
|
grub_printf ("Firmware: \"%.8s\"\n", le16_to_char (tmp, &idw[23], 8));
|
||||||
grub_printf ("Serial: \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
|
grub_printf ("Serial: \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
|
||||||
|
@ -377,7 +375,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state????
|
||||||
/* Print/dump IDENTIFY. */
|
/* Print/dump IDENTIFY. */
|
||||||
if (ident || dumpid)
|
if (ident || dumpid)
|
||||||
{
|
{
|
||||||
char buf[GRUB_DISK_SECTOR_SIZE];
|
grub_uint16_t buf[GRUB_DISK_SECTOR_SIZE / 2];
|
||||||
if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE,
|
if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE,
|
||||||
0, 0, buf, sizeof (buf)))
|
0, 0, buf, sizeof (buf)))
|
||||||
grub_printf ("Cannot read ATA IDENTIFY data\n");
|
grub_printf ("Cannot read ATA IDENTIFY data\n");
|
||||||
|
@ -386,7 +384,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state????
|
||||||
if (ident)
|
if (ident)
|
||||||
grub_hdparm_print_identify (buf);
|
grub_hdparm_print_identify (buf);
|
||||||
if (dumpid)
|
if (dumpid)
|
||||||
hexdump (0, buf, sizeof (buf));
|
hexdump (0, (char *) buf, sizeof (buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/cmos.h>
|
#include <grub/cmos.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -86,11 +87,11 @@ static grub_command_t cmd, cmd_clean;
|
||||||
GRUB_MOD_INIT(cmostest)
|
GRUB_MOD_INIT(cmostest)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
|
cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
|
||||||
"cmostest BYTE:BIT",
|
N_("BYTE:BIT"),
|
||||||
"Test bit at BYTE:BIT in CMOS.");
|
N_("Test bit at BYTE:BIT in CMOS."));
|
||||||
cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean,
|
cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean,
|
||||||
"cmosclean BYTE:BIT",
|
N_("BYTE:BIT"),
|
||||||
"Clean bit at BYTE:BIT in CMOS.");
|
N_("Clean bit at BYTE:BIT in CMOS."));
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(cmostest)
|
GRUB_MOD_FINI(cmostest)
|
||||||
|
|
|
@ -178,11 +178,11 @@ list_mappings (void)
|
||||||
/* Show: list mappings. */
|
/* Show: list mappings. */
|
||||||
if (! map_head)
|
if (! map_head)
|
||||||
{
|
{
|
||||||
grub_printf ("No drives have been remapped\n");
|
grub_puts_ (N_("No drives have been remapped"));
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_printf ("OS disk #num ------> GRUB/BIOS device\n");
|
grub_puts_ (N_("OS disk #num ------> GRUB/BIOS device"));
|
||||||
drivemap_node_t *curnode = map_head;
|
drivemap_node_t *curnode = map_head;
|
||||||
while (curnode)
|
while (curnode)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +363,7 @@ uninstall_int13_handler (void)
|
||||||
static int
|
static int
|
||||||
grub_get_root_biosnumber_drivemap (void)
|
grub_get_root_biosnumber_drivemap (void)
|
||||||
{
|
{
|
||||||
char *biosnum;
|
const char *biosnum;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
|
||||||
|
|
|
@ -74,27 +74,27 @@ grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (!grub_apm_get_info (&info))
|
if (!grub_apm_get_info (&info))
|
||||||
return grub_error (GRUB_ERR_IO, "no APM found");
|
return grub_error (GRUB_ERR_IO, "no APM found");
|
||||||
|
|
||||||
grub_printf ("Vesion %u.%u\n"
|
grub_printf_ (N_("Vesion %u.%u\n"
|
||||||
"32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n"
|
"32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n"
|
||||||
"16-bit CS = 0x%x, len = 0x%x\n"
|
"16-bit CS = 0x%x, len = 0x%x\n"
|
||||||
"DS = 0x%x, len = 0x%x\n",
|
"DS = 0x%x, len = 0x%x\n"),
|
||||||
info.version >> 8, info.version & 0xff,
|
info.version >> 8, info.version & 0xff,
|
||||||
info.cseg, info.cseg_len, info.offset,
|
info.cseg, info.cseg_len, info.offset,
|
||||||
info.cseg_16, info.cseg_16_len,
|
info.cseg_16, info.cseg_16_len,
|
||||||
info.dseg, info.dseg_len);
|
info.dseg, info.dseg_len);
|
||||||
grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED
|
grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED
|
||||||
? "16-bit protected interface supported\n"
|
? _("16-bit protected interface supported\n")
|
||||||
: "16-bit protected interface unsupported\n");
|
: _("16-bit protected interface unsupported\n"));
|
||||||
grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED
|
grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED
|
||||||
? "32-bit protected interface supported\n"
|
? _("32-bit protected interface supported\n")
|
||||||
: "32-bit protected interface unsupported\n");
|
: _("32-bit protected interface unsupported\n"));
|
||||||
grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN
|
grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN
|
||||||
? "CPU Idle slows down processor\n"
|
? _("CPU Idle slows down processor\n")
|
||||||
: "CPU Idle doesn't slow down processor\n");
|
: _("CPU Idle doesn't slow down processor\n"));
|
||||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED
|
grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED
|
||||||
? "APM disabled\n" : "APM enabled\n");
|
? _("APM disabled\n") : _("APM enabled\n"));
|
||||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED
|
grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED
|
||||||
? "APM disengaged\n" : "APM engaged\n");
|
? _("APM disengaged\n") : _("APM engaged\n"));
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/cpu/io.h>
|
#include <grub/cpu/io.h>
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv2+");
|
GRUB_MOD_LICENSE ("GPLv2+");
|
||||||
|
|
||||||
|
@ -35,23 +36,23 @@ static int keylen = 0;
|
||||||
static int noled = 0;
|
static int noled = 0;
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
{"num", 'n', 0, "set numlock mode", "[on|off]", ARG_TYPE_STRING},
|
{"num", 'n', 0, N_("set numlock mode"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"caps", 'c', 0, "set capslock mode", "[on|off]", ARG_TYPE_STRING},
|
{"caps", 'c', 0, N_("set capslock mode"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"scroll", 's', 0, "set scrolllock mode", "[on|off]", ARG_TYPE_STRING},
|
{"scroll", 's', 0, N_("set scrolllock mode"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"insert", 0, 0, "set insert mode", "[on|off]", ARG_TYPE_STRING},
|
{"insert", 0, 0, N_("set insert mode"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"pause", 0, 0, "set pause mode", "[on|off]", ARG_TYPE_STRING},
|
{"pause", 0, 0, N_("set pause mode"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"left-shift", 0, 0, "press left shift", "[on|off]", ARG_TYPE_STRING},
|
{"left-shift", 0, 0, N_("press left shift"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"right-shift", 0, 0, "press right shift", "[on|off]", ARG_TYPE_STRING},
|
{"right-shift", 0, 0, N_("press right shift"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"sysrq", 0, 0, "press SysRq", "[on|off]", ARG_TYPE_STRING},
|
{"sysrq", 0, 0, N_("press SysRq"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"numkey", 0, 0, "press NumLock key", "[on|off]", ARG_TYPE_STRING},
|
{"numkey", 0, 0, N_("press NumLock key"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"capskey", 0, 0, "press CapsLock key", "[on|off]", ARG_TYPE_STRING},
|
{"capskey", 0, 0, N_("press CapsLock key"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"scrollkey", 0, 0, "press ScrollLock key", "[on|off]", ARG_TYPE_STRING},
|
{"scrollkey", 0, 0, N_("press ScrollLock key"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"insertkey", 0, 0, "press Insert key", "[on|off]", ARG_TYPE_STRING},
|
{"insertkey", 0, 0, N_("press Insert key"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"left-alt", 0, 0, "press left alt", "[on|off]", ARG_TYPE_STRING},
|
{"left-alt", 0, 0, N_("press left alt"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"right-alt", 0, 0, "press right alt", "[on|off]", ARG_TYPE_STRING},
|
{"right-alt", 0, 0, N_("press right alt"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"left-ctrl", 0, 0, "press left ctrl", "[on|off]", ARG_TYPE_STRING},
|
{"left-ctrl", 0, 0, N_("press left ctrl"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"right-ctrl", 0, 0, "press right ctrl", "[on|off]", ARG_TYPE_STRING},
|
{"right-ctrl", 0, 0, N_("press right ctrl"), "[on|off]", ARG_TYPE_STRING},
|
||||||
{"no-led", 0, 0, "don't update LED state", 0, 0},
|
{"no-led", 0, 0, N_("don't update LED state"), 0, 0},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
static int simple_flag_offsets[]
|
static int simple_flag_offsets[]
|
||||||
|
@ -62,8 +63,8 @@ static grub_uint32_t andmask = 0xffffffff, ormask = 0;
|
||||||
struct
|
struct
|
||||||
keysym
|
keysym
|
||||||
{
|
{
|
||||||
char *unshifted_name; /* the name in unshifted state */
|
const char *unshifted_name; /* the name in unshifted state */
|
||||||
char *shifted_name; /* the name in shifted state */
|
const char *shifted_name; /* the name in shifted state */
|
||||||
unsigned char unshifted_ascii; /* the ascii code in unshifted state */
|
unsigned char unshifted_ascii; /* the ascii code in unshifted state */
|
||||||
unsigned char shifted_ascii; /* the ascii code in shifted state */
|
unsigned char shifted_ascii; /* the ascii code in shifted state */
|
||||||
unsigned char keycode; /* keyboard scancode */
|
unsigned char keycode; /* keyboard scancode */
|
||||||
|
@ -364,13 +365,13 @@ grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_extcmd_t cmd;
|
static grub_extcmd_t cmd;
|
||||||
static void *preboot_hook;
|
static struct grub_preboot *preboot_hook;
|
||||||
|
|
||||||
GRUB_MOD_INIT (sendkey)
|
GRUB_MOD_INIT (sendkey)
|
||||||
{
|
{
|
||||||
cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0,
|
cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0,
|
||||||
"sendkey [KEYSTROKE1] [KEYSTROKE2] ...",
|
N_("[KEYSTROKE1] [KEYSTROKE2] ..."),
|
||||||
"Emulate a keystroke", options);
|
N_("Emulate a keystroke"), options);
|
||||||
|
|
||||||
preboot_hook
|
preboot_hook
|
||||||
= grub_loader_register_preboot_hook (grub_sendkey_preboot,
|
= grub_loader_register_preboot_hook (grub_sendkey_preboot,
|
||||||
|
|
|
@ -31,7 +31,7 @@ grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
char **args __attribute__ ((unused)))
|
char **args __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
grub_printf ("Run 'go' to resume GRUB.\n");
|
grub_puts_ (N_("Run 'go' to resume GRUB."));
|
||||||
grub_ieee1275_enter ();
|
grub_ieee1275_enter ();
|
||||||
grub_cls ();
|
grub_cls ();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -344,7 +344,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||||
int bsd_part = -1;
|
int bsd_part = -1;
|
||||||
{
|
{
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
char *hdbiasstr;
|
const char *hdbiasstr;
|
||||||
int hdbias = 0;
|
int hdbias = 0;
|
||||||
hdbiasstr = grub_env_get ("legacy_hdbias");
|
hdbiasstr = grub_env_get ("legacy_hdbias");
|
||||||
if (hdbiasstr)
|
if (hdbiasstr)
|
||||||
|
@ -723,7 +723,7 @@ grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unuse
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
|
||||||
grub_printf ("Enter password:");
|
grub_puts_ (N_("Enter password: "));
|
||||||
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
||||||
return GRUB_ACCESS_DENIED;
|
return GRUB_ACCESS_DENIED;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ open_envblk_file (char *filename)
|
||||||
|
|
||||||
if (! filename)
|
if (! filename)
|
||||||
{
|
{
|
||||||
char *prefix;
|
const char *prefix;
|
||||||
|
|
||||||
prefix = grub_env_get ("prefix");
|
prefix = grub_env_get ("prefix");
|
||||||
if (prefix)
|
if (prefix)
|
||||||
|
@ -346,7 +346,7 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
|
||||||
while (argc)
|
while (argc)
|
||||||
{
|
{
|
||||||
char *value;
|
const char *value;
|
||||||
|
|
||||||
value = grub_env_get (args[0]);
|
value = grub_env_get (args[0]);
|
||||||
if (value)
|
if (value)
|
||||||
|
|
|
@ -26,13 +26,13 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static const char *names[] =
|
static const char *names[] =
|
||||||
{
|
{
|
||||||
[GRUB_MEMORY_AVAILABLE] = "available",
|
[GRUB_MEMORY_AVAILABLE] = N_("available"),
|
||||||
[GRUB_MEMORY_RESERVED] = "reserved",
|
[GRUB_MEMORY_RESERVED] = N_("reserved"),
|
||||||
[GRUB_MEMORY_ACPI] = "ACPI reclamaible",
|
[GRUB_MEMORY_ACPI] = N_("ACPI reclamaible"),
|
||||||
[GRUB_MEMORY_NVS] = "NVS",
|
[GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage"),
|
||||||
[GRUB_MEMORY_BADRAM] = "BadRAM",
|
[GRUB_MEMORY_BADRAM] = N_("BadRAM"),
|
||||||
[GRUB_MEMORY_CODE] = "firmware code",
|
[GRUB_MEMORY_CODE] = N_("firmware code"),
|
||||||
[GRUB_MEMORY_HOLE] = "hole"
|
[GRUB_MEMORY_HOLE] = N_("hole")
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -46,11 +46,11 @@ grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_memory_type_t type)
|
grub_memory_type_t type)
|
||||||
{
|
{
|
||||||
if (type < ARRAY_SIZE (names) && names[type])
|
if (type < ARRAY_SIZE (names) && names[type])
|
||||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n",
|
grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"),
|
||||||
(long long) addr, (long long) size, names[type]);
|
(long long) addr, (long long) size, _(names[type]));
|
||||||
else
|
else
|
||||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
|
grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"),
|
||||||
(long long) addr, (long long) size, type);
|
(long long) addr, (long long) size, type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifndef GRUB_MACHINE_EMU
|
#ifndef GRUB_MACHINE_EMU
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct grub_pci_classname
|
||||||
{
|
{
|
||||||
int class;
|
int class;
|
||||||
int subclass;
|
int subclass;
|
||||||
char *desc;
|
const char *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct grub_pci_classname grub_pci_classes[] =
|
static const struct grub_pci_classname grub_pci_classes[] =
|
||||||
|
|
|
@ -31,7 +31,7 @@ static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
{0, 'v', 0, N_("Save read value into variable VARNAME."),
|
{0, 'v', 0, N_("Save read value into variable VARNAME."),
|
||||||
"VARNAME", ARG_TYPE_STRING},
|
N_("VARNAME"), ARG_TYPE_STRING},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,19 +28,19 @@
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
{"class", 1, GRUB_ARG_OPTION_REPEATABLE,
|
{"class", 1, GRUB_ARG_OPTION_REPEATABLE,
|
||||||
N_("Menu entry type."), "STRING", ARG_TYPE_STRING},
|
N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING},
|
||||||
{"users", 2, 0,
|
{"users", 2, 0,
|
||||||
N_("Users allowed to boot this entry."), "USERNAME", ARG_TYPE_STRING},
|
N_("Users allowed to boot this entry."), N_("USERNAME"), ARG_TYPE_STRING},
|
||||||
{"hotkey", 3, 0,
|
{"hotkey", 3, 0,
|
||||||
N_("Keyboard key for this entry."), "KEY", ARG_TYPE_STRING},
|
N_("Keyboard key for this entry."), N_("KEY"), ARG_TYPE_STRING},
|
||||||
{"source", 4, 0,
|
{"source", 4, 0,
|
||||||
N_("Menu entry definition as a string."), "STRING", ARG_TYPE_STRING},
|
N_("Menu entry definition as a string."), N_("STRING"), ARG_TYPE_STRING},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
char *name;
|
const char *name;
|
||||||
int key;
|
int key;
|
||||||
} hotkey_aliases[] =
|
} hotkey_aliases[] =
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,7 +145,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_dl_t mod;
|
grub_dl_t mod;
|
||||||
|
|
||||||
grub_printf ("Name\tRef Count\tDependencies\n");
|
grub_printf_ (N_("Name\tRef Count\tDependencies\n"));
|
||||||
FOR_DL_MODULES (mod)
|
FOR_DL_MODULES (mod)
|
||||||
{
|
{
|
||||||
grub_dl_dep_t dep;
|
grub_dl_dep_t dep;
|
||||||
|
@ -165,13 +165,13 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exit */
|
/* exit */
|
||||||
static grub_err_t
|
static grub_err_t __attribute__ ((noreturn))
|
||||||
grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
|
grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
char *argv[] __attribute__ ((unused)))
|
char *argv[] __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
grub_exit ();
|
grub_exit ();
|
||||||
return 0;
|
/* Not reached. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd_cat, cmd_help;
|
static grub_command_t cmd_cat, cmd_help;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/cs5536.h>
|
#include <grub/cs5536.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -38,43 +39,44 @@ grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
if (!grub_cs5536_find (&dev))
|
if (!grub_cs5536_find (&dev))
|
||||||
{
|
{
|
||||||
grub_printf ("No CS5536 found\n");
|
grub_puts_ (N_("No CS5536 found"));
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev),
|
grub_printf_ (N_("CS5536 at %d:%d.%d\n"), grub_pci_get_bus (dev),
|
||||||
grub_pci_get_device (dev), grub_pci_get_function (dev));
|
grub_pci_get_device (dev), grub_pci_get_function (dev));
|
||||||
|
|
||||||
err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase);
|
err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
grub_printf ("SMB base = 0x%x\n", smbbase);
|
grub_printf_ (N_("SMB base = 0x%x\n"), smbbase);
|
||||||
|
|
||||||
for (i = GRUB_SMB_RAM_START_ADDR;
|
for (i = GRUB_SMB_RAM_START_ADDR;
|
||||||
i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++)
|
i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++)
|
||||||
{
|
{
|
||||||
struct grub_smbus_spd spd;
|
struct grub_smbus_spd spd;
|
||||||
grub_memset (&spd, 0, sizeof (spd));
|
grub_memset (&spd, 0, sizeof (spd));
|
||||||
grub_printf ("Device %d\n", i);
|
grub_printf_ (N_("Device %d\n"), i);
|
||||||
err = grub_cs5536_read_spd (smbbase, i, &spd);
|
err = grub_cs5536_read_spd (smbbase, i, &spd);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
grub_printf ("Written SPD bytes: %d B.\n", spd.written_size);
|
grub_printf_ (N_("Written SPD bytes: %d B.\n"), spd.written_size);
|
||||||
grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size);
|
grub_printf_ (N_("Total flash size: %d B.\n"),
|
||||||
|
1 << spd.log_total_flash_size);
|
||||||
if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2)
|
if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2)
|
||||||
{
|
{
|
||||||
char str[sizeof (spd.ddr2.part_number) + 1];
|
char str[sizeof (spd.ddr2.part_number) + 1];
|
||||||
grub_printf ("Memory type: DDR2.\n");
|
grub_puts_ (N_("Memory type: DDR2."));
|
||||||
grub_memcpy (str, spd.ddr2.part_number,
|
grub_memcpy (str, spd.ddr2.part_number,
|
||||||
sizeof (spd.ddr2.part_number));
|
sizeof (spd.ddr2.part_number));
|
||||||
str[sizeof (spd.ddr2.part_number)] = 0;
|
str[sizeof (spd.ddr2.part_number)] = 0;
|
||||||
grub_printf ("Part no: %s.\n", str);
|
grub_printf_ (N_("Part no: %s.\n"), str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
grub_printf ("Memory type: Unknown.\n");
|
grub_puts_ (N_("Memory type: Unknown."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -85,7 +87,7 @@ static grub_command_t cmd;
|
||||||
GRUB_MOD_INIT(lsspd)
|
GRUB_MOD_INIT(lsspd)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0,
|
cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0,
|
||||||
"Print Memory information.");
|
N_("Print Memory information."));
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(lsspd)
|
GRUB_MOD_FINI(lsspd)
|
||||||
|
|
|
@ -37,9 +37,9 @@ static struct grub_parttool *parts = 0;
|
||||||
static int curhandle = 0;
|
static int curhandle = 0;
|
||||||
static grub_dl_t mymod;
|
static grub_dl_t mymod;
|
||||||
static char helpmsg[] =
|
static char helpmsg[] =
|
||||||
"Perform COMMANDS on partition.\n"
|
N_("Perform COMMANDS on partition.\n"
|
||||||
"Use \"parttool PARTITION help\" for the list "
|
"Use \"parttool PARTITION help\" for the list "
|
||||||
"of available commands.";
|
"of available commands.");
|
||||||
|
|
||||||
int
|
int
|
||||||
grub_parttool_register(const char *part_name,
|
grub_parttool_register(const char *part_name,
|
||||||
|
@ -128,7 +128,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GRUB_PARTTOOL_ARG_VAL:
|
case GRUB_PARTTOOL_ARG_VAL:
|
||||||
grub_printf ("=VAL");
|
grub_xputs (_("=VAL"));
|
||||||
spacing -= 4;
|
spacing -= 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -137,18 +137,18 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
while (spacing-- > 0)
|
while (spacing-- > 0)
|
||||||
grub_printf (" ");
|
grub_printf (" ");
|
||||||
grub_printf ("%s\n", curarg->desc);
|
grub_puts_ (curarg->desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! found)
|
if (! found)
|
||||||
grub_printf ("Sorry no parttool is available for %s\n",
|
grub_printf_ (N_("Sorry no parttool is available for %s\n"),
|
||||||
dev->disk->partition->partmap->name);
|
dev->disk->partition->partmap->name);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
{
|
{
|
||||||
grub_printf ("%s\n", helpmsg);
|
grub_puts_ (helpmsg);
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
return err;
|
return err;
|
||||||
if (! label)
|
if (! label)
|
||||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"uuid for this FS isn't supported yet");
|
"label for this FS isn't supported yet");
|
||||||
|
|
||||||
if (state[0].set)
|
if (state[0].set)
|
||||||
grub_env_set (state[0].arg, label);
|
grub_env_set (state[0].arg, label);
|
||||||
|
|
|
@ -24,13 +24,12 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t __attribute__ ((noreturn))
|
||||||
grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
char **args __attribute__ ((unused)))
|
char **args __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
grub_reboot ();
|
grub_reboot ();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd;
|
static grub_command_t cmd;
|
||||||
|
|
|
@ -66,12 +66,12 @@ static struct pci_register pci_registers[] =
|
||||||
|
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
{0, 'd', 0, "Select device by vendor and device IDs.",
|
{0, 'd', 0, N_("Select device by vendor and device IDs."),
|
||||||
"[vendor]:[device]", ARG_TYPE_STRING},
|
N_("[vendor]:[device]"), ARG_TYPE_STRING},
|
||||||
{0, 's', 0, "Select device by its position on the bus.",
|
{0, 's', 0, N_("Select device by its position on the bus."),
|
||||||
"[bus]:[slot][.func]", ARG_TYPE_STRING},
|
N_("[bus]:[slot][.func]"), ARG_TYPE_STRING},
|
||||||
{0, 'v', 0, "Save read value into variable VARNAME.",
|
{0, 'v', 0, N_("Save read value into variable VARNAME."),
|
||||||
"VARNAME", ARG_TYPE_STRING},
|
N_("VARNAME"), ARG_TYPE_STRING},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
|
||||||
|
|
||||||
if (!write_mask)
|
if (!write_mask)
|
||||||
{
|
{
|
||||||
grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr,
|
grub_printf (N_("Register %x of %d:%d.%d is %x\n"), regaddr,
|
||||||
grub_pci_get_bus (dev),
|
grub_pci_get_bus (dev),
|
||||||
grub_pci_get_device (dev),
|
grub_pci_get_device (dev),
|
||||||
grub_pci_get_function (dev),
|
grub_pci_get_function (dev),
|
||||||
|
|
|
@ -47,8 +47,8 @@ grub_cmd_time (grub_command_t ctxt __attribute__ ((unused)),
|
||||||
(cmd->func) (cmd, argc - 1, &args[1]);
|
(cmd->func) (cmd, argc - 1, &args[1]);
|
||||||
end = grub_get_time_ms ();
|
end = grub_get_time_ms ();
|
||||||
|
|
||||||
grub_printf ("Elapsed time: %d.%03d seconds \n", (end - start) / 1000,
|
grub_printf_ (N_("Elapsed time: %d.%03d seconds \n"), (end - start) / 1000,
|
||||||
(end - start) % 1000);
|
(end - start) % 1000);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,36 +52,36 @@ hook (const struct grub_video_mode_info *info)
|
||||||
grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp);
|
grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp);
|
||||||
|
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
|
||||||
grub_printf ("Text-only ");
|
grub_xputs (_("Text-only "));
|
||||||
/* Show mask and position details for direct color modes. */
|
/* Show mask and position details for direct color modes. */
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)
|
||||||
grub_printf ("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d",
|
grub_printf_ (N_("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d"),
|
||||||
info->red_mask_size,
|
info->red_mask_size,
|
||||||
info->green_mask_size,
|
info->green_mask_size,
|
||||||
info->blue_mask_size,
|
info->blue_mask_size,
|
||||||
info->reserved_mask_size,
|
info->reserved_mask_size,
|
||||||
info->red_field_pos,
|
info->red_field_pos,
|
||||||
info->green_field_pos,
|
info->green_field_pos,
|
||||||
info->blue_field_pos,
|
info->blue_field_pos,
|
||||||
info->reserved_field_pos);
|
info->reserved_field_pos);
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
|
||||||
grub_printf ("Packed ");
|
grub_xputs (_("Packed "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV)
|
||||||
grub_printf ("YUV ");
|
grub_xputs (_("YUV "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR)
|
||||||
grub_printf ("Planar ");
|
grub_xputs (_("Planar "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES)
|
||||||
grub_printf ("Hercules ");
|
grub_xputs (_("Hercules "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA)
|
||||||
grub_printf ("CGA ");
|
grub_xputs (_("CGA "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4)
|
||||||
grub_printf ("Non-chain 4 ");
|
grub_xputs (_("Non-chain 4 "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP)
|
||||||
grub_printf ("Monochrome ");
|
grub_xputs (_("Monochrome "));
|
||||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN)
|
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN)
|
||||||
grub_printf ("Unknown ");
|
grub_xputs (_("Unknown "));
|
||||||
|
|
||||||
grub_printf ("\n");
|
grub_xputs ("\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -93,19 +93,19 @@ print_edid (struct grub_video_edid_info *edid_info)
|
||||||
|
|
||||||
if (grub_video_edid_checksum (edid_info))
|
if (grub_video_edid_checksum (edid_info))
|
||||||
{
|
{
|
||||||
grub_printf (" EDID checksum invalid\n");
|
grub_puts_ (N_(" EDID checksum invalid"));
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_printf (" EDID version: %u.%u\n",
|
grub_printf_ (N_(" EDID version: %u.%u\n"),
|
||||||
edid_info->version, edid_info->revision);
|
edid_info->version, edid_info->revision);
|
||||||
if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height)
|
if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height)
|
||||||
== GRUB_ERR_NONE)
|
== GRUB_ERR_NONE)
|
||||||
grub_printf (" Preferred mode: %ux%u\n", edid_width, edid_height);
|
grub_printf_ (N_(" Preferred mode: %ux%u\n"), edid_width, edid_height);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
grub_printf (" No preferred mode available\n");
|
grub_printf_ (N_(" No preferred mode available\n"));
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,20 +147,20 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
id = grub_video_get_driver_id ();
|
id = grub_video_get_driver_id ();
|
||||||
|
|
||||||
grub_printf ("List of supported video modes:\n");
|
grub_puts_ (N_("List of supported video modes:"));
|
||||||
grub_printf ("Legend: P=Packed pixel, D=Direct color, "
|
grub_puts_ (N_("Legend: P=Packed pixel, D=Direct color, "
|
||||||
"mask/pos=R/G/B/reserved\n");
|
"mask/pos=R/G/B/reserved"));
|
||||||
|
|
||||||
FOR_VIDEO_ADAPTERS (adapter)
|
FOR_VIDEO_ADAPTERS (adapter)
|
||||||
{
|
{
|
||||||
struct grub_video_mode_info info;
|
struct grub_video_mode_info info;
|
||||||
struct grub_video_edid_info edid_info;
|
struct grub_video_edid_info edid_info;
|
||||||
|
|
||||||
grub_printf ("Adapter '%s':\n", adapter->name);
|
grub_printf_ (N_("Adapter '%s':\n"), adapter->name);
|
||||||
|
|
||||||
if (!adapter->iterate)
|
if (!adapter->iterate)
|
||||||
{
|
{
|
||||||
grub_printf (" No info available\n");
|
grub_puts_ (N_(" No info available"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
if (adapter->init ())
|
if (adapter->init ())
|
||||||
{
|
{
|
||||||
grub_printf (" Failed\n");
|
grub_puts_ (N_(" Failed"));
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -215,12 +215,13 @@ static grub_command_t cmd_vbe;
|
||||||
|
|
||||||
GRUB_MOD_INIT(videoinfo)
|
GRUB_MOD_INIT(videoinfo)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, "[WxH[xD]]",
|
cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, N_("[WxH[xD]]"),
|
||||||
N_("List available video modes. If "
|
N_("List available video modes. If "
|
||||||
"resolution is given show only modes"
|
"resolution is given show only modes"
|
||||||
" matching it."));
|
" matching it."));
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
#ifdef GRUB_MACHINE_PCBIOS
|
||||||
cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, "[WxH[xD]]",
|
cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo,
|
||||||
|
N_("[WxH[xD]]"),
|
||||||
N_("List available video modes. If "
|
N_("List available video modes. If "
|
||||||
"resolution is given show only modes"
|
"resolution is given show only modes"
|
||||||
" matching it."));
|
" matching it."));
|
||||||
|
|
|
@ -74,6 +74,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_video_create_render_target (&text_layer, width, height,
|
grub_video_create_render_target (&text_layer, width, height,
|
||||||
GRUB_VIDEO_MODE_TYPE_RGB
|
GRUB_VIDEO_MODE_TYPE_RGB
|
||||||
| GRUB_VIDEO_MODE_TYPE_ALPHA);
|
| GRUB_VIDEO_MODE_TYPE_ALPHA);
|
||||||
|
if (!text_layer)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
grub_video_set_active_render_target (text_layer);
|
grub_video_set_active_render_target (text_layer);
|
||||||
|
|
||||||
|
@ -191,6 +193,11 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_video_delete_render_target (text_layer);
|
||||||
|
grub_video_restore ();
|
||||||
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd;
|
static grub_command_t cmd;
|
||||||
|
|
|
@ -436,7 +436,7 @@ wildcard_expand (const char *s, char ***strs)
|
||||||
|
|
||||||
else if (*start == '/') /* no device part */
|
else if (*start == '/') /* no device part */
|
||||||
{
|
{
|
||||||
char *root;
|
const char *root;
|
||||||
char *prefix;
|
char *prefix;
|
||||||
|
|
||||||
root = grub_env_get ("root");
|
root = grub_env_get ("root");
|
||||||
|
|
|
@ -51,10 +51,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
|
||||||
char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
|
char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
|
||||||
char *ptr;
|
char *ptr;
|
||||||
grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
|
grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
|
||||||
|
int low = 0;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
|
||||||
|
|
||||||
|
if (argc > 1 && grub_strcmp (args[0], "-l") == 0)
|
||||||
|
{
|
||||||
|
low = 1;
|
||||||
|
argc--;
|
||||||
|
args++;
|
||||||
|
}
|
||||||
|
|
||||||
serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
|
serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
|
||||||
|
|
||||||
GRUB_MD_MD5->init (&ctx);
|
GRUB_MD_MD5->init (&ctx);
|
||||||
|
@ -75,10 +83,11 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
|
||||||
(unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
|
(unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
|
||||||
(unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
|
(unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
|
||||||
(unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
|
(unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
|
||||||
for (ptr = uuid_string; *ptr; ptr++)
|
if (!low)
|
||||||
*ptr = grub_toupper (*ptr);
|
for (ptr = uuid_string; *ptr; ptr++)
|
||||||
|
*ptr = grub_toupper (*ptr);
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
grub_printf ("%s", uuid_string);
|
grub_printf ("%s\n", uuid_string);
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
grub_env_set (args[1], uuid_string);
|
grub_env_set (args[1], uuid_string);
|
||||||
|
|
||||||
|
@ -91,9 +100,10 @@ static grub_command_t cmd;
|
||||||
GRUB_MOD_INIT (xnu_uuid)
|
GRUB_MOD_INIT (xnu_uuid)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
|
cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
|
||||||
N_("GRUBUUID [VARNAME]"),
|
N_("[-l] GRUBUUID [VARNAME]"),
|
||||||
N_("Transform 64-bit UUID to format "
|
N_("Transform 64-bit UUID to format "
|
||||||
"suitable for XNU."));
|
"suitable for XNU. If -l is given keep "
|
||||||
|
"it lowercase as done by blkid."));
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI (xnu_uuid)
|
GRUB_MOD_FINI (xnu_uuid)
|
||||||
|
|
|
@ -305,7 +305,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
else
|
else
|
||||||
grub_dprintf ("ahci", "AHCI is already in OS mode\n");
|
grub_dprintf ("ahci", "AHCI is already in OS mode\n");
|
||||||
|
|
||||||
if (~(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN))
|
if (!(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN))
|
||||||
grub_dprintf ("ahci", "AHCI is in compat mode. Switching\n");
|
grub_dprintf ("ahci", "AHCI is in compat mode. Switching\n");
|
||||||
else
|
else
|
||||||
grub_dprintf ("ahci", "AHCI is in AHCI mode.\n");
|
grub_dprintf ("ahci", "AHCI is in AHCI mode.\n");
|
||||||
|
@ -706,7 +706,7 @@ static struct grub_ata_dev grub_ahci_dev =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void *fini_hnd;
|
static struct grub_preboot *fini_hnd;
|
||||||
|
|
||||||
GRUB_MOD_INIT(ahci)
|
GRUB_MOD_INIT(ahci)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,29 +29,27 @@ static grub_ata_dev_t grub_ata_dev_list;
|
||||||
|
|
||||||
/* Byteorder has to be changed before strings can be read. */
|
/* Byteorder has to be changed before strings can be read. */
|
||||||
static void
|
static void
|
||||||
grub_ata_strncpy (char *dst, char *src, grub_size_t len)
|
grub_ata_strncpy (grub_uint16_t *dst16, grub_uint16_t *src16, grub_size_t len)
|
||||||
{
|
{
|
||||||
grub_uint16_t *src16 = (grub_uint16_t *) src;
|
|
||||||
grub_uint16_t *dst16 = (grub_uint16_t *) dst;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < len / 2; i++)
|
for (i = 0; i < len / 2; i++)
|
||||||
*(dst16++) = grub_be_to_cpu16 (*(src16++));
|
*(dst16++) = grub_be_to_cpu16 (*(src16++));
|
||||||
dst[len] = '\0';
|
dst16[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_ata_dumpinfo (struct grub_ata *dev, char *info)
|
grub_ata_dumpinfo (struct grub_ata *dev, grub_uint16_t *info)
|
||||||
{
|
{
|
||||||
char text[41];
|
grub_uint16_t text[21];
|
||||||
|
|
||||||
/* The device information was read, dump it for debugging. */
|
/* The device information was read, dump it for debugging. */
|
||||||
grub_ata_strncpy (text, info + 20, 20);
|
grub_ata_strncpy (text, info + 10, 20);
|
||||||
grub_dprintf ("ata", "Serial: %s\n", text);
|
grub_dprintf ("ata", "Serial: %s\n", (char *) text);
|
||||||
grub_ata_strncpy (text, info + 46, 8);
|
grub_ata_strncpy (text, info + 23, 8);
|
||||||
grub_dprintf ("ata", "Firmware: %s\n", text);
|
grub_dprintf ("ata", "Firmware: %s\n", (char *) text);
|
||||||
grub_ata_strncpy (text, info + 54, 40);
|
grub_ata_strncpy (text, info + 27, 40);
|
||||||
grub_dprintf ("ata", "Model: %s\n", text);
|
grub_dprintf ("ata", "Model: %s\n", (char *) text);
|
||||||
|
|
||||||
if (! dev->atapi)
|
if (! dev->atapi)
|
||||||
{
|
{
|
||||||
|
@ -65,7 +63,7 @@ static grub_err_t
|
||||||
grub_atapi_identify (struct grub_ata *dev)
|
grub_atapi_identify (struct grub_ata *dev)
|
||||||
{
|
{
|
||||||
struct grub_disk_ata_pass_through_parms parms;
|
struct grub_disk_ata_pass_through_parms parms;
|
||||||
char *info;
|
grub_uint16_t *info;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
||||||
|
@ -105,17 +103,19 @@ static grub_err_t
|
||||||
grub_ata_identify (struct grub_ata *dev)
|
grub_ata_identify (struct grub_ata *dev)
|
||||||
{
|
{
|
||||||
struct grub_disk_ata_pass_through_parms parms;
|
struct grub_disk_ata_pass_through_parms parms;
|
||||||
char *info;
|
grub_uint64_t *info64;
|
||||||
|
grub_uint32_t *info32;
|
||||||
grub_uint16_t *info16;
|
grub_uint16_t *info16;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
||||||
if (! info)
|
info32 = (grub_uint32_t *) info64;
|
||||||
|
info16 = (grub_uint16_t *) info64;
|
||||||
|
if (! info16)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
info16 = (grub_uint16_t *) info;
|
|
||||||
grub_memset (&parms, 0, sizeof (parms));
|
grub_memset (&parms, 0, sizeof (parms));
|
||||||
parms.buffer = info;
|
parms.buffer = info16;
|
||||||
parms.size = GRUB_DISK_SECTOR_SIZE;
|
parms.size = GRUB_DISK_SECTOR_SIZE;
|
||||||
parms.taskfile.disk = 0xE0;
|
parms.taskfile.disk = 0xE0;
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ grub_ata_identify (struct grub_ata *dev)
|
||||||
if (err || parms.size != GRUB_DISK_SECTOR_SIZE)
|
if (err || parms.size != GRUB_DISK_SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
grub_uint8_t sts = parms.taskfile.status;
|
grub_uint8_t sts = parms.taskfile.status;
|
||||||
grub_free (info);
|
grub_free (info16);
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
|
if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
|
||||||
| GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
|
| GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
|
||||||
|
@ -167,14 +167,14 @@ grub_ata_identify (struct grub_ata *dev)
|
||||||
|
|
||||||
/* Determine the amount of sectors. */
|
/* Determine the amount of sectors. */
|
||||||
if (dev->addr != GRUB_ATA_LBA48)
|
if (dev->addr != GRUB_ATA_LBA48)
|
||||||
dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
|
dev->size = grub_le_to_cpu32 (info32[30]);
|
||||||
else
|
else
|
||||||
dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
|
dev->size = grub_le_to_cpu64 (info64[25]);
|
||||||
|
|
||||||
if (info16[106] & (1 << 12))
|
if (info16[106] & (1 << 12))
|
||||||
{
|
{
|
||||||
grub_uint32_t secsize;
|
grub_uint32_t secsize;
|
||||||
secsize = grub_le_to_cpu32 (*((grub_uint32_t *) &info16[117]));
|
secsize = grub_le_to_cpu32 (grub_get_unaligned32 (&info16[117]));
|
||||||
if (secsize & (secsize - 1) || !secsize
|
if (secsize & (secsize - 1) || !secsize
|
||||||
|| secsize > 1048576)
|
|| secsize > 1048576)
|
||||||
secsize = 256;
|
secsize = 256;
|
||||||
|
@ -191,9 +191,9 @@ grub_ata_identify (struct grub_ata *dev)
|
||||||
dev->heads = info16[3];
|
dev->heads = info16[3];
|
||||||
dev->sectors_per_track = info16[6];
|
dev->sectors_per_track = info16[6];
|
||||||
|
|
||||||
grub_ata_dumpinfo (dev, info);
|
grub_ata_dumpinfo (dev, info16);
|
||||||
|
|
||||||
grub_free(info);
|
grub_free (info16);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,6 +791,4 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
grub_disk_close (parent);
|
grub_disk_close (parent);
|
||||||
return device_name;
|
return device_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,38 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
/* Dirty trick to solve circular dependency. */
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
|
||||||
|
#include <grub/util/misc.h>
|
||||||
|
|
||||||
|
#undef GRUB_MD_SHA256
|
||||||
|
#undef GRUB_MD_SHA512
|
||||||
|
|
||||||
|
static const gcry_md_spec_t *
|
||||||
|
grub_md_sha256_real (void)
|
||||||
|
{
|
||||||
|
const gcry_md_spec_t *ret;
|
||||||
|
ret = grub_crypto_lookup_md_by_name ("sha256");
|
||||||
|
if (!ret)
|
||||||
|
grub_util_error ("Coulnd't load sha256");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gcry_md_spec_t *
|
||||||
|
grub_md_sha512_real (void)
|
||||||
|
{
|
||||||
|
const gcry_md_spec_t *ret;
|
||||||
|
ret = grub_crypto_lookup_md_by_name ("sha512");
|
||||||
|
if (!ret)
|
||||||
|
grub_util_error ("Coulnd't load sha512");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GRUB_MD_SHA256 grub_md_sha256_real()
|
||||||
|
#define GRUB_MD_SHA512 grub_md_sha512_real()
|
||||||
|
#endif
|
||||||
|
|
||||||
struct grub_geli_key
|
struct grub_geli_key
|
||||||
{
|
{
|
||||||
grub_uint8_t iv_key[64];
|
grub_uint8_t iv_key[64];
|
||||||
|
@ -194,7 +226,7 @@ grub_util_get_geli_uuid (const char *dev)
|
||||||
|
|
||||||
uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1);
|
uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1);
|
||||||
if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0)
|
if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0)
|
||||||
grub_util_error ("couldn't read ELI metadata");
|
grub_util_error (_("couldn't read ELI metadata"));
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (header) <= 512);
|
COMPILE_TIME_ASSERT (sizeof (header) <= 512);
|
||||||
header = (void *) &hdr;
|
header = (void *) &hdr;
|
||||||
|
@ -203,7 +235,7 @@ grub_util_get_geli_uuid (const char *dev)
|
||||||
if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC))
|
if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC))
|
||||||
|| grub_le_to_cpu32 (header->version) > 5
|
|| grub_le_to_cpu32 (header->version) > 5
|
||||||
|| grub_le_to_cpu32 (header->version) < 1)
|
|| grub_le_to_cpu32 (header->version) < 1)
|
||||||
grub_util_error ("wrong ELI magic or version");
|
grub_util_error (_("wrong ELI magic or version"));
|
||||||
|
|
||||||
err = make_uuid ((void *) &hdr, uuid);
|
err = make_uuid ((void *) &hdr, uuid);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -386,15 +418,15 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
keysize = grub_le_to_cpu16 (header.keylen) / 8;
|
keysize = grub_le_to_cpu16 (header.keylen) / 8;
|
||||||
grub_memset (zero, 0, sizeof (zero));
|
grub_memset (zero, 0, sizeof (zero));
|
||||||
|
|
||||||
grub_printf ("Attempting to decrypt master key...\n");
|
grub_puts_ (N_("Attempting to decrypt master key..."));
|
||||||
|
|
||||||
/* Get the passphrase from the user. */
|
/* Get the passphrase from the user. */
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
if (source->partition)
|
if (source->partition)
|
||||||
tmp = grub_partition_get_name (source->partition);
|
tmp = grub_partition_get_name (source->partition);
|
||||||
grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name,
|
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||||
source->partition ? "," : "", tmp ? : "",
|
source->partition ? "," : "", tmp ? : "",
|
||||||
dev->uuid);
|
dev->uuid);
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
||||||
|
@ -481,7 +513,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
|
|
||||||
if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0)
|
if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0)
|
||||||
continue;
|
continue;
|
||||||
grub_printf ("Slot %d opened\n", i);
|
grub_printf_ (N_("Slot %d opened\n"), i);
|
||||||
|
|
||||||
/* Set the master key. */
|
/* Set the master key. */
|
||||||
if (!dev->rekey)
|
if (!dev->rekey)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -621,11 +622,12 @@ grub_disk_biosdisk_fini (void)
|
||||||
GRUB_MOD_INIT(biosdisk)
|
GRUB_MOD_INIT(biosdisk)
|
||||||
{
|
{
|
||||||
struct grub_biosdisk_cdrp *cdrp
|
struct grub_biosdisk_cdrp *cdrp
|
||||||
= (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
|
= (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
|
||||||
|
grub_uint8_t boot_drive;
|
||||||
|
|
||||||
if (grub_disk_firmware_is_tainted)
|
if (grub_disk_firmware_is_tainted)
|
||||||
{
|
{
|
||||||
grub_printf ("Firmware is marked as tainted, refusing to initialize.\n");
|
grub_puts_ (N_("Firmware is marked as tainted, refusing to initialize."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
grub_disk_firmware_fini = grub_disk_biosdisk_fini;
|
grub_disk_firmware_fini = grub_disk_biosdisk_fini;
|
||||||
|
@ -633,15 +635,16 @@ GRUB_MOD_INIT(biosdisk)
|
||||||
grub_memset (cdrp, 0, sizeof (*cdrp));
|
grub_memset (cdrp, 0, sizeof (*cdrp));
|
||||||
cdrp->size = sizeof (*cdrp);
|
cdrp->size = sizeof (*cdrp);
|
||||||
cdrp->media_type = 0xFF;
|
cdrp->media_type = 0xFF;
|
||||||
if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) &&
|
boot_drive = (grub_boot_device >> 24);
|
||||||
((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
|
if ((! grub_biosdisk_get_cdinfo_int13_extensions (boot_drive, cdrp))
|
||||||
== GRUB_BIOSDISK_CDTYPE_NO_EMUL))
|
&& ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
|
||||||
|
== GRUB_BIOSDISK_CDTYPE_NO_EMUL))
|
||||||
cd_drive = cdrp->drive_no;
|
cd_drive = cdrp->drive_no;
|
||||||
/* Since diskboot.S rejects devices over 0x90 it must be a CD booted with
|
/* Since diskboot.S rejects devices over 0x90 it must be a CD booted with
|
||||||
cdboot.S
|
cdboot.S
|
||||||
*/
|
*/
|
||||||
if (grub_boot_drive >= 0x90)
|
if (boot_drive >= 0x90)
|
||||||
cd_drive = grub_boot_drive;
|
cd_drive = boot_drive;
|
||||||
|
|
||||||
grub_disk_dev_register (&grub_biosdisk_dev);
|
grub_disk_dev_register (&grub_biosdisk_dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,7 +316,7 @@ luks_recover_key (grub_disk_t source,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
grub_printf ("Attempting to decrypt master key...\n");
|
grub_puts_ (N_("Attempting to decrypt master key..."));
|
||||||
keysize = grub_be_to_cpu32 (header.keyBytes);
|
keysize = grub_be_to_cpu32 (header.keyBytes);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
||||||
|
@ -332,7 +332,7 @@ luks_recover_key (grub_disk_t source,
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
if (source->partition)
|
if (source->partition)
|
||||||
tmp = grub_partition_get_name (source->partition);
|
tmp = grub_partition_get_name (source->partition);
|
||||||
grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name,
|
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||||
source->partition ? "," : "", tmp ? : "",
|
source->partition ? "," : "", tmp ? : "",
|
||||||
dev->uuid);
|
dev->uuid);
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
|
@ -434,7 +434,7 @@ luks_recover_key (grub_disk_t source,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_printf ("Slot %d opened\n", i);
|
grub_printf_ (N_("Slot %d opened\n"), i);
|
||||||
|
|
||||||
/* Set the master key. */
|
/* Set the master key. */
|
||||||
gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
|
gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* lvm.c - module to read Logical Volumes. */
|
/* lvm.c - module to read Logical Volumes. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
|
* Copyright (C) 2006,2007,2008,2009,2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/lvm.h>
|
#include <grub/lvm.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/emu/misc.h>
|
#include <grub/emu/misc.h>
|
||||||
|
@ -42,7 +44,7 @@ static int is_lv_readable (struct grub_lvm_lv *lv);
|
||||||
at the number. In case STR is not found, *P will be NULL and the
|
at the number. In case STR is not found, *P will be NULL and the
|
||||||
return value will be 0. */
|
return value will be 0. */
|
||||||
static int
|
static int
|
||||||
grub_lvm_getvalue (char **p, char *str)
|
grub_lvm_getvalue (char **p, const char *str)
|
||||||
{
|
{
|
||||||
*p = grub_strstr (*p, str);
|
*p = grub_strstr (*p, str);
|
||||||
if (! *p)
|
if (! *p)
|
||||||
|
@ -67,7 +69,7 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_lvm_check_flag (char *p, char *str, char *flag)
|
grub_lvm_check_flag (char *p, const char *str, const char *flag)
|
||||||
{
|
{
|
||||||
int len_str = grub_strlen (str), len_flag = grub_strlen (flag);
|
int len_str = grub_strlen (str), len_flag = grub_strlen (flag);
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -153,7 +155,11 @@ do_lvm_scan (const char *scan_for)
|
||||||
for (vg = vg_list; vg; vg = vg->next)
|
for (vg = vg_list; vg; vg = vg->next)
|
||||||
for (pv = vg->pvs; pv; pv = pv->next)
|
for (pv = vg->pvs; pv; pv = pv->next)
|
||||||
if (pv->disk && pv->disk->id == disk->id
|
if (pv->disk && pv->disk->id == disk->id
|
||||||
&& pv->disk->dev->id == disk->dev->id)
|
&& pv->disk->dev->id == disk->dev->id
|
||||||
|
&& grub_partition_get_start (pv->disk->partition)
|
||||||
|
== grub_partition_get_start (disk->partition)
|
||||||
|
&& grub_disk_get_size (pv->disk)
|
||||||
|
== grub_disk_get_size (disk))
|
||||||
{
|
{
|
||||||
grub_disk_close (disk);
|
grub_disk_close (disk);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -770,7 +776,7 @@ grub_lvm_memberlist (grub_disk_t disk)
|
||||||
for (pv = lv->vg->pvs; pv; pv = pv->next)
|
for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||||
{
|
{
|
||||||
if (!pv->disk)
|
if (!pv->disk)
|
||||||
grub_util_error ("Couldn't find PV %s. Check your device.map",
|
grub_util_error (_("Couldn't find PV %s. Check your device.map"),
|
||||||
pv->name);
|
pv->name);
|
||||||
tmp = grub_malloc (sizeof (*tmp));
|
tmp = grub_malloc (sizeof (*tmp));
|
||||||
tmp->disk = pv->disk;
|
tmp->disk = pv->disk;
|
||||||
|
|
|
@ -216,11 +216,11 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
|
||||||
array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9;
|
array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9;
|
||||||
array->index = grub_le_to_cpu32 (sb.this_disk.number);
|
array->index = grub_le_to_cpu32 (sb.this_disk.number);
|
||||||
array->uuid_len = 16;
|
array->uuid_len = 16;
|
||||||
array->uuid = grub_malloc (16);
|
uuid = grub_malloc (16);
|
||||||
|
array->uuid = (char *) uuid;
|
||||||
if (!array->uuid)
|
if (!array->uuid)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
uuid = (grub_uint32_t *) array->uuid;
|
|
||||||
uuid[0] = grub_swap_bytes32 (sb.set_uuid0);
|
uuid[0] = grub_swap_bytes32 (sb.set_uuid0);
|
||||||
uuid[1] = grub_swap_bytes32 (sb.set_uuid1);
|
uuid[1] = grub_swap_bytes32 (sb.set_uuid1);
|
||||||
uuid[2] = grub_swap_bytes32 (sb.set_uuid2);
|
uuid[2] = grub_swap_bytes32 (sb.set_uuid2);
|
||||||
|
|
|
@ -86,30 +86,24 @@ static struct grub_disk_dev grub_memdisk_dev =
|
||||||
|
|
||||||
GRUB_MOD_INIT(memdisk)
|
GRUB_MOD_INIT(memdisk)
|
||||||
{
|
{
|
||||||
auto int hook (struct grub_module_header *);
|
struct grub_module_header *header;
|
||||||
int hook (struct grub_module_header *header)
|
FOR_MODULES (header)
|
||||||
{
|
if (header->type == OBJ_TYPE_MEMDISK)
|
||||||
if (header->type == OBJ_TYPE_MEMDISK)
|
{
|
||||||
{
|
char *memdisk_orig_addr;
|
||||||
char *memdisk_orig_addr;
|
memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
|
||||||
memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
|
|
||||||
|
|
||||||
grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
|
grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
|
||||||
|
|
||||||
memdisk_size = header->size - sizeof (struct grub_module_header);
|
memdisk_size = header->size - sizeof (struct grub_module_header);
|
||||||
memdisk_addr = grub_malloc (memdisk_size);
|
memdisk_addr = grub_malloc (memdisk_size);
|
||||||
|
|
||||||
grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
|
grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
|
||||||
grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
|
grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
|
||||||
|
|
||||||
grub_disk_dev_register (&grub_memdisk_dev);
|
grub_disk_dev_register (&grub_memdisk_dev);
|
||||||
return 1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_module_iterate (hook);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(memdisk)
|
GRUB_MOD_FINI(memdisk)
|
||||||
|
|
|
@ -116,12 +116,13 @@ grub_pata_wait (void)
|
||||||
static void
|
static void
|
||||||
grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size)
|
grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size)
|
||||||
{
|
{
|
||||||
grub_uint16_t *buf16 = (grub_uint16_t *) buf;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Read in the data, word by word. */
|
/* Read in the data, word by word. */
|
||||||
for (i = 0; i < size / 2; i++)
|
for (i = 0; i < size / 2; i++)
|
||||||
buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
|
grub_set_unaligned16 (buf + 2 * i,
|
||||||
|
grub_le_to_cpu16 (grub_inw(dev->ioaddress
|
||||||
|
+ GRUB_ATA_REG_DATA)));
|
||||||
if (size & 1)
|
if (size & 1)
|
||||||
buf[size - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress
|
buf[size - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress
|
||||||
+ GRUB_ATA_REG_DATA));
|
+ GRUB_ATA_REG_DATA));
|
||||||
|
@ -130,12 +131,11 @@ grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size)
|
||||||
static void
|
static void
|
||||||
grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size)
|
grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size)
|
||||||
{
|
{
|
||||||
grub_uint16_t *buf16 = (grub_uint16_t *) buf;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Write the data, word by word. */
|
/* Write the data, word by word. */
|
||||||
for (i = 0; i < size / 2; i++)
|
for (i = 0; i < size / 2; i++)
|
||||||
grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
|
grub_outw(grub_cpu_to_le16 (grub_get_unaligned16 (buf + 2 * i)), dev->ioaddress + GRUB_ATA_REG_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ATA pass through support, used by hdparm.mod. */
|
/* ATA pass through support, used by hdparm.mod. */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/raid.h>
|
#include <grub/raid.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/util/misc.h>
|
#include <grub/util/misc.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,7 +120,11 @@ scan_devices (const char *arname)
|
||||||
struct grub_raid_member *m;
|
struct grub_raid_member *m;
|
||||||
for (m = arr->members; m < arr->members + arr->nr_devs; m++)
|
for (m = arr->members; m < arr->members + arr->nr_devs; m++)
|
||||||
if (m->device && m->device->id == disk->id
|
if (m->device && m->device->id == disk->id
|
||||||
&& m->device->dev->id == m->device->dev->id)
|
&& m->device->dev->id == disk->dev->id
|
||||||
|
&& grub_partition_get_start (m->device->partition)
|
||||||
|
== grub_partition_get_start (disk->partition)
|
||||||
|
&& grub_disk_get_size (m->device)
|
||||||
|
== grub_disk_get_size (disk))
|
||||||
{
|
{
|
||||||
grub_disk_close (disk);
|
grub_disk_close (disk);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -327,23 +332,6 @@ grub_raid_close (grub_disk_t disk __attribute ((unused)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
grub_raid_block_xor (char *buf1, const char *buf2, int size)
|
|
||||||
{
|
|
||||||
grub_size_t *p1;
|
|
||||||
const grub_size_t *p2;
|
|
||||||
|
|
||||||
p1 = (grub_size_t *) buf1;
|
|
||||||
p2 = (const grub_size_t *) buf2;
|
|
||||||
size /= GRUB_CPU_SIZEOF_VOID_P;
|
|
||||||
|
|
||||||
while (size)
|
|
||||||
{
|
|
||||||
*(p1++) ^= *(p2++);
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
grub_size_t size, char *buf)
|
grub_size_t size, char *buf)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/raid.h>
|
#include <grub/raid.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_raid_block_xor (buf, buf2, size);
|
grub_crypto_xor (buf, buf2, buf2, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_free (buf2);
|
grub_free (buf2);
|
||||||
|
|
|
@ -23,70 +23,44 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/raid.h>
|
#include <grub/raid.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_uint8_t raid6_table1[256][256];
|
/* x**y. */
|
||||||
static grub_uint8_t raid6_table2[256][256];
|
static grub_uint8_t powx[255 * 2];
|
||||||
|
/* Such an s that x**s = y */
|
||||||
|
static int powx_inv[256];
|
||||||
|
static const grub_uint8_t poly = 0x1d;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
|
grub_raid_block_mulx (int mul, char *buf, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
grub_uint8_t *p;
|
grub_uint8_t *p;
|
||||||
|
|
||||||
p = (grub_uint8_t *) buf;
|
p = (grub_uint8_t *) buf;
|
||||||
for (i = 0; i < size; i++, p++)
|
for (i = 0; i < size; i++, p++)
|
||||||
*p = raid6_table1[mul][*p];
|
if (*p)
|
||||||
|
*p = powx[mul + powx_inv[*p]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_raid6_init_table (void)
|
grub_raid6_init_table (void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
grub_uint8_t cur = 1;
|
||||||
raid6_table1[i][1] = raid6_table1[1][i] = i;
|
for (i = 0; i < 255; i++)
|
||||||
|
{
|
||||||
for (i = 2; i < 256; i++)
|
powx[i] = cur;
|
||||||
for (j = i; j < 256; j++)
|
powx[i + 255] = cur;
|
||||||
{
|
powx_inv[cur] = i;
|
||||||
int n;
|
if (cur & 0x80)
|
||||||
grub_uint8_t c;
|
cur = (cur << 1) ^ poly;
|
||||||
|
else
|
||||||
n = i >> 1;
|
cur <<= 1;
|
||||||
|
}
|
||||||
c = raid6_table1[n][j];
|
|
||||||
c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
|
|
||||||
if (i & 1)
|
|
||||||
c ^= j;
|
|
||||||
|
|
||||||
raid6_table1[j][i] = raid6_table1[i][j] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
raid6_table2[0][0] = 1;
|
|
||||||
for (i = 1; i < 256; i++)
|
|
||||||
raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
|
|
||||||
|
|
||||||
for (i = 0; i < 254; i++)
|
|
||||||
for (j = 0; j < 254; j++)
|
|
||||||
{
|
|
||||||
grub_uint8_t c, n;
|
|
||||||
int k;
|
|
||||||
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
k = i - j;
|
|
||||||
if (k < 0)
|
|
||||||
k += 255;
|
|
||||||
|
|
||||||
c = n = raid6_table2[k][k] ^ 1;
|
|
||||||
for (k = 0; k < 253; k++)
|
|
||||||
c = raid6_table1[c][n];
|
|
||||||
|
|
||||||
raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -122,12 +96,12 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
{
|
{
|
||||||
if ((array->members[pos].device) &&
|
if ((array->members[pos].device) &&
|
||||||
(! grub_disk_read (array->members[pos].device,
|
(! grub_disk_read (array->members[pos].device,
|
||||||
array->members[i].start_sector + sector,
|
array->members[pos].start_sector + sector,
|
||||||
0, size, buf)))
|
0, size, buf)))
|
||||||
{
|
{
|
||||||
grub_raid_block_xor (pbuf, buf, size);
|
grub_crypto_xor (pbuf, pbuf, buf, size);
|
||||||
grub_raid_block_mul (raid6_table2[i][i], buf, size);
|
grub_raid_block_mulx (i, buf, size);
|
||||||
grub_raid_block_xor (qbuf, buf, size);
|
grub_crypto_xor (qbuf, qbuf, buf, size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -154,10 +128,10 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
/* One bad device */
|
/* One bad device */
|
||||||
if ((array->members[p].device) &&
|
if ((array->members[p].device) &&
|
||||||
(! grub_disk_read (array->members[p].device,
|
(! grub_disk_read (array->members[p].device,
|
||||||
array->members[i].start_sector + sector,
|
array->members[p].start_sector + sector,
|
||||||
0, size, buf)))
|
0, size, buf)))
|
||||||
{
|
{
|
||||||
grub_raid_block_xor (buf, pbuf, size);
|
grub_crypto_xor (buf, buf, pbuf, size);
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,17 +143,17 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
if (grub_disk_read (array->members[q].device,
|
if (grub_disk_read (array->members[q].device,
|
||||||
array->members[i].start_sector + sector, 0, size, buf))
|
array->members[q].start_sector + sector, 0, size, buf))
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
grub_raid_block_xor (buf, qbuf, size);
|
grub_crypto_xor (buf, buf, qbuf, size);
|
||||||
grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
|
grub_raid_block_mulx (255 - bad1, buf,
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Two bad devices */
|
/* Two bad devices */
|
||||||
grub_uint8_t c;
|
int c;
|
||||||
|
|
||||||
if ((! array->members[p].device) || (! array->members[q].device))
|
if ((! array->members[p].device) || (! array->members[q].device))
|
||||||
{
|
{
|
||||||
|
@ -188,26 +162,26 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_disk_read (array->members[p].device,
|
if (grub_disk_read (array->members[p].device,
|
||||||
array->members[i].start_sector + sector,
|
array->members[p].start_sector + sector,
|
||||||
0, size, buf))
|
0, size, buf))
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
grub_raid_block_xor (pbuf, buf, size);
|
grub_crypto_xor (pbuf, pbuf, buf, size);
|
||||||
|
|
||||||
if (grub_disk_read (array->members[q].device,
|
if (grub_disk_read (array->members[q].device,
|
||||||
array->members[i].start_sector + sector,
|
array->members[q].start_sector + sector,
|
||||||
0, size, buf))
|
0, size, buf))
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
grub_raid_block_xor (qbuf, buf, size);
|
grub_crypto_xor (qbuf, qbuf, buf, size);
|
||||||
|
|
||||||
c = raid6_table2[bad2][bad1];
|
c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255;
|
||||||
grub_raid_block_mul (c, qbuf, size);
|
grub_raid_block_mulx (c, qbuf, size);
|
||||||
|
|
||||||
c = raid6_table1[raid6_table2[bad2][bad2]][c];
|
c = (bad2 + c) % 255;
|
||||||
grub_raid_block_mul (c, pbuf, size);
|
grub_raid_block_mulx (c, pbuf, size);
|
||||||
|
|
||||||
grub_raid_block_xor (pbuf, qbuf, size);
|
grub_crypto_xor (pbuf, pbuf, qbuf, size);
|
||||||
grub_memcpy (buf, pbuf, size);
|
grub_memcpy (buf, pbuf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#define bit_LM (1 << 29)
|
#define bit_LM (1 << 29)
|
||||||
|
|
||||||
char *
|
const char *
|
||||||
grub_efiemu_get_default_core_name (void)
|
grub_efiemu_get_default_core_name (void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,8 @@ grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
|
||||||
if (! get_table && ! data)
|
if (! get_table && ! data)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
"you must set at least get_table or data");
|
"you must set at least get_table or data");
|
||||||
if ((err = grub_efiemu_unregister_configuration_table (guid)))
|
err = grub_efiemu_unregister_configuration_table (guid);
|
||||||
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
|
tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
|
||||||
|
@ -226,7 +227,7 @@ grub_efiemu_autocore (void)
|
||||||
{
|
{
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
char *filename;
|
char *filename;
|
||||||
char *suffix;
|
const char *suffix;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
if (grub_efiemu_sizeof_uintn_t () != 0)
|
if (grub_efiemu_sizeof_uintn_t () != 0)
|
||||||
|
|
|
@ -201,10 +201,10 @@ efiemu_alloc_requests (void)
|
||||||
- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
|
- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
|
||||||
if (align_overhead == GRUB_EFIEMU_PAGESIZE)
|
if (align_overhead == GRUB_EFIEMU_PAGESIZE)
|
||||||
align_overhead = 0;
|
align_overhead = 0;
|
||||||
curptr = ((grub_uint8_t *)curptr) + align_overhead;
|
curptr = ((grub_uint8_t *) curptr) + align_overhead;
|
||||||
|
|
||||||
/* Add the region to memory map */
|
/* Add the region to memory map */
|
||||||
grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
|
grub_efiemu_add_to_mmap ((grub_addr_t) typestart,
|
||||||
curptr - typestart, reqorder[i]);
|
curptr - typestart, reqorder[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +404,8 @@ grub_efiemu_mmap_fill (void)
|
||||||
GRUB_EFI_ACPI_MEMORY_NVS);
|
GRUB_EFI_ACPI_MEMORY_NVS);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
grub_printf ("Unknown memory type %d. Assuming unusable\n", type);
|
grub_dprintf ("efiemu",
|
||||||
|
"Unknown memory type %d. Assuming unusable\n", type);
|
||||||
case GRUB_MEMORY_RESERVED:
|
case GRUB_MEMORY_RESERVED:
|
||||||
return grub_efiemu_add_to_mmap (addr, size,
|
return grub_efiemu_add_to_mmap (addr, size,
|
||||||
GRUB_EFI_UNUSABLE_MEMORY);
|
GRUB_EFI_UNUSABLE_MEMORY);
|
||||||
|
|
|
@ -97,10 +97,9 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
|
||||||
grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
|
grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
|
||||||
sizeof (cur->guid));
|
sizeof (cur->guid));
|
||||||
if (cur->get_table)
|
if (cur->get_table)
|
||||||
conftables[i].vendor_table
|
conftables[i].vendor_table = (grub_addr_t) cur->get_table (cur->data);
|
||||||
= PTR_TO_UINT64 (cur->get_table (cur->data));
|
|
||||||
else
|
else
|
||||||
conftables[i].vendor_table = PTR_TO_UINT64 (cur->data);
|
conftables[i].vendor_table = (grub_addr_t) cur->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = SUFFIX (grub_efiemu_crc) ();
|
err = SUFFIX (grub_efiemu_crc) ();
|
||||||
|
|
|
@ -169,7 +169,7 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle,
|
||||||
else
|
else
|
||||||
ptv_rels[ptv_written].plustype = 0;
|
ptv_rels[ptv_written].plustype = 0;
|
||||||
|
|
||||||
ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
|
ptv_rels[ptv_written].addr = (grub_addr_t) addr;
|
||||||
ptv_rels[ptv_written].size = size;
|
ptv_rels[ptv_written].size = size;
|
||||||
ptv_written++;
|
ptv_written++;
|
||||||
|
|
||||||
|
@ -179,10 +179,10 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle,
|
||||||
|
|
||||||
/* Compute the value */
|
/* Compute the value */
|
||||||
if (minus_handle)
|
if (minus_handle)
|
||||||
value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle));
|
value -= (grub_addr_t) grub_efiemu_mm_obtain_request (minus_handle);
|
||||||
|
|
||||||
if (plus_handle)
|
if (plus_handle)
|
||||||
value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle));
|
value += (grub_addr_t) grub_efiemu_mm_obtain_request (plus_handle);
|
||||||
|
|
||||||
/* Write the value */
|
/* Write the value */
|
||||||
switch (size)
|
switch (size)
|
||||||
|
@ -248,16 +248,16 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
|
||||||
switch (cur_relloc->size)
|
switch (cur_relloc->size)
|
||||||
{
|
{
|
||||||
case 8:
|
case 8:
|
||||||
*((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
|
*((grub_uint64_t *) (grub_addr_t) cur_relloc->addr) += corr;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
*((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
|
*((grub_uint32_t *) (grub_addr_t) cur_relloc->addr) += corr;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
*((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
|
*((grub_uint16_t *) (grub_addr_t) cur_relloc->addr) += corr;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
*((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
|
*((grub_uint8_t *) (grub_addr_t) cur_relloc->addr) += corr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,7 +608,7 @@ grub_font_load (const char *filename)
|
||||||
|
|
||||||
if (!font->name)
|
if (!font->name)
|
||||||
{
|
{
|
||||||
grub_printf ("Note: Font has no name.\n");
|
grub_dprintf ("font", "Font has no name.\n");
|
||||||
font->name = grub_strdup ("Unknown");
|
font->name = grub_strdup ("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
struct grub_font_node *node;
|
struct grub_font_node *node;
|
||||||
|
|
||||||
grub_printf ("Loaded fonts:\n");
|
grub_puts_ (N_("Loaded fonts:"));
|
||||||
for (node = grub_font_list; node; node = node->next)
|
for (node = grub_font_list; node; node = node->next)
|
||||||
{
|
{
|
||||||
grub_font_t font = node->value;
|
grub_font_t font = node->value;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -32,15 +33,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
struct grub_affs_bblock
|
struct grub_affs_bblock
|
||||||
{
|
{
|
||||||
grub_uint8_t type[3];
|
grub_uint8_t type[3];
|
||||||
grub_uint8_t flags;
|
grub_uint8_t version;
|
||||||
grub_uint32_t checksum;
|
grub_uint32_t checksum;
|
||||||
grub_uint32_t rootblock;
|
grub_uint32_t rootblock;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Set if the filesystem is a AFFS filesystem. Otherwise this is an
|
|
||||||
OFS filesystem. */
|
|
||||||
#define GRUB_AFFS_FLAG_FFS 1
|
|
||||||
|
|
||||||
/* The affs rootblock. */
|
/* The affs rootblock. */
|
||||||
struct grub_affs_rblock
|
struct grub_affs_rblock
|
||||||
{
|
{
|
||||||
|
@ -85,19 +82,19 @@ struct grub_affs_file
|
||||||
#define GRUB_AFFS_BLOCKPTR_OFFSET 24
|
#define GRUB_AFFS_BLOCKPTR_OFFSET 24
|
||||||
#define GRUB_AFFS_SYMLINK_OFFSET 24
|
#define GRUB_AFFS_SYMLINK_OFFSET 24
|
||||||
|
|
||||||
#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225)
|
#define GRUB_AFFS_FILETYPE_REG 0xfffffffd
|
||||||
|
#define GRUB_AFFS_FILETYPE_DIR 2
|
||||||
#define GRUB_AFFS_FILETYPE_DIR -3
|
|
||||||
#define GRUB_AFFS_FILETYPE_REG 2
|
|
||||||
#define GRUB_AFFS_FILETYPE_SYMLINK 3
|
#define GRUB_AFFS_FILETYPE_SYMLINK 3
|
||||||
|
|
||||||
|
|
||||||
struct grub_fshelp_node
|
struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_affs_data *data;
|
struct grub_affs_data *data;
|
||||||
grub_disk_addr_t block;
|
grub_uint32_t block;
|
||||||
struct grub_fshelp_node *parent;
|
struct grub_fshelp_node *parent;
|
||||||
struct grub_affs_file di;
|
struct grub_affs_file di;
|
||||||
|
grub_uint32_t *block_cache;
|
||||||
|
grub_uint32_t last_block_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about a "mounted" affs filesystem. */
|
/* Information about a "mounted" affs filesystem. */
|
||||||
|
@ -120,32 +117,46 @@ static grub_dl_t my_mod;
|
||||||
static grub_disk_addr_t
|
static grub_disk_addr_t
|
||||||
grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
{
|
{
|
||||||
int links;
|
grub_uint32_t target, curblock;
|
||||||
grub_uint32_t pos;
|
grub_uint32_t pos;
|
||||||
int block = node->block;
|
|
||||||
struct grub_affs_file file;
|
struct grub_affs_file file;
|
||||||
struct grub_affs_data *data = node->data;
|
struct grub_affs_data *data = node->data;
|
||||||
grub_uint64_t mod;
|
grub_uint64_t mod;
|
||||||
|
|
||||||
|
if (!node->block_cache)
|
||||||
|
{
|
||||||
|
node->block_cache = grub_malloc ((((grub_be_to_cpu32 (node->di.size)
|
||||||
|
+ 511) >> 9) / data->htsize + 1)
|
||||||
|
* sizeof (node->block_cache[0]));
|
||||||
|
if (!node->block_cache)
|
||||||
|
return -1;
|
||||||
|
node->last_block_cache = 0;
|
||||||
|
node->block_cache[0] = node->block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Files are at most 2G on AFFS, so no need for 64-bit division. */
|
||||||
|
target = (grub_uint32_t) fileblock / data->htsize;
|
||||||
|
mod = (grub_uint32_t) fileblock % data->htsize;
|
||||||
/* Find the block that points to the fileblock we are looking up by
|
/* Find the block that points to the fileblock we are looking up by
|
||||||
following the chain until the right table is reached. */
|
following the chain until the right table is reached. */
|
||||||
for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
|
for (curblock = node->last_block_cache + 1; curblock <= target; curblock++)
|
||||||
{
|
{
|
||||||
grub_disk_read (data->disk, block + data->blocksize - 1,
|
grub_disk_read (data->disk,
|
||||||
|
node->block_cache[curblock - 1] + data->blocksize - 1,
|
||||||
data->blocksize * (GRUB_DISK_SECTOR_SIZE
|
data->blocksize * (GRUB_DISK_SECTOR_SIZE
|
||||||
- GRUB_AFFS_FILE_LOCATION),
|
- GRUB_AFFS_FILE_LOCATION),
|
||||||
sizeof (file), &file);
|
sizeof (file), &file);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
block = grub_be_to_cpu32 (file.extension);
|
node->block_cache[curblock] = grub_be_to_cpu32 (file.extension);
|
||||||
|
node->last_block_cache = curblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate the fileblock to the block within the right table. */
|
/* Translate the fileblock to the block within the right table. */
|
||||||
fileblock = mod;
|
grub_disk_read (data->disk, node->block_cache[target],
|
||||||
grub_disk_read (data->disk, block,
|
|
||||||
GRUB_AFFS_BLOCKPTR_OFFSET
|
GRUB_AFFS_BLOCKPTR_OFFSET
|
||||||
+ (data->htsize - fileblock - 1) * sizeof (pos),
|
+ (data->htsize - mod - 1) * sizeof (pos),
|
||||||
sizeof (pos), &pos);
|
sizeof (pos), &pos);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -153,21 +164,6 @@ grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
return grub_be_to_cpu32 (pos);
|
return grub_be_to_cpu32 (pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read LEN bytes from the file described by DATA starting with byte
|
|
||||||
POS. Return the amount of read bytes in READ. */
|
|
||||||
static grub_ssize_t
|
|
||||||
grub_affs_read_file (grub_fshelp_node_t node,
|
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
|
||||||
unsigned offset, unsigned length),
|
|
||||||
int pos, grub_size_t len, char *buf)
|
|
||||||
{
|
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
|
||||||
pos, len, buf, grub_affs_read_block,
|
|
||||||
grub_be_to_cpu32 (node->di.size), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct grub_affs_data *
|
static struct grub_affs_data *
|
||||||
grub_affs_mount (grub_disk_t disk)
|
grub_affs_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +174,7 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
int checksum = 0;
|
int checksum = 0;
|
||||||
int blocksize = 0;
|
int blocksize = 0;
|
||||||
|
|
||||||
data = grub_malloc (sizeof (struct grub_affs_data));
|
data = grub_zalloc (sizeof (struct grub_affs_data));
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -196,18 +192,12 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test if the filesystem is a OFS filesystem. */
|
/* Test if the filesystem is a OFS filesystem. */
|
||||||
if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
|
if (data->bblock.version < 1)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
|
grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the bootblock. */
|
|
||||||
grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
|
|
||||||
&data->bblock);
|
|
||||||
if (grub_errno)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* No sane person uses more than 8KB for a block. At least I hope
|
/* No sane person uses more than 8KB for a block. At least I hope
|
||||||
for that person because in that case this won't work. */
|
for that person because in that case this won't work. */
|
||||||
rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
|
rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
|
||||||
|
@ -270,18 +260,21 @@ grub_affs_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
struct grub_affs_data *data = node->data;
|
struct grub_affs_data *data = node->data;
|
||||||
char *symlink;
|
char *symlink;
|
||||||
|
const grub_size_t symlink_size = (data->blocksize * GRUB_DISK_SECTOR_SIZE
|
||||||
|
- 225);
|
||||||
|
|
||||||
symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
|
symlink = grub_malloc (symlink_size + 1);
|
||||||
if (!symlink)
|
if (!symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
|
grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
|
||||||
GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
|
symlink_size, symlink);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
{
|
{
|
||||||
grub_free (symlink);
|
grub_free (symlink);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
symlink[symlink_size] = 1;
|
||||||
grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
|
grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
|
||||||
return symlink;
|
return symlink;
|
||||||
}
|
}
|
||||||
|
@ -300,25 +293,25 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
struct grub_affs_data *data = dir->data;
|
struct grub_affs_data *data = dir->data;
|
||||||
grub_uint32_t *hashtable;
|
grub_uint32_t *hashtable;
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
|
auto int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block,
|
||||||
grub_disk_addr_t block,
|
|
||||||
const struct grub_affs_file *fil);
|
const struct grub_affs_file *fil);
|
||||||
|
|
||||||
int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
|
int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block,
|
||||||
grub_disk_addr_t block,
|
|
||||||
const struct grub_affs_file *fil)
|
const struct grub_affs_file *fil)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
node = grub_malloc (sizeof (*node));
|
grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1];
|
||||||
|
|
||||||
|
node = grub_zalloc (sizeof (*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
grub_free (hashtable);
|
grub_free (hashtable);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR)
|
if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG)
|
||||||
type = GRUB_FSHELP_REG;
|
type = GRUB_FSHELP_REG;
|
||||||
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG)
|
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR)
|
||||||
type = GRUB_FSHELP_DIR;
|
type = GRUB_FSHELP_DIR;
|
||||||
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK)
|
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK)
|
||||||
type = GRUB_FSHELP_SYMLINK;
|
type = GRUB_FSHELP_SYMLINK;
|
||||||
|
@ -330,7 +323,10 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
node->di = *fil;
|
node->di = *fil;
|
||||||
node->parent = dir;
|
node->parent = dir;
|
||||||
|
|
||||||
if (hook (name, type, node))
|
*grub_latin1_to_utf8 (name_u8, fil->name,
|
||||||
|
grub_min (fil->namelen, sizeof (fil->name))) = '\0';
|
||||||
|
|
||||||
|
if (hook ((char *) name_u8, type, node))
|
||||||
{
|
{
|
||||||
grub_free (hashtable);
|
grub_free (hashtable);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -339,7 +335,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the directory entries for `.' and `..'. */
|
/* Create the directory entries for `.' and `..'. */
|
||||||
node = grub_malloc (sizeof (*node));
|
node = grub_zalloc (sizeof (*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -348,7 +344,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
if (dir->parent)
|
if (dir->parent)
|
||||||
{
|
{
|
||||||
node = grub_malloc (sizeof (*node));
|
node = grub_zalloc (sizeof (*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
return 1;
|
return 1;
|
||||||
*node = *dir->parent;
|
*node = *dir->parent;
|
||||||
|
@ -356,7 +352,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
|
hashtable = grub_zalloc (data->htsize * sizeof (*hashtable));
|
||||||
if (!hashtable)
|
if (!hashtable)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -367,7 +363,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
for (i = 0; i < data->htsize; i++)
|
for (i = 0; i < data->htsize; i++)
|
||||||
{
|
{
|
||||||
grub_uint64_t next;
|
grub_uint32_t next;
|
||||||
|
|
||||||
if (!hashtable[i])
|
if (!hashtable[i])
|
||||||
continue;
|
continue;
|
||||||
|
@ -385,9 +381,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
file.name[file.namelen] = '\0';
|
if (grub_affs_create_node (next, &file))
|
||||||
|
|
||||||
if (grub_affs_create_node ((char *) (file.name), next, &file))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
next = grub_be_to_cpu32 (file.next);
|
next = grub_be_to_cpu32 (file.next);
|
||||||
|
@ -441,10 +435,13 @@ grub_affs_open (struct grub_file *file, const char *name)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_affs_close (grub_file_t file)
|
grub_affs_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
|
struct grub_affs_data *data =
|
||||||
|
(struct grub_affs_data *) file->data;
|
||||||
|
|
||||||
|
grub_free (data->diropen.block_cache);
|
||||||
grub_free (file->data);
|
grub_free (file->data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
@ -452,7 +449,6 @@ grub_affs_close (grub_file_t file)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read LEN bytes data from FILE into BUF. */
|
/* Read LEN bytes data from FILE into BUF. */
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
|
grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
@ -460,13 +456,12 @@ grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
struct grub_affs_data *data =
|
struct grub_affs_data *data =
|
||||||
(struct grub_affs_data *) file->data;
|
(struct grub_affs_data *) file->data;
|
||||||
|
|
||||||
int size = grub_affs_read_file (&data->diropen, file->read_hook,
|
return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen,
|
||||||
file->offset, len, buf);
|
file->read_hook,
|
||||||
|
file->offset, len, buf, grub_affs_read_block,
|
||||||
return size;
|
grub_be_to_cpu32 (data->diropen.di.size), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_affs_dir (grub_device_t device, const char *path,
|
grub_affs_dir (grub_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
|
|
|
@ -1,720 +1,3 @@
|
||||||
/* afs.c - The native AtheOS file-system. */
|
#define MODE_AFS 1
|
||||||
/*
|
#include "bfs.c"
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/file.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
#ifdef MODE_BIGENDIAN
|
|
||||||
#define GRUB_AFS_FSNAME_SUFFIX "_be"
|
|
||||||
#else
|
|
||||||
#define GRUB_AFS_FSNAME_SUFFIX ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
|
|
||||||
#else
|
|
||||||
#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GRUB_AFS_DIRECT_BLOCK_COUNT 12
|
|
||||||
#define GRUB_AFS_BLOCKS_PER_DI_RUN 4
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
#define GRUB_AFS_SBLOCK_SECTOR 1
|
|
||||||
#define GRUB_AFS_SBLOCK_MAGIC1 0x42465331 /* BFS1. */
|
|
||||||
#else
|
|
||||||
#define GRUB_AFS_SBLOCK_SECTOR 2
|
|
||||||
#define GRUB_AFS_SBLOCK_MAGIC1 0x41465331 /* AFS1. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GRUB_AFS_SBLOCK_MAGIC2 0xdd121031
|
|
||||||
#define GRUB_AFS_SBLOCK_MAGIC3 0x15b6830e
|
|
||||||
|
|
||||||
#define GRUB_AFS_INODE_MAGIC 0x64358428
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
#define GRUB_AFS_BTREE_MAGIC 0x69f6c2e8
|
|
||||||
#else
|
|
||||||
#define GRUB_AFS_BTREE_MAGIC 0x65768995
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GRUB_AFS_BNODE_SIZE 1024
|
|
||||||
|
|
||||||
#define GRUB_AFS_S_IFMT 00170000
|
|
||||||
#define GRUB_AFS_S_IFLNK 0120000
|
|
||||||
|
|
||||||
#define GRUB_AFS_S_IFREG 0100000
|
|
||||||
#define GRUB_AFS_S_IFDIR 0040000
|
|
||||||
#define GRUB_AFS_S_IFIFO 0010000
|
|
||||||
|
|
||||||
#define GRUB_AFS_NULL_VAL ((grub_afs_bvalue_t)-1)
|
|
||||||
|
|
||||||
#ifdef MODE_BIGENDIAN
|
|
||||||
#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x)
|
|
||||||
#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x)
|
|
||||||
#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x)
|
|
||||||
#else
|
|
||||||
#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x)
|
|
||||||
#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x)
|
|
||||||
#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
#define B_KEY_INDEX_ALIGN 8
|
|
||||||
#else
|
|
||||||
#define B_KEY_INDEX_ALIGN 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \
|
|
||||||
((char *) (node) \
|
|
||||||
+ ALIGN_UP (sizeof (struct grub_afs_bnode) \
|
|
||||||
+ node->key_size, \
|
|
||||||
B_KEY_INDEX_ALIGN)))
|
|
||||||
|
|
||||||
#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \
|
|
||||||
((char *) B_KEY_INDEX_OFFSET (node) + \
|
|
||||||
node->key_count * 2))
|
|
||||||
|
|
||||||
typedef grub_uint64_t grub_afs_off_t;
|
|
||||||
typedef grub_uint64_t grub_afs_bigtime;
|
|
||||||
typedef grub_uint64_t grub_afs_bvalue_t;
|
|
||||||
|
|
||||||
struct grub_afs_blockrun
|
|
||||||
{
|
|
||||||
grub_uint32_t group;
|
|
||||||
grub_uint16_t start;
|
|
||||||
grub_uint16_t len;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct grub_afs_datastream
|
|
||||||
{
|
|
||||||
struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT];
|
|
||||||
grub_afs_off_t max_direct_range;
|
|
||||||
struct grub_afs_blockrun indirect;
|
|
||||||
grub_afs_off_t max_indirect_range;
|
|
||||||
struct grub_afs_blockrun double_indirect;
|
|
||||||
grub_afs_off_t max_double_indirect_range;
|
|
||||||
grub_afs_off_t size;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct grub_afs_bnode
|
|
||||||
{
|
|
||||||
grub_afs_bvalue_t left;
|
|
||||||
grub_afs_bvalue_t right;
|
|
||||||
grub_afs_bvalue_t overflow;
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
grub_uint16_t key_count;
|
|
||||||
grub_uint16_t key_size;
|
|
||||||
#else
|
|
||||||
grub_uint32_t key_count;
|
|
||||||
grub_uint32_t key_size;
|
|
||||||
#endif
|
|
||||||
char key_data[0];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
struct grub_afs_btree
|
|
||||||
{
|
|
||||||
grub_uint32_t magic;
|
|
||||||
grub_uint32_t unused1;
|
|
||||||
grub_uint32_t tree_depth;
|
|
||||||
grub_uint32_t unused2;
|
|
||||||
grub_afs_bvalue_t root;
|
|
||||||
grub_uint32_t unused3[4];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
#else
|
|
||||||
struct grub_afs_btree
|
|
||||||
{
|
|
||||||
grub_uint32_t magic;
|
|
||||||
grub_afs_bvalue_t root;
|
|
||||||
grub_uint32_t tree_depth;
|
|
||||||
grub_afs_bvalue_t last_node;
|
|
||||||
grub_afs_bvalue_t first_free;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Beware that following structure describes AtheFS and if you write code
|
|
||||||
which uses currently unused fields check it with both AtheFS and BeFS.
|
|
||||||
*/
|
|
||||||
struct grub_afs_sblock
|
|
||||||
{
|
|
||||||
char name[32];
|
|
||||||
grub_uint32_t magic1;
|
|
||||||
grub_uint32_t byte_order;
|
|
||||||
grub_uint32_t block_size;
|
|
||||||
grub_uint32_t block_shift;
|
|
||||||
grub_afs_off_t num_blocks;
|
|
||||||
grub_afs_off_t used_blocks;
|
|
||||||
grub_uint32_t inode_size;
|
|
||||||
grub_uint32_t magic2;
|
|
||||||
grub_uint32_t block_per_group; /* Number of blocks per allocation
|
|
||||||
group. (Max 65536) */
|
|
||||||
grub_uint32_t alloc_group_shift; /* Number of bits to shift a group
|
|
||||||
number to get a byte address. */
|
|
||||||
grub_uint32_t alloc_group_count;
|
|
||||||
grub_uint32_t flags;
|
|
||||||
struct grub_afs_blockrun log_block;
|
|
||||||
grub_afs_off_t log_start;
|
|
||||||
grub_uint32_t valid_log_blocks;
|
|
||||||
grub_uint32_t log_size;
|
|
||||||
grub_uint32_t magic3;
|
|
||||||
struct grub_afs_blockrun root_dir; /* Root dir inode. */
|
|
||||||
struct grub_afs_blockrun deleted_files; /* Directory containing files
|
|
||||||
scheduled for deletion. */
|
|
||||||
struct grub_afs_blockrun index_dir; /* Directory of index files. */
|
|
||||||
grub_uint32_t boot_loader_size;
|
|
||||||
grub_uint32_t pad[7];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct grub_afs_inode
|
|
||||||
{
|
|
||||||
grub_uint32_t magic1;
|
|
||||||
struct grub_afs_blockrun inode_num;
|
|
||||||
grub_uint32_t uid;
|
|
||||||
grub_uint32_t gid;
|
|
||||||
grub_uint32_t mode;
|
|
||||||
grub_uint32_t flags;
|
|
||||||
#ifndef MODE_BFS
|
|
||||||
grub_uint32_t link_count;
|
|
||||||
#endif
|
|
||||||
grub_afs_bigtime create_time;
|
|
||||||
grub_afs_bigtime modified_time;
|
|
||||||
struct grub_afs_blockrun parent;
|
|
||||||
struct grub_afs_blockrun attrib_dir;
|
|
||||||
grub_uint32_t index_type; /* Key data-key only used for index files. */
|
|
||||||
grub_uint32_t inode_size;
|
|
||||||
grub_uint32_t unused;
|
|
||||||
struct grub_afs_datastream stream;
|
|
||||||
grub_uint32_t pad[4];
|
|
||||||
grub_uint32_t small_data[1];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct grub_fshelp_node
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data;
|
|
||||||
struct grub_afs_inode inode;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct grub_afs_data
|
|
||||||
{
|
|
||||||
grub_disk_t disk;
|
|
||||||
struct grub_afs_sblock sblock;
|
|
||||||
struct grub_afs_inode *inode;
|
|
||||||
struct grub_fshelp_node diropen;
|
|
||||||
};
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
|
||||||
|
|
||||||
static grub_afs_off_t
|
|
||||||
grub_afs_run_to_num (struct grub_afs_sblock *sb,
|
|
||||||
struct grub_afs_blockrun *run)
|
|
||||||
{
|
|
||||||
return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group)
|
|
||||||
* sb->block_per_group + grub_afs_to_cpu16 (run->start));
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_afs_read_inode (struct grub_afs_data *data,
|
|
||||||
grub_uint32_t ino, struct grub_afs_inode *inode)
|
|
||||||
{
|
|
||||||
return grub_disk_read (data->disk,
|
|
||||||
ino *
|
|
||||||
(data->sblock.block_size >> GRUB_DISK_SECTOR_BITS),
|
|
||||||
0, sizeof (struct grub_afs_inode),
|
|
||||||
inode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_disk_addr_t
|
|
||||||
grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|
||||||
{
|
|
||||||
struct grub_afs_sblock *sb = &node->data->sblock;
|
|
||||||
struct grub_afs_datastream *ds = &node->inode.stream;
|
|
||||||
|
|
||||||
if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
|
|
||||||
{
|
|
||||||
if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len))
|
|
||||||
return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock;
|
|
||||||
fileblock -= grub_afs_to_cpu16 (ds->direct[i].len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
|
|
||||||
{
|
|
||||||
int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
|
|
||||||
struct grub_afs_blockrun indir[ptrs_per_blk];
|
|
||||||
grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fileblock -= grub_afs_to_cpu64 (ds->max_direct_range);
|
|
||||||
for (i = 0; i < ds->indirect.len; i++, blk++)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (grub_disk_read (node->data->disk,
|
|
||||||
blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS),
|
|
||||||
0, sizeof (indir),
|
|
||||||
indir))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (j = 0; j < ptrs_per_blk; j++)
|
|
||||||
{
|
|
||||||
if (fileblock < grub_afs_to_cpu16 (indir[j].len))
|
|
||||||
return grub_afs_run_to_num (sb, &indir[j]) + fileblock;
|
|
||||||
|
|
||||||
fileblock -= grub_afs_to_cpu16 (indir[j].len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
|
|
||||||
struct grub_afs_blockrun indir[ptrs_per_blk];
|
|
||||||
|
|
||||||
/* ([idblk][idptr]) ([dblk][dptr]) [blk] */
|
|
||||||
int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range);
|
|
||||||
|
|
||||||
int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
|
|
||||||
int dblk_size = dptr_size * ptrs_per_blk;
|
|
||||||
int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN;
|
|
||||||
int idblk_size = idptr_size * ptrs_per_blk;
|
|
||||||
|
|
||||||
int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN;
|
|
||||||
int dptr = (cur_pos / dptr_size) % ptrs_per_blk;
|
|
||||||
int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN;
|
|
||||||
int idptr = (cur_pos / idptr_size) % ptrs_per_blk;
|
|
||||||
int idblk = (cur_pos / idblk_size);
|
|
||||||
|
|
||||||
if (grub_disk_read (node->data->disk,
|
|
||||||
(grub_afs_run_to_num (sb, &ds->double_indirect)
|
|
||||||
+ idblk) *
|
|
||||||
(sb->block_size >> GRUB_DISK_SECTOR_BITS),
|
|
||||||
0, sizeof (indir),
|
|
||||||
indir))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (grub_disk_read (node->data->disk,
|
|
||||||
(grub_afs_run_to_num (sb, &indir[idptr]) + dblk) *
|
|
||||||
(sb->block_size >> GRUB_DISK_SECTOR_BITS),
|
|
||||||
0, sizeof (indir),
|
|
||||||
indir))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return grub_afs_run_to_num (sb, &indir[dptr]) + off;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_ssize_t
|
|
||||||
grub_afs_read_file (grub_fshelp_node_t node,
|
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
|
||||||
unsigned offset, unsigned length),
|
|
||||||
int pos, grub_size_t len, char *buf)
|
|
||||||
{
|
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
|
||||||
pos, len, buf, grub_afs_read_block,
|
|
||||||
grub_afs_to_cpu64 (node->inode.stream.size),
|
|
||||||
node->data->sblock.block_shift
|
|
||||||
- GRUB_DISK_SECTOR_BITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
grub_afs_read_symlink (grub_fshelp_node_t node)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size);
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
size = sizeof (node->inode.stream);
|
|
||||||
ret = grub_zalloc (size + 1);
|
|
||||||
if (! ret)
|
|
||||||
return 0;
|
|
||||||
grub_memcpy (ret, (char *) &(node->inode.stream),
|
|
||||||
sizeof (node->inode.stream));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = grub_zalloc (size + 1);
|
|
||||||
if (! ret)
|
|
||||||
return 0;
|
|
||||||
grub_afs_read_file (node, 0, 0, size, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
grub_afs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
int NESTED_FUNC_ATTR
|
|
||||||
(*hook) (const char *filename,
|
|
||||||
enum grub_fshelp_filetype filetype,
|
|
||||||
grub_fshelp_node_t node))
|
|
||||||
{
|
|
||||||
struct grub_afs_btree head;
|
|
||||||
char node_data [GRUB_AFS_BNODE_SIZE];
|
|
||||||
struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((dir->inode.stream.size == 0)
|
|
||||||
|| ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT)
|
|
||||||
!= GRUB_AFS_S_IFDIR))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
|
|
||||||
if (grub_errno)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root),
|
|
||||||
GRUB_AFS_BNODE_SIZE, (char *) node);
|
|
||||||
if (grub_errno)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++)
|
|
||||||
{
|
|
||||||
grub_afs_bvalue_t blk;
|
|
||||||
|
|
||||||
blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]);
|
|
||||||
grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node);
|
|
||||||
if (grub_errno)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->key_count)
|
|
||||||
{
|
|
||||||
grub_uint32_t cur_key = 0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int key_start, key_size;
|
|
||||||
grub_uint16_t *index;
|
|
||||||
|
|
||||||
index = B_KEY_INDEX_OFFSET (node);
|
|
||||||
|
|
||||||
key_start = (cur_key > 0)
|
|
||||||
? grub_afs_to_cpu16 (index[cur_key - 1]) : 0;
|
|
||||||
key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start;
|
|
||||||
if (key_size > 0)
|
|
||||||
{
|
|
||||||
char filename [key_size + 1];
|
|
||||||
struct grub_fshelp_node *fdiro;
|
|
||||||
int mode, type;
|
|
||||||
|
|
||||||
fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
|
|
||||||
if (! fdiro)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fdiro->data = dir->data;
|
|
||||||
if (grub_afs_read_inode (dir->data,
|
|
||||||
grub_afs_to_cpu64
|
|
||||||
(B_KEY_VALUE_OFFSET (node) [cur_key]),
|
|
||||||
&fdiro->inode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
grub_memcpy (filename, &node->key_data[key_start], key_size);
|
|
||||||
filename [key_size] = 0;
|
|
||||||
|
|
||||||
mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT);
|
|
||||||
if (mode == GRUB_AFS_S_IFDIR)
|
|
||||||
type = GRUB_FSHELP_DIR;
|
|
||||||
else if (mode == GRUB_AFS_S_IFREG)
|
|
||||||
type = GRUB_FSHELP_REG;
|
|
||||||
else if (mode == GRUB_AFS_S_IFLNK)
|
|
||||||
type = GRUB_FSHELP_SYMLINK;
|
|
||||||
else
|
|
||||||
type = GRUB_FSHELP_UNKNOWN;
|
|
||||||
|
|
||||||
if (hook (filename, type, fdiro))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_key++;
|
|
||||||
if (cur_key >= grub_afs_to_cpu32 (node->key_count))
|
|
||||||
{
|
|
||||||
if (node->right == GRUB_AFS_NULL_VAL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right),
|
|
||||||
GRUB_AFS_BNODE_SIZE, (char *) node);
|
|
||||||
if (grub_errno)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cur_key = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
grub_afs_validate_sblock (struct grub_afs_sblock *sb)
|
|
||||||
{
|
|
||||||
if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
|
|
||||||
{
|
|
||||||
sb->magic2 = grub_afs_to_cpu32 (sb->magic2);
|
|
||||||
sb->magic3 = grub_afs_to_cpu32 (sb->magic3);
|
|
||||||
sb->block_shift = grub_afs_to_cpu32 (sb->block_shift);
|
|
||||||
sb->block_size = grub_afs_to_cpu32 (sb->block_size);
|
|
||||||
sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks);
|
|
||||||
sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks);
|
|
||||||
sb->inode_size = grub_afs_to_cpu32 (sb->inode_size);
|
|
||||||
sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
|
|
||||||
sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift);
|
|
||||||
sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group);
|
|
||||||
sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
|
|
||||||
sb->log_size = grub_afs_to_cpu32 (sb->log_size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) ||
|
|
||||||
(sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
sb->block_per_group = 1 << (sb->alloc_group_shift);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size)
|
|
||||||
|| (sb->used_blocks > sb->num_blocks )
|
|
||||||
|| (sb->inode_size != sb->block_size)
|
|
||||||
|| (0 == sb->block_size)
|
|
||||||
#ifndef MODE_BFS
|
|
||||||
|| ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
|
|
||||||
sb->block_per_group * sb->block_size)
|
|
||||||
|| (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
|
|
||||||
|| (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size)
|
|
||||||
|| (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grub_afs_data *
|
|
||||||
grub_afs_mount (grub_disk_t disk)
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data = 0;
|
|
||||||
|
|
||||||
data = grub_malloc (sizeof (struct grub_afs_data));
|
|
||||||
if (!data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Read the superblock. */
|
|
||||||
if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0,
|
|
||||||
sizeof (struct grub_afs_sblock), &data->sblock))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (! grub_afs_validate_sblock (&data->sblock))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
data->diropen.data = data;
|
|
||||||
data->inode = &data->diropen.inode;
|
|
||||||
data->disk = disk;
|
|
||||||
|
|
||||||
if (grub_afs_read_inode (data,
|
|
||||||
grub_afs_run_to_num (&data->sblock,
|
|
||||||
&data->sblock.root_dir),
|
|
||||||
data->inode))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem");
|
|
||||||
|
|
||||||
grub_free (data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_afs_open (struct grub_file *file, const char *name)
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data;
|
|
||||||
struct grub_fshelp_node *fdiro = 0;
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
data = grub_afs_mount (file->device->disk);
|
|
||||||
if (! data)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir,
|
|
||||||
grub_afs_read_symlink, GRUB_FSHELP_REG);
|
|
||||||
if (grub_errno)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode));
|
|
||||||
grub_free (fdiro);
|
|
||||||
|
|
||||||
file->size = grub_afs_to_cpu64 (data->inode->stream.size);
|
|
||||||
file->data = data;
|
|
||||||
file->offset = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_free (data);
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_ssize_t
|
|
||||||
grub_afs_read (grub_file_t file, char *buf, grub_size_t len)
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data = (struct grub_afs_data *) file->data;
|
|
||||||
|
|
||||||
return grub_afs_read_file (&data->diropen, file->read_hook,
|
|
||||||
file->offset, len, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_afs_close (grub_file_t file)
|
|
||||||
{
|
|
||||||
grub_free (file->data);
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_afs_dir (grub_device_t device, const char *path,
|
|
||||||
int (*hook) (const char *filename,
|
|
||||||
const struct grub_dirhook_info *info))
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data = 0;
|
|
||||||
struct grub_fshelp_node *fdiro = 0;
|
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR iterate (const char *filename,
|
|
||||||
enum grub_fshelp_filetype filetype,
|
|
||||||
grub_fshelp_node_t node);
|
|
||||||
|
|
||||||
int NESTED_FUNC_ATTR iterate (const char *filename,
|
|
||||||
enum grub_fshelp_filetype filetype,
|
|
||||||
grub_fshelp_node_t node)
|
|
||||||
{
|
|
||||||
struct grub_dirhook_info info;
|
|
||||||
grub_memset (&info, 0, sizeof (info));
|
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
|
||||||
info.mtimeset = 1;
|
|
||||||
#ifdef MODE_BFS
|
|
||||||
info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
|
|
||||||
#else
|
|
||||||
info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
|
|
||||||
1000000, 0);
|
|
||||||
#endif
|
|
||||||
grub_free (node);
|
|
||||||
return hook (filename, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
data = grub_afs_mount (device->disk);
|
|
||||||
if (! data)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir,
|
|
||||||
grub_afs_read_symlink, GRUB_FSHELP_DIR);
|
|
||||||
if (grub_errno)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
grub_afs_iterate_dir (fdiro, iterate);
|
|
||||||
|
|
||||||
if (fdiro != &data->diropen)
|
|
||||||
grub_free (fdiro);
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_free (data);
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_afs_label (grub_device_t device, char **label)
|
|
||||||
{
|
|
||||||
struct grub_afs_data *data;
|
|
||||||
grub_disk_t disk = device->disk;
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
data = grub_afs_mount (disk);
|
|
||||||
if (data)
|
|
||||||
*label = grub_strndup (data->sblock.name, sizeof (data->sblock.name));
|
|
||||||
else
|
|
||||||
*label = NULL;
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
|
|
||||||
grub_free (data);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct grub_fs grub_afs_fs = {
|
|
||||||
.name = GRUB_AFS_FSNAME,
|
|
||||||
.dir = grub_afs_dir,
|
|
||||||
.open = grub_afs_open,
|
|
||||||
.read = grub_afs_read,
|
|
||||||
.close = grub_afs_close,
|
|
||||||
.label = grub_afs_label,
|
|
||||||
.next = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
|
|
||||||
GRUB_MOD_INIT (befs_be)
|
|
||||||
#elif defined (MODE_BFS)
|
|
||||||
GRUB_MOD_INIT (befs)
|
|
||||||
#elif defined (MODE_BIGENDIAN)
|
|
||||||
GRUB_MOD_INIT (afs_be)
|
|
||||||
#else
|
|
||||||
GRUB_MOD_INIT (afs)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
grub_fs_register (&grub_afs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
|
|
||||||
GRUB_MOD_FINI (befs_be)
|
|
||||||
#elif defined (MODE_BFS)
|
|
||||||
GRUB_MOD_FINI (befs)
|
|
||||||
#elif defined (MODE_BIGENDIAN)
|
|
||||||
GRUB_MOD_FINI (afs_be)
|
|
||||||
#else
|
|
||||||
GRUB_MOD_FINI (afs)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
grub_fs_unregister (&grub_afs_fs);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#define MODE_BIGENDIAN 1
|
|
||||||
#include "afs.c"
|
|
|
@ -1,3 +0,0 @@
|
||||||
/* befs.c - The native BeOS/Haiku file-system. */
|
|
||||||
#define MODE_BFS 1
|
|
||||||
#include "afs.c"
|
|
|
@ -1,4 +0,0 @@
|
||||||
/* befs.c - The native BeOS/Haiku file-system. */
|
|
||||||
#define MODE_BFS 1
|
|
||||||
#define MODE_BIGENDIAN 1
|
|
||||||
#include "afs.c"
|
|
1050
grub-core/fs/bfs.c
Normal file
1050
grub-core/fs/bfs.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -26,11 +26,23 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/lib/crc.h>
|
#include <grub/lib/crc.h>
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
|
#include <minilzo.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_BTRFS_SIGNATURE "_BHRfS_M"
|
#define GRUB_BTRFS_SIGNATURE "_BHRfS_M"
|
||||||
|
|
||||||
|
/* From http://www.oberhumer.com/opensource/lzo/lzofaq.php
|
||||||
|
* LZO will expand incompressible data by a little amount. I still haven't
|
||||||
|
* computed the exact values, but I suggest using these formulas for
|
||||||
|
* a worst-case expansion calculation:
|
||||||
|
*
|
||||||
|
* output_block_size = input_block_size + (input_block_size / 16) + 64 + 3
|
||||||
|
* */
|
||||||
|
#define GRUB_BTRFS_LZO_BLOCK_SIZE 4096
|
||||||
|
#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \
|
||||||
|
(GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3)
|
||||||
|
|
||||||
typedef grub_uint8_t grub_btrfs_checksum_t[0x20];
|
typedef grub_uint8_t grub_btrfs_checksum_t[0x20];
|
||||||
typedef grub_uint16_t grub_btrfs_uuid_t[8];
|
typedef grub_uint16_t grub_btrfs_uuid_t[8];
|
||||||
|
|
||||||
|
@ -41,7 +53,7 @@ struct grub_btrfs_device
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_btrfs_superblock
|
struct grub_btrfs_superblock
|
||||||
{
|
{
|
||||||
grub_btrfs_checksum_t checksum;
|
grub_btrfs_checksum_t checksum;
|
||||||
grub_btrfs_uuid_t uuid;
|
grub_btrfs_uuid_t uuid;
|
||||||
grub_uint8_t dummy[0x10];
|
grub_uint8_t dummy[0x10];
|
||||||
|
@ -160,7 +172,8 @@ struct grub_btrfs_leaf_descriptor
|
||||||
{
|
{
|
||||||
unsigned depth;
|
unsigned depth;
|
||||||
unsigned allocated;
|
unsigned allocated;
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
grub_disk_addr_t addr;
|
grub_disk_addr_t addr;
|
||||||
unsigned iter;
|
unsigned iter;
|
||||||
unsigned maxiter;
|
unsigned maxiter;
|
||||||
|
@ -179,7 +192,7 @@ struct grub_btrfs_time
|
||||||
{
|
{
|
||||||
grub_int64_t sec;
|
grub_int64_t sec;
|
||||||
grub_uint32_t nanosec;
|
grub_uint32_t nanosec;
|
||||||
} __attribute__ ((aligned(4)));
|
} __attribute__ ((aligned (4)));
|
||||||
|
|
||||||
struct grub_btrfs_inode
|
struct grub_btrfs_inode
|
||||||
{
|
{
|
||||||
|
@ -215,12 +228,13 @@ struct grub_btrfs_extent_data
|
||||||
|
|
||||||
#define GRUB_BTRFS_COMPRESSION_NONE 0
|
#define GRUB_BTRFS_COMPRESSION_NONE 0
|
||||||
#define GRUB_BTRFS_COMPRESSION_ZLIB 1
|
#define GRUB_BTRFS_COMPRESSION_ZLIB 1
|
||||||
|
#define GRUB_BTRFS_COMPRESSION_LZO 2
|
||||||
|
|
||||||
#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
|
#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100
|
||||||
|
|
||||||
static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2,
|
static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2,
|
||||||
256 * 1048576 * 2,
|
256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2
|
||||||
1048576ULL * 1048576ULL * 2 };
|
};
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
|
@ -283,7 +297,7 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
||||||
grub_disk_addr_t addr, unsigned i, unsigned m, int l)
|
grub_disk_addr_t addr, unsigned i, unsigned m, int l)
|
||||||
{
|
{
|
||||||
desc->depth++;
|
desc->depth++;
|
||||||
|
@ -307,7 +321,7 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
||||||
static int
|
static int
|
||||||
next (struct grub_btrfs_data *data,
|
next (struct grub_btrfs_data *data,
|
||||||
struct grub_btrfs_leaf_descriptor *desc,
|
struct grub_btrfs_leaf_descriptor *desc,
|
||||||
grub_disk_addr_t *outaddr, grub_size_t *outsize,
|
grub_disk_addr_t * outaddr, grub_size_t * outsize,
|
||||||
struct grub_btrfs_key *key_out)
|
struct grub_btrfs_key *key_out)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -330,17 +344,17 @@ next (struct grub_btrfs_data *data,
|
||||||
err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter
|
err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter
|
||||||
* sizeof (node)
|
* sizeof (node)
|
||||||
+ sizeof (struct btrfs_header)
|
+ sizeof (struct btrfs_header)
|
||||||
+ desc->data[desc->depth - 1].addr, &node,
|
+ desc->data[desc->depth - 1].addr,
|
||||||
sizeof (node));
|
&node, sizeof (node));
|
||||||
if (err)
|
if (err)
|
||||||
return -err;
|
return -err;
|
||||||
|
|
||||||
err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head,
|
err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr),
|
||||||
sizeof (head));
|
&head, sizeof (head));
|
||||||
if (err)
|
if (err)
|
||||||
return -err;
|
return -err;
|
||||||
|
|
||||||
save_ref (desc, grub_le_to_cpu64 (node.addr), 0,
|
save_ref (desc, grub_le_to_cpu64 (node.addr), 0,
|
||||||
grub_le_to_cpu32 (head.nitems), !head.level);
|
grub_le_to_cpu32 (head.nitems), !head.level);
|
||||||
}
|
}
|
||||||
err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter
|
err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter
|
||||||
|
@ -354,12 +368,12 @@ next (struct grub_btrfs_data *data,
|
||||||
*outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header)
|
*outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header)
|
||||||
+ grub_le_to_cpu32 (leaf.offset);
|
+ grub_le_to_cpu32 (leaf.offset);
|
||||||
*key_out = leaf.key;
|
*key_out = leaf.key;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
lower_bound (struct grub_btrfs_data *data,
|
lower_bound (struct grub_btrfs_data *data,
|
||||||
const struct grub_btrfs_key *key_in,
|
const struct grub_btrfs_key *key_in,
|
||||||
struct grub_btrfs_key *key_out,
|
struct grub_btrfs_key *key_out,
|
||||||
grub_disk_addr_t root,
|
grub_disk_addr_t root,
|
||||||
grub_disk_addr_t *outaddr, grub_size_t *outsize,
|
grub_disk_addr_t *outaddr, grub_size_t *outsize,
|
||||||
|
@ -410,8 +424,9 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
grub_dprintf ("btrfs",
|
grub_dprintf ("btrfs",
|
||||||
"internal node (depth %d) %" PRIxGRUB_UINT64_T
|
"internal node (depth %d) %" PRIxGRUB_UINT64_T
|
||||||
" %x %" PRIxGRUB_UINT64_T "\n", depth,
|
" %x %" PRIxGRUB_UINT64_T "\n", depth,
|
||||||
node.key.object_id, node.key.type, node.key.offset);
|
node.key.object_id, node.key.type,
|
||||||
|
node.key.offset);
|
||||||
|
|
||||||
if (key_cmp (&node.key, key_in) == 0)
|
if (key_cmp (&node.key, key_in) == 0)
|
||||||
{
|
{
|
||||||
err = GRUB_ERR_NONE;
|
err = GRUB_ERR_NONE;
|
||||||
|
@ -433,7 +448,7 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
err = GRUB_ERR_NONE;
|
err = GRUB_ERR_NONE;
|
||||||
if (desc)
|
if (desc)
|
||||||
err = save_ref (desc, addr - sizeof (head), i - 1,
|
err = save_ref (desc, addr - sizeof (head), i - 1,
|
||||||
grub_le_to_cpu32 (head.nitems), 0);
|
grub_le_to_cpu32 (head.nitems), 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
addr = grub_le_to_cpu64 (node_last.addr);
|
addr = grub_le_to_cpu64 (node_last.addr);
|
||||||
|
@ -457,7 +472,7 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
&leaf, sizeof (leaf));
|
&leaf, sizeof (leaf));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
grub_dprintf ("btrfs",
|
grub_dprintf ("btrfs",
|
||||||
"leaf (depth %d) %" PRIxGRUB_UINT64_T
|
"leaf (depth %d) %" PRIxGRUB_UINT64_T
|
||||||
" %x %" PRIxGRUB_UINT64_T "\n", depth,
|
" %x %" PRIxGRUB_UINT64_T "\n", depth,
|
||||||
|
@ -465,31 +480,31 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
if (key_cmp (&leaf.key, key_in) == 0)
|
if (key_cmp (&leaf.key, key_in) == 0)
|
||||||
{
|
{
|
||||||
grub_memcpy (key_out, &leaf.key, sizeof(*key_out));
|
grub_memcpy (key_out, &leaf.key, sizeof (*key_out));
|
||||||
*outsize = grub_le_to_cpu32 (leaf.size);
|
*outsize = grub_le_to_cpu32 (leaf.size);
|
||||||
*outaddr = addr + grub_le_to_cpu32 (leaf.offset);
|
*outaddr = addr + grub_le_to_cpu32 (leaf.offset);
|
||||||
if (desc)
|
if (desc)
|
||||||
return save_ref (desc, addr - sizeof (head), i,
|
return save_ref (desc, addr - sizeof (head), i,
|
||||||
grub_le_to_cpu32 (head.nitems), 1);
|
grub_le_to_cpu32 (head.nitems), 1);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_cmp (&leaf.key, key_in) > 0)
|
if (key_cmp (&leaf.key, key_in) > 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
have_last = 1;
|
have_last = 1;
|
||||||
leaf_last = leaf;
|
leaf_last = leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_last)
|
if (have_last)
|
||||||
{
|
{
|
||||||
grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out));
|
grub_memcpy (key_out, &leaf_last.key, sizeof (*key_out));
|
||||||
*outsize = grub_le_to_cpu32 (leaf_last.size);
|
*outsize = grub_le_to_cpu32 (leaf_last.size);
|
||||||
*outaddr = addr + grub_le_to_cpu32 (leaf_last.offset);
|
*outaddr = addr + grub_le_to_cpu32 (leaf_last.offset);
|
||||||
if (desc)
|
if (desc)
|
||||||
return save_ref (desc, addr - sizeof (head), i - 1,
|
return save_ref (desc, addr - sizeof (head), i - 1,
|
||||||
grub_le_to_cpu32 (head.nitems), 1);
|
grub_le_to_cpu32 (head.nitems), 1);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
*outsize = 0;
|
*outsize = 0;
|
||||||
*outaddr = 0;
|
*outaddr = 0;
|
||||||
|
@ -503,8 +518,7 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_device_t
|
static grub_device_t
|
||||||
find_device (struct grub_btrfs_data *data, grub_uint64_t id,
|
find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
|
||||||
int do_rescan)
|
|
||||||
{
|
{
|
||||||
grub_device_t dev_found = NULL;
|
grub_device_t dev_found = NULL;
|
||||||
auto int hook (const char *name);
|
auto int hook (const char *name);
|
||||||
|
@ -540,7 +554,7 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id,
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_found = dev;
|
dev_found = dev;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -579,17 +593,16 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
|
||||||
grub_disk_addr_t addr,
|
|
||||||
void *buf, grub_size_t size)
|
void *buf, grub_size_t size)
|
||||||
{
|
{
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
grub_uint8_t *ptr;
|
grub_uint8_t *ptr;
|
||||||
struct grub_btrfs_key *key;
|
struct grub_btrfs_key *key;
|
||||||
struct grub_btrfs_chunk_item *chunk;
|
struct grub_btrfs_chunk_item *chunk;
|
||||||
grub_uint64_t csize;
|
grub_uint64_t csize;
|
||||||
grub_err_t err = 0;
|
grub_err_t err = 0;
|
||||||
struct grub_btrfs_key key_out;
|
struct grub_btrfs_key key_out;
|
||||||
int challoc = 0;
|
int challoc = 0;
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
@ -601,15 +614,15 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
addr);
|
addr);
|
||||||
for (ptr = data->sblock.bootstrap_mapping;
|
for (ptr = data->sblock.bootstrap_mapping;
|
||||||
ptr < data->sblock.bootstrap_mapping
|
ptr < data->sblock.bootstrap_mapping
|
||||||
+ sizeof (data->sblock.bootstrap_mapping)
|
+ sizeof (data->sblock.bootstrap_mapping)
|
||||||
- sizeof (struct grub_btrfs_key);
|
- sizeof (struct grub_btrfs_key);)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
key = (struct grub_btrfs_key *) ptr;
|
key = (struct grub_btrfs_key *) ptr;
|
||||||
if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK)
|
if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK)
|
||||||
break;
|
break;
|
||||||
chunk = (struct grub_btrfs_chunk_item *) (key + 1);
|
chunk = (struct grub_btrfs_chunk_item *) (key + 1);
|
||||||
grub_dprintf ("btrfs", "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n",
|
grub_dprintf ("btrfs",
|
||||||
|
"%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n",
|
||||||
grub_le_to_cpu64 (key->offset),
|
grub_le_to_cpu64 (key->offset),
|
||||||
grub_le_to_cpu64 (chunk->size));
|
grub_le_to_cpu64 (chunk->size));
|
||||||
if (grub_le_to_cpu64 (key->offset) <= addr
|
if (grub_le_to_cpu64 (key->offset) <= addr
|
||||||
|
@ -704,11 +717,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
middle = grub_divmod64 (off,
|
middle = grub_divmod64 (off,
|
||||||
grub_le_to_cpu64 (chunk->stripe_length),
|
grub_le_to_cpu64 (chunk->stripe_length),
|
||||||
&low);
|
&low);
|
||||||
|
|
||||||
high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes),
|
high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes),
|
||||||
&stripen);
|
&stripen);
|
||||||
stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length)
|
stripe_offset =
|
||||||
* high;
|
low + grub_le_to_cpu64 (chunk->stripe_length) * high;
|
||||||
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
|
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -719,14 +732,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
middle = grub_divmod64 (off,
|
middle = grub_divmod64 (off,
|
||||||
grub_le_to_cpu64 (chunk->stripe_length),
|
grub_le_to_cpu64 (chunk->stripe_length),
|
||||||
&low);
|
&low);
|
||||||
|
|
||||||
high = grub_divmod64 (middle,
|
high = grub_divmod64 (middle,
|
||||||
grub_le_to_cpu16 (chunk->nsubstripes),
|
grub_le_to_cpu16 (chunk->nstripes)
|
||||||
|
/ grub_le_to_cpu16 (chunk->nsubstripes),
|
||||||
&stripen);
|
&stripen);
|
||||||
stripen *= grub_le_to_cpu16 (chunk->nstripes)
|
stripen *= grub_le_to_cpu16 (chunk->nsubstripes);
|
||||||
/ grub_le_to_cpu16 (chunk->nsubstripes);
|
redundancy = grub_le_to_cpu16 (chunk->nsubstripes);
|
||||||
redundancy = grub_le_to_cpu16 (chunk->nstripes)
|
|
||||||
/ grub_le_to_cpu16 (chunk->nsubstripes);
|
|
||||||
stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length)
|
stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length)
|
||||||
* high;
|
* high;
|
||||||
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
|
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
|
||||||
|
@ -759,7 +771,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
paddr = stripe->offset + stripe_offset;
|
paddr = stripe->offset + stripe_offset;
|
||||||
|
|
||||||
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
|
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
|
||||||
"+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %"
|
"+0x%" PRIxGRUB_UINT64_T
|
||||||
|
" (%d stripes (%d substripes) of %"
|
||||||
PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T
|
PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T
|
||||||
" maps to 0x%" PRIxGRUB_UINT64_T "\n",
|
" maps to 0x%" PRIxGRUB_UINT64_T "\n",
|
||||||
grub_le_to_cpu64 (key->offset),
|
grub_le_to_cpu64 (key->offset),
|
||||||
|
@ -769,7 +782,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
grub_le_to_cpu64 (chunk->stripe_length),
|
grub_le_to_cpu64 (chunk->stripe_length),
|
||||||
stripen, stripe->offset);
|
stripen, stripe->offset);
|
||||||
grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T
|
grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T
|
||||||
" for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr,
|
" for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr,
|
||||||
addr);
|
addr);
|
||||||
|
|
||||||
dev = find_device (data, stripe->device_id, j);
|
dev = find_device (data, stripe->device_id, j);
|
||||||
|
@ -815,7 +828,7 @@ grub_btrfs_mount (grub_device_t dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
data = grub_zalloc (sizeof (*data));
|
data = grub_zalloc (sizeof (*data));
|
||||||
if (! data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = read_sblock (dev->disk, &data->sblock);
|
err = read_sblock (dev->disk, &data->sblock);
|
||||||
|
@ -866,8 +879,7 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data,
|
||||||
key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM;
|
key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM;
|
||||||
key_in.offset = 0;
|
key_in.offset = 0;
|
||||||
|
|
||||||
err = lower_bound (data, &key_in, &key_out, tree,
|
err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL);
|
||||||
&elemaddr, &elemsize, NULL);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (num != key_out.object_id
|
if (num != key_out.object_id
|
||||||
|
@ -877,6 +889,76 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data,
|
||||||
return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode));
|
return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
|
||||||
|
char *obuf, grub_size_t osize)
|
||||||
|
{
|
||||||
|
grub_uint32_t total_size, cblock_size, ret = 0;
|
||||||
|
unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE];
|
||||||
|
|
||||||
|
total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf));
|
||||||
|
ibuf += sizeof (total_size);
|
||||||
|
|
||||||
|
if (isize < total_size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Jump forward to first block with requested data. */
|
||||||
|
while (off >= GRUB_BTRFS_LZO_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf));
|
||||||
|
ibuf += sizeof (cblock_size);
|
||||||
|
|
||||||
|
if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
off -= GRUB_BTRFS_LZO_BLOCK_SIZE;
|
||||||
|
ibuf += cblock_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (osize > 0)
|
||||||
|
{
|
||||||
|
lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE;
|
||||||
|
|
||||||
|
cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf));
|
||||||
|
ibuf += sizeof (cblock_size);
|
||||||
|
|
||||||
|
if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Block partially filled with requested data. */
|
||||||
|
if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
grub_size_t to_copy = grub_min(osize, GRUB_BTRFS_LZO_BLOCK_SIZE - off);
|
||||||
|
|
||||||
|
if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize,
|
||||||
|
NULL) != LZO_E_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
to_copy = grub_min(to_copy, usize);
|
||||||
|
grub_memcpy(obuf, buf + off, to_copy);
|
||||||
|
|
||||||
|
osize -= to_copy;
|
||||||
|
ret += to_copy;
|
||||||
|
obuf += to_copy;
|
||||||
|
ibuf += cblock_size;
|
||||||
|
off = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decompress whole block directly to output buffer. */
|
||||||
|
if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf,
|
||||||
|
&usize, NULL) != LZO_E_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
osize -= usize;
|
||||||
|
ret += usize;
|
||||||
|
obuf += usize;
|
||||||
|
ibuf += cblock_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
grub_uint64_t ino, grub_uint64_t tree,
|
grub_uint64_t ino, grub_uint64_t tree,
|
||||||
|
@ -909,6 +991,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if ((grub_ssize_t) elemsize < ((char *) &data->extent->inl
|
||||||
|
- (char *) data->extent))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "extent descriptor is too short");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
data->extstart = grub_le_to_cpu64 (key_out.offset);
|
data->extstart = grub_le_to_cpu64 (key_out.offset);
|
||||||
data->extsize = elemsize;
|
data->extsize = elemsize;
|
||||||
data->extent = grub_malloc (elemsize);
|
data->extent = grub_malloc (elemsize);
|
||||||
|
@ -917,26 +1005,22 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
if (!data->extent)
|
if (!data->extent)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
err = grub_btrfs_read_logical (data, elemaddr,
|
err = grub_btrfs_read_logical (data, elemaddr, data->extent,
|
||||||
data->extent, elemsize);
|
elemsize);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
data->extend = data->extstart
|
data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size);
|
||||||
+ grub_le_to_cpu64 (data->extent->size);
|
|
||||||
if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR
|
if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR
|
||||||
&& (char *) &data->extent + elemsize
|
&& (char *) &data->extent + elemsize
|
||||||
>= (char *) &data->extent->filled
|
>= (char *) &data->extent->filled + sizeof (data->extent->filled))
|
||||||
+ sizeof (data->extent->filled))
|
data->extend =
|
||||||
data->extend = data->extstart
|
data->extstart + grub_le_to_cpu64 (data->extent->filled);
|
||||||
+ grub_le_to_cpu64 (data->extent->filled);
|
|
||||||
|
|
||||||
grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%"
|
grub_dprintf ("btrfs", "regular extent 0x%" PRIxGRUB_UINT64_T "+0x%"
|
||||||
PRIxGRUB_UINT64_T " (0x%"
|
PRIxGRUB_UINT64_T "\n",
|
||||||
PRIxGRUB_UINT64_T ")\n",
|
|
||||||
grub_le_to_cpu64 (key_out.offset),
|
grub_le_to_cpu64 (key_out.offset),
|
||||||
grub_le_to_cpu64 (data->extent->size),
|
grub_le_to_cpu64 (data->extent->size));
|
||||||
grub_le_to_cpu64 (data->extent->filled));
|
|
||||||
if (data->extend <= pos)
|
if (data->extend <= pos)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
||||||
|
@ -956,7 +1040,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE
|
if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE
|
||||||
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB)
|
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB
|
||||||
|
&& data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"compression type 0x%x not supported",
|
"compression type 0x%x not supported",
|
||||||
|
@ -966,8 +1051,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
if (data->extent->encoding)
|
if (data->extent->encoding)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported");
|
||||||
"encoding not supported");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,6 +1067,15 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
!= (grub_ssize_t) csize)
|
!= (grub_ssize_t) csize)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO)
|
||||||
|
{
|
||||||
|
if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize -
|
||||||
|
((grub_uint8_t *) data->extent->inl
|
||||||
|
- (grub_uint8_t *) data->extent),
|
||||||
|
extoff, buf, csize)
|
||||||
|
!= (grub_ssize_t) csize)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
grub_memcpy (buf, data->extent->inl + extoff, csize);
|
grub_memcpy (buf, data->extent->inl + extoff, csize);
|
||||||
break;
|
break;
|
||||||
|
@ -992,10 +1085,13 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
grub_memset (buf, 0, csize);
|
grub_memset (buf, 0, csize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB)
|
|
||||||
|
if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
grub_uint64_t zsize;
|
grub_uint64_t zsize;
|
||||||
|
grub_ssize_t ret;
|
||||||
|
|
||||||
zsize = grub_le_to_cpu64 (data->extent->compressed_size);
|
zsize = grub_le_to_cpu64 (data->extent->compressed_size);
|
||||||
tmp = grub_malloc (zsize);
|
tmp = grub_malloc (zsize);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
|
@ -1008,27 +1104,35 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (grub_zlib_decompress (tmp, zsize, extoff
|
|
||||||
+ grub_le_to_cpu64 (data->extent->offset),
|
if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB)
|
||||||
buf, csize) != (grub_ssize_t) csize)
|
ret = grub_zlib_decompress (tmp, zsize, extoff
|
||||||
{
|
+ grub_le_to_cpu64 (data->extent->offset),
|
||||||
grub_free (tmp);
|
buf, csize);
|
||||||
return -1;
|
else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO)
|
||||||
}
|
ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff
|
||||||
|
+ grub_le_to_cpu64 (data->extent->offset),
|
||||||
|
buf, csize);
|
||||||
|
else
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
|
|
||||||
|
if (ret != (grub_ssize_t) csize)
|
||||||
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = grub_btrfs_read_logical (data,
|
err = grub_btrfs_read_logical (data,
|
||||||
grub_le_to_cpu64 (data->extent->laddr)
|
grub_le_to_cpu64 (data->extent->laddr)
|
||||||
+ grub_le_to_cpu64 (data->extent->offset)
|
+ grub_le_to_cpu64 (data->extent->offset)
|
||||||
+ extoff,
|
+ extoff, buf, csize);
|
||||||
buf, csize);
|
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"unsupported extent type 0x%x", data->extent->type);
|
"unsupported extent type 0x%x", data->extent->type);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buf += csize;
|
buf += csize;
|
||||||
|
@ -1096,9 +1200,9 @@ find_path (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM;
|
key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM;
|
||||||
key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen));
|
key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen));
|
||||||
|
|
||||||
err = lower_bound (data, key, &key_out, *tree,
|
err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize,
|
||||||
&elemaddr, &elemsize, NULL);
|
NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_free (direl);
|
grub_free (direl);
|
||||||
|
@ -1140,7 +1244,7 @@ find_path (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
for (cdirel = direl;
|
for (cdirel = direl;
|
||||||
(grub_uint8_t *) cdirel - (grub_uint8_t *) direl
|
(grub_uint8_t *) cdirel - (grub_uint8_t *) direl
|
||||||
< (grub_ssize_t) elemsize;
|
< (grub_ssize_t) elemsize;
|
||||||
cdirel = (void *) ((grub_uint8_t *) (direl + 1)
|
cdirel = (void *) ((grub_uint8_t *) (direl + 1)
|
||||||
+ grub_le_to_cpu16 (cdirel->n)
|
+ grub_le_to_cpu16 (cdirel->n)
|
||||||
+ grub_le_to_cpu16 (cdirel->m)))
|
+ grub_le_to_cpu16 (cdirel->m)))
|
||||||
|
@ -1174,7 +1278,7 @@ find_path (struct grub_btrfs_data *data,
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP,
|
return grub_error (GRUB_ERR_SYMLINK_LOOP,
|
||||||
"too deep nesting of symlinks");
|
"too deep nesting of symlinks");
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_btrfs_read_inode (data, &inode,
|
err = grub_btrfs_read_inode (data, &inode,
|
||||||
cdirel->key.object_id, *tree);
|
cdirel->key.object_id, *tree);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1205,10 +1309,9 @@ find_path (struct grub_btrfs_data *data,
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path,
|
grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path,
|
||||||
grub_strlen (path) + 1);
|
grub_strlen (path) + 1);
|
||||||
grub_free (path_alloc);
|
grub_free (path_alloc);
|
||||||
grub_free (origpath);
|
|
||||||
path = path_alloc = tmp;
|
path = path_alloc = tmp;
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
{
|
{
|
||||||
|
@ -1247,8 +1350,7 @@ find_path (struct grub_btrfs_data *data,
|
||||||
grub_free (origpath);
|
grub_free (origpath);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = grub_btrfs_read_logical (data, elemaddr,
|
err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri));
|
||||||
&ri, sizeof (ri));
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_free (direl);
|
grub_free (direl);
|
||||||
|
@ -1279,19 +1381,21 @@ find_path (struct grub_btrfs_data *data,
|
||||||
grub_free (path_alloc);
|
grub_free (path_alloc);
|
||||||
grub_free (origpath);
|
grub_free (origpath);
|
||||||
grub_free (direl);
|
grub_free (direl);
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x",
|
return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x",
|
||||||
cdirel->key.type);
|
cdirel->key.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_free (direl);
|
grub_free (direl);
|
||||||
|
grub_free (origpath);
|
||||||
|
grub_free (path_alloc);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_btrfs_dir (grub_device_t device, const char *path,
|
grub_btrfs_dir (grub_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
const struct grub_dirhook_info *info))
|
const struct grub_dirhook_info *info))
|
||||||
{
|
{
|
||||||
struct grub_btrfs_data *data = grub_btrfs_mount (device);
|
struct grub_btrfs_data *data = grub_btrfs_mount (device);
|
||||||
struct grub_btrfs_key key_in, key_out;
|
struct grub_btrfs_key key_in, key_out;
|
||||||
|
@ -1310,23 +1414,28 @@ grub_btrfs_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
err = find_path (data, path, &key_in, &tree, &type);
|
err = find_path (data, path, &key_in, &tree, &type);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_btrfs_unmount (data);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY)
|
if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY)
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
|
{
|
||||||
|
grub_btrfs_unmount (data);
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
|
||||||
|
}
|
||||||
|
|
||||||
err = lower_bound (data, &key_in, &key_out, tree,
|
err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc);
|
||||||
&elemaddr, &elemsize, &desc);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_btrfs_unmount (data);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM
|
if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM
|
||||||
|| key_out.object_id != key_in.object_id)
|
|| key_out.object_id != key_in.object_id)
|
||||||
{
|
{
|
||||||
r = next (data, &desc, &elemaddr, &elemsize, &key_out);
|
r = next (data, &desc, &elemaddr, &elemsize, &key_out);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
{
|
goto out;
|
||||||
free_iterator (&desc);
|
|
||||||
return -r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1344,18 +1453,21 @@ grub_btrfs_dir (grub_device_t device, const char *path,
|
||||||
direl = grub_malloc (allocated + 1);
|
direl = grub_malloc (allocated + 1);
|
||||||
if (!direl)
|
if (!direl)
|
||||||
{
|
{
|
||||||
free_iterator (&desc);
|
r = -grub_errno;
|
||||||
return grub_errno;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize);
|
err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
r = -err;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (cdirel = direl;
|
for (cdirel = direl;
|
||||||
(grub_uint8_t *) cdirel - (grub_uint8_t *) direl
|
(grub_uint8_t *) cdirel - (grub_uint8_t *) direl
|
||||||
< (grub_ssize_t) elemsize;
|
< (grub_ssize_t) elemsize;
|
||||||
cdirel = (void *) ((grub_uint8_t *) (direl + 1)
|
cdirel = (void *) ((grub_uint8_t *) (direl + 1)
|
||||||
+ grub_le_to_cpu16 (cdirel->n)
|
+ grub_le_to_cpu16 (cdirel->n)
|
||||||
+ grub_le_to_cpu16 (cdirel->m)))
|
+ grub_le_to_cpu16 (cdirel->m)))
|
||||||
|
@ -1384,7 +1496,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
|
||||||
}
|
}
|
||||||
while (r > 0);
|
while (r > 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
grub_free (direl);
|
grub_free (direl);
|
||||||
|
|
||||||
free_iterator (&desc);
|
free_iterator (&desc);
|
||||||
|
@ -1456,7 +1568,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid)
|
||||||
*uuid = NULL;
|
*uuid = NULL;
|
||||||
|
|
||||||
data = grub_btrfs_mount (device);
|
data = grub_btrfs_mount (device);
|
||||||
if (! data)
|
if (!data)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
||||||
|
@ -1482,7 +1594,7 @@ grub_btrfs_label (grub_device_t device, char **label)
|
||||||
*label = NULL;
|
*label = NULL;
|
||||||
|
|
||||||
data = grub_btrfs_mount (device);
|
data = grub_btrfs_mount (device);
|
||||||
if (! data)
|
if (!data)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
*label = grub_strndup (data->sblock.label, sizeof (data->sblock.label));
|
*label = grub_strndup (data->sblock.label, sizeof (data->sblock.label));
|
||||||
|
@ -1492,26 +1604,55 @@ grub_btrfs_label (grub_device_t device, char **label)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_fs grub_btrfs_fs =
|
|
||||||
{
|
|
||||||
.name = "btrfs",
|
|
||||||
.dir = grub_btrfs_dir,
|
|
||||||
.open = grub_btrfs_open,
|
|
||||||
.read = grub_btrfs_read,
|
|
||||||
.close = grub_btrfs_close,
|
|
||||||
.uuid = grub_btrfs_uuid,
|
|
||||||
.label = grub_btrfs_label,
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
.reserved_first_sector = 1,
|
static grub_err_t
|
||||||
#endif
|
grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
};
|
unsigned int *nsectors,
|
||||||
|
grub_embed_type_t embed_type,
|
||||||
|
grub_disk_addr_t **sectors)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
GRUB_MOD_INIT(btrfs)
|
if (embed_type != GRUB_EMBED_PCBIOS)
|
||||||
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
"BtrFS currently supports only PC-BIOS embedding");
|
||||||
|
|
||||||
|
if (64 * 2 - 1 < *nsectors)
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
"Your core.img is unusually large. "
|
||||||
|
"It won't fit in the embedding area.");
|
||||||
|
|
||||||
|
*nsectors = 64 * 2 - 1;
|
||||||
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
|
if (!*sectors)
|
||||||
|
return grub_errno;
|
||||||
|
for (i = 0; i < *nsectors; i++)
|
||||||
|
(*sectors)[i] = i + 1;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct grub_fs grub_btrfs_fs = {
|
||||||
|
.name = "btrfs",
|
||||||
|
.dir = grub_btrfs_dir,
|
||||||
|
.open = grub_btrfs_open,
|
||||||
|
.read = grub_btrfs_read,
|
||||||
|
.close = grub_btrfs_close,
|
||||||
|
.uuid = grub_btrfs_uuid,
|
||||||
|
.label = grub_btrfs_label,
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
.embed = grub_btrfs_embed,
|
||||||
|
.reserved_first_sector = 1,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
GRUB_MOD_INIT (btrfs)
|
||||||
{
|
{
|
||||||
grub_fs_register (&grub_btrfs_fs);
|
grub_fs_register (&grub_btrfs_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(btrfs)
|
GRUB_MOD_FINI (btrfs)
|
||||||
{
|
{
|
||||||
grub_fs_unregister (&grub_btrfs_fs);
|
grub_fs_unregister (&grub_btrfs_fs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
#define ATTR_TYPE 0160000
|
||||||
|
#define ATTR_FILE 0100000
|
||||||
|
#define ATTR_DIR 0040000
|
||||||
|
#define ATTR_LNK 0120000
|
||||||
|
|
||||||
#ifndef MODE_USTAR
|
#ifndef MODE_USTAR
|
||||||
/* cpio support */
|
/* cpio support */
|
||||||
#define MAGIC_BCPIO 070707
|
#define MAGIC_BCPIO 070707
|
||||||
|
@ -71,60 +76,94 @@ struct head
|
||||||
struct grub_cpio_data
|
struct grub_cpio_data
|
||||||
{
|
{
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
grub_uint32_t hofs;
|
grub_off_t hofs;
|
||||||
grub_uint32_t dofs;
|
grub_off_t dofs;
|
||||||
grub_uint32_t size;
|
grub_off_t size;
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
char *linkname;
|
||||||
|
grub_size_t linkname_alloc;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
canonicalize (char *name)
|
||||||
|
{
|
||||||
|
char *iptr, *optr;
|
||||||
|
for (iptr = name, optr = name; *iptr; )
|
||||||
|
{
|
||||||
|
while (*iptr == '/')
|
||||||
|
iptr++;
|
||||||
|
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
|
||||||
|
{
|
||||||
|
iptr += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while (*iptr && *iptr != '/')
|
||||||
|
*optr++ = *iptr++;
|
||||||
|
if (*iptr)
|
||||||
|
*optr++ = *iptr++;
|
||||||
|
}
|
||||||
|
*optr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
||||||
grub_int32_t *mtime, grub_uint32_t * ofs)
|
grub_int32_t *mtime, grub_disk_addr_t *ofs,
|
||||||
|
grub_uint32_t *mode)
|
||||||
{
|
{
|
||||||
#ifndef MODE_USTAR
|
#ifndef MODE_USTAR
|
||||||
struct head hd;
|
struct head hd;
|
||||||
|
|
||||||
if (grub_disk_read
|
if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
|
||||||
(data->disk, 0, data->hofs, sizeof (hd), &hd))
|
return grub_errno;
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
if (hd.magic != MAGIC_BCPIO)
|
if (hd.magic != MAGIC_BCPIO)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
|
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
|
||||||
|
|
||||||
data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
|
data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
|
||||||
if (mtime)
|
if (mtime)
|
||||||
*mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2;
|
*mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2;
|
||||||
|
if (mode)
|
||||||
|
*mode = hd.mode;
|
||||||
|
|
||||||
if (hd.namesize & 1)
|
if (hd.namesize & 1)
|
||||||
hd.namesize++;
|
hd.namesize++;
|
||||||
|
|
||||||
if ((*name = grub_malloc (hd.namesize)) == NULL)
|
*name = grub_malloc (hd.namesize + 1);
|
||||||
return grub_errno;
|
if (*name == NULL)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
|
if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
|
||||||
hd.namesize, *name))
|
hd.namesize, *name))
|
||||||
{
|
{
|
||||||
grub_free (*name);
|
grub_free (*name);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
(*name)[hd.namesize] = 0;
|
||||||
|
|
||||||
if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
|
if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
|
||||||
&& ! grub_memcmp(*name, "TRAILER!!!", 11))
|
&& grub_memcmp(*name, "TRAILER!!!", 11) == 0)
|
||||||
{
|
{
|
||||||
*ofs = 0;
|
*ofs = 0;
|
||||||
return GRUB_ERR_NONE;
|
grub_free (*name);
|
||||||
}
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
data->dofs = data->hofs + sizeof (hd) + hd.namesize;
|
canonicalize (*name);
|
||||||
*ofs = data->dofs + data->size;
|
|
||||||
if (data->size & 1)
|
data->dofs = data->hofs + sizeof (hd) + hd.namesize;
|
||||||
(*ofs)++;
|
*ofs = data->dofs + data->size;
|
||||||
|
if (data->size & 1)
|
||||||
|
(*ofs)++;
|
||||||
#else
|
#else
|
||||||
struct head hd;
|
struct head hd;
|
||||||
|
int reread = 0, have_longname = 0, have_longlink = 0;
|
||||||
|
|
||||||
if (grub_disk_read
|
for (reread = 0; reread < 3; reread++)
|
||||||
(data->disk, 0, data->hofs, sizeof (hd), &hd))
|
{
|
||||||
|
if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (!hd.name[0])
|
if (!hd.name[0])
|
||||||
|
@ -136,15 +175,102 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
||||||
if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
|
if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
|
return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
|
||||||
|
|
||||||
if ((*name = grub_strdup (hd.name)) == NULL)
|
if (hd.typeflag == 'L')
|
||||||
return grub_errno;
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_size_t namesize = grub_strtoull (hd.size, NULL, 8);
|
||||||
|
*name = grub_malloc (namesize + 1);
|
||||||
|
if (*name == NULL)
|
||||||
|
return grub_errno;
|
||||||
|
err = grub_disk_read (data->disk, 0,
|
||||||
|
data->hofs + GRUB_DISK_SECTOR_SIZE, namesize,
|
||||||
|
*name);
|
||||||
|
(*name)[namesize] = 0;
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
data->hofs += GRUB_DISK_SECTOR_SIZE
|
||||||
|
+ ((namesize + GRUB_DISK_SECTOR_SIZE - 1) &
|
||||||
|
~(GRUB_DISK_SECTOR_SIZE - 1));
|
||||||
|
have_longname = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
data->size = grub_strtoul (hd.size, NULL, 8);
|
if (hd.typeflag == 'K')
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_size_t linksize = grub_strtoull (hd.size, NULL, 8);
|
||||||
|
if (data->linkname_alloc < linksize + 1)
|
||||||
|
{
|
||||||
|
char *n;
|
||||||
|
n = grub_malloc (2 * (linksize + 1));
|
||||||
|
if (!n)
|
||||||
|
return grub_errno;
|
||||||
|
grub_free (data->linkname);
|
||||||
|
data->linkname = n;
|
||||||
|
data->linkname_alloc = 2 * (linksize + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = grub_disk_read (data->disk, 0,
|
||||||
|
data->hofs + GRUB_DISK_SECTOR_SIZE, linksize,
|
||||||
|
data->linkname);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
data->linkname[linksize] = 0;
|
||||||
|
data->hofs += GRUB_DISK_SECTOR_SIZE
|
||||||
|
+ ((linksize + GRUB_DISK_SECTOR_SIZE - 1) &
|
||||||
|
~(GRUB_DISK_SECTOR_SIZE - 1));
|
||||||
|
have_longlink = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_longname)
|
||||||
|
{
|
||||||
|
*name = grub_strdup (hd.name);
|
||||||
|
if (*name == NULL)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->size = grub_strtoull (hd.size, NULL, 8);
|
||||||
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
|
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
|
||||||
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
|
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
|
||||||
~(GRUB_DISK_SECTOR_SIZE - 1));
|
~(GRUB_DISK_SECTOR_SIZE - 1));
|
||||||
if (mtime)
|
if (mtime)
|
||||||
*mtime = grub_strtoul (hd.mtime, NULL, 8);
|
*mtime = grub_strtoul (hd.mtime, NULL, 8);
|
||||||
|
if (mode)
|
||||||
|
{
|
||||||
|
*mode = grub_strtoul (hd.mode, NULL, 8);
|
||||||
|
switch (hd.typeflag)
|
||||||
|
{
|
||||||
|
case '2':
|
||||||
|
*mode |= ATTR_LNK;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
*mode |= ATTR_FILE;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
*mode |= ATTR_DIR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!have_longlink)
|
||||||
|
{
|
||||||
|
if (data->linkname_alloc < 101)
|
||||||
|
{
|
||||||
|
char *n;
|
||||||
|
n = grub_malloc (101);
|
||||||
|
if (!n)
|
||||||
|
return grub_errno;
|
||||||
|
grub_free (data->linkname);
|
||||||
|
data->linkname = n;
|
||||||
|
data->linkname_alloc = 101;
|
||||||
|
}
|
||||||
|
grub_memcpy (data->linkname, hd.linkname, sizeof (hd.linkname));
|
||||||
|
data->linkname[100] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
canonicalize (*name);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +292,7 @@ grub_cpio_mount (grub_disk_t disk)
|
||||||
#endif
|
#endif
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
|
data = (struct grub_cpio_data *) grub_zalloc (sizeof (*data));
|
||||||
if (!data)
|
if (!data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -186,15 +312,107 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cpio_dir (grub_device_t device, const char *path,
|
handle_symlink (struct grub_cpio_data *data,
|
||||||
|
const char *fn, char **name,
|
||||||
|
grub_uint32_t mode, int *restart)
|
||||||
|
{
|
||||||
|
grub_size_t flen;
|
||||||
|
char *target;
|
||||||
|
#ifndef MODE_USTAR
|
||||||
|
grub_err_t err;
|
||||||
|
#endif
|
||||||
|
char *ptr;
|
||||||
|
char *lastslash;
|
||||||
|
grub_size_t prefixlen;
|
||||||
|
char *rest;
|
||||||
|
grub_size_t size;
|
||||||
|
|
||||||
|
*restart = 0;
|
||||||
|
|
||||||
|
if ((mode & ATTR_TYPE) != ATTR_LNK)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
flen = grub_strlen (fn);
|
||||||
|
if (grub_memcmp (*name, fn, flen) != 0
|
||||||
|
|| ((*name)[flen] != 0 && (*name)[flen] != '/'))
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
rest = *name + flen;
|
||||||
|
lastslash = rest;
|
||||||
|
if (*rest)
|
||||||
|
rest++;
|
||||||
|
while (lastslash >= *name && *lastslash != '/')
|
||||||
|
lastslash--;
|
||||||
|
if (lastslash >= *name)
|
||||||
|
prefixlen = lastslash - *name;
|
||||||
|
else
|
||||||
|
prefixlen = 0;
|
||||||
|
|
||||||
|
if (prefixlen)
|
||||||
|
prefixlen++;
|
||||||
|
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
size = grub_strlen (data->linkname);
|
||||||
|
#else
|
||||||
|
size = data->size;
|
||||||
|
#endif
|
||||||
|
if (size == 0)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
target = grub_malloc (size + grub_strlen (*name) + 2);
|
||||||
|
if (!target)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
grub_memcpy (target + prefixlen, data->linkname, size);
|
||||||
|
#else
|
||||||
|
err = grub_disk_read (data->disk, 0, data->dofs, data->size,
|
||||||
|
target + prefixlen);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
if (target[prefixlen] == '/')
|
||||||
|
{
|
||||||
|
grub_memmove (target, target + prefixlen, data->size - 1);
|
||||||
|
ptr = target + data->size - 1;
|
||||||
|
ptr = grub_stpcpy (ptr, rest);
|
||||||
|
*ptr = 0;
|
||||||
|
grub_dprintf ("cpio", "symlink redirected %s to %s\n",
|
||||||
|
*name, target);
|
||||||
|
grub_free (*name);
|
||||||
|
*name = target;
|
||||||
|
*restart = 1;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
if (prefixlen)
|
||||||
|
{
|
||||||
|
grub_memcpy (target, *name, prefixlen);
|
||||||
|
target[prefixlen] = '/';
|
||||||
|
}
|
||||||
|
ptr = target + prefixlen + size;
|
||||||
|
ptr = grub_stpcpy (ptr, rest);
|
||||||
|
*ptr = 0;
|
||||||
|
grub_dprintf ("cpio", "symlink redirected %s to %s\n",
|
||||||
|
*name, target);
|
||||||
|
grub_free (*name);
|
||||||
|
*name = target;
|
||||||
|
*restart = 1;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cpio_dir (grub_device_t device, const char *path_in,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
const struct grub_dirhook_info *info))
|
const struct grub_dirhook_info *info))
|
||||||
{
|
{
|
||||||
struct grub_cpio_data *data;
|
struct grub_cpio_data *data;
|
||||||
grub_uint32_t ofs;
|
grub_disk_addr_t ofs;
|
||||||
char *prev, *name;
|
char *prev, *name, *path, *ptr;
|
||||||
const char *np;
|
grub_size_t len;
|
||||||
int len;
|
int symlinknest = 0;
|
||||||
|
|
||||||
|
path = grub_strdup (path_in + 1);
|
||||||
|
if (!path)
|
||||||
|
return grub_errno;
|
||||||
|
for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--)
|
||||||
|
*ptr = 0;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -202,35 +420,39 @@ grub_cpio_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
data = grub_cpio_mount (device->disk);
|
data = grub_cpio_mount (device->disk);
|
||||||
if (!data)
|
if (!data)
|
||||||
goto fail;
|
{
|
||||||
|
grub_free (path);
|
||||||
np = path + 1;
|
return grub_errno;
|
||||||
len = grub_strlen (path) - 1;
|
}
|
||||||
|
|
||||||
|
len = grub_strlen (path);
|
||||||
data->hofs = 0;
|
data->hofs = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
grub_int32_t mtime;
|
grub_int32_t mtime;
|
||||||
|
grub_uint32_t mode;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
if (grub_cpio_find_file (data, &name, &mtime, &ofs))
|
if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!ofs)
|
if (!ofs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (grub_memcmp (np, name, len) == 0)
|
if (grub_memcmp (path, name, len) == 0
|
||||||
|
&& (name[len] == 0 || name[len] == '/' || len == 0))
|
||||||
{
|
{
|
||||||
char *p, *n;
|
char *p, *n;
|
||||||
|
|
||||||
n = name + len;
|
n = name + len;
|
||||||
if (*n == '/')
|
while (*n == '/')
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
p = grub_strchr (name + len, '/');
|
p = grub_strchr (n, '/');
|
||||||
if (p)
|
if (p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
if ((!prev) || (grub_strcmp (prev, name) != 0))
|
if (((!prev) || (grub_strcmp (prev, n) != 0)) && *n != 0)
|
||||||
{
|
{
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
@ -238,19 +460,42 @@ grub_cpio_dir (grub_device_t device, const char *path,
|
||||||
info.mtime = mtime;
|
info.mtime = mtime;
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
|
|
||||||
hook (name + len, &info);
|
hook (n, &info);
|
||||||
grub_free (prev);
|
grub_free (prev);
|
||||||
prev = name;
|
prev = name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
grub_free (name);
|
{
|
||||||
|
int restart;
|
||||||
|
err = handle_symlink (data, name, &path, mode, &restart);
|
||||||
|
grub_free (name);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
if (restart)
|
||||||
|
{
|
||||||
|
len = grub_strlen (path);
|
||||||
|
if (++symlinknest == 8)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_SYMLINK_LOOP,
|
||||||
|
"too deep nesting of symlinks");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
ofs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
grub_free (name);
|
||||||
data->hofs = ofs;
|
data->hofs = ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
|
grub_free (path);
|
||||||
grub_free (prev);
|
grub_free (prev);
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
grub_free (data->linkname);
|
||||||
|
#endif
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
@ -259,23 +504,33 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cpio_open (grub_file_t file, const char *name)
|
grub_cpio_open (grub_file_t file, const char *name_in)
|
||||||
{
|
{
|
||||||
struct grub_cpio_data *data;
|
struct grub_cpio_data *data;
|
||||||
grub_uint32_t ofs;
|
grub_disk_addr_t ofs;
|
||||||
char *fn;
|
char *fn;
|
||||||
int i, j;
|
char *name = grub_strdup (name_in + 1);
|
||||||
|
int symlinknest = 0;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
data = grub_cpio_mount (file->device->disk);
|
data = grub_cpio_mount (file->device->disk);
|
||||||
if (!data)
|
if (!data)
|
||||||
goto fail;
|
{
|
||||||
|
grub_free (name);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
data->hofs = 0;
|
data->hofs = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (grub_cpio_find_file (data, &fn, NULL, &ofs))
|
grub_uint32_t mode;
|
||||||
|
int restart;
|
||||||
|
|
||||||
|
if (grub_cpio_find_file (data, &fn, NULL, &ofs, &mode))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!ofs)
|
if (!ofs)
|
||||||
|
@ -284,33 +539,31 @@ grub_cpio_open (grub_file_t file, const char *name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare NAME and FN by hand in order to cope with duplicate
|
if (handle_symlink (data, fn, &name, mode, &restart))
|
||||||
slashes. */
|
|
||||||
i = 0;
|
|
||||||
j = 0;
|
|
||||||
while (name[i] == '/')
|
|
||||||
i++;
|
|
||||||
while (1)
|
|
||||||
{
|
{
|
||||||
if (name[i] != fn[j])
|
grub_free (fn);
|
||||||
goto no_match;
|
goto fail;
|
||||||
|
|
||||||
if (name[i] == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
while (name[i] == '/' && name[i+1] == '/')
|
|
||||||
i++;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name[i] != fn[j])
|
if (restart)
|
||||||
|
{
|
||||||
|
ofs = 0;
|
||||||
|
if (++symlinknest == 8)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_SYMLINK_LOOP,
|
||||||
|
"too deep nesting of symlinks");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
goto no_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strcmp (name, fn) != 0)
|
||||||
goto no_match;
|
goto no_match;
|
||||||
|
|
||||||
file->data = data;
|
file->data = data;
|
||||||
file->size = data->size;
|
file->size = data->size;
|
||||||
grub_free (fn);
|
grub_free (fn);
|
||||||
|
grub_free (name);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
@ -321,8 +574,11 @@ grub_cpio_open (grub_file_t file, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
grub_free (data->linkname);
|
||||||
|
#endif
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
grub_free (name);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
@ -342,7 +598,13 @@ grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cpio_close (grub_file_t file)
|
grub_cpio_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
struct grub_cpio_data *data;
|
||||||
|
|
||||||
|
data = file->data;
|
||||||
|
#ifdef MODE_USTAR
|
||||||
|
grub_free (data->linkname);
|
||||||
|
#endif
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
|
2
grub-core/fs/exfat.c
Normal file
2
grub-core/fs/exfat.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define MODE_EXFAT 1
|
||||||
|
#include "fat.c"
|
|
@ -337,7 +337,7 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_ext4_extent_header *
|
static struct grub_ext4_extent_header *
|
||||||
grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
|
grub_ext4_find_leaf (struct grub_ext2_data *data, grub_properly_aligned_t *buf,
|
||||||
struct grub_ext4_extent_header *ext_block,
|
struct grub_ext4_extent_header *ext_block,
|
||||||
grub_uint32_t fileblock)
|
grub_uint32_t fileblock)
|
||||||
{
|
{
|
||||||
|
@ -387,7 +387,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
|
|
||||||
if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
|
if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
|
||||||
{
|
{
|
||||||
char buf[EXT2_BLOCK_SIZE(data)];
|
GRUB_PROPERLY_ALIGNED_ARRAY (buf, EXT2_BLOCK_SIZE(data));
|
||||||
struct grub_ext4_extent_header *leaf;
|
struct grub_ext4_extent_header *leaf;
|
||||||
struct grub_ext4_extent *ext;
|
struct grub_ext4_extent *ext;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -30,28 +30,117 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_FAT_DIR_ENTRY_SIZE 32
|
enum
|
||||||
|
{
|
||||||
|
GRUB_FAT_ATTR_READ_ONLY = 0x01,
|
||||||
|
GRUB_FAT_ATTR_HIDDEN = 0x02,
|
||||||
|
GRUB_FAT_ATTR_SYSTEM = 0x04,
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
|
GRUB_FAT_ATTR_VOLUME_ID = 0x08,
|
||||||
|
#endif
|
||||||
|
GRUB_FAT_ATTR_DIRECTORY = 0x10,
|
||||||
|
GRUB_FAT_ATTR_ARCHIVE = 0x20,
|
||||||
|
|
||||||
#define GRUB_FAT_ATTR_READ_ONLY 0x01
|
#ifndef MODE_EXFAT
|
||||||
#define GRUB_FAT_ATTR_HIDDEN 0x02
|
GRUB_FAT_ATTR_LONG_NAME = (GRUB_FAT_ATTR_READ_ONLY
|
||||||
#define GRUB_FAT_ATTR_SYSTEM 0x04
|
| GRUB_FAT_ATTR_HIDDEN
|
||||||
#define GRUB_FAT_ATTR_VOLUME_ID 0x08
|
| GRUB_FAT_ATTR_SYSTEM
|
||||||
#define GRUB_FAT_ATTR_DIRECTORY 0x10
|
| GRUB_FAT_ATTR_VOLUME_ID),
|
||||||
#define GRUB_FAT_ATTR_ARCHIVE 0x20
|
#endif
|
||||||
|
GRUB_FAT_ATTR_VALID = (GRUB_FAT_ATTR_READ_ONLY
|
||||||
|
| GRUB_FAT_ATTR_HIDDEN
|
||||||
|
| GRUB_FAT_ATTR_SYSTEM
|
||||||
|
| GRUB_FAT_ATTR_DIRECTORY
|
||||||
|
| GRUB_FAT_ATTR_ARCHIVE
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
|
| GRUB_FAT_ATTR_VOLUME_ID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
#define GRUB_FAT_MAXFILE 256
|
#ifdef MODE_EXFAT
|
||||||
|
struct grub_exfat_bpb
|
||||||
|
{
|
||||||
|
grub_uint8_t jmp_boot[3];
|
||||||
|
grub_uint8_t oem_name[8];
|
||||||
|
grub_uint8_t mbz[53];
|
||||||
|
grub_uint64_t num_hidden_sectors;
|
||||||
|
grub_uint64_t num_total_sectors;
|
||||||
|
grub_uint32_t num_reserved_sectors;
|
||||||
|
grub_uint32_t sectors_per_fat;
|
||||||
|
grub_uint32_t cluster_offset;
|
||||||
|
grub_uint32_t cluster_count;
|
||||||
|
grub_uint32_t root_cluster;
|
||||||
|
grub_uint32_t num_serial;
|
||||||
|
grub_uint16_t fs_revision;
|
||||||
|
grub_uint16_t volume_flags;
|
||||||
|
grub_uint8_t bytes_per_sector_shift;
|
||||||
|
grub_uint8_t sectors_per_cluster_shift;
|
||||||
|
grub_uint8_t num_fats;
|
||||||
|
grub_uint8_t num_ph_drive;
|
||||||
|
grub_uint8_t reserved[8];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
typedef struct grub_exfat_bpb grub_current_fat_bpb_t;
|
||||||
|
#else
|
||||||
|
typedef struct grub_fat_bpb grub_current_fat_bpb_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \
|
#ifdef MODE_EXFAT
|
||||||
| GRUB_FAT_ATTR_HIDDEN \
|
struct grub_fat_dir_entry
|
||||||
| GRUB_FAT_ATTR_SYSTEM \
|
{
|
||||||
| GRUB_FAT_ATTR_VOLUME_ID)
|
grub_uint8_t entry_type;
|
||||||
#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \
|
union
|
||||||
| GRUB_FAT_ATTR_HIDDEN \
|
{
|
||||||
| GRUB_FAT_ATTR_SYSTEM \
|
grub_uint8_t placeholder[31];
|
||||||
| GRUB_FAT_ATTR_DIRECTORY \
|
struct {
|
||||||
| GRUB_FAT_ATTR_ARCHIVE \
|
grub_uint8_t secondary_count;
|
||||||
| GRUB_FAT_ATTR_VOLUME_ID)
|
grub_uint16_t checksum;
|
||||||
|
grub_uint16_t attr;
|
||||||
|
grub_uint16_t reserved1;
|
||||||
|
grub_uint32_t c_time;
|
||||||
|
grub_uint32_t m_time;
|
||||||
|
grub_uint32_t a_time;
|
||||||
|
grub_uint8_t c_time_tenth;
|
||||||
|
grub_uint8_t m_time_tenth;
|
||||||
|
grub_uint8_t a_time_tenth;
|
||||||
|
grub_uint8_t reserved2[9];
|
||||||
|
} __attribute__ ((packed)) file;
|
||||||
|
struct {
|
||||||
|
grub_uint8_t flags;
|
||||||
|
grub_uint8_t reserved1;
|
||||||
|
grub_uint8_t name_length;
|
||||||
|
grub_uint16_t name_hash;
|
||||||
|
grub_uint16_t reserved2;
|
||||||
|
grub_uint64_t valid_size;
|
||||||
|
grub_uint32_t reserved3;
|
||||||
|
grub_uint32_t first_cluster;
|
||||||
|
grub_uint64_t file_size;
|
||||||
|
} __attribute__ ((packed)) stream_extension;
|
||||||
|
struct {
|
||||||
|
grub_uint8_t flags;
|
||||||
|
grub_uint16_t str[15];
|
||||||
|
} __attribute__ ((packed)) file_name;
|
||||||
|
struct {
|
||||||
|
grub_uint8_t character_count;
|
||||||
|
grub_uint16_t str[11];
|
||||||
|
grub_uint8_t reserved[8];
|
||||||
|
} __attribute__ ((packed)) volume_label;
|
||||||
|
} __attribute__ ((packed)) type_specific;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_fat_dir_node
|
||||||
|
{
|
||||||
|
grub_uint32_t attr;
|
||||||
|
grub_uint32_t first_cluster;
|
||||||
|
grub_uint64_t file_size;
|
||||||
|
grub_uint64_t valid_size;
|
||||||
|
int have_stream;
|
||||||
|
int is_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct grub_fat_dir_node grub_fat_dir_node_t;
|
||||||
|
|
||||||
|
#else
|
||||||
struct grub_fat_dir_entry
|
struct grub_fat_dir_entry
|
||||||
{
|
{
|
||||||
grub_uint8_t name[11];
|
grub_uint8_t name[11];
|
||||||
|
@ -80,6 +169,10 @@ struct grub_fat_long_name_entry
|
||||||
grub_uint16_t name3[2];
|
grub_uint16_t name3[2];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
typedef struct grub_fat_dir_entry grub_fat_dir_node_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct grub_fat_data
|
struct grub_fat_data
|
||||||
{
|
{
|
||||||
int logical_sector_bits;
|
int logical_sector_bits;
|
||||||
|
@ -90,8 +183,10 @@ struct grub_fat_data
|
||||||
int fat_size;
|
int fat_size;
|
||||||
|
|
||||||
grub_uint32_t root_cluster;
|
grub_uint32_t root_cluster;
|
||||||
|
#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;
|
||||||
|
#endif
|
||||||
|
|
||||||
int cluster_bits;
|
int cluster_bits;
|
||||||
grub_uint32_t cluster_eof_mark;
|
grub_uint32_t cluster_eof_mark;
|
||||||
|
@ -109,6 +204,7 @@ struct grub_fat_data
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
static int
|
static int
|
||||||
fat_log2 (unsigned x)
|
fat_log2 (unsigned x)
|
||||||
{
|
{
|
||||||
|
@ -125,11 +221,12 @@ fat_log2 (unsigned x)
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct grub_fat_data *
|
static struct grub_fat_data *
|
||||||
grub_fat_mount (grub_disk_t disk)
|
grub_fat_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
struct grub_fat_bpb bpb;
|
grub_current_fat_bpb_t bpb;
|
||||||
struct grub_fat_data *data = 0;
|
struct grub_fat_data *data = 0;
|
||||||
grub_uint32_t first_fat, magic;
|
grub_uint32_t first_fat, magic;
|
||||||
|
|
||||||
|
@ -144,20 +241,35 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
|
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ",
|
||||||
|
sizeof (bpb.oem_name)) != 0)
|
||||||
|
goto fail;
|
||||||
|
#else
|
||||||
if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
|
if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
|
||||||
&& grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
|
&& grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
|
||||||
&& grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
|
&& grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the sizes of logical sectors and clusters. */
|
/* Get the sizes of logical sectors and clusters. */
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->logical_sector_bits = bpb.bytes_per_sector_shift;
|
||||||
|
#else
|
||||||
data->logical_sector_bits =
|
data->logical_sector_bits =
|
||||||
fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
|
fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
|
||||||
if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
|
#endif
|
||||||
|
if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS
|
||||||
|
|| data->logical_sector_bits >= 16)
|
||||||
goto fail;
|
goto fail;
|
||||||
data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
|
data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->cluster_bits = bpb.sectors_per_cluster_shift;
|
||||||
|
#else
|
||||||
data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
|
data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
|
||||||
if (data->cluster_bits < 0)
|
#endif
|
||||||
|
if (data->cluster_bits < 0 || data->cluster_bits > 25)
|
||||||
goto fail;
|
goto fail;
|
||||||
data->cluster_bits += data->logical_sector_bits;
|
data->cluster_bits += data->logical_sector_bits;
|
||||||
|
|
||||||
|
@ -167,18 +279,28 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
if (data->fat_sector == 0)
|
if (data->fat_sector == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat)
|
||||||
|
<< data->logical_sector_bits);
|
||||||
|
#else
|
||||||
data->sectors_per_fat = ((bpb.sectors_per_fat_16
|
data->sectors_per_fat = ((bpb.sectors_per_fat_16
|
||||||
? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
|
? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
|
||||||
: grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
|
: grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
|
||||||
<< data->logical_sector_bits);
|
<< data->logical_sector_bits);
|
||||||
|
#endif
|
||||||
if (data->sectors_per_fat == 0)
|
if (data->sectors_per_fat == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Get the number of sectors in this volume. */
|
/* Get the number of sectors in this volume. */
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors))
|
||||||
|
<< data->logical_sector_bits);
|
||||||
|
#else
|
||||||
data->num_sectors = ((bpb.num_total_sectors_16
|
data->num_sectors = ((bpb.num_total_sectors_16
|
||||||
? grub_le_to_cpu16 (bpb.num_total_sectors_16)
|
? grub_le_to_cpu16 (bpb.num_total_sectors_16)
|
||||||
: grub_le_to_cpu32 (bpb.num_total_sectors_32))
|
: grub_le_to_cpu32 (bpb.num_total_sectors_32))
|
||||||
<< data->logical_sector_bits);
|
<< data->logical_sector_bits);
|
||||||
|
#endif
|
||||||
if (data->num_sectors == 0)
|
if (data->num_sectors == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -186,22 +308,44 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
if (bpb.num_fats == 0)
|
if (bpb.num_fats == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
|
data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
|
||||||
data->num_root_sectors
|
data->num_root_sectors
|
||||||
= ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
|
= ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
|
||||||
* GRUB_FAT_DIR_ENTRY_SIZE
|
* sizeof (struct grub_fat_dir_entry)
|
||||||
+ grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
|
+ grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
|
||||||
>> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
|
>> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
|
||||||
<< (data->logical_sector_bits));
|
<< (data->logical_sector_bits));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset)
|
||||||
|
<< data->logical_sector_bits);
|
||||||
|
data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count)
|
||||||
|
<< data->logical_sector_bits);
|
||||||
|
#else
|
||||||
data->cluster_sector = data->root_sector + data->num_root_sectors;
|
data->cluster_sector = data->root_sector + data->num_root_sectors;
|
||||||
data->num_clusters = (((data->num_sectors - data->cluster_sector)
|
data->num_clusters = (((data->num_sectors - data->cluster_sector)
|
||||||
>> (data->cluster_bits + data->logical_sector_bits))
|
>> (data->cluster_bits + data->logical_sector_bits))
|
||||||
+ 2);
|
+ 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (data->num_clusters <= 2)
|
if (data->num_clusters <= 2)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
{
|
||||||
|
/* exFAT. */
|
||||||
|
grub_uint16_t flags = grub_le_to_cpu16 (bpb.volume_flags);
|
||||||
|
|
||||||
|
data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster);
|
||||||
|
data->fat_size = 32;
|
||||||
|
data->cluster_eof_mark = 0xffffffff;
|
||||||
|
|
||||||
|
if ((flags & 0x1) && bpb.num_fats > 1)
|
||||||
|
data->fat_sector += data->sectors_per_fat;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (! bpb.sectors_per_fat_16)
|
if (! bpb.sectors_per_fat_16)
|
||||||
{
|
{
|
||||||
/* FAT32. */
|
/* FAT32. */
|
||||||
|
@ -243,6 +387,7 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
data->cluster_eof_mark = 0xfff8;
|
data->cluster_eof_mark = 0xfff8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* More sanity checks. */
|
/* More sanity checks. */
|
||||||
if (data->num_sectors <= data->fat_sector)
|
if (data->num_sectors <= data->fat_sector)
|
||||||
|
@ -274,17 +419,25 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serial number. */
|
/* Serial number. */
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->uuid = grub_le_to_cpu32 (bpb.num_serial);
|
||||||
|
#else
|
||||||
if (bpb.sectors_per_fat_16)
|
if (bpb.sectors_per_fat_16)
|
||||||
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
|
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
|
||||||
else
|
else
|
||||||
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
|
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MODE_EXFAT
|
||||||
/* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
|
/* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
|
||||||
descriptor, even if it is a so-called superfloppy (e.g. an USB key).
|
descriptor, even if it is a so-called superfloppy (e.g. an USB key).
|
||||||
The check may be too strict for this kind of stupid BIOSes, as
|
The check may be too strict for this kind of stupid BIOSes, as
|
||||||
they overwrite the media descriptor. */
|
they overwrite the media descriptor. */
|
||||||
if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
|
if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
#else
|
||||||
|
(void) magic;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start from the root directory. */
|
/* Start from the root directory. */
|
||||||
data->file_cluster = data->root_cluster;
|
data->file_cluster = data->root_cluster;
|
||||||
|
@ -311,6 +464,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
grub_ssize_t ret = 0;
|
grub_ssize_t ret = 0;
|
||||||
unsigned long sector;
|
unsigned long sector;
|
||||||
|
|
||||||
|
#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 (data->file_cluster == ~0U)
|
||||||
|
@ -324,13 +478,14 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Calculate the logical cluster number and offset. */
|
/* Calculate the logical cluster number and offset. */
|
||||||
logical_cluster_bits = (data->cluster_bits
|
logical_cluster_bits = (data->cluster_bits
|
||||||
+ data->logical_sector_bits
|
+ data->logical_sector_bits
|
||||||
+ GRUB_DISK_SECTOR_BITS);
|
+ GRUB_DISK_SECTOR_BITS);
|
||||||
logical_cluster = offset >> logical_cluster_bits;
|
logical_cluster = offset >> logical_cluster_bits;
|
||||||
offset &= (1 << logical_cluster_bits) - 1;
|
offset &= (1ULL << logical_cluster_bits) - 1;
|
||||||
|
|
||||||
if (logical_cluster < data->cur_cluster_num)
|
if (logical_cluster < data->cur_cluster_num)
|
||||||
{
|
{
|
||||||
|
@ -422,13 +577,116 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
static grub_err_t
|
||||||
|
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
int (*hook) (const char *filename,
|
||||||
|
grub_fat_dir_node_t *node))
|
||||||
|
{
|
||||||
|
struct grub_fat_dir_entry dir;
|
||||||
|
grub_ssize_t offset = -sizeof(dir);
|
||||||
|
grub_uint16_t *unibuf;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
unibuf = grub_malloc (15 * 256 * 2);
|
||||||
|
filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
offset += sizeof (dir);
|
||||||
|
|
||||||
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
|
offset, sizeof (dir), (char *) &dir)
|
||||||
|
!= sizeof (dir))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dir.entry_type == 0)
|
||||||
|
break;
|
||||||
|
if (!(dir.entry_type & 0x80))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dir.entry_type == 0x85)
|
||||||
|
{
|
||||||
|
unsigned i, nsec, slots = 0;
|
||||||
|
grub_fat_dir_node_t node;
|
||||||
|
|
||||||
|
nsec = dir.type_specific.file.secondary_count;
|
||||||
|
|
||||||
|
node.attr = grub_cpu_to_le32 (dir.type_specific.file.attr);
|
||||||
|
node.have_stream = 0;
|
||||||
|
for (i = 0; i < nsec; i++)
|
||||||
|
{
|
||||||
|
struct grub_fat_dir_entry sec;
|
||||||
|
offset += sizeof (sec);
|
||||||
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
|
offset, sizeof (sec), (char *) &sec)
|
||||||
|
!= sizeof (sec))
|
||||||
|
break;
|
||||||
|
if (!(sec.entry_type & 0x80))
|
||||||
|
continue;
|
||||||
|
if (!(sec.entry_type & 0x40))
|
||||||
|
break;
|
||||||
|
switch (sec.entry_type)
|
||||||
|
{
|
||||||
|
case 0xc0:
|
||||||
|
node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster);
|
||||||
|
node.valid_size
|
||||||
|
= grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size);
|
||||||
|
node.file_size
|
||||||
|
= grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
|
||||||
|
node.have_stream = 1;
|
||||||
|
break;
|
||||||
|
case 0xc1:
|
||||||
|
grub_memcpy (unibuf + slots * 15,
|
||||||
|
sec.type_specific.file_name.str, 30);
|
||||||
|
slots++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
grub_dprintf ("exfat", "unknown secondary type 0x%02x\n",
|
||||||
|
sec.entry_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != nsec)
|
||||||
|
{
|
||||||
|
offset -= sizeof (dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
|
||||||
|
slots * 15) = '\0';
|
||||||
|
|
||||||
|
if (hook (filename, &node))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Allocation bitmap. */
|
||||||
|
if (dir.entry_type == 0x81)
|
||||||
|
continue;
|
||||||
|
/* Upcase table. */
|
||||||
|
if (dir.entry_type == 0x82)
|
||||||
|
continue;
|
||||||
|
/* Volume label. */
|
||||||
|
if (dir.entry_type == 0x83)
|
||||||
|
continue;
|
||||||
|
grub_dprintf ("exfat", "unknown primary type 0x%02x\n", dir.entry_type);
|
||||||
|
}
|
||||||
|
grub_free (filename);
|
||||||
|
grub_free (unibuf);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
struct grub_fat_dir_entry *dir))
|
struct grub_fat_dir_entry *dir))
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry dir;
|
struct grub_fat_dir_entry dir;
|
||||||
char *filename, *filep = 0;
|
char *filename;
|
||||||
|
char *filep = 0;
|
||||||
grub_uint16_t *unibuf;
|
grub_uint16_t *unibuf;
|
||||||
int slot = -1, slots = -1;
|
int slot = -1, slots = -1;
|
||||||
int checksum = -1;
|
int checksum = -1;
|
||||||
|
@ -438,7 +696,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
|
||||||
|
|
||||||
/* Allocate space enough to hold a long name. */
|
/* Allocate space enough to hold a long name. */
|
||||||
filename = grub_malloc (0x40 * 13 * 4 + 1);
|
filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
|
unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
|
||||||
if (! filename || ! unibuf)
|
if (! filename || ! unibuf)
|
||||||
{
|
{
|
||||||
|
@ -455,10 +713,11 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
offset += sizeof (dir);
|
offset += sizeof (dir);
|
||||||
|
|
||||||
/* Read a directory entry. */
|
/* Read a directory entry. */
|
||||||
if ((grub_fat_read_data (disk, data, 0,
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
offset, sizeof (dir), (char *) &dir)
|
offset, sizeof (dir), (char *) &dir)
|
||||||
!= sizeof (dir) || dir.name[0] == 0))
|
!= sizeof (dir) || dir.name[0] == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle long name entries. */
|
/* Handle long name entries. */
|
||||||
if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
|
if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
|
||||||
{
|
{
|
||||||
|
@ -543,7 +802,6 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
filep++;
|
filep++;
|
||||||
}
|
}
|
||||||
*filep = '\0';
|
*filep = '\0';
|
||||||
|
|
||||||
if (hook (filename, &dir))
|
if (hook (filename, &dir))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -553,7 +811,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Find the underlying directory or file in PATH and return the
|
/* Find the underlying directory or file in PATH and return the
|
||||||
next path. If there is no next path or an error occurs, return NULL.
|
next path. If there is no next path or an error occurs, return NULL.
|
||||||
|
@ -569,8 +827,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
int call_hook;
|
int call_hook;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
|
auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir);
|
||||||
int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
|
int iter_hook (const char *filename, grub_fat_dir_node_t *dir)
|
||||||
{
|
{
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
@ -578,8 +836,13 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
|
info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
|
||||||
info.case_insensitive = 1;
|
info.case_insensitive = 1;
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
if (!dir->have_stream)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
|
if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
if (*dirname == '\0' && call_hook)
|
if (*dirname == '\0' && call_hook)
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
|
|
||||||
|
@ -587,9 +850,14 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
data->attr = dir->attr;
|
data->attr = dir->attr;
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
data->file_size = dir->file_size;
|
||||||
|
data->file_cluster = dir->first_cluster;
|
||||||
|
#else
|
||||||
data->file_size = grub_le_to_cpu32 (dir->file_size);
|
data->file_size = grub_le_to_cpu32 (dir->file_size);
|
||||||
data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
|
data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
|
||||||
| grub_le_to_cpu16 (dir->first_cluster_low));
|
| grub_le_to_cpu16 (dir->first_cluster_low));
|
||||||
|
#endif
|
||||||
data->cur_cluster_num = ~0U;
|
data->cur_cluster_num = ~0U;
|
||||||
|
|
||||||
if (call_hook)
|
if (call_hook)
|
||||||
|
@ -745,14 +1013,67 @@ grub_fat_close (grub_file_t file)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
static grub_err_t
|
||||||
|
grub_fat_label (grub_device_t device, char **label)
|
||||||
|
{
|
||||||
|
struct grub_fat_dir_entry dir;
|
||||||
|
grub_ssize_t offset = -sizeof(dir);
|
||||||
|
struct grub_fat_data *data;
|
||||||
|
grub_disk_t disk = device->disk;
|
||||||
|
|
||||||
|
data = grub_fat_mount (disk);
|
||||||
|
if (! data)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
*label = NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
offset += sizeof (dir);
|
||||||
|
|
||||||
|
if (grub_fat_read_data (disk, data, 0,
|
||||||
|
offset, sizeof (dir), (char *) &dir)
|
||||||
|
!= sizeof (dir))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dir.entry_type == 0)
|
||||||
|
break;
|
||||||
|
if (!(dir.entry_type & 0x80))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Volume label. */
|
||||||
|
if (dir.entry_type == 0x83)
|
||||||
|
{
|
||||||
|
grub_size_t chc;
|
||||||
|
*label = grub_malloc (11 * 4 + 1);
|
||||||
|
if (!*label)
|
||||||
|
{
|
||||||
|
grub_free (data);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
chc = dir.type_specific.volume_label.character_count;
|
||||||
|
if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str))
|
||||||
|
chc = ARRAY_SIZE (dir.type_specific.volume_label.str);
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) *label,
|
||||||
|
dir.type_specific.volume_label.str, chc) = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
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;
|
struct grub_fat_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|
||||||
auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
|
auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir);
|
||||||
int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
|
int iter_hook (const char *filename, grub_fat_dir_node_t *dir)
|
||||||
{
|
{
|
||||||
if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
|
if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
{
|
{
|
||||||
|
@ -787,6 +1108,8 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_uuid (grub_device_t device, char **uuid)
|
grub_fat_uuid (grub_device_t device, char **uuid)
|
||||||
{
|
{
|
||||||
|
@ -798,9 +1121,12 @@ grub_fat_uuid (grub_device_t device, char **uuid)
|
||||||
data = grub_fat_mount (disk);
|
data = grub_fat_mount (disk);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
char *ptr;
|
||||||
*uuid = grub_xasprintf ("%04x-%04x",
|
*uuid = grub_xasprintf ("%04x-%04x",
|
||||||
(grub_uint16_t) (data->uuid >> 16),
|
(grub_uint16_t) (data->uuid >> 16),
|
||||||
(grub_uint16_t) data->uuid);
|
(grub_uint16_t) data->uuid);
|
||||||
|
for (ptr = *uuid; ptr && *ptr; ptr++)
|
||||||
|
*ptr = grub_toupper (*ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*uuid = NULL;
|
*uuid = NULL;
|
||||||
|
@ -814,7 +1140,11 @@ grub_fat_uuid (grub_device_t device, char **uuid)
|
||||||
|
|
||||||
static struct grub_fs grub_fat_fs =
|
static struct grub_fs grub_fat_fs =
|
||||||
{
|
{
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
.name = "exfat",
|
||||||
|
#else
|
||||||
.name = "fat",
|
.name = "fat",
|
||||||
|
#endif
|
||||||
.dir = grub_fat_dir,
|
.dir = grub_fat_dir,
|
||||||
.open = grub_fat_open,
|
.open = grub_fat_open,
|
||||||
.read = grub_fat_read,
|
.read = grub_fat_read,
|
||||||
|
@ -822,18 +1152,31 @@ static struct grub_fs grub_fat_fs =
|
||||||
.label = grub_fat_label,
|
.label = grub_fat_label,
|
||||||
.uuid = grub_fat_uuid,
|
.uuid = grub_fat_uuid,
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
/* ExFAT BPB is 30 larger than FAT32 one. */
|
||||||
|
.reserved_first_sector = 0,
|
||||||
|
#else
|
||||||
.reserved_first_sector = 1,
|
.reserved_first_sector = 1,
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
.next = 0
|
.next = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
GRUB_MOD_INIT(exfat)
|
||||||
|
#else
|
||||||
GRUB_MOD_INIT(fat)
|
GRUB_MOD_INIT(fat)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
|
||||||
grub_fs_register (&grub_fat_fs);
|
grub_fs_register (&grub_fat_fs);
|
||||||
my_mod = mod;
|
my_mod = mod;
|
||||||
}
|
}
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
GRUB_MOD_FINI(exfat)
|
||||||
|
#else
|
||||||
GRUB_MOD_FINI(fat)
|
GRUB_MOD_FINI(fat)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
grub_fs_unregister (&grub_fat_fs);
|
grub_fs_unregister (&grub_fat_fs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
|
||||||
char fpath[grub_strlen (currpath) + 1];
|
char fpath[grub_strlen (currpath) + 1];
|
||||||
char *name = fpath;
|
char *name = fpath;
|
||||||
char *next;
|
char *next;
|
||||||
// unsigned int pos = 0;
|
|
||||||
enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
|
enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
|
||||||
grub_fshelp_node_t currnode = currroot;
|
grub_fshelp_node_t currnode = currroot;
|
||||||
grub_fshelp_node_t oldnode = currroot;
|
grub_fshelp_node_t oldnode = currroot;
|
||||||
|
|
|
@ -244,22 +244,24 @@ static grub_ssize_t
|
||||||
grub_hfs_read_file (struct grub_hfs_data *data,
|
grub_hfs_read_file (struct grub_hfs_data *data,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
int pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
int i;
|
grub_off_t i;
|
||||||
int blockcnt;
|
grub_off_t blockcnt;
|
||||||
|
|
||||||
blockcnt = ((len + pos)
|
blockcnt = grub_divmod64 (((len + pos)
|
||||||
+ data->blksz - 1) / data->blksz;
|
+ data->blksz - 1), data->blksz, 0);
|
||||||
|
|
||||||
for (i = pos / data->blksz; i < blockcnt; i++)
|
for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++)
|
||||||
{
|
{
|
||||||
int blknr;
|
grub_disk_addr_t blknr;
|
||||||
int blockoff = pos % data->blksz;
|
grub_off_t blockoff;
|
||||||
int blockend = data->blksz;
|
grub_off_t blockend = data->blksz;
|
||||||
|
|
||||||
int skipfirst = 0;
|
int skipfirst = 0;
|
||||||
|
|
||||||
|
grub_divmod64 (pos, data->blksz, &blockoff);
|
||||||
|
|
||||||
blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
|
blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -267,7 +269,7 @@ grub_hfs_read_file (struct grub_hfs_data *data,
|
||||||
/* Last block. */
|
/* Last block. */
|
||||||
if (i == blockcnt - 1)
|
if (i == blockcnt - 1)
|
||||||
{
|
{
|
||||||
blockend = (len + pos) % data->blksz;
|
grub_divmod64 ((len + pos), data->blksz, &blockend);
|
||||||
|
|
||||||
/* The last portion is exactly EXT2_BLOCK_SIZE (data). */
|
/* The last portion is exactly EXT2_BLOCK_SIZE (data). */
|
||||||
if (! blockend)
|
if (! blockend)
|
||||||
|
@ -275,7 +277,7 @@ grub_hfs_read_file (struct grub_hfs_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First block. */
|
/* First block. */
|
||||||
if (i == pos / data->blksz)
|
if (i == grub_divmod64 (pos, data->blksz, 0))
|
||||||
{
|
{
|
||||||
skipfirst = blockoff;
|
skipfirst = blockoff;
|
||||||
blockend -= skipfirst;
|
blockend -= skipfirst;
|
||||||
|
@ -748,10 +750,7 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key,
|
||||||
entry. In case of a non-leaf mode it will be used to lookup
|
entry. In case of a non-leaf mode it will be used to lookup
|
||||||
the rest of the tree. */
|
the rest of the tree. */
|
||||||
if (cmp <= 0)
|
if (cmp <= 0)
|
||||||
{
|
found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));
|
||||||
grub_uint32_t *node = (grub_uint32_t *) rec->data;
|
|
||||||
found = grub_be_to_cpu32 (*node);
|
|
||||||
}
|
|
||||||
else /* The key can not be found in the tree. */
|
else /* The key can not be found in the tree. */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -815,7 +814,7 @@ grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
|
||||||
struct grub_hfs_catalog_key *ckey = rec->key;
|
struct grub_hfs_catalog_key *ckey = rec->key;
|
||||||
|
|
||||||
if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
|
if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
|
||||||
found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
|
found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));
|
||||||
|
|
||||||
if (hnd->type == 0xFF && ckey->strlen > 0)
|
if (hnd->type == 0xFF && ckey->strlen > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -181,7 +181,8 @@ enum grub_hfsplus_filetype
|
||||||
struct grub_hfsplus_catkey_internal
|
struct grub_hfsplus_catkey_internal
|
||||||
{
|
{
|
||||||
grub_uint32_t parent;
|
grub_uint32_t parent;
|
||||||
char *name;
|
const grub_uint16_t *name;
|
||||||
|
grub_size_t namelen;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Internal representation of an extent overflow key. */
|
/* Internal representation of an extent overflow key. */
|
||||||
|
@ -214,7 +215,7 @@ struct grub_fshelp_node
|
||||||
struct grub_hfsplus_btree
|
struct grub_hfsplus_btree
|
||||||
{
|
{
|
||||||
grub_uint32_t root;
|
grub_uint32_t root;
|
||||||
int nodesize;
|
grub_size_t nodesize;
|
||||||
|
|
||||||
/* Catalog file node. */
|
/* Catalog file node. */
|
||||||
struct grub_fshelp_node file;
|
struct grub_fshelp_node file;
|
||||||
|
@ -236,7 +237,7 @@ struct grub_hfsplus_data
|
||||||
|
|
||||||
/* This is the offset into the physical disk for an embedded HFS+
|
/* This is the offset into the physical disk for an embedded HFS+
|
||||||
filesystem (one inside a plain HFS wrapper). */
|
filesystem (one inside a plain HFS wrapper). */
|
||||||
int embedded_offset;
|
grub_disk_addr_t embedded_offset;
|
||||||
int case_sensitive;
|
int case_sensitive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -245,15 +246,14 @@ static grub_dl_t my_mod;
|
||||||
|
|
||||||
/* Return the offset of the record with the index INDEX, in the node
|
/* Return the offset of the record with the index INDEX, in the node
|
||||||
NODE which is part of the B+ tree BTREE. */
|
NODE which is part of the B+ tree BTREE. */
|
||||||
static inline unsigned int
|
static inline grub_off_t
|
||||||
grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
|
grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_btnode *node, int index)
|
struct grub_hfsplus_btnode *node, int index)
|
||||||
{
|
{
|
||||||
char *cnode = (char *) node;
|
char *cnode = (char *) node;
|
||||||
grub_uint16_t *recptr;
|
void *recptr;
|
||||||
recptr = (grub_uint16_t *) (&cnode[btree->nodesize
|
recptr = (&cnode[btree->nodesize - index * sizeof (grub_uint16_t) - 2]);
|
||||||
- index * sizeof (grub_uint16_t) - 2]);
|
return grub_be_to_cpu16 (grub_get_unaligned16 (recptr));
|
||||||
return grub_be_to_cpu16 (*recptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a pointer to the record with the index INDEX, in the node
|
/* Return a pointer to the record with the index INDEX, in the node
|
||||||
|
@ -263,7 +263,7 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_btnode *node, int index)
|
struct grub_hfsplus_btnode *node, int index)
|
||||||
{
|
{
|
||||||
char *cnode = (char *) node;
|
char *cnode = (char *) node;
|
||||||
unsigned int offset;
|
grub_off_t offset;
|
||||||
offset = grub_hfsplus_btree_recoffset (btree, node, index);
|
offset = grub_hfsplus_btree_recoffset (btree, node, index);
|
||||||
return (struct grub_hfsplus_key *) &cnode[offset];
|
return (struct grub_hfsplus_key *) &cnode[offset];
|
||||||
}
|
}
|
||||||
|
@ -272,12 +272,12 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
|
||||||
/* Find the extent that points to FILEBLOCK. If it is not in one of
|
/* Find the extent that points to FILEBLOCK. If it is not in one of
|
||||||
the 8 extents described by EXTENT, return -1. In that case set
|
the 8 extents described by EXTENT, return -1. In that case set
|
||||||
FILEBLOCK to the next block. */
|
FILEBLOCK to the next block. */
|
||||||
static int
|
static grub_disk_addr_t
|
||||||
grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
|
grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
|
||||||
int *fileblock)
|
grub_disk_addr_t *fileblock)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
grub_size_t blksleft = *fileblock;
|
grub_disk_addr_t blksleft = *fileblock;
|
||||||
|
|
||||||
/* First lookup the file in the given extents. */
|
/* First lookup the file in the given extents. */
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
|
@ -288,7 +288,7 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
|
||||||
}
|
}
|
||||||
|
|
||||||
*fileblock = blksleft;
|
*fileblock = blksleft;
|
||||||
return -1;
|
return 0xffffffffffffffffULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -296,7 +296,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_key_internal *key,
|
struct grub_hfsplus_key_internal *key,
|
||||||
int (*compare_keys) (struct grub_hfsplus_key *keya,
|
int (*compare_keys) (struct grub_hfsplus_key *keya,
|
||||||
struct grub_hfsplus_key_internal *keyb),
|
struct grub_hfsplus_key_internal *keyb),
|
||||||
struct grub_hfsplus_btnode **matchnode, int *keyoffset);
|
struct grub_hfsplus_btnode **matchnode,
|
||||||
|
grub_off_t *keyoffset);
|
||||||
|
|
||||||
static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
|
static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
|
||||||
struct grub_hfsplus_key_internal *keyb);
|
struct grub_hfsplus_key_internal *keyb);
|
||||||
|
@ -307,15 +308,15 @@ static grub_disk_addr_t
|
||||||
grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
{
|
{
|
||||||
struct grub_hfsplus_btnode *nnode = 0;
|
struct grub_hfsplus_btnode *nnode = 0;
|
||||||
int blksleft = fileblock;
|
grub_disk_addr_t blksleft = fileblock;
|
||||||
struct grub_hfsplus_extent *extents = &node->extents[0];
|
struct grub_hfsplus_extent *extents = &node->extents[0];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
struct grub_hfsplus_extkey *key;
|
struct grub_hfsplus_extkey *key;
|
||||||
struct grub_hfsplus_extkey_internal extoverflow;
|
struct grub_hfsplus_key_internal extoverflow;
|
||||||
int blk;
|
grub_disk_addr_t blk;
|
||||||
int ptr;
|
grub_off_t ptr;
|
||||||
|
|
||||||
/* Try to find this block in the current set of extents. */
|
/* Try to find this block in the current set of extents. */
|
||||||
blk = grub_hfsplus_find_block (extents, &blksleft);
|
blk = grub_hfsplus_find_block (extents, &blksleft);
|
||||||
|
@ -325,7 +326,7 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
grub_free (nnode);
|
grub_free (nnode);
|
||||||
nnode = 0;
|
nnode = 0;
|
||||||
|
|
||||||
if (blk != -1)
|
if (blk != 0xffffffffffffffffULL)
|
||||||
return (blk
|
return (blk
|
||||||
+ (node->data->embedded_offset >> (node->data->log2blksize
|
+ (node->data->embedded_offset >> (node->data->log2blksize
|
||||||
- GRUB_DISK_SECTOR_BITS)));
|
- GRUB_DISK_SECTOR_BITS)));
|
||||||
|
@ -341,11 +342,11 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the key to look for in the extent overflow file. */
|
/* Set up the key to look for in the extent overflow file. */
|
||||||
extoverflow.fileid = node->fileid;
|
extoverflow.extkey.fileid = node->fileid;
|
||||||
extoverflow.start = fileblock - blksleft;
|
extoverflow.extkey.start = fileblock - blksleft;
|
||||||
|
|
||||||
if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
|
if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
|
||||||
(struct grub_hfsplus_key_internal *) &extoverflow,
|
&extoverflow,
|
||||||
grub_hfsplus_cmp_extkey, &nnode, &ptr))
|
grub_hfsplus_cmp_extkey, &nnode, &ptr))
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_READ_ERROR,
|
grub_error (GRUB_ERR_READ_ERROR,
|
||||||
|
@ -376,7 +377,7 @@ static grub_ssize_t
|
||||||
grub_hfsplus_read_file (grub_fshelp_node_t node,
|
grub_hfsplus_read_file (grub_fshelp_node_t node,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
int pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
||||||
pos, len, buf, grub_hfsplus_read_block,
|
pos, len, buf, grub_hfsplus_read_block,
|
||||||
|
@ -411,9 +412,9 @@ grub_hfsplus_mount (grub_disk_t disk)
|
||||||
data->embedded_offset = 0;
|
data->embedded_offset = 0;
|
||||||
if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
|
if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
|
||||||
{
|
{
|
||||||
int extent_start;
|
grub_disk_addr_t extent_start;
|
||||||
int ablk_size;
|
grub_disk_addr_t ablk_size;
|
||||||
int ablk_start;
|
grub_disk_addr_t ablk_start;
|
||||||
|
|
||||||
/* See if there's an embedded HFS+ filesystem. */
|
/* See if there's an embedded HFS+ filesystem. */
|
||||||
if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
|
if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
|
||||||
|
@ -518,8 +519,6 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
|
||||||
{
|
{
|
||||||
struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
|
struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
|
||||||
struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
|
struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
|
||||||
char *filename;
|
|
||||||
int i;
|
|
||||||
int diff;
|
int diff;
|
||||||
|
|
||||||
/* Safe unsigned comparison */
|
/* Safe unsigned comparison */
|
||||||
|
@ -529,29 +528,35 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
|
||||||
if (aparent < catkey_b->parent)
|
if (aparent < catkey_b->parent)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Change the filename in keya so the endianness is correct. */
|
diff = grub_memcmp (catkey_a->name, catkey_b->name,
|
||||||
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
|
grub_min (grub_be_to_cpu16 (catkey_a->namelen),
|
||||||
catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]);
|
catkey_b->namelen)
|
||||||
|
* sizeof (catkey_a->name[0]));
|
||||||
|
if (diff == 0)
|
||||||
|
diff = grub_be_to_cpu16 (catkey_a->namelen) - catkey_b->namelen;
|
||||||
|
|
||||||
filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1);
|
|
||||||
|
|
||||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name,
|
|
||||||
grub_be_to_cpu16 (catkey_a->namelen)))
|
|
||||||
return -1; /* XXX: This error never occurs, but in case it happens
|
|
||||||
just skip this entry. */
|
|
||||||
|
|
||||||
diff = grub_strncmp (filename, catkey_b->name,
|
|
||||||
grub_be_to_cpu16 (catkey_a->namelen));
|
|
||||||
|
|
||||||
grub_free (filename);
|
|
||||||
|
|
||||||
/* The endianness was changed to host format, change it back to
|
|
||||||
whatever it was. */
|
|
||||||
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
|
|
||||||
catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]);
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compare the on disk catalog key KEYA with the catalog key we are
|
||||||
|
looking for (KEYB). */
|
||||||
|
static int
|
||||||
|
grub_hfsplus_cmp_catkey_id (struct grub_hfsplus_key *keya,
|
||||||
|
struct grub_hfsplus_key_internal *keyb)
|
||||||
|
{
|
||||||
|
struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
|
||||||
|
struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
|
||||||
|
|
||||||
|
/* Safe unsigned comparison */
|
||||||
|
grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent);
|
||||||
|
if (aparent > catkey_b->parent)
|
||||||
|
return 1;
|
||||||
|
if (aparent < catkey_b->parent)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare the on disk extent overflow key KEYA with the extent
|
/* Compare the on disk extent overflow key KEYA with the extent
|
||||||
overflow key we are looking for (KEYB). */
|
overflow key we are looking for (KEYB). */
|
||||||
static int
|
static int
|
||||||
|
@ -601,10 +606,10 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
|
||||||
static int
|
static int
|
||||||
grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
|
grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_btnode *first_node,
|
struct grub_hfsplus_btnode *first_node,
|
||||||
int first_rec,
|
grub_disk_addr_t first_rec,
|
||||||
int (*hook) (void *record))
|
int (*hook) (void *record))
|
||||||
{
|
{
|
||||||
int rec;
|
grub_disk_addr_t rec;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -642,12 +647,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_key_internal *key,
|
struct grub_hfsplus_key_internal *key,
|
||||||
int (*compare_keys) (struct grub_hfsplus_key *keya,
|
int (*compare_keys) (struct grub_hfsplus_key *keya,
|
||||||
struct grub_hfsplus_key_internal *keyb),
|
struct grub_hfsplus_key_internal *keyb),
|
||||||
struct grub_hfsplus_btnode **matchnode, int *keyoffset)
|
struct grub_hfsplus_btnode **matchnode,
|
||||||
|
grub_off_t *keyoffset)
|
||||||
{
|
{
|
||||||
grub_uint64_t currnode;
|
grub_uint64_t currnode;
|
||||||
char *node;
|
char *node;
|
||||||
struct grub_hfsplus_btnode *nodedesc;
|
struct grub_hfsplus_btnode *nodedesc;
|
||||||
int rec;
|
grub_disk_addr_t rec;
|
||||||
|
|
||||||
node = grub_malloc (btree->nodesize);
|
node = grub_malloc (btree->nodesize);
|
||||||
if (! node)
|
if (! node)
|
||||||
|
@ -660,7 +666,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
|
|
||||||
/* Read a node. */
|
/* Read a node. */
|
||||||
if (grub_hfsplus_read_file (&btree->file, 0,
|
if (grub_hfsplus_read_file (&btree->file, 0,
|
||||||
(long)currnode * (long)btree->nodesize,
|
(grub_disk_addr_t) currnode
|
||||||
|
* (grub_disk_addr_t) btree->nodesize,
|
||||||
btree->nodesize, (char *) node) <= 0)
|
btree->nodesize, (char *) node) <= 0)
|
||||||
{
|
{
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
@ -689,7 +696,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
}
|
}
|
||||||
else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX)
|
else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX)
|
||||||
{
|
{
|
||||||
grub_uint32_t *pointer;
|
void *pointer;
|
||||||
|
|
||||||
/* The place where the key could have been found didn't
|
/* The place where the key could have been found didn't
|
||||||
contain the key. This means that the previous match
|
contain the key. This means that the previous match
|
||||||
|
@ -701,10 +708,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
that we are looking for. The last match that is
|
that we are looking for. The last match that is
|
||||||
found will be used to locate the child which can
|
found will be used to locate the child which can
|
||||||
contain the record. */
|
contain the record. */
|
||||||
pointer = (grub_uint32_t *) ((char *) currkey
|
pointer = ((char *) currkey
|
||||||
+ grub_be_to_cpu16 (currkey->keylen)
|
+ grub_be_to_cpu16 (currkey->keylen)
|
||||||
+ 2);
|
+ 2);
|
||||||
currnode = grub_be_to_cpu32 (*pointer);
|
currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer));
|
||||||
match = 1;
|
match = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -770,6 +777,11 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (type == GRUB_FSHELP_UNKNOWN)
|
if (type == GRUB_FSHELP_UNKNOWN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
|
||||||
|
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
|
if (! filename)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Make sure the byte order of the UTF16 string is correct. */
|
/* Make sure the byte order of the UTF16 string is correct. */
|
||||||
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
||||||
{
|
{
|
||||||
|
@ -780,18 +792,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1);
|
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
|
||||||
if (! filename)
|
grub_be_to_cpu16 (catkey->namelen)) = '\0';
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
|
|
||||||
grub_be_to_cpu16 (catkey->namelen)))
|
|
||||||
{
|
|
||||||
grub_free (filename);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
filename[grub_be_to_cpu16 (catkey->namelen)] = '\0';
|
|
||||||
|
|
||||||
/* Restore the byte order to what it was previously. */
|
/* Restore the byte order to what it was previously. */
|
||||||
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
||||||
|
@ -801,22 +803,18 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (! dir->data->case_sensitive)
|
if (! dir->data->case_sensitive)
|
||||||
type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||||
|
|
||||||
/* Only accept valid nodes. */
|
/* A valid node is found; setup the node and call the
|
||||||
if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
|
callback function. */
|
||||||
{
|
node = grub_malloc (sizeof (*node));
|
||||||
/* A valid node is found; setup the node and call the
|
node->data = dir->data;
|
||||||
callback function. */
|
|
||||||
node = grub_malloc (sizeof (*node));
|
|
||||||
node->data = dir->data;
|
|
||||||
|
|
||||||
grub_memcpy (node->extents, fileinfo->data.extents,
|
grub_memcpy (node->extents, fileinfo->data.extents,
|
||||||
sizeof (node->extents));
|
sizeof (node->extents));
|
||||||
node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
|
node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
|
||||||
node->size = grub_be_to_cpu64 (fileinfo->data.size);
|
node->size = grub_be_to_cpu64 (fileinfo->data.size);
|
||||||
node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
|
node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
|
||||||
|
|
||||||
ret = hook (filename, type, node);
|
ret = hook (filename, type, node);
|
||||||
}
|
|
||||||
|
|
||||||
grub_free (filename);
|
grub_free (filename);
|
||||||
|
|
||||||
|
@ -825,11 +823,12 @@ 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;
|
||||||
int ptr;
|
grub_disk_addr_t ptr;
|
||||||
|
|
||||||
/* Create a key that points to the first entry in the directory. */
|
/* Create a key that points to the first entry in the directory. */
|
||||||
intern.catkey.parent = dir->fileid;
|
intern.catkey.parent = dir->fileid;
|
||||||
intern.catkey.name = "";
|
intern.catkey.name = 0;
|
||||||
|
intern.catkey.namelen = 0;
|
||||||
|
|
||||||
/* First lookup the first entry. */
|
/* First lookup the first entry. */
|
||||||
if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
|
if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
|
||||||
|
@ -894,7 +893,6 @@ grub_hfsplus_close (grub_file_t file)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read LEN bytes data from FILE into BUF. */
|
/* Read LEN bytes data from FILE into BUF. */
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
|
grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
@ -902,13 +900,10 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
struct grub_hfsplus_data *data =
|
struct grub_hfsplus_data *data =
|
||||||
(struct grub_hfsplus_data *) file->data;
|
(struct grub_hfsplus_data *) file->data;
|
||||||
|
|
||||||
int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
|
return grub_hfsplus_read_file (&data->opened_file, file->read_hook,
|
||||||
file->offset, len, buf);
|
file->offset, len, buf);
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfsplus_dir (grub_device_t device, const char *path,
|
grub_hfsplus_dir (grub_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
|
@ -963,13 +958,59 @@ grub_hfsplus_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfsplus_label (grub_device_t device __attribute__((unused))
|
grub_hfsplus_label (grub_device_t device, char **label)
|
||||||
, char **label __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
/* XXX: It's not documented how to read a label. */
|
struct grub_hfsplus_data *data;
|
||||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_disk_t disk = device->disk;
|
||||||
"reading the label of a HFS+ "
|
struct grub_hfsplus_catkey *catkey;
|
||||||
"partition is not implemented");
|
int i, label_len;
|
||||||
|
struct grub_hfsplus_key_internal intern;
|
||||||
|
struct grub_hfsplus_btnode *node;
|
||||||
|
grub_disk_addr_t ptr;
|
||||||
|
|
||||||
|
*label = 0;
|
||||||
|
|
||||||
|
data = grub_hfsplus_mount (disk);
|
||||||
|
if (!data)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
/* Create a key that points to the label. */
|
||||||
|
intern.catkey.parent = 1;
|
||||||
|
intern.catkey.name = 0;
|
||||||
|
intern.catkey.namelen = 0;
|
||||||
|
|
||||||
|
/* First lookup the first entry. */
|
||||||
|
if (grub_hfsplus_btree_search (&data->catalog_tree, &intern,
|
||||||
|
grub_hfsplus_cmp_catkey_id, &node, &ptr))
|
||||||
|
{
|
||||||
|
grub_free (data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
catkey = (struct grub_hfsplus_catkey *)
|
||||||
|
grub_hfsplus_btree_recptr (&data->catalog_tree, node, 0);
|
||||||
|
|
||||||
|
label_len = grub_be_to_cpu16 (catkey->namelen);
|
||||||
|
for (i = 0; i < label_len; i++)
|
||||||
|
{
|
||||||
|
catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
|
||||||
|
|
||||||
|
/* If the name is obviously invalid, skip this node. */
|
||||||
|
if (catkey->name[i] == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
|
if (! *label)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name,
|
||||||
|
label_len) = '\0';
|
||||||
|
|
||||||
|
grub_free (node);
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get mtime. */
|
/* Get mtime. */
|
||||||
|
|
|
@ -149,22 +149,29 @@ struct grub_iso9660_data
|
||||||
{
|
{
|
||||||
struct grub_iso9660_primary_voldesc voldesc;
|
struct grub_iso9660_primary_voldesc voldesc;
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
unsigned int first_sector;
|
|
||||||
int rockridge;
|
int rockridge;
|
||||||
int susp_skip;
|
int susp_skip;
|
||||||
int joliet;
|
int joliet;
|
||||||
|
struct grub_fshelp_node *node;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_fshelp_node
|
struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_iso9660_data *data;
|
struct grub_iso9660_data *data;
|
||||||
struct grub_iso9660_dir dirent;
|
grub_size_t have_dirents, alloc_dirents;
|
||||||
unsigned int size;
|
int have_symlink;
|
||||||
unsigned int blk;
|
struct grub_iso9660_dir dirents[8];
|
||||||
unsigned int dir_blk;
|
char symlink[0];
|
||||||
unsigned int dir_off;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLAG_TYPE_PLAIN = 0,
|
||||||
|
FLAG_TYPE_DIR = 2,
|
||||||
|
FLAG_TYPE = 3,
|
||||||
|
FLAG_MORE_EXTENTS = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,35 +221,77 @@ iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf)
|
||||||
|
{
|
||||||
|
grub_size_t i = 0;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
grub_size_t toread;
|
||||||
|
grub_err_t err;
|
||||||
|
while (i < node->have_dirents
|
||||||
|
&& off >= grub_le_to_cpu32 (node->dirents[i].size))
|
||||||
|
{
|
||||||
|
off -= grub_le_to_cpu32 (node->dirents[i].size);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == node->have_dirents)
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range");
|
||||||
|
toread = grub_le_to_cpu32 (node->dirents[i].size);
|
||||||
|
if (toread > len)
|
||||||
|
toread = len;
|
||||||
|
err = grub_disk_read (node->data->disk,
|
||||||
|
((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ,
|
||||||
|
off, toread, buf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
len -= toread;
|
||||||
|
off += toread;
|
||||||
|
buf += toread;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
|
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
|
||||||
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
|
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
|
||||||
every entry. */
|
every entry. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
|
grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
|
||||||
int sua_block, int sua_pos, int sua_size,
|
grub_ssize_t sua_size,
|
||||||
grub_err_t (*hook)
|
grub_err_t (*hook)
|
||||||
(struct grub_iso9660_susp_entry *entry))
|
(struct grub_iso9660_susp_entry *entry))
|
||||||
{
|
{
|
||||||
char *sua;
|
char *sua;
|
||||||
struct grub_iso9660_susp_entry *entry;
|
struct grub_iso9660_susp_entry *entry;
|
||||||
|
grub_disk_addr_t ce_block;
|
||||||
|
int is_ce = 0;
|
||||||
|
|
||||||
auto grub_err_t load_sua (void);
|
auto grub_err_t load_sua (void);
|
||||||
|
|
||||||
/* Load a part of the System Usage Area. */
|
/* Load a part of the System Usage Area. */
|
||||||
grub_err_t load_sua (void)
|
grub_err_t load_sua (void)
|
||||||
{
|
{
|
||||||
|
grub_err_t err;
|
||||||
sua = grub_malloc (sua_size);
|
sua = grub_malloc (sua_size);
|
||||||
if (!sua)
|
if (!sua)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_disk_read (data->disk, sua_block, sua_pos,
|
if (is_ce)
|
||||||
sua_size, sua))
|
err = grub_disk_read (node->data->disk, ce_block, off,
|
||||||
return grub_errno;
|
sua_size, sua);
|
||||||
|
else
|
||||||
|
err = read_node (node, off, sua_size, sua);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
entry = (struct grub_iso9660_susp_entry *) sua;
|
entry = (struct grub_iso9660_susp_entry *) sua;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sua_size <= 0)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
if (load_sua ())
|
if (load_sua ())
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -259,10 +308,11 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
|
||||||
{
|
{
|
||||||
struct grub_iso9660_susp_ce *ce;
|
struct grub_iso9660_susp_ce *ce;
|
||||||
|
|
||||||
|
is_ce = 1;
|
||||||
ce = (struct grub_iso9660_susp_ce *) entry;
|
ce = (struct grub_iso9660_susp_ce *) entry;
|
||||||
sua_size = grub_le_to_cpu32 (ce->len);
|
sua_size = grub_le_to_cpu32 (ce->len);
|
||||||
sua_pos = grub_le_to_cpu32 (ce->off);
|
off = grub_le_to_cpu32 (ce->off);
|
||||||
sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
|
ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
|
||||||
|
|
||||||
grub_free (sua);
|
grub_free (sua);
|
||||||
if (load_sua ())
|
if (load_sua ())
|
||||||
|
@ -281,34 +331,32 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
grub_iso9660_convert_string (grub_uint16_t *us, int len)
|
grub_iso9660_convert_string (grub_uint8_t *us, int len)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
grub_uint16_t t[len];
|
||||||
|
|
||||||
p = grub_malloc (len * 4 + 1);
|
p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (! p)
|
if (! p)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<len; i++)
|
||||||
us[i] = grub_be_to_cpu16 (us[i]);
|
t[i] = grub_be_to_cpu16 (grub_get_unaligned16 (us + 2 * i));
|
||||||
|
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
|
*grub_utf16_to_utf8 ((grub_uint8_t *) p, t, len) = '\0';
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_iso9660_data *
|
static grub_err_t
|
||||||
grub_iso9660_mount (grub_disk_t disk)
|
set_rockridge (struct grub_iso9660_data *data)
|
||||||
{
|
{
|
||||||
struct grub_iso9660_data *data = 0;
|
|
||||||
struct grub_iso9660_dir rootdir;
|
|
||||||
int sua_pos;
|
int sua_pos;
|
||||||
int sua_size;
|
int sua_size;
|
||||||
char *sua;
|
char *sua;
|
||||||
|
struct grub_iso9660_dir rootdir;
|
||||||
struct grub_iso9660_susp_entry *entry;
|
struct grub_iso9660_susp_entry *entry;
|
||||||
struct grub_iso9660_primary_voldesc voldesc;
|
|
||||||
int block;
|
|
||||||
|
|
||||||
auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
|
auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
|
||||||
|
|
||||||
|
@ -324,6 +372,74 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->rockridge = 0;
|
||||||
|
|
||||||
|
/* Read the system use area and test it to see if SUSP is
|
||||||
|
supported. */
|
||||||
|
if (grub_disk_read (data->disk,
|
||||||
|
(grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
||||||
|
<< GRUB_ISO9660_LOG2_BLKSZ), 0,
|
||||||
|
sizeof (rootdir), (char *) &rootdir))
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
|
||||||
|
|
||||||
|
sua_pos = (sizeof (rootdir) + rootdir.namelen
|
||||||
|
+ (rootdir.namelen % 2) - 1);
|
||||||
|
sua_size = rootdir.len - sua_pos;
|
||||||
|
|
||||||
|
if (!sua_size)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
sua = grub_malloc (sua_size);
|
||||||
|
if (! sua)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_disk_read (data->disk,
|
||||||
|
(grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
||||||
|
<< GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
|
||||||
|
sua_size, sua))
|
||||||
|
{
|
||||||
|
grub_free (sua);
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = (struct grub_iso9660_susp_entry *) sua;
|
||||||
|
|
||||||
|
/* Test if the SUSP protocol is used on this filesystem. */
|
||||||
|
if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
|
||||||
|
{
|
||||||
|
struct grub_fshelp_node rootnode;
|
||||||
|
|
||||||
|
rootnode.data = data;
|
||||||
|
rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents);
|
||||||
|
rootnode.have_dirents = 1;
|
||||||
|
rootnode.have_symlink = 0;
|
||||||
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
|
/* The 2nd data byte stored how many bytes are skipped every time
|
||||||
|
to get to the SUA (System Usage Area). */
|
||||||
|
data->susp_skip = entry->data[2];
|
||||||
|
entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
|
||||||
|
|
||||||
|
/* Iterate over the entries in the SUA area to detect
|
||||||
|
extensions. */
|
||||||
|
if (grub_iso9660_susp_iterate (&rootnode,
|
||||||
|
sua_pos, sua_size, susp_iterate))
|
||||||
|
{
|
||||||
|
grub_free (sua);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grub_free (sua);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_iso9660_data *
|
||||||
|
grub_iso9660_mount (grub_disk_t disk)
|
||||||
|
{
|
||||||
|
struct grub_iso9660_data *data = 0;
|
||||||
|
struct grub_iso9660_primary_voldesc voldesc;
|
||||||
|
int block;
|
||||||
|
|
||||||
data = grub_zalloc (sizeof (struct grub_iso9660_data));
|
data = grub_zalloc (sizeof (struct grub_iso9660_data));
|
||||||
if (! data)
|
if (! data)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -351,9 +467,11 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
|
if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
|
||||||
copy_voldesc = 1;
|
copy_voldesc = 1;
|
||||||
else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
|
else if (!data->rockridge
|
||||||
(voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
|
&& (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP)
|
||||||
|
&& (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f)
|
||||||
|
&&
|
||||||
((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */
|
((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */
|
||||||
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
|
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
|
||||||
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
|
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
|
||||||
|
@ -363,57 +481,16 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_voldesc)
|
if (copy_voldesc)
|
||||||
grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
|
{
|
||||||
sizeof (struct grub_iso9660_primary_voldesc));
|
grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
|
||||||
|
sizeof (struct grub_iso9660_primary_voldesc));
|
||||||
|
if (set_rockridge (data))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
block++;
|
block++;
|
||||||
} while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
|
} while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
|
||||||
|
|
||||||
/* Read the system use area and test it to see if SUSP is
|
|
||||||
supported. */
|
|
||||||
if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
|
||||||
<< GRUB_ISO9660_LOG2_BLKSZ), 0,
|
|
||||||
sizeof (rootdir), (char *) &rootdir))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
sua_pos = (sizeof (rootdir) + rootdir.namelen
|
|
||||||
+ (rootdir.namelen % 2) - 1);
|
|
||||||
sua_size = rootdir.len - sua_pos;
|
|
||||||
|
|
||||||
sua = grub_malloc (sua_size);
|
|
||||||
if (! sua)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
|
||||||
<< GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
|
|
||||||
sua_size, sua))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = (struct grub_iso9660_susp_entry *) sua;
|
|
||||||
|
|
||||||
/* Test if the SUSP protocol is used on this filesystem. */
|
|
||||||
if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
|
|
||||||
{
|
|
||||||
/* The 2nd data byte stored how many bytes are skipped every time
|
|
||||||
to get to the SUA (System Usage Area). */
|
|
||||||
data->susp_skip = entry->data[2];
|
|
||||||
entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
|
|
||||||
|
|
||||||
/* Iterate over the entries in the SUA area to detect
|
|
||||||
extensions. */
|
|
||||||
if (grub_iso9660_susp_iterate (data,
|
|
||||||
(grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
|
||||||
<< GRUB_ISO9660_LOG2_BLKSZ),
|
|
||||||
sua_pos, sua_size, susp_iterate))
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -425,42 +502,125 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
static char *
|
static char *
|
||||||
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
int sua_off;
|
return node->have_symlink
|
||||||
int sua_size;
|
? grub_strdup (node->symlink
|
||||||
char *symlink = 0;
|
+ (node->have_dirents) * sizeof (node->dirents[0])
|
||||||
int addslash = 0;
|
- sizeof (node->dirents)) : grub_strdup ("");
|
||||||
|
}
|
||||||
|
|
||||||
auto void add_part (const char *part, int len);
|
static grub_off_t
|
||||||
auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
|
get_node_size (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
grub_off_t ret = 0;
|
||||||
|
grub_size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < node->have_dirents; i++)
|
||||||
|
ret += grub_le_to_cpu32 (node->dirents[i].size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
int NESTED_FUNC_ATTR
|
||||||
|
(*hook) (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node))
|
||||||
|
{
|
||||||
|
struct grub_iso9660_dir dirent;
|
||||||
|
grub_off_t offset = 0;
|
||||||
|
char *filename = 0;
|
||||||
|
int filename_alloc = 0;
|
||||||
|
enum grub_fshelp_filetype type;
|
||||||
|
grub_off_t len;
|
||||||
|
char *symlink = 0;
|
||||||
|
|
||||||
/* Extend the symlink. */
|
/* Extend the symlink. */
|
||||||
void add_part (const char *part, int len)
|
auto inline void __attribute__ ((always_inline)) add_part (const char *part,
|
||||||
{
|
int len2);
|
||||||
int size = grub_strlen (symlink);
|
|
||||||
|
|
||||||
symlink = grub_realloc (symlink, size + len + 1);
|
auto inline void __attribute__ ((always_inline)) add_part (const char *part,
|
||||||
|
int len2)
|
||||||
|
{
|
||||||
|
int size = symlink ? grub_strlen (symlink) : 0;
|
||||||
|
|
||||||
|
symlink = grub_realloc (symlink, size + len2 + 1);
|
||||||
if (! symlink)
|
if (! symlink)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
grub_strncat (symlink, part, len);
|
symlink[size] = 0;
|
||||||
|
grub_strncat (symlink, part, len2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in a symlink. */
|
auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
|
||||||
grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
|
|
||||||
|
grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
|
||||||
{
|
{
|
||||||
if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
|
/* The filename in the rock ridge entry. */
|
||||||
|
if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
|
||||||
|
{
|
||||||
|
/* The flags are stored at the data position 0, here the
|
||||||
|
filename type is stored. */
|
||||||
|
if (entry->data[0] & GRUB_ISO9660_RR_DOT)
|
||||||
|
filename = ".";
|
||||||
|
else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
|
||||||
|
filename = "..";
|
||||||
|
else if (entry->len >= 5)
|
||||||
|
{
|
||||||
|
grub_size_t size = 1, csize = 1;
|
||||||
|
char *old;
|
||||||
|
csize = size = entry->len - 5;
|
||||||
|
old = filename;
|
||||||
|
if (filename_alloc)
|
||||||
|
{
|
||||||
|
size += grub_strlen (filename);
|
||||||
|
filename = grub_realloc (filename, size + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename_alloc = 1;
|
||||||
|
filename = grub_zalloc (size + 1);
|
||||||
|
filename[0] = 0;
|
||||||
|
}
|
||||||
|
if (!filename)
|
||||||
|
{
|
||||||
|
filename = old;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
filename_alloc = 1;
|
||||||
|
grub_strncat (filename, (char *) &entry->data[1], csize);
|
||||||
|
filename[size] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* The mode information (st_mode). */
|
||||||
|
else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
|
||||||
|
{
|
||||||
|
/* At position 0 of the PX record the st_mode information is
|
||||||
|
stored (little-endian). */
|
||||||
|
grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
|
||||||
|
& GRUB_ISO9660_FSTYPE_MASK);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case GRUB_ISO9660_FSTYPE_DIR:
|
||||||
|
type = GRUB_FSHELP_DIR;
|
||||||
|
break;
|
||||||
|
case GRUB_ISO9660_FSTYPE_REG:
|
||||||
|
type = GRUB_FSHELP_REG;
|
||||||
|
break;
|
||||||
|
case GRUB_ISO9660_FSTYPE_SYMLINK:
|
||||||
|
type = GRUB_FSHELP_SYMLINK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = GRUB_FSHELP_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
|
||||||
{
|
{
|
||||||
unsigned int pos = 1;
|
unsigned int pos = 1;
|
||||||
|
|
||||||
/* The symlink is not stored as a POSIX symlink, translate it. */
|
/* The symlink is not stored as a POSIX symlink, translate it. */
|
||||||
while (pos < grub_le_to_cpu32 (entry->len))
|
while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len))
|
||||||
{
|
{
|
||||||
if (addslash)
|
|
||||||
{
|
|
||||||
add_part ("/", 1);
|
|
||||||
addslash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The current position is the `Component Flag'. */
|
/* The current position is the `Component Flag'. */
|
||||||
switch (entry->data[pos] & 30)
|
switch (entry->data[pos] & 30)
|
||||||
{
|
{
|
||||||
|
@ -469,10 +629,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
/* The data on pos + 2 is the actual data, pos + 1
|
/* The data on pos + 2 is the actual data, pos + 1
|
||||||
is the length. Both are part of the `Component
|
is the length. Both are part of the `Component
|
||||||
Record'. */
|
Record'. */
|
||||||
|
if (symlink && (entry->data[pos] & 1))
|
||||||
|
add_part ("/", 1);
|
||||||
add_part ((char *) &entry->data[pos + 2],
|
add_part ((char *) &entry->data[pos + 2],
|
||||||
entry->data[pos + 1]);
|
entry->data[pos + 1]);
|
||||||
if ((entry->data[pos] & 1))
|
|
||||||
addslash = 1;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -502,109 +662,13 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1
|
len = get_node_size (dir);
|
||||||
- (node->dirent.namelen % 2)
|
|
||||||
+ node->data->susp_skip);
|
|
||||||
sua_size = node->dirent.len - sua_off;
|
|
||||||
|
|
||||||
symlink = grub_malloc (1);
|
for (; offset < len; offset += dirent.len)
|
||||||
if (!symlink)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*symlink = '\0';
|
|
||||||
|
|
||||||
if (grub_iso9660_susp_iterate (node->data, node->dir_blk,
|
|
||||||
node->dir_off + sua_off,
|
|
||||||
sua_size, susp_iterate_sl))
|
|
||||||
{
|
{
|
||||||
grub_free (symlink);
|
symlink = 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return symlink;
|
if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
int NESTED_FUNC_ATTR
|
|
||||||
(*hook) (const char *filename,
|
|
||||||
enum grub_fshelp_filetype filetype,
|
|
||||||
grub_fshelp_node_t node))
|
|
||||||
{
|
|
||||||
struct grub_iso9660_dir dirent;
|
|
||||||
unsigned int offset = 0;
|
|
||||||
char *filename;
|
|
||||||
int filename_alloc = 0;
|
|
||||||
enum grub_fshelp_filetype type;
|
|
||||||
|
|
||||||
auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
|
|
||||||
|
|
||||||
grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
|
|
||||||
{
|
|
||||||
/* The filename in the rock ridge entry. */
|
|
||||||
if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
|
|
||||||
{
|
|
||||||
/* The flags are stored at the data position 0, here the
|
|
||||||
filename type is stored. */
|
|
||||||
if (entry->data[0] & GRUB_ISO9660_RR_DOT)
|
|
||||||
filename = ".";
|
|
||||||
else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
|
|
||||||
filename = "..";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int size = 1;
|
|
||||||
if (filename)
|
|
||||||
{
|
|
||||||
size += grub_strlen (filename);
|
|
||||||
grub_realloc (filename,
|
|
||||||
grub_strlen (filename)
|
|
||||||
+ entry->len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = entry->len - 5;
|
|
||||||
filename = grub_zalloc (size + 1);
|
|
||||||
}
|
|
||||||
filename_alloc = 1;
|
|
||||||
grub_strncpy (filename, (char *) &entry->data[1], size);
|
|
||||||
filename[size] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* The mode information (st_mode). */
|
|
||||||
else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
|
|
||||||
{
|
|
||||||
/* At position 0 of the PX record the st_mode information is
|
|
||||||
stored (little-endian). */
|
|
||||||
grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
|
|
||||||
& GRUB_ISO9660_FSTYPE_MASK);
|
|
||||||
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case GRUB_ISO9660_FSTYPE_DIR:
|
|
||||||
type = GRUB_FSHELP_DIR;
|
|
||||||
break;
|
|
||||||
case GRUB_ISO9660_FSTYPE_REG:
|
|
||||||
type = GRUB_FSHELP_REG;
|
|
||||||
break;
|
|
||||||
case GRUB_ISO9660_FSTYPE_SYMLINK:
|
|
||||||
type = GRUB_FSHELP_SYMLINK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = GRUB_FSHELP_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; offset < dir->size; offset += dirent.len)
|
|
||||||
{
|
|
||||||
if (grub_disk_read (dir->data->disk,
|
|
||||||
(dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
|
|
||||||
+ offset / GRUB_DISK_SECTOR_SIZE,
|
|
||||||
offset % GRUB_DISK_SECTOR_SIZE,
|
|
||||||
sizeof (dirent), (char *) &dirent))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* The end of the block, skip to the next one. */
|
/* The end of the block, skip to the next one. */
|
||||||
|
@ -629,39 +693,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
type = GRUB_FSHELP_UNKNOWN;
|
type = GRUB_FSHELP_UNKNOWN;
|
||||||
|
|
||||||
if (dir->data->rockridge
|
if (dir->data->rockridge
|
||||||
&& grub_iso9660_susp_iterate (dir->data,
|
&& grub_iso9660_susp_iterate (dir, sua_off, sua_size,
|
||||||
(dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
|
susp_iterate_dir))
|
||||||
+ (sua_off
|
|
||||||
/ GRUB_DISK_SECTOR_SIZE),
|
|
||||||
sua_off % GRUB_DISK_SECTOR_SIZE,
|
|
||||||
sua_size, susp_iterate_dir))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Read the name. */
|
/* Read the name. */
|
||||||
if (grub_disk_read (dir->data->disk,
|
if (read_node (dir, nameoffset, dirent.namelen, (char *) name))
|
||||||
(dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
|
|
||||||
+ nameoffset / GRUB_DISK_SECTOR_SIZE,
|
|
||||||
nameoffset % GRUB_DISK_SECTOR_SIZE,
|
|
||||||
dirent.namelen, (char *) name))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
node = grub_malloc (sizeof (struct grub_fshelp_node));
|
node = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||||
if (!node)
|
if (!node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
node->alloc_dirents = ARRAY_SIZE (node->dirents);
|
||||||
|
node->have_dirents = 1;
|
||||||
|
|
||||||
/* Setup a new node. */
|
/* Setup a new node. */
|
||||||
node->data = dir->data;
|
node->data = dir->data;
|
||||||
node->size = grub_le_to_cpu32 (dirent.size);
|
node->have_symlink = 0;
|
||||||
node->blk = grub_le_to_cpu32 (dirent.first_sector);
|
|
||||||
node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
|
|
||||||
+ offset / GRUB_DISK_SECTOR_SIZE);
|
|
||||||
node->dir_off = offset % GRUB_DISK_SECTOR_SIZE;
|
|
||||||
|
|
||||||
/* If the filetype was not stored using rockridge, use
|
/* If the filetype was not stored using rockridge, use
|
||||||
whatever is stored in the iso9660 filesystem. */
|
whatever is stored in the iso9660 filesystem. */
|
||||||
if (type == GRUB_FSHELP_UNKNOWN)
|
if (type == GRUB_FSHELP_UNKNOWN)
|
||||||
{
|
{
|
||||||
if ((dirent.flags & 3) == 2)
|
if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
|
||||||
type = GRUB_FSHELP_DIR;
|
type = GRUB_FSHELP_DIR;
|
||||||
else
|
else
|
||||||
type = GRUB_FSHELP_REG;
|
type = GRUB_FSHELP_REG;
|
||||||
|
@ -678,7 +733,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
/* . and .. */
|
/* . and .. */
|
||||||
if (dirent.namelen == 1 && (name[0] == 0 || name[0] == 1))
|
if (dirent.namelen == 1 && (name[0] == 0 || name[0] == 1))
|
||||||
continue;
|
{
|
||||||
|
grub_free (node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
filename = name;
|
filename = name;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +747,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
oldname = filename;
|
oldname = filename;
|
||||||
filename = grub_iso9660_convert_string
|
filename = grub_iso9660_convert_string
|
||||||
((grub_uint16_t *) oldname, dirent.namelen >> 1);
|
((grub_uint8_t *) oldname, dirent.namelen >> 1);
|
||||||
|
|
||||||
semicolon = grub_strrchr (filename, ';');
|
semicolon = grub_strrchr (filename, ';');
|
||||||
if (semicolon)
|
if (semicolon)
|
||||||
|
@ -701,7 +759,64 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
filename_alloc = 1;
|
filename_alloc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->dirent = dirent;
|
node->dirents[0] = dirent;
|
||||||
|
while (dirent.flags & FLAG_MORE_EXTENTS)
|
||||||
|
{
|
||||||
|
offset += dirent.len;
|
||||||
|
if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
|
||||||
|
{
|
||||||
|
if (filename_alloc)
|
||||||
|
grub_free (filename);
|
||||||
|
grub_free (node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (node->have_dirents >= node->alloc_dirents)
|
||||||
|
{
|
||||||
|
struct grub_fshelp_node *new_node;
|
||||||
|
node->alloc_dirents *= 2;
|
||||||
|
new_node = grub_realloc (node,
|
||||||
|
sizeof (struct grub_fshelp_node)
|
||||||
|
+ ((node->alloc_dirents
|
||||||
|
- ARRAY_SIZE (node->dirents))
|
||||||
|
* sizeof (node->dirents[0])));
|
||||||
|
if (!new_node)
|
||||||
|
{
|
||||||
|
if (filename_alloc)
|
||||||
|
grub_free (filename);
|
||||||
|
grub_free (node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
node = new_node;
|
||||||
|
}
|
||||||
|
node->dirents[node->have_dirents++] = dirent;
|
||||||
|
}
|
||||||
|
if (symlink)
|
||||||
|
{
|
||||||
|
if ((node->alloc_dirents - node->have_dirents)
|
||||||
|
* sizeof (node->dirents[0]) < grub_strlen (symlink) + 1)
|
||||||
|
{
|
||||||
|
struct grub_fshelp_node *new_node;
|
||||||
|
new_node = grub_realloc (node,
|
||||||
|
sizeof (struct grub_fshelp_node)
|
||||||
|
+ ((node->alloc_dirents
|
||||||
|
- ARRAY_SIZE (node->dirents))
|
||||||
|
* sizeof (node->dirents[0]))
|
||||||
|
+ grub_strlen (symlink) + 1);
|
||||||
|
if (!new_node)
|
||||||
|
{
|
||||||
|
if (filename_alloc)
|
||||||
|
grub_free (filename);
|
||||||
|
grub_free (node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
node = new_node;
|
||||||
|
}
|
||||||
|
node->have_symlink = 1;
|
||||||
|
grub_strcpy (node->symlink
|
||||||
|
+ node->have_dirents * sizeof (node->dirents[0])
|
||||||
|
- sizeof (node->dirents), symlink);
|
||||||
|
grub_free (symlink);
|
||||||
|
}
|
||||||
if (hook (filename, type, node))
|
if (hook (filename, type, node))
|
||||||
{
|
{
|
||||||
if (filename_alloc)
|
if (filename_alloc)
|
||||||
|
@ -738,7 +853,7 @@ grub_iso9660_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime);
|
info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime);
|
||||||
|
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
|
@ -751,8 +866,10 @@ grub_iso9660_dir (grub_device_t device, const char *path,
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
rootnode.data = data;
|
rootnode.data = data;
|
||||||
rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
|
rootnode.alloc_dirents = 0;
|
||||||
rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
|
rootnode.have_dirents = 1;
|
||||||
|
rootnode.have_symlink = 0;
|
||||||
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
/* Use the fshelp function to traverse the path. */
|
/* Use the fshelp function to traverse the path. */
|
||||||
if (grub_fshelp_find_file (path, &rootnode,
|
if (grub_fshelp_find_file (path, &rootnode,
|
||||||
|
@ -792,8 +909,10 @@ grub_iso9660_open (struct grub_file *file, const char *name)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
rootnode.data = data;
|
rootnode.data = data;
|
||||||
rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
|
rootnode.alloc_dirents = 0;
|
||||||
rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
|
rootnode.have_dirents = 1;
|
||||||
|
rootnode.have_symlink = 0;
|
||||||
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
/* Use the fshelp function to traverse the path. */
|
/* Use the fshelp function to traverse the path. */
|
||||||
if (grub_fshelp_find_file (name, &rootnode,
|
if (grub_fshelp_find_file (name, &rootnode,
|
||||||
|
@ -803,10 +922,9 @@ grub_iso9660_open (struct grub_file *file, const char *name)
|
||||||
GRUB_FSHELP_REG))
|
GRUB_FSHELP_REG))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->first_sector = foundnode->blk;
|
data->node = foundnode;
|
||||||
|
|
||||||
file->data = data;
|
file->data = data;
|
||||||
file->size = foundnode->size;
|
file->size = get_node_size (foundnode);
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -828,10 +946,7 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
|
||||||
/* XXX: The file is stored in as a single extent. */
|
/* XXX: The file is stored in as a single extent. */
|
||||||
data->disk->read_hook = file->read_hook;
|
data->disk->read_hook = file->read_hook;
|
||||||
grub_disk_read (data->disk,
|
read_node (data->node, file->offset, len, buf);
|
||||||
data->first_sector << GRUB_ISO9660_LOG2_BLKSZ,
|
|
||||||
file->offset,
|
|
||||||
len, buf);
|
|
||||||
data->disk->read_hook = NULL;
|
data->disk->read_hook = NULL;
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
|
@ -844,7 +959,10 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_iso9660_close (grub_file_t file)
|
grub_iso9660_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
struct grub_iso9660_data *data =
|
||||||
|
(struct grub_iso9660_data *) file->data;
|
||||||
|
grub_free (data->node);
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
@ -861,8 +979,7 @@ grub_iso9660_label (grub_device_t device, char **label)
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
if (data->joliet)
|
if (data->joliet)
|
||||||
*label = grub_iso9660_convert_string
|
*label = grub_iso9660_convert_string (data->voldesc.volname, 16);
|
||||||
((grub_uint16_t *) &data->voldesc.volname, 16);
|
|
||||||
else
|
else
|
||||||
*label = grub_strndup ((char *) data->voldesc.volname, 32);
|
*label = grub_strndup ((char *) data->voldesc.volname, 32);
|
||||||
if (*label)
|
if (*label)
|
||||||
|
|
|
@ -52,9 +52,9 @@ struct grub_jfs_sblock
|
||||||
grub_uint32_t blksz;
|
grub_uint32_t blksz;
|
||||||
grub_uint16_t log2_blksz;
|
grub_uint16_t log2_blksz;
|
||||||
|
|
||||||
grub_uint8_t unused[71];
|
grub_uint8_t unused[79];
|
||||||
grub_uint8_t volname[11];
|
grub_uint8_t volname[11];
|
||||||
grub_uint8_t unused2[32];
|
grub_uint8_t unused2[24];
|
||||||
grub_uint8_t uuid[16];
|
grub_uint8_t uuid[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ struct grub_jfs_inode
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
grub_uint8_t unused[32];
|
grub_uint8_t unused[32];
|
||||||
grub_uint8_t path[128];
|
grub_uint8_t path[256];
|
||||||
} symlink;
|
} symlink;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
@ -238,7 +238,10 @@ struct grub_jfs_diropen
|
||||||
struct grub_jfs_leaf_next_dirent *next_leaf;
|
struct grub_jfs_leaf_next_dirent *next_leaf;
|
||||||
|
|
||||||
/* The filename and inode of the last read dirent. */
|
/* The filename and inode of the last read dirent. */
|
||||||
char name[255];
|
/* On-disk name is at most 255 UTF-16 codepoints.
|
||||||
|
Every UTF-16 codepoint is at most 4 UTF-8 bytes.
|
||||||
|
*/
|
||||||
|
char name[256 * GRUB_MAX_UTF8_PER_UTF16 + 1];
|
||||||
grub_uint32_t ino;
|
grub_uint32_t ino;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
@ -253,11 +256,11 @@ static grub_int64_t
|
||||||
grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
|
grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
|
||||||
grub_uint64_t blk)
|
grub_uint64_t blk)
|
||||||
{
|
{
|
||||||
auto int getblk (struct grub_jfs_treehead *treehead,
|
auto grub_int64_t getblk (struct grub_jfs_treehead *treehead,
|
||||||
struct grub_jfs_tree_extent *extents);
|
struct grub_jfs_tree_extent *extents);
|
||||||
|
|
||||||
int getblk (struct grub_jfs_treehead *treehead,
|
grub_int64_t getblk (struct grub_jfs_treehead *treehead,
|
||||||
struct grub_jfs_tree_extent *extents)
|
struct grub_jfs_tree_extent *extents)
|
||||||
{
|
{
|
||||||
int found = -1;
|
int found = -1;
|
||||||
int i;
|
int i;
|
||||||
|
@ -269,7 +272,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
|
||||||
/* Read the leafnode. */
|
/* Read the leafnode. */
|
||||||
if (grub_le_to_cpu32 (extents[i].offset2) <= blk
|
if (grub_le_to_cpu32 (extents[i].offset2) <= blk
|
||||||
&& ((grub_le_to_cpu16 (extents[i].extent.length))
|
&& ((grub_le_to_cpu16 (extents[i].extent.length))
|
||||||
+ (extents[i].extent.length2 << 8)
|
+ (extents[i].extent.length2 << 16)
|
||||||
+ grub_le_to_cpu32 (extents[i].offset2)) > blk)
|
+ grub_le_to_cpu32 (extents[i].offset2)) > blk)
|
||||||
return (blk - grub_le_to_cpu32 (extents[i].offset2)
|
return (blk - grub_le_to_cpu32 (extents[i].offset2)
|
||||||
+ grub_le_to_cpu32 (extents[i].extent.blk2));
|
+ grub_le_to_cpu32 (extents[i].extent.blk2));
|
||||||
|
@ -288,7 +291,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
|
||||||
} tree;
|
} tree;
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
if (grub_disk_read (data->disk,
|
||||||
grub_le_to_cpu32 (extents[found].extent.blk2)
|
((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2))
|
||||||
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
|
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
|
||||||
- GRUB_DISK_SECTOR_BITS), 0,
|
- GRUB_DISK_SECTOR_BITS), 0,
|
||||||
sizeof (tree), (char *) &tree))
|
sizeof (tree), (char *) &tree))
|
||||||
|
@ -479,7 +482,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro)
|
||||||
struct grub_jfs_leaf_next_dirent *next_leaf;
|
struct grub_jfs_leaf_next_dirent *next_leaf;
|
||||||
int len;
|
int len;
|
||||||
int nextent;
|
int nextent;
|
||||||
grub_uint16_t filename[255];
|
grub_uint16_t filename[256];
|
||||||
|
|
||||||
auto void addstr (grub_uint16_t *uname, int ulen);
|
auto void addstr (grub_uint16_t *uname, int ulen);
|
||||||
|
|
||||||
|
@ -487,7 +490,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro)
|
||||||
void addstr (grub_uint16_t *name, int ulen)
|
void addstr (grub_uint16_t *name, int ulen)
|
||||||
{
|
{
|
||||||
while (ulen--)
|
while (ulen--)
|
||||||
filename[strpos++] = *(name++);
|
filename[strpos++] = grub_le_to_cpu16 (*(name++));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The last node, read in more. */
|
/* The last node, read in more. */
|
||||||
|
@ -558,10 +561,10 @@ static grub_ssize_t
|
||||||
grub_jfs_read_file (struct grub_jfs_data *data,
|
grub_jfs_read_file (struct grub_jfs_data *data,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
grub_uint64_t pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
grub_uint64_t i;
|
grub_off_t i;
|
||||||
grub_uint64_t blockcnt;
|
grub_off_t blockcnt;
|
||||||
|
|
||||||
blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
|
blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
|
||||||
>> grub_le_to_cpu16 (data->sblock.log2_blksz);
|
>> grub_le_to_cpu16 (data->sblock.log2_blksz);
|
||||||
|
@ -708,14 +711,14 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path,
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
|
grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
|
||||||
{
|
{
|
||||||
grub_uint64_t size = grub_le_to_cpu64 (data->currinode.size);
|
grub_size_t size = grub_le_to_cpu64 (data->currinode.size);
|
||||||
char symlink[size + 1];
|
char symlink[size + 1];
|
||||||
|
|
||||||
if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
|
if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
||||||
|
|
||||||
if (size <= 128)
|
if (size <= sizeof (data->currinode.symlink.path))
|
||||||
grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128);
|
grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size);
|
||||||
else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
|
else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -888,6 +891,8 @@ grub_jfs_label (grub_device_t device, char **label)
|
||||||
else
|
else
|
||||||
*label = 0;
|
*label = 0;
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ typedef grub_uint16_t grub_minix_ino_t;
|
||||||
#define grub_minix_le_to_cpu_ino grub_le_to_cpu16
|
#define grub_minix_le_to_cpu_ino grub_le_to_cpu16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
|
#define GRUB_MINIX_INODE_SIZE(data) (grub_le_to_cpu32 (data->inode.size))
|
||||||
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
||||||
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
|
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
|
||||||
(data->inode.dir_zones[blk]))
|
(data->inode.dir_zones[blk]))
|
||||||
|
@ -76,11 +76,11 @@ typedef grub_uint16_t grub_minix_ino_t;
|
||||||
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
||||||
+ grub_le_to_cpu16 (data->sblock.log2_zone_size))
|
+ grub_le_to_cpu16 (data->sblock.log2_zone_size))
|
||||||
#endif
|
#endif
|
||||||
#define GRUB_MINIX_ZONESZ (data->block_size \
|
#define GRUB_MINIX_ZONESZ (1 << (data->log_block_size \
|
||||||
<< grub_le_to_cpu16 (data->sblock.log2_zone_size))
|
+ grub_le_to_cpu16 (data->sblock.log2_zone_size)))
|
||||||
|
|
||||||
#ifdef MODE_MINIX3
|
#ifdef MODE_MINIX3
|
||||||
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * (data->block_size / GRUB_DISK_SECTOR_SIZE))
|
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << (data->log_block_size - GRUB_DISK_SECTOR_BITS))
|
||||||
#else
|
#else
|
||||||
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ)
|
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ)
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,16 +132,15 @@ struct grub_minix_inode
|
||||||
grub_uint32_t dir_zones[7];
|
grub_uint32_t dir_zones[7];
|
||||||
grub_uint32_t indir_zone;
|
grub_uint32_t indir_zone;
|
||||||
grub_uint32_t double_indir_zone;
|
grub_uint32_t double_indir_zone;
|
||||||
grub_uint32_t unused;
|
grub_uint32_t triple_indir_zone;
|
||||||
|
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
struct grub_minix_inode
|
struct grub_minix_inode
|
||||||
{
|
{
|
||||||
grub_uint16_t mode;
|
grub_uint16_t mode;
|
||||||
grub_uint16_t uid;
|
grub_uint16_t uid;
|
||||||
grub_uint16_t size;
|
grub_uint32_t size;
|
||||||
grub_uint32_t ctime;
|
grub_uint32_t mtime;
|
||||||
grub_uint8_t gid;
|
grub_uint8_t gid;
|
||||||
grub_uint8_t nlinks;
|
grub_uint8_t nlinks;
|
||||||
grub_uint16_t dir_zones[7];
|
grub_uint16_t dir_zones[7];
|
||||||
|
@ -160,7 +159,7 @@ struct grub_minix_data
|
||||||
int linknest;
|
int linknest;
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
int filename_size;
|
int filename_size;
|
||||||
grub_size_t block_size;
|
grub_size_t log_block_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
@ -168,15 +167,19 @@ static grub_dl_t my_mod;
|
||||||
static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
|
static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
static int
|
static grub_minix_uintn_t
|
||||||
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
||||||
{
|
{
|
||||||
int indir;
|
grub_minix_uintn_t indir;
|
||||||
|
const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ
|
||||||
|
/ GRUB_MINIX_INODE_BLKSZ (data));
|
||||||
|
|
||||||
auto int grub_get_indir (int, int);
|
auto grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t,
|
||||||
|
grub_minix_uintn_t);
|
||||||
|
|
||||||
/* Read the block pointer in ZONE, on the offset NUM. */
|
/* Read the block pointer in ZONE, on the offset NUM. */
|
||||||
int grub_get_indir (int zone, int num)
|
grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t zone,
|
||||||
|
grub_minix_uintn_t num)
|
||||||
{
|
{
|
||||||
grub_minix_uintn_t indirn;
|
grub_minix_uintn_t indirn;
|
||||||
grub_disk_read (data->disk,
|
grub_disk_read (data->disk,
|
||||||
|
@ -192,25 +195,38 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
||||||
|
|
||||||
/* Indirect block. */
|
/* Indirect block. */
|
||||||
blk -= GRUB_MINIX_INODE_DIR_BLOCKS;
|
blk -= GRUB_MINIX_INODE_DIR_BLOCKS;
|
||||||
if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
|
if (blk < block_per_zone)
|
||||||
{
|
{
|
||||||
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
|
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
|
||||||
return indir;
|
return indir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Double indirect block. */
|
/* Double indirect block. */
|
||||||
blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
|
blk -= block_per_zone;
|
||||||
if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
|
if (blk < block_per_zone * block_per_zone)
|
||||||
* (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
|
|
||||||
{
|
{
|
||||||
indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
|
indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
|
||||||
blk / GRUB_MINIX_ZONESZ);
|
blk / block_per_zone);
|
||||||
|
|
||||||
indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
|
indir = grub_get_indir (indir, blk % block_per_zone);
|
||||||
|
|
||||||
return indir;
|
return indir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (MODE_MINIX3) || defined (MODE_MINIX2)
|
||||||
|
blk -= block_per_zone * block_per_zone;
|
||||||
|
if (blk < ((grub_uint64_t) block_per_zone * (grub_uint64_t) block_per_zone
|
||||||
|
* (grub_uint64_t) block_per_zone))
|
||||||
|
{
|
||||||
|
indir = grub_get_indir (grub_minix_le_to_cpu_n (data->inode.triple_indir_zone),
|
||||||
|
(blk / block_per_zone) / block_per_zone);
|
||||||
|
indir = grub_get_indir (indir, (blk / block_per_zone) % block_per_zone);
|
||||||
|
indir = grub_get_indir (indir, blk % block_per_zone);
|
||||||
|
|
||||||
|
return indir;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This should never happen. */
|
/* This should never happen. */
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
|
grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
|
||||||
|
|
||||||
|
@ -235,14 +251,15 @@ grub_minix_read_file (struct grub_minix_data *data,
|
||||||
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
|
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
|
||||||
len = GRUB_MINIX_INODE_SIZE (data) - pos;
|
len = GRUB_MINIX_INODE_SIZE (data) - pos;
|
||||||
|
|
||||||
blockcnt = grub_divmod64 ((len + pos + data->block_size - 1),
|
blockcnt = ((len + pos + (1 << data->log_block_size) - 1)
|
||||||
data->block_size, 0);
|
>> data->log_block_size);
|
||||||
posblock = grub_divmod64 (pos, data->block_size, &blockoff);
|
posblock = pos >> data->log_block_size;
|
||||||
|
blockoff = pos & ((1 << data->log_block_size) - 1);
|
||||||
|
|
||||||
for (i = posblock; i < blockcnt; i++)
|
for (i = posblock; i < blockcnt; i++)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t blknr;
|
grub_disk_addr_t blknr;
|
||||||
grub_uint64_t blockend = data->block_size;
|
grub_uint64_t blockend = 1 << data->log_block_size;
|
||||||
grub_off_t skipfirst = 0;
|
grub_off_t skipfirst = 0;
|
||||||
|
|
||||||
blknr = grub_minix_get_file_block (data, i);
|
blknr = grub_minix_get_file_block (data, i);
|
||||||
|
@ -252,10 +269,10 @@ grub_minix_read_file (struct grub_minix_data *data,
|
||||||
/* Last block. */
|
/* Last block. */
|
||||||
if (i == blockcnt - 1)
|
if (i == blockcnt - 1)
|
||||||
{
|
{
|
||||||
grub_divmod64 (len + pos, data->block_size, &blockend);
|
blockend = (len + pos) & ((1 << data->log_block_size) - 1);
|
||||||
|
|
||||||
if (!blockend)
|
if (!blockend)
|
||||||
blockend = data->block_size;
|
blockend = 1 << data->log_block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First block. */
|
/* First block. */
|
||||||
|
@ -273,7 +290,7 @@ grub_minix_read_file (struct grub_minix_data *data,
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buf += data->block_size - skipfirst;
|
buf += (1 << data->log_block_size) - skipfirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -463,9 +480,14 @@ grub_minix_mount (grub_disk_t disk)
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
data->linknest = 0;
|
data->linknest = 0;
|
||||||
#ifdef MODE_MINIX3
|
#ifdef MODE_MINIX3
|
||||||
data->block_size = grub_le_to_cpu16 (data->sblock.block_size);
|
if ((grub_le_to_cpu16 (data->sblock.block_size)
|
||||||
|
& (grub_le_to_cpu16 (data->sblock.block_size) - 1))
|
||||||
|
|| grub_le_to_cpu16 (data->sblock.block_size) == 0)
|
||||||
|
goto fail;
|
||||||
|
for (data->log_block_size = 0; (1 << data->log_block_size)
|
||||||
|
< grub_le_to_cpu16 (data->sblock.block_size); data->log_block_size++);
|
||||||
#else
|
#else
|
||||||
data->block_size = 1024U;
|
data->log_block_size = 10;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -536,11 +558,7 @@ grub_minix_dir (grub_device_t device, const char *path,
|
||||||
info.dir = ((GRUB_MINIX_INODE_MODE (data)
|
info.dir = ((GRUB_MINIX_INODE_MODE (data)
|
||||||
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
|
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
#ifndef MODE_MINIX2
|
|
||||||
info.mtime = grub_le_to_cpu32 (data->inode.ctime);
|
|
||||||
#else
|
|
||||||
info.mtime = grub_le_to_cpu32 (data->inode.mtime);
|
info.mtime = grub_le_to_cpu32 (data->inode.mtime);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hook (filename, &info) ? 1 : 0)
|
if (hook (filename, &info) ? 1 : 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -58,6 +58,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
in 512 block size */
|
in 512 block size */
|
||||||
#define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3)
|
#define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3)
|
||||||
|
|
||||||
|
#define LOG_INODE_SIZE 7
|
||||||
struct grub_nilfs2_inode
|
struct grub_nilfs2_inode
|
||||||
{
|
{
|
||||||
grub_uint64_t i_blocks;
|
grub_uint64_t i_blocks;
|
||||||
|
@ -207,6 +208,7 @@ struct grub_nilfs2_btree_node
|
||||||
grub_uint8_t bn_level;
|
grub_uint8_t bn_level;
|
||||||
grub_uint16_t bn_nchildren;
|
grub_uint16_t bn_nchildren;
|
||||||
grub_uint32_t bn_pad;
|
grub_uint32_t bn_pad;
|
||||||
|
grub_uint64_t keys[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_nilfs2_palloc_group_desc
|
struct grub_nilfs2_palloc_group_desc
|
||||||
|
@ -214,6 +216,7 @@ struct grub_nilfs2_palloc_group_desc
|
||||||
grub_uint32_t pg_nfrees;
|
grub_uint32_t pg_nfrees;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LOG_NILFS_DAT_ENTRY_SIZE 5
|
||||||
struct grub_nilfs2_dat_entry
|
struct grub_nilfs2_dat_entry
|
||||||
{
|
{
|
||||||
grub_uint64_t de_blocknr;
|
grub_uint64_t de_blocknr;
|
||||||
|
@ -296,17 +299,17 @@ static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
|
||||||
static inline unsigned long
|
static inline unsigned long
|
||||||
grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data)
|
grub_nilfs2_log_palloc_entries_per_group (struct grub_nilfs2_data *data)
|
||||||
{
|
{
|
||||||
return 1UL << (LOG2_BLOCK_SIZE (data) + 3);
|
return LOG2_BLOCK_SIZE (data) + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
|
grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t nr, grub_uint64_t * offset)
|
grub_uint64_t nr, grub_uint64_t * offset)
|
||||||
{
|
{
|
||||||
return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data),
|
*offset = nr & ((1 << grub_nilfs2_log_palloc_entries_per_group (data)) - 1);
|
||||||
offset);
|
return nr >> grub_nilfs2_log_palloc_entries_per_group (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
|
@ -317,55 +320,58 @@ grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data,
|
grub_nilfs2_log_entries_per_block_log (struct grub_nilfs2_data *data,
|
||||||
unsigned long entry_size)
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
return NILFS2_BLOCK_SIZE (data) / entry_size;
|
return LOG2_BLOCK_SIZE (data) - log_entry_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data,
|
grub_nilfs2_blocks_per_group_log (struct grub_nilfs2_data *data,
|
||||||
unsigned long entry_size)
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data),
|
return (1 << (grub_nilfs2_log_palloc_entries_per_group (data)
|
||||||
grub_nilfs2_entries_per_block (data,
|
- grub_nilfs2_log_entries_per_block_log (data,
|
||||||
entry_size)) + 1;
|
log_entry_size))) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data,
|
grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data,
|
||||||
unsigned long entry_size)
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
return grub_nilfs2_palloc_groups_per_desc_block (data) *
|
return grub_nilfs2_palloc_groups_per_desc_block (data) *
|
||||||
grub_nilfs2_blocks_per_group (data, entry_size) + 1;
|
grub_nilfs2_blocks_per_group_log (data, log_entry_size) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data,
|
grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data,
|
||||||
unsigned long group,
|
unsigned long group,
|
||||||
unsigned long entry_size)
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
grub_uint32_t desc_block =
|
grub_uint32_t desc_block =
|
||||||
group / grub_nilfs2_palloc_groups_per_desc_block (data);
|
group / grub_nilfs2_palloc_groups_per_desc_block (data);
|
||||||
return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size);
|
return desc_block * grub_nilfs2_blocks_per_desc_block_log (data,
|
||||||
|
log_entry_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data,
|
grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data,
|
||||||
unsigned long group,
|
unsigned long group,
|
||||||
unsigned long entry_size)
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
unsigned long desc_offset = group %
|
unsigned long desc_offset = group %
|
||||||
grub_nilfs2_palloc_groups_per_desc_block (data);
|
grub_nilfs2_palloc_groups_per_desc_block (data);
|
||||||
|
|
||||||
return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 +
|
return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size)
|
||||||
desc_offset * grub_nilfs2_blocks_per_group (data, entry_size);
|
+ 1
|
||||||
|
+ desc_offset * grub_nilfs2_blocks_per_group_log (data, log_entry_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data,
|
grub_nilfs2_palloc_entry_offset_log (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t nr, unsigned long entry_size)
|
grub_uint64_t nr,
|
||||||
|
unsigned long log_entry_size)
|
||||||
{
|
{
|
||||||
unsigned long group;
|
unsigned long group;
|
||||||
grub_uint64_t group_offset;
|
grub_uint64_t group_offset;
|
||||||
|
@ -373,10 +379,9 @@ grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data,
|
||||||
group = grub_nilfs2_palloc_group (data, nr, &group_offset);
|
group = grub_nilfs2_palloc_group (data, nr, &group_offset);
|
||||||
|
|
||||||
return grub_nilfs2_palloc_bitmap_block_offset (data, group,
|
return grub_nilfs2_palloc_bitmap_block_offset (data, group,
|
||||||
entry_size) + 1 +
|
1 << log_entry_size) + 1 +
|
||||||
grub_divmod64 (group_offset, grub_nilfs2_entries_per_block (data,
|
(group_offset >> grub_nilfs2_log_entries_per_block_log (data,
|
||||||
entry_size),
|
log_entry_size));
|
||||||
NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,9 +400,9 @@ grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node)
|
||||||
static inline grub_uint64_t *
|
static inline grub_uint64_t *
|
||||||
grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node)
|
grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node)
|
||||||
{
|
{
|
||||||
return (grub_uint64_t *) ((char *) (node + 1) +
|
return (node->keys +
|
||||||
((node->bn_flags & NILFS_BTREE_NODE_ROOT) ?
|
((node->bn_flags & NILFS_BTREE_NODE_ROOT) ?
|
||||||
0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
|
0 : (NILFS_BTREE_NODE_EXTRA_PAD_SIZE / sizeof (grub_uint64_t))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
|
@ -498,7 +503,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t key, int need_translate)
|
grub_uint64_t key, int need_translate)
|
||||||
{
|
{
|
||||||
struct grub_nilfs2_btree_node *node;
|
struct grub_nilfs2_btree_node *node;
|
||||||
unsigned char block[NILFS2_BLOCK_SIZE (data)];
|
GRUB_PROPERLY_ALIGNED_ARRAY (block, NILFS2_BLOCK_SIZE (data));
|
||||||
grub_uint64_t ptr;
|
grub_uint64_t ptr;
|
||||||
int level, found, index;
|
int level, found, index;
|
||||||
|
|
||||||
|
@ -582,12 +587,11 @@ grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key)
|
||||||
grub_uint64_t blockno, offset;
|
grub_uint64_t blockno, offset;
|
||||||
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
|
||||||
blockno = grub_nilfs2_palloc_entry_offset (data, key,
|
blockno = grub_nilfs2_palloc_entry_offset_log (data, key,
|
||||||
sizeof (struct
|
LOG_NILFS_DAT_ENTRY_SIZE);
|
||||||
grub_nilfs2_dat_entry));
|
|
||||||
|
|
||||||
grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry),
|
offset = ((key * sizeof (struct grub_nilfs2_dat_entry))
|
||||||
NILFS2_BLOCK_SIZE (data), &offset);
|
& ((1 << LOG2_BLOCK_SIZE (data)) - 1));
|
||||||
|
|
||||||
pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0);
|
pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0);
|
||||||
if (pptr == (grub_uint64_t) - 1)
|
if (pptr == (grub_uint64_t) - 1)
|
||||||
|
@ -628,7 +632,7 @@ grub_nilfs2_read_file (grub_fshelp_node_t node,
|
||||||
sector,
|
sector,
|
||||||
unsigned offset,
|
unsigned offset,
|
||||||
unsigned length),
|
unsigned length),
|
||||||
int pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
||||||
pos, len, buf, grub_nilfs2_read_block,
|
pos, len, buf, grub_nilfs2_read_block,
|
||||||
|
@ -652,8 +656,8 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data,
|
||||||
sizeof(struct grub_nilfs2_checkpoint).
|
sizeof(struct grub_nilfs2_checkpoint).
|
||||||
*/
|
*/
|
||||||
blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) /
|
blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) /
|
||||||
sizeof (struct grub_nilfs2_checkpoint), &offset);
|
sizeof (struct grub_nilfs2_checkpoint), &offset);
|
||||||
|
|
||||||
pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1);
|
pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1);
|
||||||
if (pptr == (grub_uint64_t) - 1)
|
if (pptr == (grub_uint64_t) - 1)
|
||||||
{
|
{
|
||||||
|
@ -686,12 +690,11 @@ grub_nilfs2_read_inode (struct grub_nilfs2_data *data,
|
||||||
grub_disk_t disk = data->disk;
|
grub_disk_t disk = data->disk;
|
||||||
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
|
||||||
blockno = grub_nilfs2_palloc_entry_offset (data, ino,
|
blockno = grub_nilfs2_palloc_entry_offset_log (data, ino,
|
||||||
sizeof (struct
|
LOG_INODE_SIZE);
|
||||||
grub_nilfs2_inode));
|
|
||||||
|
|
||||||
grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino,
|
offset = ((sizeof (struct grub_nilfs2_inode) * ino)
|
||||||
NILFS2_BLOCK_SIZE (data), &offset);
|
& ((1 << LOG2_BLOCK_SIZE (data)) - 1));
|
||||||
pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1);
|
pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1);
|
||||||
if (pptr == (grub_uint64_t) - 1)
|
if (pptr == (grub_uint64_t) - 1)
|
||||||
{
|
{
|
||||||
|
@ -866,7 +869,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
|
||||||
enum grub_fshelp_filetype filetype,
|
enum grub_fshelp_filetype filetype,
|
||||||
grub_fshelp_node_t node))
|
grub_fshelp_node_t node))
|
||||||
{
|
{
|
||||||
unsigned int fpos = 0;
|
grub_off_t fpos = 0;
|
||||||
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
|
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
|
||||||
|
|
||||||
if (!diro->inode_read)
|
if (!diro->inode_read)
|
||||||
|
@ -1117,7 +1120,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid)
|
||||||
{
|
{
|
||||||
*uuid =
|
*uuid =
|
||||||
grub_xasprintf
|
grub_xasprintf
|
||||||
("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x",
|
("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
data->sblock.s_uuid[0], data->sblock.s_uuid[1],
|
data->sblock.s_uuid[0], data->sblock.s_uuid[1],
|
||||||
data->sblock.s_uuid[2], data->sblock.s_uuid[3],
|
data->sblock.s_uuid[2], data->sblock.s_uuid[3],
|
||||||
data->sblock.s_uuid[4], data->sblock.s_uuid[5],
|
data->sblock.s_uuid[4], data->sblock.s_uuid[5],
|
||||||
|
@ -1150,7 +1153,7 @@ grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm)
|
||||||
if (!data)
|
if (!data)
|
||||||
*tm = 0;
|
*tm = 0;
|
||||||
else
|
else
|
||||||
*tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime);
|
*tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_wtime);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
@ -1178,6 +1181,11 @@ static struct grub_fs grub_nilfs2_fs = {
|
||||||
|
|
||||||
GRUB_MOD_INIT (nilfs2)
|
GRUB_MOD_INIT (nilfs2)
|
||||||
{
|
{
|
||||||
|
COMPILE_TIME_ASSERT ((1 << LOG_NILFS_DAT_ENTRY_SIZE)
|
||||||
|
== sizeof (struct
|
||||||
|
grub_nilfs2_dat_entry));
|
||||||
|
COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
|
||||||
|
== sizeof (struct grub_nilfs2_inode));
|
||||||
grub_fs_register (&grub_nilfs2_fs);
|
grub_fs_register (&grub_nilfs2_fs);
|
||||||
my_mod = mod;
|
my_mod = mod;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define grub_fshelp_node grub_ntfs_file
|
||||||
|
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
@ -30,10 +32,30 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
ntfscomp_func_t grub_ntfscomp_func;
|
#define grub_fshelp_node grub_ntfs_file
|
||||||
|
|
||||||
|
static inline grub_uint16_t
|
||||||
|
u16at (void *ptr, grub_size_t ofs)
|
||||||
|
{
|
||||||
|
return grub_le_to_cpu16 (grub_get_unaligned16 ((char *) ptr + ofs));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline grub_uint32_t
|
||||||
|
u32at (void *ptr, grub_size_t ofs)
|
||||||
|
{
|
||||||
|
return grub_le_to_cpu32 (grub_get_unaligned32 ((char *) ptr + ofs));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline grub_uint64_t
|
||||||
|
u64at (void *ptr, grub_size_t ofs)
|
||||||
|
{
|
||||||
|
return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs));
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_ntfscomp_func_t grub_ntfscomp_func;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
|
fixup (struct grub_ntfs_data *data, char *buf, int len, const char *magic)
|
||||||
{
|
{
|
||||||
int ss;
|
int ss;
|
||||||
char *pu;
|
char *pu;
|
||||||
|
@ -56,7 +78,8 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
|
||||||
pu += 2;
|
pu += 2;
|
||||||
if (u16at (buf, 0) != us)
|
if (u16at (buf, 0) != us)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
|
return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
|
||||||
v16at (buf, 0) = v16at (pu, 0);
|
buf[0] = pu[0];
|
||||||
|
buf[1] = pu[1];
|
||||||
ss--;
|
ss--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +110,7 @@ static void
|
||||||
init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
|
init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
|
||||||
{
|
{
|
||||||
at->mft = mft;
|
at->mft = mft;
|
||||||
at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0;
|
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
|
||||||
at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
|
at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
|
||||||
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
|
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +126,7 @@ free_attr (struct grub_ntfs_attr *at)
|
||||||
static char *
|
static char *
|
||||||
find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
{
|
{
|
||||||
if (at->flags & AF_ALST)
|
if (at->flags & GRUB_NTFS_AF_ALST)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
while (at->attr_nxt < at->attr_end)
|
while (at->attr_nxt < at->attr_end)
|
||||||
|
@ -114,14 +137,14 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
{
|
{
|
||||||
char *new_pos;
|
char *new_pos;
|
||||||
|
|
||||||
if (at->flags & AF_MMFT)
|
if (at->flags & GRUB_NTFS_AF_MMFT)
|
||||||
{
|
{
|
||||||
if ((grub_disk_read
|
if ((grub_disk_read
|
||||||
(at->mft->data->disk, v32at (at->attr_cur, 0x10), 0,
|
(at->mft->data->disk, u32at (at->attr_cur, 0x10), 0,
|
||||||
512, at->emft_buf))
|
512, at->emft_buf))
|
||||||
||
|
||
|
||||||
(grub_disk_read
|
(grub_disk_read
|
||||||
(at->mft->data->disk, v32at (at->attr_cur, 0x14), 0,
|
(at->mft->data->disk, u32at (at->attr_cur, 0x14), 0,
|
||||||
512, at->emft_buf + 512)))
|
512, at->emft_buf + 512)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -160,7 +183,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
while ((unsigned char) *at->attr_cur != 0xFF)
|
while ((unsigned char) *at->attr_cur != 0xFF)
|
||||||
{
|
{
|
||||||
at->attr_nxt += u16at (at->attr_cur, 4);
|
at->attr_nxt += u16at (at->attr_cur, 4);
|
||||||
if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST)
|
if ((unsigned char) *at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
|
||||||
at->attr_end = at->attr_cur;
|
at->attr_end = at->attr_cur;
|
||||||
if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
|
if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
|
||||||
return at->attr_cur;
|
return at->attr_cur;
|
||||||
|
@ -170,7 +193,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
{
|
{
|
||||||
char *pa;
|
char *pa;
|
||||||
|
|
||||||
at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR);
|
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||||
if (at->emft_buf == NULL)
|
if (at->emft_buf == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -199,7 +222,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
||||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
at->attr_end = at->attr_end + u32at (pa, 4);
|
||||||
}
|
}
|
||||||
at->flags |= AF_ALST;
|
at->flags |= GRUB_NTFS_AF_ALST;
|
||||||
while (at->attr_nxt < at->attr_end)
|
while (at->attr_nxt < at->attr_end)
|
||||||
{
|
{
|
||||||
if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
|
if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
|
||||||
|
@ -209,13 +232,16 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
if (at->attr_nxt >= at->attr_end)
|
if (at->attr_nxt >= at->attr_end)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((at->flags & AF_MMFT) && (attr == AT_DATA))
|
if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA))
|
||||||
{
|
{
|
||||||
at->flags |= AF_GPOS;
|
at->flags |= GRUB_NTFS_AF_GPOS;
|
||||||
at->attr_cur = at->attr_nxt;
|
at->attr_cur = at->attr_nxt;
|
||||||
pa = at->attr_cur;
|
pa = at->attr_cur;
|
||||||
v32at (pa, 0x10) = at->mft->data->mft_start;
|
grub_set_unaligned32 ((char *) pa + 0x10,
|
||||||
v32at (pa, 0x14) = at->mft->data->mft_start + 1;
|
grub_cpu_to_le32 (at->mft->data->mft_start));
|
||||||
|
grub_set_unaligned32 ((char *) pa + 0x14,
|
||||||
|
grub_cpu_to_le32 (at->mft->data->mft_start
|
||||||
|
+ 1));
|
||||||
pa = at->attr_nxt + u16at (pa, 4);
|
pa = at->attr_nxt + u16at (pa, 4);
|
||||||
while (pa < at->attr_end)
|
while (pa < at->attr_end)
|
||||||
{
|
{
|
||||||
|
@ -223,13 +249,13 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
|
||||||
break;
|
break;
|
||||||
if (read_attr
|
if (read_attr
|
||||||
(at, pa + 0x10,
|
(at, pa + 0x10,
|
||||||
u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR),
|
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||||
at->mft->data->mft_size << BLK_SHR, 0, 0))
|
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
pa += u16at (pa, 4);
|
pa += u16at (pa, 4);
|
||||||
}
|
}
|
||||||
at->attr_nxt = at->attr_cur;
|
at->attr_nxt = at->attr_cur;
|
||||||
at->flags &= ~AF_GPOS;
|
at->flags &= ~GRUB_NTFS_AF_GPOS;
|
||||||
}
|
}
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
@ -245,13 +271,13 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
|
||||||
init_attr (at, mft);
|
init_attr (at, mft);
|
||||||
if ((pa = find_attr (at, attr)) == NULL)
|
if ((pa = find_attr (at, attr)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((at->flags & AF_ALST) == 0)
|
if ((at->flags & GRUB_NTFS_AF_ALST) == 0)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if ((pa = find_attr (at, attr)) == NULL)
|
if ((pa = find_attr (at, attr)) == NULL)
|
||||||
break;
|
break;
|
||||||
if (at->flags & AF_ALST)
|
if (at->flags & GRUB_NTFS_AF_ALST)
|
||||||
return pa;
|
return pa;
|
||||||
}
|
}
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -296,7 +322,7 @@ retry:
|
||||||
c2 = ((unsigned char) (*run) >> 4);
|
c2 = ((unsigned char) (*run) >> 4);
|
||||||
if (!c1)
|
if (!c1)
|
||||||
{
|
{
|
||||||
if ((ctx->attr) && (ctx->attr->flags & AF_ALST))
|
if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST))
|
||||||
{
|
{
|
||||||
void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset,
|
unsigned offset,
|
||||||
|
@ -325,9 +351,9 @@ retry:
|
||||||
run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */
|
run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */
|
||||||
ctx->curr_lcn += val;
|
ctx->curr_lcn += val;
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
ctx->flags |= RF_BLNK;
|
ctx->flags |= GRUB_NTFS_RF_BLNK;
|
||||||
else
|
else
|
||||||
ctx->flags &= ~RF_BLNK;
|
ctx->flags &= ~GRUB_NTFS_RF_BLNK;
|
||||||
ctx->cur_run = run;
|
ctx->cur_run = run;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +371,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
|
||||||
return ctx->curr_lcn;
|
return ctx->curr_lcn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (ctx->flags & RF_BLNK) ? 0 : (block -
|
return (ctx->flags & GRUB_NTFS_RF_BLNK) ? 0 : (block -
|
||||||
ctx->curr_vcn + ctx->curr_lcn);
|
ctx->curr_vcn + ctx->curr_lcn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,24 +402,24 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u16at (pa, 0xC) & FLAG_COMPRESSED)
|
if (u16at (pa, 0xC) & GRUB_NTFS_FLAG_COMPRESSED)
|
||||||
ctx->flags |= RF_COMP;
|
ctx->flags |= GRUB_NTFS_RF_COMP;
|
||||||
else
|
else
|
||||||
ctx->flags &= ~RF_COMP;
|
ctx->flags &= ~GRUB_NTFS_RF_COMP;
|
||||||
ctx->cur_run = pa + u16at (pa, 0x20);
|
ctx->cur_run = pa + u16at (pa, 0x20);
|
||||||
|
|
||||||
if (ctx->flags & RF_COMP)
|
if (ctx->flags & GRUB_NTFS_RF_COMP)
|
||||||
{
|
{
|
||||||
if (!cached)
|
if (!cached)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
|
return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
|
||||||
|
|
||||||
if (at->sbuf)
|
if (at->sbuf)
|
||||||
{
|
{
|
||||||
if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
|
if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == at->save_pos)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t n;
|
grub_disk_addr_t n;
|
||||||
|
|
||||||
n = COM_LEN - (ofs - at->save_pos);
|
n = GRUB_NTFS_COM_LEN - (ofs - at->save_pos);
|
||||||
if (n > len)
|
if (n > len)
|
||||||
n = len;
|
n = len;
|
||||||
|
|
||||||
|
@ -408,17 +434,17 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
at->sbuf = grub_malloc (COM_LEN);
|
at->sbuf = grub_malloc (GRUB_NTFS_COM_LEN);
|
||||||
if (at->sbuf == NULL)
|
if (at->sbuf == NULL)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
at->save_pos = 1;
|
at->save_pos = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
|
vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC / ctx->comp.spc);
|
||||||
ctx->target_vcn &= ~0xF;
|
ctx->target_vcn &= ~0xF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0);
|
vcn = ctx->target_vcn = grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, 0);
|
||||||
|
|
||||||
ctx->next_vcn = u32at (pa, 0x10);
|
ctx->next_vcn = u32at (pa, 0x10);
|
||||||
ctx->curr_lcn = 0;
|
ctx->curr_lcn = 0;
|
||||||
|
@ -428,12 +454,12 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at->flags & AF_GPOS)
|
if (at->flags & GRUB_NTFS_AF_GPOS)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t st0, st1;
|
grub_disk_addr_t st0, st1;
|
||||||
grub_uint64_t m;
|
grub_uint64_t m;
|
||||||
|
|
||||||
grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
|
grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, &m);
|
||||||
|
|
||||||
st0 =
|
st0 =
|
||||||
(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
|
(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
|
||||||
|
@ -445,12 +471,12 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
st1 = ctx->curr_lcn * ctx->comp.spc;
|
st1 = ctx->curr_lcn * ctx->comp.spc;
|
||||||
}
|
}
|
||||||
v32at (dest, 0) = st0;
|
grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0));
|
||||||
v32at (dest, 4) = st1;
|
grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ctx->flags & RF_COMP))
|
if (!(ctx->flags & GRUB_NTFS_RF_COMP))
|
||||||
{
|
{
|
||||||
unsigned int pow;
|
unsigned int pow;
|
||||||
|
|
||||||
|
@ -481,12 +507,12 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
|
||||||
save_cur = at->attr_cur;
|
save_cur = at->attr_cur;
|
||||||
at->attr_nxt = at->attr_cur;
|
at->attr_nxt = at->attr_cur;
|
||||||
attr = (unsigned char) *at->attr_nxt;
|
attr = (unsigned char) *at->attr_nxt;
|
||||||
if (at->flags & AF_ALST)
|
if (at->flags & GRUB_NTFS_AF_ALST)
|
||||||
{
|
{
|
||||||
char *pa;
|
char *pa;
|
||||||
grub_disk_addr_t vcn;
|
grub_disk_addr_t vcn;
|
||||||
|
|
||||||
vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
|
vcn = grub_divmod64 (ofs, at->mft->data->spc << GRUB_NTFS_BLK_SHR, 0);
|
||||||
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
|
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
|
||||||
while (pa < at->attr_end)
|
while (pa < at->attr_end)
|
||||||
{
|
{
|
||||||
|
@ -513,8 +539,8 @@ static grub_err_t
|
||||||
read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
|
read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
|
||||||
{
|
{
|
||||||
if (read_attr
|
if (read_attr
|
||||||
(&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR),
|
(&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||||
data->mft_size << BLK_SHR, 0, 0))
|
data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0))
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
|
return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
|
||||||
return fixup (data, buf, data->mft_size, "FILE");
|
return fixup (data, buf, data->mft_size, "FILE");
|
||||||
}
|
}
|
||||||
|
@ -526,7 +552,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
|
||||||
|
|
||||||
mft->inode_read = 1;
|
mft->inode_read = 1;
|
||||||
|
|
||||||
mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
|
mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||||
if (mft->buf == NULL)
|
if (mft->buf == NULL)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -541,7 +567,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
|
||||||
{
|
{
|
||||||
char *pa;
|
char *pa;
|
||||||
|
|
||||||
pa = locate_attr (&mft->attr, mft, AT_DATA);
|
pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA);
|
||||||
if (pa == NULL)
|
if (pa == NULL)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
|
return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
|
||||||
|
|
||||||
|
@ -550,7 +576,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
|
||||||
else
|
else
|
||||||
mft->size = u64at (pa, 0x30);
|
mft->size = u64at (pa, 0x30);
|
||||||
|
|
||||||
if ((mft->attr.flags & AF_ALST) == 0)
|
if ((mft->attr.flags & GRUB_NTFS_AF_ALST) == 0)
|
||||||
mft->attr.attr_end = 0; /* Don't jump to attribute list */
|
mft->attr.attr_end = 0; /* Don't jump to attribute list */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -595,6 +621,7 @@ list_file (struct grub_ntfs_file *diro, char *pos,
|
||||||
{
|
{
|
||||||
enum grub_fshelp_filetype type;
|
enum grub_fshelp_filetype type;
|
||||||
struct grub_ntfs_file *fdiro;
|
struct grub_ntfs_file *fdiro;
|
||||||
|
grub_uint32_t attr;
|
||||||
|
|
||||||
if (u16at (pos, 4))
|
if (u16at (pos, 4))
|
||||||
{
|
{
|
||||||
|
@ -602,9 +629,13 @@ list_file (struct grub_ntfs_file *diro, char *pos,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
type =
|
attr = u32at (pos, 0x48);
|
||||||
(u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
|
if (attr & GRUB_NTFS_ATTR_REPARSE)
|
||||||
GRUB_FSHELP_REG;
|
type = GRUB_FSHELP_SYMLINK;
|
||||||
|
else if (attr & GRUB_NTFS_ATTR_DIRECTORY)
|
||||||
|
type = GRUB_FSHELP_DIR;
|
||||||
|
else
|
||||||
|
type = GRUB_FSHELP_REG;
|
||||||
|
|
||||||
fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
|
fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
|
||||||
if (!fdiro)
|
if (!fdiro)
|
||||||
|
@ -617,12 +648,18 @@ list_file (struct grub_ntfs_file *diro, char *pos,
|
||||||
else
|
else
|
||||||
fdiro->mtime = u64at (pos, 0x28);
|
fdiro->mtime = u64at (pos, 0x28);
|
||||||
|
|
||||||
ustr = grub_malloc (ns * 4 + 1);
|
ustr = grub_malloc (ns * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (ustr == NULL)
|
if (ustr == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np,
|
{
|
||||||
ns) = '\0';
|
grub_uint16_t tmp[ns];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 ((char *) np
|
||||||
|
+ 2 * i));
|
||||||
|
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) ustr, tmp, ns) = '\0';
|
||||||
|
}
|
||||||
if (namespace)
|
if (namespace)
|
||||||
type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
@ -639,6 +676,102 @@ list_file (struct grub_ntfs_file *diro, char *pos,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct symlink_descriptor
|
||||||
|
{
|
||||||
|
grub_uint32_t type;
|
||||||
|
grub_uint32_t total_len;
|
||||||
|
grub_uint16_t off1;
|
||||||
|
grub_uint16_t len1;
|
||||||
|
grub_uint16_t off2;
|
||||||
|
grub_uint16_t len2;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
static char *
|
||||||
|
grub_ntfs_read_symlink (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
struct grub_ntfs_file *mft;
|
||||||
|
struct symlink_descriptor symdesc;
|
||||||
|
grub_err_t err;
|
||||||
|
grub_uint16_t *buf16;
|
||||||
|
char *buf, *end;
|
||||||
|
grub_size_t len;
|
||||||
|
grub_size_t i;
|
||||||
|
char *pa;
|
||||||
|
grub_size_t off;
|
||||||
|
|
||||||
|
mft = (struct grub_ntfs_file *) node;
|
||||||
|
|
||||||
|
mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||||
|
if (mft->buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (read_mft (mft->data, mft->buf, mft->ino))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK);
|
||||||
|
if (pa == NULL)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "no $SYMLINK in MFT 0x%X", mft->ino);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = read_attr (&mft->attr, (char *) &symdesc, 0,
|
||||||
|
sizeof (struct symlink_descriptor), 1, 0);
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
switch (grub_cpu_to_le32 (symdesc.type))
|
||||||
|
{
|
||||||
|
case 0xa000000c:
|
||||||
|
off = (sizeof (struct symlink_descriptor) + 4
|
||||||
|
+ grub_cpu_to_le32 (symdesc.off1));
|
||||||
|
len = grub_cpu_to_le32 (symdesc.len1);
|
||||||
|
break;
|
||||||
|
case 0xa0000003:
|
||||||
|
off = (sizeof (struct symlink_descriptor)
|
||||||
|
+ grub_cpu_to_le32 (symdesc.off1));
|
||||||
|
len = grub_cpu_to_le32 (symdesc.len1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)",
|
||||||
|
grub_cpu_to_le32 (symdesc.type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf16 = grub_malloc (len);
|
||||||
|
if (!buf16)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
err = read_attr (&mft->attr, (char *) buf16, off, len, 1, 0);
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buf = grub_malloc (len * 2 + 1);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
grub_free (buf16);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len / 2; i++)
|
||||||
|
{
|
||||||
|
buf16[i] = grub_le_to_cpu16 (buf16[i]);
|
||||||
|
if (buf16[i] == '\\')
|
||||||
|
buf16[i] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
end = (char *) grub_utf16_to_utf8 ((grub_uint8_t *) buf, buf16, len / 2);
|
||||||
|
*end = '\0';
|
||||||
|
/* Split the sequence to avoid GCC thinking that this is a trigraph. */
|
||||||
|
if (grub_memcmp (buf, "/?" "?/", 4) == 0 && buf[5] == ':' && buf[6] == '/'
|
||||||
|
&& grub_isalpha (buf[4]))
|
||||||
|
{
|
||||||
|
grub_memmove (buf, buf + 6, end - buf + 1 - 6);
|
||||||
|
end -= 6;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
int NESTED_FUNC_ATTR
|
int NESTED_FUNC_ATTR
|
||||||
|
@ -668,7 +801,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
init_attr (at, mft);
|
init_attr (at, mft);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
|
if ((cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT)) == NULL)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
|
grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -694,7 +827,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
bitmap_len = 0;
|
bitmap_len = 0;
|
||||||
free_attr (at);
|
free_attr (at);
|
||||||
init_attr (at, mft);
|
init_attr (at, mft);
|
||||||
while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL)
|
while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL)
|
||||||
{
|
{
|
||||||
int ofs;
|
int ofs;
|
||||||
|
|
||||||
|
@ -735,7 +868,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
free_attr (at);
|
free_attr (at);
|
||||||
cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION);
|
cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION);
|
||||||
while (cur_pos != NULL)
|
while (cur_pos != NULL)
|
||||||
{
|
{
|
||||||
/* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
|
/* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
|
||||||
|
@ -743,7 +876,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
(u32at (cur_pos, 0x40) == 0x490024) &&
|
(u32at (cur_pos, 0x40) == 0x490024) &&
|
||||||
(u32at (cur_pos, 0x44) == 0x300033))
|
(u32at (cur_pos, 0x44) == 0x300033))
|
||||||
break;
|
break;
|
||||||
cur_pos = find_attr (at, AT_INDEX_ALLOCATION);
|
cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!cur_pos) && (bitmap))
|
if ((!cur_pos) && (bitmap))
|
||||||
|
@ -756,7 +889,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
{
|
{
|
||||||
grub_disk_addr_t v, i;
|
grub_disk_addr_t v, i;
|
||||||
|
|
||||||
indx = grub_malloc (mft->data->idx_size << BLK_SHR);
|
indx = grub_malloc (mft->data->idx_size << GRUB_NTFS_BLK_SHR);
|
||||||
if (indx == NULL)
|
if (indx == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -766,8 +899,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (*bitmap & v)
|
if (*bitmap & v)
|
||||||
{
|
{
|
||||||
if ((read_attr
|
if ((read_attr
|
||||||
(at, indx, i * (mft->data->idx_size << BLK_SHR),
|
(at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
|
||||||
(mft->data->idx_size << BLK_SHR), 0, 0))
|
(mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0))
|
||||||
|| (fixup (mft->data, indx, mft->data->idx_size, "INDX")))
|
|| (fixup (mft->data, indx, mft->data->idx_size, "INDX")))
|
||||||
goto done;
|
goto done;
|
||||||
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
|
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
|
||||||
|
@ -814,32 +947,32 @@ grub_ntfs_mount (grub_disk_t disk)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
|
data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
|
||||||
data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR);
|
data->spc = bpb.sectors_per_cluster * (data->blocksize >> GRUB_NTFS_BLK_SHR);
|
||||||
|
|
||||||
if (bpb.clusters_per_mft > 0)
|
if (bpb.clusters_per_mft > 0)
|
||||||
data->mft_size = data->spc * bpb.clusters_per_mft;
|
data->mft_size = data->spc * bpb.clusters_per_mft;
|
||||||
else
|
else
|
||||||
data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR);
|
data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR);
|
||||||
|
|
||||||
if (bpb.clusters_per_index > 0)
|
if (bpb.clusters_per_index > 0)
|
||||||
data->idx_size = data->spc * bpb.clusters_per_index;
|
data->idx_size = data->spc * bpb.clusters_per_index;
|
||||||
else
|
else
|
||||||
data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR);
|
data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR);
|
||||||
|
|
||||||
data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
|
data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
|
||||||
|
|
||||||
if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
|
if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->mmft.data = data;
|
data->mmft.data = data;
|
||||||
data->cmft.data = data;
|
data->cmft.data = data;
|
||||||
|
|
||||||
data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR);
|
data->mmft.buf = grub_malloc (data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||||
if (!data->mmft.buf)
|
if (!data->mmft.buf)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (grub_disk_read
|
if (grub_disk_read
|
||||||
(disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf))
|
(disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->uuid = grub_le_to_cpu64 (bpb.num_serial);
|
data->uuid = grub_le_to_cpu64 (bpb.num_serial);
|
||||||
|
@ -847,10 +980,10 @@ grub_ntfs_mount (grub_disk_t disk)
|
||||||
if (fixup (data, data->mmft.buf, data->mft_size, "FILE"))
|
if (fixup (data, data->mmft.buf, data->mft_size, "FILE"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA))
|
if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (init_file (&data->cmft, FILE_ROOT))
|
if (init_file (&data->cmft, GRUB_NTFS_FILE_ROOT))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -901,7 +1034,7 @@ grub_ntfs_dir (grub_device_t device, const char *path,
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
|
grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
|
||||||
0, GRUB_FSHELP_DIR);
|
grub_ntfs_read_symlink, GRUB_FSHELP_DIR);
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -939,7 +1072,7 @@ grub_ntfs_open (grub_file_t file, const char *name)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir,
|
grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir,
|
||||||
0, GRUB_FSHELP_REG);
|
grub_ntfs_read_symlink, GRUB_FSHELP_REG);
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1030,7 +1163,7 @@ grub_ntfs_label (grub_device_t device, char **label)
|
||||||
|
|
||||||
if (!mft->inode_read)
|
if (!mft->inode_read)
|
||||||
{
|
{
|
||||||
mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
|
mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||||
if (mft->buf == NULL)
|
if (mft->buf == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -1039,7 +1172,7 @@ grub_ntfs_label (grub_device_t device, char **label)
|
||||||
}
|
}
|
||||||
|
|
||||||
init_attr (&mft->attr, mft);
|
init_attr (&mft->attr, mft);
|
||||||
pa = find_attr (&mft->attr, AT_VOLUME_NAME);
|
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
|
||||||
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -1048,8 +1181,14 @@ grub_ntfs_label (grub_device_t device, char **label)
|
||||||
len = u32at (pa, 0x10) / 2;
|
len = u32at (pa, 0x10) / 2;
|
||||||
buf = grub_malloc (len * 4 + 1);
|
buf = grub_malloc (len * 4 + 1);
|
||||||
pa += u16at (pa, 0x14);
|
pa += u16at (pa, 0x14);
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) =
|
{
|
||||||
'\0';
|
grub_uint16_t tmp[len];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (pa + 2 * i));
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) buf, tmp, len) =
|
||||||
|
'\0';
|
||||||
|
}
|
||||||
*label = buf;
|
*label = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1087,14 +1226,15 @@ grub_ntfs_uuid (grub_device_t device, char **uuid)
|
||||||
if (*uuid)
|
if (*uuid)
|
||||||
for (ptr = *uuid; *ptr; ptr++)
|
for (ptr = *uuid; *ptr; ptr++)
|
||||||
*ptr = grub_toupper (*ptr);
|
*ptr = grub_toupper (*ptr);
|
||||||
|
free_file (&data->mmft);
|
||||||
|
free_file (&data->cmft);
|
||||||
|
grub_free (data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*uuid = NULL;
|
*uuid = NULL;
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
grub_free (data);
|
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/ntfs.h>
|
#include <grub/ntfs.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
@ -35,7 +34,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc)
|
||||||
(cc->disk,
|
(cc->disk,
|
||||||
(cc->comp_table[cc->comp_head][1] -
|
(cc->comp_table[cc->comp_head][1] -
|
||||||
(cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
|
(cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
|
||||||
cc->spc << BLK_SHR, cc->cbuf))
|
cc->spc << GRUB_NTFS_BLK_SHR, cc->cbuf))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
cc->cbuf_vcn++;
|
cc->cbuf_vcn++;
|
||||||
if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
|
if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
|
||||||
|
@ -47,7 +46,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
|
decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
|
||||||
{
|
{
|
||||||
if (cc->cbuf_ofs >= (cc->spc << BLK_SHR))
|
if (cc->cbuf_ofs >= (cc->spc << GRUB_NTFS_BLK_SHR))
|
||||||
{
|
{
|
||||||
if (decomp_nextvcn (cc))
|
if (decomp_nextvcn (cc))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -87,7 +86,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
|
||||||
bits = copied = tag = 0;
|
bits = copied = tag = 0;
|
||||||
while (cnt > 0)
|
while (cnt > 0)
|
||||||
{
|
{
|
||||||
if (copied > COM_LEN)
|
if (copied > GRUB_NTFS_COM_LEN)
|
||||||
return grub_error (GRUB_ERR_BAD_FS,
|
return grub_error (GRUB_ERR_BAD_FS,
|
||||||
"compression block too large");
|
"compression block too large");
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cnt != COM_LEN)
|
if (cnt != GRUB_NTFS_COM_LEN)
|
||||||
return grub_error (GRUB_ERR_BAD_FS,
|
return grub_error (GRUB_ERR_BAD_FS,
|
||||||
"invalid compression block size");
|
"invalid compression block size");
|
||||||
}
|
}
|
||||||
|
@ -160,7 +159,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = (cc->spc << BLK_SHR) - cc->cbuf_ofs;
|
n = (cc->spc << GRUB_NTFS_BLK_SHR) - cc->cbuf_ofs;
|
||||||
if (n > cnt)
|
if (n > cnt)
|
||||||
n = cnt;
|
n = cnt;
|
||||||
if ((dest) && (n))
|
if ((dest) && (n))
|
||||||
|
@ -179,7 +178,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
{
|
{
|
||||||
int cpb = COM_SEC / ctx->comp.spc;
|
int cpb = GRUB_NTFS_COM_SEC / ctx->comp.spc;
|
||||||
|
|
||||||
while (num)
|
while (num)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +191,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "invalid compression block");
|
return grub_error (GRUB_ERR_BAD_FS, "invalid compression block");
|
||||||
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
|
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
|
||||||
ctx->comp.cbuf_vcn = ctx->target_vcn;
|
ctx->comp.cbuf_vcn = ctx->target_vcn;
|
||||||
ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR);
|
ctx->comp.cbuf_ofs = (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
|
||||||
if (ctx->target_vcn >= ctx->next_vcn)
|
if (ctx->target_vcn >= ctx->next_vcn)
|
||||||
{
|
{
|
||||||
if (grub_ntfs_read_run_list (ctx))
|
if (grub_ntfs_read_run_list (ctx))
|
||||||
|
@ -200,7 +199,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
}
|
}
|
||||||
while (ctx->target_vcn + 16 > ctx->next_vcn)
|
while (ctx->target_vcn + 16 > ctx->next_vcn)
|
||||||
{
|
{
|
||||||
if (ctx->flags & RF_BLNK)
|
if (ctx->flags & GRUB_NTFS_RF_BLNK)
|
||||||
break;
|
break;
|
||||||
ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn;
|
ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn;
|
||||||
ctx->comp.comp_table[ctx->comp.comp_tail][1] =
|
ctx->comp.comp_table[ctx->comp.comp_tail][1] =
|
||||||
|
@ -216,15 +215,15 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
nn = num;
|
nn = num;
|
||||||
num -= nn;
|
num -= nn;
|
||||||
|
|
||||||
if (ctx->flags & RF_BLNK)
|
if (ctx->flags & GRUB_NTFS_RF_BLNK)
|
||||||
{
|
{
|
||||||
ctx->target_vcn += nn * cpb;
|
ctx->target_vcn += nn * cpb;
|
||||||
if (ctx->comp.comp_tail == 0)
|
if (ctx->comp.comp_tail == 0)
|
||||||
{
|
{
|
||||||
if (buf)
|
if (buf)
|
||||||
{
|
{
|
||||||
grub_memset (buf, 0, nn * COM_LEN);
|
grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN);
|
||||||
buf += nn * COM_LEN;
|
buf += nn * GRUB_NTFS_COM_LEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -234,7 +233,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
if (decomp_block (&ctx->comp, buf))
|
if (decomp_block (&ctx->comp, buf))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
if (buf)
|
if (buf)
|
||||||
buf += COM_LEN;
|
buf += GRUB_NTFS_COM_LEN;
|
||||||
nn--;
|
nn--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,9 +258,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
(ctx->comp.comp_table[ctx->comp.comp_head][1] -
|
(ctx->comp.comp_table[ctx->comp.comp_head][1] -
|
||||||
(ctx->comp.comp_table[ctx->comp.comp_head][0] -
|
(ctx->comp.comp_table[ctx->comp.comp_head][0] -
|
||||||
ctx->target_vcn)) * ctx->comp.spc, 0,
|
ctx->target_vcn)) * ctx->comp.spc, 0,
|
||||||
tt * (ctx->comp.spc << BLK_SHR), buf))
|
tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
buf += tt * (ctx->comp.spc << BLK_SHR);
|
buf += tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
|
||||||
}
|
}
|
||||||
nn -= tt;
|
nn -= tt;
|
||||||
if (ctx->target_vcn >=
|
if (ctx->target_vcn >=
|
||||||
|
@ -276,9 +275,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
|
||||||
(ctx->comp.disk,
|
(ctx->comp.disk,
|
||||||
(ctx->target_vcn - ctx->curr_vcn +
|
(ctx->target_vcn - ctx->curr_vcn +
|
||||||
ctx->curr_lcn) * ctx->comp.spc, 0,
|
ctx->curr_lcn) * ctx->comp.spc, 0,
|
||||||
nn * (ctx->comp.spc << BLK_SHR), buf))
|
nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
buf += nn * (ctx->comp.spc << BLK_SHR);
|
buf += nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
|
||||||
}
|
}
|
||||||
ctx->target_vcn += nn;
|
ctx->target_vcn += nn;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +293,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
||||||
grub_err_t ret;
|
grub_err_t ret;
|
||||||
|
|
||||||
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
|
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
|
||||||
ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR);
|
ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << GRUB_NTFS_BLK_SHR);
|
||||||
if (!ctx->comp.cbuf)
|
if (!ctx->comp.cbuf)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -304,17 +303,17 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
||||||
|
|
||||||
if ((vcn > ctx->target_vcn) &&
|
if ((vcn > ctx->target_vcn) &&
|
||||||
(read_block
|
(read_block
|
||||||
(ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC)))
|
(ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / GRUB_NTFS_COM_SEC)))
|
||||||
{
|
{
|
||||||
ret = grub_errno;
|
ret = grub_errno;
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofs % COM_LEN)
|
if (ofs % GRUB_NTFS_COM_LEN)
|
||||||
{
|
{
|
||||||
grub_uint32_t t, n, o;
|
grub_uint32_t t, n, o;
|
||||||
|
|
||||||
t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
|
t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
|
||||||
if (read_block (ctx, at->sbuf, 1))
|
if (read_block (ctx, at->sbuf, 1))
|
||||||
{
|
{
|
||||||
ret = grub_errno;
|
ret = grub_errno;
|
||||||
|
@ -323,8 +322,8 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
||||||
|
|
||||||
at->save_pos = t;
|
at->save_pos = t;
|
||||||
|
|
||||||
o = ofs % COM_LEN;
|
o = ofs % GRUB_NTFS_COM_LEN;
|
||||||
n = COM_LEN - o;
|
n = GRUB_NTFS_COM_LEN - o;
|
||||||
if (n > len)
|
if (n > len)
|
||||||
n = len;
|
n = len;
|
||||||
grub_memcpy (dest, &at->sbuf[o], n);
|
grub_memcpy (dest, &at->sbuf[o], n);
|
||||||
|
@ -334,19 +333,19 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
|
||||||
len -= n;
|
len -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_block (ctx, dest, len / COM_LEN))
|
if (read_block (ctx, dest, len / GRUB_NTFS_COM_LEN))
|
||||||
{
|
{
|
||||||
ret = grub_errno;
|
ret = grub_errno;
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest += (len / COM_LEN) * COM_LEN;
|
dest += (len / GRUB_NTFS_COM_LEN) * GRUB_NTFS_COM_LEN;
|
||||||
len = len % COM_LEN;
|
len = len % GRUB_NTFS_COM_LEN;
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
grub_uint32_t t;
|
grub_uint32_t t;
|
||||||
|
|
||||||
t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
|
t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
|
||||||
if (read_block (ctx, at->sbuf, 1))
|
if (read_block (ctx, at->sbuf, 1))
|
||||||
{
|
{
|
||||||
ret = grub_errno;
|
ret = grub_errno;
|
||||||
|
|
|
@ -57,8 +57,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
|
#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
|
||||||
/* If the 3rd bit of an item state is set, then it's visible. */
|
/* If the 3rd bit of an item state is set, then it's visible. */
|
||||||
#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
|
#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
|
||||||
#define REISERFS_MAX_LABEL_LENGTH 16
|
|
||||||
#define REISERFS_LABEL_OFFSET 0x64
|
|
||||||
|
|
||||||
#define S_IFLNK 0xA000
|
#define S_IFLNK 0xA000
|
||||||
|
|
||||||
|
@ -109,6 +107,7 @@ struct grub_reiserfs_superblock
|
||||||
grub_uint32_t inode_generation;
|
grub_uint32_t inode_generation;
|
||||||
grub_uint8_t unused[4];
|
grub_uint8_t unused[4];
|
||||||
grub_uint16_t uuid[8];
|
grub_uint16_t uuid[8];
|
||||||
|
char label[16];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_reiserfs_journal_header
|
struct grub_reiserfs_journal_header
|
||||||
|
@ -1323,14 +1322,24 @@ grub_reiserfs_dir (grub_device_t device, const char *path,
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_reiserfs_label (grub_device_t device, char **label)
|
grub_reiserfs_label (grub_device_t device, char **label)
|
||||||
{
|
{
|
||||||
*label = grub_malloc (REISERFS_MAX_LABEL_LENGTH);
|
struct grub_reiserfs_data *data;
|
||||||
if (*label)
|
grub_disk_t disk = device->disk;
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
data = grub_reiserfs_mount (disk);
|
||||||
|
if (data)
|
||||||
{
|
{
|
||||||
grub_disk_read (device->disk,
|
*label = grub_strndup (data->superblock.label,
|
||||||
REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
|
sizeof (data->superblock.label));
|
||||||
REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH,
|
|
||||||
*label);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*label = NULL;
|
||||||
|
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ grub_romfs_mount (grub_device_t dev)
|
||||||
if (err)
|
if (err)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1)
|
for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1)
|
||||||
&& ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
&& ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
||||||
if (!*ptr)
|
if (!*ptr)
|
||||||
break;
|
break;
|
||||||
if ((void *) ptr == &sb + 1)
|
if ((void *) ptr == &sb + 1)
|
||||||
|
@ -124,7 +124,7 @@ grub_romfs_mount (grub_device_t dev)
|
||||||
if (err)
|
if (err)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1)
|
for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1)
|
||||||
&& ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
&& ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
||||||
if (!*ptr)
|
if (!*ptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -166,17 +166,18 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
{
|
{
|
||||||
grub_disk_addr_t caddr;
|
grub_disk_addr_t caddr;
|
||||||
struct grub_romfs_file_header hdr;
|
struct grub_romfs_file_header hdr;
|
||||||
grub_size_t a = 0;
|
|
||||||
char *name = NULL;
|
|
||||||
unsigned nptr;
|
unsigned nptr;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
grub_size_t a = 0;
|
||||||
|
grub_properly_aligned_t *name = NULL;
|
||||||
|
|
||||||
for (caddr = dir->data_addr; caddr;
|
for (caddr = dir->data_addr; caddr;
|
||||||
caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1))
|
caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1))
|
||||||
{
|
{
|
||||||
grub_disk_addr_t naddr = caddr + sizeof (hdr);
|
grub_disk_addr_t naddr = caddr + sizeof (hdr);
|
||||||
grub_uint32_t csum = 0;
|
grub_uint32_t csum = 0;
|
||||||
enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN;
|
enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN;
|
||||||
struct grub_fshelp_node *node;
|
struct grub_fshelp_node *node = NULL;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS,
|
err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
@ -189,9 +190,9 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
}
|
}
|
||||||
for (nptr = 0; ; nptr++, naddr += 16)
|
for (nptr = 0; ; nptr++, naddr += 16)
|
||||||
{
|
{
|
||||||
if (a >= nptr)
|
if (a <= nptr)
|
||||||
{
|
{
|
||||||
char *on;
|
grub_properly_aligned_t *on;
|
||||||
a = 2 * (nptr + 1);
|
a = 2 * (nptr + 1);
|
||||||
on = name;
|
on = name;
|
||||||
name = grub_realloc (name, a * 16);
|
name = grub_realloc (name, a * 16);
|
||||||
|
@ -201,13 +202,14 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
COMPILE_TIME_ASSERT (16 % sizeof (name[0]) == 0);
|
||||||
err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS,
|
err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
naddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
naddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
16, name + 16 * nptr);
|
16, name + (16 / sizeof (name[0])) * nptr);
|
||||||
if (err)
|
if (err)
|
||||||
return 1;
|
return 1;
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
if (!name[16 * nptr + j])
|
if (!((char *) name)[16 * nptr + j])
|
||||||
break;
|
break;
|
||||||
if (j != 16)
|
if (j != 16)
|
||||||
break;
|
break;
|
||||||
|
@ -292,7 +294,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hook (name, filetype, node))
|
if (hook ((char *) name, filetype, node))
|
||||||
{
|
{
|
||||||
grub_free (name);
|
grub_free (name);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -367,6 +369,7 @@ grub_romfs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
file->size = grub_be_to_cpu32 (fdiro->file.size);
|
file->size = grub_be_to_cpu32 (fdiro->file.size);
|
||||||
file->data = fdiro;
|
file->data = fdiro;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
@ -396,7 +399,10 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_romfs_close (grub_file_t file)
|
grub_romfs_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
struct grub_fshelp_node *data = file->data;
|
||||||
|
|
||||||
|
grub_free (data->data);
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -431,6 +437,7 @@ grub_romfs_label (grub_device_t device, char **label)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
(*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0;
|
(*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0;
|
||||||
|
grub_free (data);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ static grub_ssize_t
|
||||||
grub_sfs_read_file (grub_fshelp_node_t node,
|
grub_sfs_read_file (grub_fshelp_node_t node,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
int pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
||||||
pos, len, buf, grub_sfs_read_block,
|
pos, len, buf, grub_sfs_read_block,
|
||||||
|
|
|
@ -42,7 +42,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
exttblptr RAW superblock
|
exttblptr RAW superblock
|
||||||
|
|
||||||
UID/GID table is the array ot uint32_t
|
UID/GID table is the array ot uint32_t
|
||||||
unk1 contains pointer to unk3 followed by some chunk.
|
unk1 contains pointer to fragment table followed by some chunk.
|
||||||
unk2 containts one uint64_t
|
unk2 containts one uint64_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -52,13 +52,9 @@ struct grub_squash_super
|
||||||
#define SQUASH_MAGIC 0x73717368
|
#define SQUASH_MAGIC 0x73717368
|
||||||
grub_uint32_t dummy1;
|
grub_uint32_t dummy1;
|
||||||
grub_uint32_t creation_time;
|
grub_uint32_t creation_time;
|
||||||
grub_uint32_t dummy2;
|
grub_uint32_t block_size;
|
||||||
grub_uint64_t dummy3;
|
grub_uint64_t dummy3;
|
||||||
grub_uint8_t flags;
|
grub_uint64_t dummy4;
|
||||||
#define SQUASH_FLAG_UNCOMPRESSED_INODES 1
|
|
||||||
#define SQUASH_FLAG_UNCOMPRESSED_DATA 2
|
|
||||||
#define SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS 8
|
|
||||||
grub_uint8_t dummy4[7];
|
|
||||||
grub_uint16_t root_ino_offset;
|
grub_uint16_t root_ino_offset;
|
||||||
grub_uint32_t root_ino_chunk;
|
grub_uint32_t root_ino_chunk;
|
||||||
grub_uint16_t dummy5;
|
grub_uint16_t dummy5;
|
||||||
|
@ -71,7 +67,6 @@ struct grub_squash_super
|
||||||
grub_uint64_t unk2offset;
|
grub_uint64_t unk2offset;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
/* Chunk-based */
|
/* Chunk-based */
|
||||||
struct grub_squash_inode
|
struct grub_squash_inode
|
||||||
{
|
{
|
||||||
|
@ -85,16 +80,30 @@ struct grub_squash_inode
|
||||||
grub_uint32_t dummy;
|
grub_uint32_t dummy;
|
||||||
grub_uint32_t chunk;
|
grub_uint32_t chunk;
|
||||||
grub_uint32_t fragment;
|
grub_uint32_t fragment;
|
||||||
grub_uint32_t offset;
|
grub_uint16_t offset;
|
||||||
|
grub_uint16_t dummy2;
|
||||||
grub_uint32_t size;
|
grub_uint32_t size;
|
||||||
|
grub_uint32_t block_size[0];
|
||||||
} __attribute__ ((packed)) file;
|
} __attribute__ ((packed)) file;
|
||||||
|
struct {
|
||||||
|
grub_uint32_t dummy;
|
||||||
|
grub_uint64_t chunk;
|
||||||
|
grub_uint64_t size;
|
||||||
|
grub_uint32_t dummy2[3];
|
||||||
|
grub_uint32_t fragment;
|
||||||
|
grub_uint16_t offset;
|
||||||
|
grub_uint16_t dummy3;
|
||||||
|
grub_uint32_t dummy4;
|
||||||
|
grub_uint32_t block_size[0];
|
||||||
|
} __attribute__ ((packed)) long_file;
|
||||||
struct {
|
struct {
|
||||||
grub_uint32_t dummy1;
|
grub_uint32_t dummy1;
|
||||||
grub_uint32_t chunk;
|
grub_uint32_t chunk;
|
||||||
grub_uint32_t dummy2;
|
grub_uint32_t dummy2;
|
||||||
grub_uint16_t size;
|
grub_uint16_t size;
|
||||||
grub_uint32_t offset;
|
grub_uint16_t offset;
|
||||||
grub_uint16_t dummy3;
|
grub_uint16_t dummy3;
|
||||||
|
grub_uint16_t dummy4;
|
||||||
} __attribute__ ((packed)) dir;
|
} __attribute__ ((packed)) dir;
|
||||||
struct {
|
struct {
|
||||||
grub_uint64_t dummy;
|
grub_uint64_t dummy;
|
||||||
|
@ -104,12 +113,22 @@ struct grub_squash_inode
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_squash_cache_inode
|
||||||
|
{
|
||||||
|
struct grub_squash_inode ino;
|
||||||
|
grub_disk_addr_t ino_chunk;
|
||||||
|
grub_uint16_t ino_offset;
|
||||||
|
grub_uint32_t *block_sizes;
|
||||||
|
grub_disk_addr_t *cumulated_block_sizes;
|
||||||
|
};
|
||||||
|
|
||||||
/* Chunk-based. */
|
/* Chunk-based. */
|
||||||
struct grub_squash_dirent_header
|
struct grub_squash_dirent_header
|
||||||
{
|
{
|
||||||
/* Actually the value is the number of elements - 1. */
|
/* Actually the value is the number of elements - 1. */
|
||||||
grub_uint32_t nelems;
|
grub_uint32_t nelems;
|
||||||
grub_uint64_t ino_chunk;
|
grub_uint32_t ino_chunk;
|
||||||
|
grub_uint32_t dummy;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_squash_dirent
|
struct grub_squash_dirent
|
||||||
|
@ -117,46 +136,62 @@ struct grub_squash_dirent
|
||||||
grub_uint16_t ino_offset;
|
grub_uint16_t ino_offset;
|
||||||
grub_uint16_t dummy;
|
grub_uint16_t dummy;
|
||||||
grub_uint16_t type;
|
grub_uint16_t type;
|
||||||
#define SQUASH_TYPE_DIR 1
|
|
||||||
#define SQUASH_TYPE_REGULAR 2
|
|
||||||
#define SQUASH_TYPE_SYMLINK 3
|
|
||||||
/* Actually the value is the length of name - 1. */
|
/* Actually the value is the length of name - 1. */
|
||||||
grub_uint16_t namelen;
|
grub_uint16_t namelen;
|
||||||
char name[0];
|
char name[0];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SQUASH_TYPE_DIR = 1,
|
||||||
|
SQUASH_TYPE_REGULAR = 2,
|
||||||
|
SQUASH_TYPE_SYMLINK = 3,
|
||||||
|
SQUASH_TYPE_LONG_REGULAR = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct grub_squash_frag_desc
|
struct grub_squash_frag_desc
|
||||||
{
|
{
|
||||||
grub_uint64_t offset;
|
grub_uint64_t offset;
|
||||||
grub_uint64_t dummy;
|
grub_uint32_t size;
|
||||||
|
grub_uint32_t dummy;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SQUASH_CHUNK_FLAGS = 0x8000,
|
||||||
|
SQUASH_CHUNK_UNCOMPRESSED = 0x8000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SQUASH_BLOCK_FLAGS = 0x1000000,
|
||||||
|
SQUASH_BLOCK_UNCOMPRESSED = 0x1000000
|
||||||
|
};
|
||||||
|
|
||||||
#define SQUASH_CHUNK_SIZE 0x2000
|
#define SQUASH_CHUNK_SIZE 0x2000
|
||||||
#define SQUASH_CHUNK_FLAGS 0x8000
|
|
||||||
#define SQUASH_CHUNK_UNCOMPRESSED 0x8000
|
|
||||||
|
|
||||||
struct grub_squash_data
|
struct grub_squash_data
|
||||||
{
|
{
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
struct grub_squash_super sb;
|
struct grub_squash_super sb;
|
||||||
struct grub_squash_inode ino;
|
struct grub_squash_cache_inode ino;
|
||||||
grub_uint64_t fragments;
|
grub_uint64_t fragments;
|
||||||
|
int log2_blksz;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_fshelp_node
|
struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_squash_data *data;
|
struct grub_squash_data *data;
|
||||||
struct grub_squash_inode ino;
|
struct grub_squash_inode ino;
|
||||||
grub_uint32_t ino_chunk;
|
grub_disk_addr_t ino_chunk;
|
||||||
grub_uint16_t ino_offset;
|
grub_uint16_t ino_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
|
read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len,
|
||||||
grub_uint64_t chunk, grub_off_t offset)
|
grub_uint64_t chunk_start, grub_off_t offset)
|
||||||
{
|
{
|
||||||
grub_uint64_t chunk_start;
|
|
||||||
chunk_start = grub_le_to_cpu64 (chunk);
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
grub_uint64_t csize;
|
grub_uint64_t csize;
|
||||||
|
@ -164,7 +199,8 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
err = grub_disk_read (disk, chunk_start >> GRUB_DISK_SECTOR_BITS,
|
err = grub_disk_read (data->disk,
|
||||||
|
chunk_start >> GRUB_DISK_SECTOR_BITS,
|
||||||
chunk_start & (GRUB_DISK_SECTOR_SIZE - 1),
|
chunk_start & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
sizeof (d), &d);
|
sizeof (d), &d);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -182,7 +218,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
|
||||||
if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED)
|
if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t a = chunk_start + 2 + offset;
|
grub_disk_addr_t a = chunk_start + 2 + offset;
|
||||||
err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS),
|
err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS),
|
||||||
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
csize, buf);
|
csize, buf);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -197,7 +233,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
/* FIXME: buffer uncompressed data. */
|
/* FIXME: buffer uncompressed data. */
|
||||||
err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS),
|
err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS),
|
||||||
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
bsize, tmp);
|
bsize, tmp);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -234,27 +270,35 @@ squash_mount (grub_disk_t disk)
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
||||||
if (err)
|
if (err)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC)
|
if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC
|
||||||
|
|| grub_le_to_cpu32 (sb.block_size) == 0
|
||||||
|
|| ((grub_le_to_cpu32 (sb.block_size) - 1)
|
||||||
|
& grub_le_to_cpu32 (sb.block_size)))
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not squash4");
|
grub_error (GRUB_ERR_BAD_FS, "not squash4");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_disk_read (disk, grub_le_to_cpu32 (sb.unk1offset)
|
err = grub_disk_read (disk,
|
||||||
|
grub_le_to_cpu64 (sb.unk1offset)
|
||||||
>> GRUB_DISK_SECTOR_BITS,
|
>> GRUB_DISK_SECTOR_BITS,
|
||||||
grub_le_to_cpu32 (sb.unk1offset)
|
grub_le_to_cpu64 (sb.unk1offset)
|
||||||
& (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag);
|
& (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag);
|
||||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
||||||
if (err)
|
if (err)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data = grub_malloc (sizeof (*data));
|
data = grub_zalloc (sizeof (*data));
|
||||||
if (!data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
data->sb = sb;
|
data->sb = sb;
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
data->fragments = frag;
|
data->fragments = grub_le_to_cpu64 (frag);
|
||||||
|
|
||||||
|
for (data->log2_blksz = 0;
|
||||||
|
(1U << data->log2_blksz) < grub_le_to_cpu32 (data->sb.block_size);
|
||||||
|
data->log2_blksz++);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +310,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
||||||
|
|
||||||
err = read_chunk (node->data->disk, ret,
|
err = read_chunk (node->data, ret,
|
||||||
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
||||||
grub_le_to_cpu64 (node->data->sb.inodeoffset)
|
grub_le_to_cpu64 (node->data->sb.inodeoffset)
|
||||||
+ node->ino_chunk,
|
+ node->ino_chunk,
|
||||||
|
@ -293,20 +337,20 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* FIXME: why - 3 ? */
|
/* FIXME: why - 3 ? */
|
||||||
endoff = grub_le_to_cpu32 (dir->ino.dir.size) + off - 3;
|
endoff = grub_le_to_cpu16 (dir->ino.dir.size) + off - 3;
|
||||||
|
|
||||||
while (off < endoff)
|
while (off < endoff)
|
||||||
{
|
{
|
||||||
struct grub_squash_dirent_header dh;
|
struct grub_squash_dirent_header dh;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
err = read_chunk (dir->data->disk, &dh, sizeof (dh),
|
err = read_chunk (dir->data, &dh, sizeof (dh),
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return 0;
|
||||||
off += sizeof (dh);
|
off += sizeof (dh);
|
||||||
for (i = 0; i < (unsigned) grub_le_to_cpu16 (dh.nelems) + 1; i++)
|
for (i = 0; i < (unsigned) grub_le_to_cpu32 (dh.nelems) + 1; i++)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int r;
|
int r;
|
||||||
|
@ -315,14 +359,14 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
struct grub_squash_dirent di;
|
struct grub_squash_dirent di;
|
||||||
struct grub_squash_inode ino;
|
struct grub_squash_inode ino;
|
||||||
|
|
||||||
err = read_chunk (dir->data->disk, &di, sizeof (di),
|
err = read_chunk (dir->data, &di, sizeof (di),
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return 0;
|
||||||
off += sizeof (di);
|
off += sizeof (di);
|
||||||
|
|
||||||
err = read_chunk (dir->data->disk, &ino, sizeof (ino),
|
err = read_chunk (dir->data, &ino, sizeof (ino),
|
||||||
grub_le_to_cpu64 (dir->data->sb.inodeoffset)
|
grub_le_to_cpu64 (dir->data->sb.inodeoffset)
|
||||||
+ grub_le_to_cpu32 (dh.ino_chunk),
|
+ grub_le_to_cpu32 (dh.ino_chunk),
|
||||||
grub_cpu_to_le16 (di.ino_offset));
|
grub_cpu_to_le16 (di.ino_offset));
|
||||||
|
@ -332,7 +376,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
|
buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return 0;
|
return 0;
|
||||||
err = read_chunk (dir->data->disk, buf,
|
err = read_chunk (dir->data, buf,
|
||||||
grub_le_to_cpu16 (di.namelen) + 1,
|
grub_le_to_cpu16 (di.namelen) + 1,
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
|
@ -370,12 +414,21 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root)
|
||||||
grub_memset (root, 0, sizeof (*root));
|
grub_memset (root, 0, sizeof (*root));
|
||||||
root->data = data;
|
root->data = data;
|
||||||
|
|
||||||
return read_chunk (data->disk, &root->ino, sizeof (root->ino),
|
return read_chunk (data, &root->ino, sizeof (root->ino),
|
||||||
grub_le_to_cpu64 (data->sb.inodeoffset)
|
grub_le_to_cpu64 (data->sb.inodeoffset)
|
||||||
+ grub_le_to_cpu16 (data->sb.root_ino_chunk),
|
+ grub_le_to_cpu16 (data->sb.root_ino_chunk),
|
||||||
grub_cpu_to_le16 (data->sb.root_ino_offset));
|
grub_cpu_to_le16 (data->sb.root_ino_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
squash_unmount (struct grub_squash_data *data)
|
||||||
|
{
|
||||||
|
grub_free (data->ino.cumulated_block_sizes);
|
||||||
|
grub_free (data->ino.block_sizes);
|
||||||
|
grub_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_squash_dir (grub_device_t device, const char *path,
|
grub_squash_dir (grub_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
|
@ -394,6 +447,7 @@ grub_squash_dir (grub_device_t device, const char *path,
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
info.mtime = grub_le_to_cpu32 (node->ino.mtime);
|
info.mtime = grub_le_to_cpu32 (node->ino.mtime);
|
||||||
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +469,7 @@ grub_squash_dir (grub_device_t device, const char *path,
|
||||||
if (!grub_errno)
|
if (!grub_errno)
|
||||||
grub_squash_iterate_dir (fdiro, iterate);
|
grub_squash_iterate_dir (fdiro, iterate);
|
||||||
|
|
||||||
grub_free (data);
|
squash_unmount (data);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -440,53 +494,173 @@ grub_squash_open (struct grub_file *file, const char *name)
|
||||||
grub_squash_read_symlink, GRUB_FSHELP_REG);
|
grub_squash_read_symlink, GRUB_FSHELP_REG);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
{
|
{
|
||||||
grub_free (data);
|
squash_unmount (data);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->data = data;
|
file->data = data;
|
||||||
data->ino = fdiro->ino;
|
data->ino.ino = fdiro->ino;
|
||||||
file->size = grub_le_to_cpu32 (fdiro->ino.file.size);
|
data->ino.block_sizes = NULL;
|
||||||
|
data->ino.cumulated_block_sizes = NULL;
|
||||||
|
data->ino.ino_chunk = fdiro->ino_chunk;
|
||||||
|
data->ino.ino_offset = fdiro->ino_offset;
|
||||||
|
|
||||||
|
if (fdiro->ino.type
|
||||||
|
== grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||||
|
file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size);
|
||||||
|
else
|
||||||
|
file->size = grub_le_to_cpu32 (fdiro->ino.file.size);
|
||||||
|
|
||||||
|
grub_free (fdiro);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
direct_read (struct grub_squash_data *data,
|
||||||
|
struct grub_squash_cache_inode *ino,
|
||||||
|
grub_off_t off, char *buf, grub_size_t len)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_off_t cumulated_uncompressed_size = 0;
|
||||||
|
grub_uint64_t a;
|
||||||
|
grub_size_t i;
|
||||||
|
grub_size_t origlen = len;
|
||||||
|
|
||||||
|
if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||||
|
a = grub_le_to_cpu64 (ino->ino.long_file.chunk);
|
||||||
|
else
|
||||||
|
a = grub_le_to_cpu32 (ino->ino.file.chunk);
|
||||||
|
|
||||||
|
if (!ino->block_sizes)
|
||||||
|
{
|
||||||
|
grub_off_t total_size;
|
||||||
|
grub_size_t total_blocks;
|
||||||
|
grub_size_t block_offset;
|
||||||
|
if (ino->ino.type
|
||||||
|
== grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||||
|
{
|
||||||
|
total_size = grub_le_to_cpu64 (ino->ino.long_file.size);
|
||||||
|
block_offset = ((char *) &ino->ino.long_file.block_size
|
||||||
|
- (char *) &ino->ino);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
total_size = grub_le_to_cpu32 (ino->ino.file.size);
|
||||||
|
block_offset = ((char *) &ino->ino.file.block_size
|
||||||
|
- (char *) &ino->ino);
|
||||||
|
}
|
||||||
|
total_blocks = ((total_size
|
||||||
|
+ grub_le_to_cpu32 (data->sb.block_size) - 1)
|
||||||
|
>> data->log2_blksz);
|
||||||
|
ino->block_sizes = grub_malloc (total_blocks
|
||||||
|
* sizeof (ino->block_sizes[0]));
|
||||||
|
ino->cumulated_block_sizes = grub_malloc (total_blocks
|
||||||
|
* sizeof (ino->cumulated_block_sizes[0]));
|
||||||
|
if (!ino->block_sizes || !ino->cumulated_block_sizes)
|
||||||
|
{
|
||||||
|
grub_free (ino->block_sizes);
|
||||||
|
grub_free (ino->cumulated_block_sizes);
|
||||||
|
ino->block_sizes = 0;
|
||||||
|
ino->cumulated_block_sizes = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
err = read_chunk (data, ino->block_sizes,
|
||||||
|
total_blocks * sizeof (ino->block_sizes[0]),
|
||||||
|
grub_le_to_cpu64 (data->sb.inodeoffset)
|
||||||
|
+ ino->ino_chunk,
|
||||||
|
ino->ino_offset + block_offset);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (ino->block_sizes);
|
||||||
|
grub_free (ino->cumulated_block_sizes);
|
||||||
|
ino->block_sizes = 0;
|
||||||
|
ino->cumulated_block_sizes = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ino->cumulated_block_sizes[0] = 0;
|
||||||
|
for (i = 1; i < total_blocks; i++)
|
||||||
|
ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1]
|
||||||
|
+ (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == 0)
|
||||||
|
a = sizeof (struct grub_squash_super);
|
||||||
|
i = off >> data->log2_blksz;
|
||||||
|
cumulated_uncompressed_size = grub_le_to_cpu32 (data->sb.block_size)
|
||||||
|
* (grub_disk_addr_t) i;
|
||||||
|
while (cumulated_uncompressed_size < off + len)
|
||||||
|
{
|
||||||
|
grub_size_t boff, read;
|
||||||
|
boff = off - cumulated_uncompressed_size;
|
||||||
|
read = grub_le_to_cpu32 (data->sb.block_size) - boff;
|
||||||
|
if (read > len)
|
||||||
|
read = len;
|
||||||
|
if (!(ino->block_sizes[i]
|
||||||
|
& grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED)))
|
||||||
|
err = grub_zlib_disk_read (data->disk,
|
||||||
|
ino->cumulated_block_sizes[i] + a,
|
||||||
|
boff, buf, read);
|
||||||
|
else
|
||||||
|
err = grub_disk_read (data->disk,
|
||||||
|
(ino->cumulated_block_sizes[i] + a + boff)
|
||||||
|
>> GRUB_DISK_SECTOR_BITS,
|
||||||
|
(ino->cumulated_block_sizes[i] + a + boff)
|
||||||
|
& (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
read, buf);
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
off += read;
|
||||||
|
len -= read;
|
||||||
|
buf += read;
|
||||||
|
cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return origlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_squash_read_data (struct grub_squash_data *data,
|
grub_squash_read_data (struct grub_squash_data *data,
|
||||||
grub_disk_t disk, const struct grub_squash_inode *ino,
|
struct grub_squash_cache_inode *ino,
|
||||||
grub_off_t off, char *buf, grub_size_t len)
|
grub_off_t off, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_uint64_t a, b;
|
grub_uint64_t a, b;
|
||||||
|
grub_uint32_t fragment;
|
||||||
int compressed = 0;
|
int compressed = 0;
|
||||||
|
struct grub_squash_frag_desc frag;
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff)
|
if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||||
{
|
{
|
||||||
if (grub_le_to_cpu32 (ino->file.chunk))
|
a = grub_le_to_cpu64 (ino->ino.long_file.chunk);
|
||||||
a = grub_le_to_cpu32 (ino->file.chunk);
|
fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment);
|
||||||
else
|
|
||||||
a = sizeof (struct grub_squash_super);
|
|
||||||
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct grub_squash_frag_desc frag;
|
a = grub_le_to_cpu32 (ino->ino.file.chunk);
|
||||||
err = read_chunk (disk, &frag, sizeof (frag),
|
fragment = grub_le_to_cpu32 (ino->ino.file.fragment);
|
||||||
data->fragments, sizeof (frag)
|
|
||||||
* grub_le_to_cpu16 (ino->file.fragment));
|
|
||||||
if (err)
|
|
||||||
return -1;
|
|
||||||
a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk);
|
|
||||||
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b = grub_le_to_cpu32 (data->ino.file.offset) + off;
|
if (fragment == 0xffffffff)
|
||||||
|
return direct_read (data, ino, off, buf, len);
|
||||||
|
|
||||||
|
err = read_chunk (data, &frag, sizeof (frag),
|
||||||
|
data->fragments, sizeof (frag) * fragment);
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
a += grub_le_to_cpu64 (frag.offset);
|
||||||
|
compressed = !(frag.size & SQUASH_BLOCK_UNCOMPRESSED);
|
||||||
|
if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||||
|
b = grub_le_to_cpu64 (ino->ino.long_file.offset) + off;
|
||||||
|
else
|
||||||
|
b = grub_le_to_cpu32 (ino->ino.file.offset) + off;
|
||||||
|
|
||||||
/* FIXME: cache uncompressed chunks. */
|
/* FIXME: cache uncompressed chunks. */
|
||||||
if (compressed)
|
if (compressed)
|
||||||
err = grub_zlib_disk_read (disk, a, b, buf, len);
|
err = grub_zlib_disk_read (data->disk, a, b, buf, len);
|
||||||
else
|
else
|
||||||
err = grub_disk_read (disk, (a + b) >> GRUB_DISK_SECTOR_BITS,
|
err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS,
|
||||||
(a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf);
|
(a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -498,14 +672,14 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
struct grub_squash_data *data = file->data;
|
struct grub_squash_data *data = file->data;
|
||||||
|
|
||||||
return grub_squash_read_data (data, file->device->disk, &data->ino,
|
return grub_squash_read_data (data, &data->ino,
|
||||||
file->offset, buf, len);
|
file->offset, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_squash_close (grub_file_t file)
|
grub_squash_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
squash_unmount (file->data);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +692,7 @@ grub_squash_mtime (grub_device_t dev, grub_int32_t *tm)
|
||||||
if (! data)
|
if (! data)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
*tm = grub_le_to_cpu32 (data->sb.creation_time);
|
*tm = grub_le_to_cpu32 (data->sb.creation_time);
|
||||||
grub_free (data);
|
squash_unmount (data);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -317,7 +317,7 @@ struct grub_udf_partmap
|
||||||
grub_uint8_t ident[62];
|
grub_uint8_t ident[62];
|
||||||
} type2;
|
} type2;
|
||||||
};
|
};
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_udf_lvd
|
struct grub_udf_lvd
|
||||||
{
|
{
|
||||||
|
@ -820,7 +820,7 @@ read_string (grub_uint8_t *raw, grub_size_t sz)
|
||||||
for (i = 0; i < utf16len; i++)
|
for (i = 0; i < utf16len; i++)
|
||||||
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
||||||
}
|
}
|
||||||
ret = grub_malloc (utf16len * 3 + 1);
|
ret = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0';
|
*grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0';
|
||||||
grub_free (utf16);
|
grub_free (utf16);
|
||||||
|
|
|
@ -50,6 +50,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
/* Calculate in which group the inode can be found. */
|
/* Calculate in which group the inode can be found. */
|
||||||
#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
|
#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
|
||||||
|
#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz)
|
||||||
|
|
||||||
#define INODE(data,field) data->inode. field
|
#define INODE(data,field) data->inode. field
|
||||||
#ifdef MODE_UFS2
|
#ifdef MODE_UFS2
|
||||||
|
@ -214,6 +215,7 @@ struct grub_ufs_data
|
||||||
struct grub_ufs_inode inode;
|
struct grub_ufs_inode inode;
|
||||||
int ino;
|
int ino;
|
||||||
int linknest;
|
int linknest;
|
||||||
|
int log2_blksz;
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
@ -285,26 +287,28 @@ static grub_ssize_t
|
||||||
grub_ufs_read_file (struct grub_ufs_data *data,
|
grub_ufs_read_file (struct grub_ufs_data *data,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
int pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
struct grub_ufs_sblock *sblock = &data->sblock;
|
struct grub_ufs_sblock *sblock = &data->sblock;
|
||||||
int i;
|
grub_off_t i;
|
||||||
int blockcnt;
|
grub_off_t blockcnt;
|
||||||
|
|
||||||
/* Adjust len so it we can't read past the end of the file. */
|
/* Adjust len so it we can't read past the end of the file. */
|
||||||
if (len + pos > INODE_SIZE (data))
|
if (len + pos > INODE_SIZE (data))
|
||||||
len = INODE_SIZE (data) - pos;
|
len = INODE_SIZE (data) - pos;
|
||||||
|
|
||||||
blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
|
blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) >> UFS_LOG_BLKSZ (sblock);
|
||||||
|
|
||||||
for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++)
|
for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++)
|
||||||
{
|
{
|
||||||
int blknr;
|
grub_disk_addr_t blknr;
|
||||||
int blockoff = pos % UFS_BLKSZ (sblock);
|
grub_off_t blockoff;
|
||||||
int blockend = UFS_BLKSZ (sblock);
|
grub_off_t blockend = UFS_BLKSZ (sblock);
|
||||||
|
|
||||||
int skipfirst = 0;
|
int skipfirst = 0;
|
||||||
|
|
||||||
|
blockoff = pos & (UFS_BLKSZ (sblock) - 1);
|
||||||
|
|
||||||
blknr = grub_ufs_get_file_block (data, i);
|
blknr = grub_ufs_get_file_block (data, i);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -312,14 +316,14 @@ grub_ufs_read_file (struct grub_ufs_data *data,
|
||||||
/* Last block. */
|
/* Last block. */
|
||||||
if (i == blockcnt - 1)
|
if (i == blockcnt - 1)
|
||||||
{
|
{
|
||||||
blockend = (len + pos) % UFS_BLKSZ (sblock);
|
blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1);
|
||||||
|
|
||||||
if (!blockend)
|
if (!blockend)
|
||||||
blockend = UFS_BLKSZ (sblock);
|
blockend = UFS_BLKSZ (sblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First block. */
|
/* First block. */
|
||||||
if (i == (pos / (int) UFS_BLKSZ (sblock)))
|
if (i == (pos >> UFS_LOG_BLKSZ (sblock)))
|
||||||
{
|
{
|
||||||
skipfirst = blockoff;
|
skipfirst = blockoff;
|
||||||
blockend -= skipfirst;
|
blockend -= skipfirst;
|
||||||
|
@ -391,21 +395,16 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
|
grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
|
||||||
{
|
{
|
||||||
char symlink[INODE_SIZE (data)];
|
char symlink[INODE_SIZE (data) + 1];
|
||||||
|
|
||||||
if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
|
if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
||||||
|
|
||||||
if (INODE_NBLOCKS (data) == 0)
|
if (INODE_SIZE (data) <= sizeof (data->inode.symlink))
|
||||||
grub_strcpy (symlink, (char *) INODE (data, symlink));
|
grub_strcpy (symlink, (char *) INODE (data, symlink));
|
||||||
else
|
else
|
||||||
{
|
grub_ufs_read_file (data, 0, 0, INODE_SIZE (data), symlink);
|
||||||
grub_disk_read (data->disk,
|
symlink[INODE_SIZE (data)] = '\0';
|
||||||
(INODE_DIRBLOCKS (data, 0)
|
|
||||||
<< grub_le_to_cpu32 (data->sblock.log2_blksz)),
|
|
||||||
0, INODE_SIZE (data), symlink);
|
|
||||||
symlink[INODE_SIZE (data)] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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] == '/')
|
||||||
|
@ -538,8 +537,16 @@ grub_ufs_mount (grub_disk_t disk)
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
|
/* No need to byteswap bsize in this check. It works the same on both
|
||||||
|
endiannesses. */
|
||||||
|
if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC
|
||||||
|
&& data->sblock.bsize != 0
|
||||||
|
&& ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0))
|
||||||
{
|
{
|
||||||
|
for (data->log2_blksz = 0;
|
||||||
|
(1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize);
|
||||||
|
data->log2_blksz++);
|
||||||
|
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
data->linknest = 0;
|
data->linknest = 0;
|
||||||
return data;
|
return data;
|
||||||
|
@ -698,8 +705,6 @@ grub_ufs_close (grub_file_t file)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MODE_UFS2
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ufs_label (grub_device_t device, char **label)
|
grub_ufs_label (grub_device_t device, char **label)
|
||||||
{
|
{
|
||||||
|
@ -719,7 +724,6 @@ grub_ufs_label (grub_device_t device, char **label)
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ufs_uuid (grub_device_t device, char **uuid)
|
grub_ufs_uuid (grub_device_t device, char **uuid)
|
||||||
|
@ -757,11 +761,13 @@ grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
|
||||||
if (!data)
|
if (!data)
|
||||||
*tm = 0;
|
*tm = 0;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*tm = grub_le_to_cpu32 (data->sblock.mtime);
|
||||||
#ifdef MODE_UFS2
|
#ifdef MODE_UFS2
|
||||||
*tm = grub_le_to_cpu64 (data->sblock.mtime2);
|
if (*tm < (grub_int64_t) grub_le_to_cpu64 (data->sblock.mtime2))
|
||||||
#else
|
*tm = grub_le_to_cpu64 (data->sblock.mtime2);
|
||||||
*tm = grub_le_to_cpu32 (data->sblock.mtime);
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
@ -783,9 +789,7 @@ static struct grub_fs grub_ufs_fs =
|
||||||
.open = grub_ufs_open,
|
.open = grub_ufs_open,
|
||||||
.read = grub_ufs_read,
|
.read = grub_ufs_read,
|
||||||
.close = grub_ufs_close,
|
.close = grub_ufs_close,
|
||||||
#ifdef MODE_UFS2
|
|
||||||
.label = grub_ufs_label,
|
.label = grub_ufs_label,
|
||||||
#endif
|
|
||||||
.uuid = grub_ufs_uuid,
|
.uuid = grub_ufs_uuid,
|
||||||
.mtime = grub_ufs_mtime,
|
.mtime = grub_ufs_mtime,
|
||||||
.next = 0
|
.next = 0
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue