commit
91391dc52b
86 changed files with 1883 additions and 1032 deletions
|
@ -48,6 +48,7 @@ library = {
|
||||||
common = grub-core/partmap/gpt.c;
|
common = grub-core/partmap/gpt.c;
|
||||||
common = grub-core/partmap/msdos.c;
|
common = grub-core/partmap/msdos.c;
|
||||||
common = grub-core/fs/proc.c;
|
common = grub-core/fs/proc.c;
|
||||||
|
common = grub-core/fs/archelp.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
library = {
|
library = {
|
||||||
|
@ -91,7 +92,6 @@ library = {
|
||||||
common = grub-core/fs/bfs.c;
|
common = grub-core/fs/bfs.c;
|
||||||
common = grub-core/fs/btrfs.c;
|
common = grub-core/fs/btrfs.c;
|
||||||
common = grub-core/fs/cbfs.c;
|
common = grub-core/fs/cbfs.c;
|
||||||
common = grub-core/fs/archelp.c;
|
|
||||||
common = grub-core/fs/cpio.c;
|
common = grub-core/fs/cpio.c;
|
||||||
common = grub-core/fs/cpio_be.c;
|
common = grub-core/fs/cpio_be.c;
|
||||||
common = grub-core/fs/odc.c;
|
common = grub-core/fs/odc.c;
|
||||||
|
|
5
NEWS
5
NEWS
|
@ -17,6 +17,7 @@ New in 2.02:
|
||||||
files.
|
files.
|
||||||
* ZFS features support.
|
* ZFS features support.
|
||||||
* ZFS LZ4 support.
|
* ZFS LZ4 support.
|
||||||
|
* XFS V5 format support.
|
||||||
|
|
||||||
* New/improved terminal and video support:
|
* New/improved terminal and video support:
|
||||||
* Monochrome text (matching `hercules' in GRUB Legacy).
|
* Monochrome text (matching `hercules' in GRUB Legacy).
|
||||||
|
@ -145,6 +146,10 @@ New in 2.02:
|
||||||
Python 2.6.
|
Python 2.6.
|
||||||
* modinfo.sh contains build information now.
|
* modinfo.sh contains build information now.
|
||||||
* Added many new tests to improve robustness.
|
* Added many new tests to improve robustness.
|
||||||
|
* Target is built without libgcc now. Necessary builtins are reimplemented
|
||||||
|
directly. This removes requirement for target-specific runtime on build
|
||||||
|
system.
|
||||||
|
* emu libusb support removed (was broken and unmaintained).
|
||||||
|
|
||||||
* Revision control moved to git.
|
* Revision control moved to git.
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ else
|
||||||
fi
|
fi
|
||||||
grub_cv_prog_objcopy_absolute=yes
|
grub_cv_prog_objcopy_absolute=yes
|
||||||
for link_addr in 0x2000 0x8000 0x7C00; do
|
for link_addr in 0x2000 0x8000 0x7C00; do
|
||||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then :
|
if AC_TRY_COMMAND([${CC-cc} ${TARGET_CFLAGS} ${TARGET_LDFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then :
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
|
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -17,6 +17,9 @@ endif
|
||||||
if COND_arm64
|
if COND_arm64
|
||||||
CFLAGS_PLATFORM += -mcmodel=large
|
CFLAGS_PLATFORM += -mcmodel=large
|
||||||
endif
|
endif
|
||||||
|
if COND_powerpc_ieee1275
|
||||||
|
CFLAGS_PLATFORM += -mcpu=powerpc
|
||||||
|
endif
|
||||||
|
|
||||||
#FIXME: discover and check XEN headers
|
#FIXME: discover and check XEN headers
|
||||||
CPPFLAGS_XEN = -I/usr/include
|
CPPFLAGS_XEN = -I/usr/include
|
||||||
|
|
|
@ -5,6 +5,7 @@ EXTRA_DIST += gentpl.py
|
||||||
EXTRA_DIST += Makefile.util.def
|
EXTRA_DIST += Makefile.util.def
|
||||||
EXTRA_DIST += Makefile.utilgcry.def
|
EXTRA_DIST += Makefile.utilgcry.def
|
||||||
|
|
||||||
|
EXTRA_DIST += asm-tests
|
||||||
EXTRA_DIST += unicode
|
EXTRA_DIST += unicode
|
||||||
|
|
||||||
EXTRA_DIST += util/import_gcry.py
|
EXTRA_DIST += util/import_gcry.py
|
||||||
|
|
53
configure.ac
53
configure.ac
|
@ -116,6 +116,7 @@ if test "x$with_platform" = x; then
|
||||||
x86_64-*) platform=pc ;;
|
x86_64-*) platform=pc ;;
|
||||||
powerpc-*) platform=ieee1275 ;;
|
powerpc-*) platform=ieee1275 ;;
|
||||||
powerpc64-*) platform=ieee1275 ;;
|
powerpc64-*) platform=ieee1275 ;;
|
||||||
|
powerpc64le-*) platform=ieee1275 ;;
|
||||||
sparc64-*) platform=ieee1275 ;;
|
sparc64-*) platform=ieee1275 ;;
|
||||||
mipsel-*) platform=loongson ;;
|
mipsel-*) platform=loongson ;;
|
||||||
mips-*) platform=arc ;;
|
mips-*) platform=arc ;;
|
||||||
|
@ -138,6 +139,7 @@ case "$target_cpu"-"$platform" in
|
||||||
x86_64-none) ;;
|
x86_64-none) ;;
|
||||||
x86_64-*) target_cpu=i386 ;;
|
x86_64-*) target_cpu=i386 ;;
|
||||||
powerpc64-ieee1275) target_cpu=powerpc ;;
|
powerpc64-ieee1275) target_cpu=powerpc ;;
|
||||||
|
powerpc64le-ieee1275) target_cpu=powerpc ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Check if the platform is supported, make final adjustments.
|
# Check if the platform is supported, make final adjustments.
|
||||||
|
@ -560,6 +562,41 @@ AC_COMPILE_IFELSE(
|
||||||
]])],
|
]])],
|
||||||
[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])])
|
[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])])
|
||||||
|
|
||||||
|
if test x$target_cpu = xpowerpc; then
|
||||||
|
AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [
|
||||||
|
grub_cv_target_cc_big_endian=no
|
||||||
|
for cand in "-target powerpc -Wl,-EB" "-target powerpc" \
|
||||||
|
"-target powerpc-linux-gnu -Wl,-EB" "-target powerpc-linux-gnu" \
|
||||||
|
"-mbig-endian"; do
|
||||||
|
if test x"$grub_cv_target_cc_big_endian" != xno ; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
CFLAGS="$TARGET_CFLAGS $cand -Werror"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||||
|
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__)
|
||||||
|
#error still little endian
|
||||||
|
#endif
|
||||||
|
asm (".globl start; start:");
|
||||||
|
void __main (void);
|
||||||
|
void __main (void) {}
|
||||||
|
int main (void);
|
||||||
|
]], [[]])],
|
||||||
|
[grub_cv_target_cc_big_endian="$cand"], [])
|
||||||
|
done
|
||||||
|
])
|
||||||
|
|
||||||
|
if test x"$grub_cv_target_cc_big_endian" = xno ; then
|
||||||
|
AC_MSG_ERROR([could not force big-endian])
|
||||||
|
fi
|
||||||
|
|
||||||
|
skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')"
|
||||||
|
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags"
|
||||||
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags"
|
||||||
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags"
|
||||||
|
TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [
|
AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [
|
||||||
test_program=
|
test_program=
|
||||||
case "x$target_cpu-$platform" in
|
case "x$target_cpu-$platform" in
|
||||||
|
@ -686,9 +723,9 @@ if test x"$platform" != xemu ; then
|
||||||
AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [
|
AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [
|
||||||
grub_cv_target_cc_soft_float=no
|
grub_cv_target_cc_soft_float=no
|
||||||
if test "x$target_cpu" = xarm64; then
|
if test "x$target_cpu" = xarm64; then
|
||||||
CFLAGS="$TARGET_CFLAGS -march=armv8-a+nofp+nosimd -Werror"
|
CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror"
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||||
[grub_cv_target_cc_soft_float="-march=armv8-a+nofp+nosimd"], [])
|
[grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
|
||||||
fi
|
fi
|
||||||
if test "x$target_cpu" = xia64; then
|
if test "x$target_cpu" = xia64; then
|
||||||
CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
|
CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
|
||||||
|
@ -720,15 +757,7 @@ if test x"$platform" != xemu ; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float"
|
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
case x"$grub_cv_target_cc_soft_float" in
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float"
|
||||||
x"-march=armv8-a+nofp+nosimd")
|
|
||||||
# +nosimd disables also the cache opcodes that we need in asm.
|
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -march=armv8-a+nofp"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1152,7 +1181,7 @@ fi
|
||||||
|
|
||||||
# Check for libgcc symbols
|
# Check for libgcc symbols
|
||||||
if test x"$platform" = xemu; then
|
if test x"$platform" = xemu; then
|
||||||
AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
|
AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$TARGET_APPLE_LINKER" = x1 ; then
|
if test "x$TARGET_APPLE_LINKER" = x1 ; then
|
||||||
|
|
|
@ -5162,8 +5162,10 @@ by @var{shortname} which can be used to remove it (@pxref{net_del_route}).
|
||||||
Perform configuration of @var{card} using DHCP protocol. If no card name
|
Perform configuration of @var{card} using DHCP protocol. If no card name
|
||||||
is specified, try to configure all existing cards. If configuration was
|
is specified, try to configure all existing cards. If configuration was
|
||||||
successful, interface with name @var{card}@samp{:dhcp} and configured
|
successful, interface with name @var{card}@samp{:dhcp} and configured
|
||||||
address is added to @var{card}. If server provided gateway information in
|
address is added to @var{card}.
|
||||||
DHCP ACK packet, it is added as route entry with the name @var{card}@samp{:dhcp:gw}. Additionally the following DHCP options are recognized and processed:
|
@comment If server provided gateway information in
|
||||||
|
@comment DHCP ACK packet, it is added as route entry with the name @var{card}@samp{:dhcp:gw}.
|
||||||
|
Additionally the following DHCP options are recognized and processed:
|
||||||
|
|
||||||
@table @samp
|
@table @samp
|
||||||
@item 1 (Subnet Mask)
|
@item 1 (Subnet Mask)
|
||||||
|
@ -5426,10 +5428,12 @@ In order to enable authentication support, the @samp{superusers} environment
|
||||||
variable must be set to a list of usernames, separated by any of spaces,
|
variable must be set to a list of usernames, separated by any of spaces,
|
||||||
commas, semicolons, pipes, or ampersands. Superusers are permitted to use
|
commas, semicolons, pipes, or ampersands. Superusers are permitted to use
|
||||||
the GRUB command line, edit menu entries, and execute any menu entry. If
|
the GRUB command line, edit menu entries, and execute any menu entry. If
|
||||||
@samp{superusers} is set, then use of the command line is automatically
|
@samp{superusers} is set, then use of the command line and editing of menu
|
||||||
restricted to superusers.
|
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||||
|
to empty string effectively disables both access to CLI and editing of menu
|
||||||
|
entries.
|
||||||
|
|
||||||
Other users may be given access to specific menu entries by giving a list of
|
Other users may be allowed to execute specific menu entries by giving a list of
|
||||||
usernames (as above) using the @option{--users} option to the
|
usernames (as above) using the @option{--users} option to the
|
||||||
@samp{menuentry} command (@pxref{menuentry}). If the @option{--unrestricted}
|
@samp{menuentry} command (@pxref{menuentry}). If the @option{--unrestricted}
|
||||||
option is used for a menu entry, then that entry is unrestricted.
|
option is used for a menu entry, then that entry is unrestricted.
|
||||||
|
|
17
gentpl.py
17
gentpl.py
|
@ -82,7 +82,7 @@ GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"]
|
||||||
GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
|
GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
|
||||||
for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
|
for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
|
||||||
|
|
||||||
# Miscelaneous groups schedulded to disappear in future
|
# Miscellaneous groups scheduled to disappear in future
|
||||||
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
|
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
|
||||||
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
|
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
|
||||||
|
|
||||||
|
@ -834,6 +834,20 @@ def data(defn, platform):
|
||||||
var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
|
var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
|
||||||
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
gvar_add("dist_noinst_DATA", extra_dist(defn))
|
||||||
|
|
||||||
|
def transform_data(defn, platform):
|
||||||
|
name = defn['name']
|
||||||
|
|
||||||
|
var_add(installdir(defn) + "_DATA", name)
|
||||||
|
|
||||||
|
rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
|
||||||
|
(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
|
||||||
|
chmod a+x """ + name + """
|
||||||
|
""")
|
||||||
|
|
||||||
|
gvar_add("CLEANFILES", name)
|
||||||
|
gvar_add("EXTRA_DIST", extra_dist(defn))
|
||||||
|
gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
|
||||||
|
|
||||||
def script(defn, platform):
|
def script(defn, platform):
|
||||||
name = defn['name']
|
name = defn['name']
|
||||||
|
|
||||||
|
@ -881,6 +895,7 @@ rules("library", library)
|
||||||
rules("program", program)
|
rules("program", program)
|
||||||
rules("script", script)
|
rules("script", script)
|
||||||
rules("data", data)
|
rules("data", data)
|
||||||
|
rules("transform_data", transform_data)
|
||||||
|
|
||||||
write_output(section='decl')
|
write_output(section='decl')
|
||||||
write_output()
|
write_output()
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
AutoGen definitions Makefile.tpl;
|
AutoGen definitions Makefile.tpl;
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = noinst;
|
installdir = noinst;
|
||||||
name = gensyminfo.sh;
|
name = gensyminfo.sh;
|
||||||
common = gensyminfo.sh.in;
|
common = gensyminfo.sh.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = noinst;
|
installdir = noinst;
|
||||||
name = genmod.sh;
|
name = genmod.sh;
|
||||||
common = genmod.sh.in;
|
common = genmod.sh.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = noinst;
|
installdir = noinst;
|
||||||
name = modinfo.sh;
|
name = modinfo.sh;
|
||||||
common = modinfo.sh.in;
|
common = modinfo.sh.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = platform;
|
installdir = platform;
|
||||||
name = gmodule.pl;
|
name = gmodule.pl;
|
||||||
common = gmodule.pl.in;
|
common = gmodule.pl.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = platform;
|
installdir = platform;
|
||||||
name = gdb_grub;
|
name = gdb_grub;
|
||||||
common = gdb_grub.in;
|
common = gdb_grub.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = platform;
|
installdir = platform;
|
||||||
name = grub.chrp;
|
name = grub.chrp;
|
||||||
common = boot/powerpc/grub.chrp.in;
|
common = boot/powerpc/grub.chrp.in;
|
||||||
enable = powerpc_ieee1275;
|
enable = powerpc_ieee1275;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
transform_data = {
|
||||||
installdir = platform;
|
installdir = platform;
|
||||||
name = bootinfo.txt;
|
name = bootinfo.txt;
|
||||||
common = boot/powerpc/bootinfo.txt.in;
|
common = boot/powerpc/bootinfo.txt.in;
|
||||||
|
|
|
@ -344,7 +344,7 @@ printhex:
|
||||||
nop
|
nop
|
||||||
srl $t1, $a0, 28
|
srl $t1, $a0, 28
|
||||||
addiu $t1, $t1, -10
|
addiu $t1, $t1, -10
|
||||||
blt $t1, $zero, 2f
|
bltz $t1, 2f
|
||||||
sll $a0, $a0, 4
|
sll $a0, $a0, 4
|
||||||
addiu $t1, $t1, 'A'-10-'0'
|
addiu $t1, $t1, 'A'-10-'0'
|
||||||
2: addiu $t1, $t1, '0'+10
|
2: addiu $t1, $t1, '0'+10
|
||||||
|
@ -398,7 +398,7 @@ read_spd:
|
||||||
move $t2, $a0
|
move $t2, $a0
|
||||||
move $t3, $ra
|
move $t3, $ra
|
||||||
lui $a0, %hi(read_spd_fail)
|
lui $a0, %hi(read_spd_fail)
|
||||||
addiu $a0, $a0, %hi(read_spd_fail)
|
addiu $a0, $a0, %lo(read_spd_fail)
|
||||||
|
|
||||||
/* Send START. */
|
/* Send START. */
|
||||||
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F)
|
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F)
|
||||||
|
@ -547,7 +547,7 @@ gpio_dump:
|
||||||
#endif
|
#endif
|
||||||
gpio_dump_end:
|
gpio_dump_end:
|
||||||
|
|
||||||
.p2align
|
.p2align 3
|
||||||
|
|
||||||
write_dumpreg:
|
write_dumpreg:
|
||||||
ld $t2, 0($t6)
|
ld $t2, 0($t6)
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/cpu/kernel.h>
|
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
#define BASE_ADDR 8
|
#define BASE_ADDR 8
|
||||||
|
@ -33,7 +32,6 @@
|
||||||
.globl __start, _start, start
|
.globl __start, _start, start
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
mips_attributes
|
|
||||||
__start:
|
__start:
|
||||||
_start:
|
_start:
|
||||||
start:
|
start:
|
||||||
|
|
|
@ -55,7 +55,7 @@ grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
|
||||||
int err;
|
int err;
|
||||||
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
|
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
|
||||||
if (err)
|
if (err)
|
||||||
grub_util_error ("mapping 0x%llx failed (error %d)\n",
|
grub_util_error ("mapping 0x%llx failed (error %d)",
|
||||||
(unsigned long long) base, err);
|
(unsigned long long) base, err);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -750,7 +750,10 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev,
|
||||||
{
|
{
|
||||||
cdata->td_head_virt = grub_ohci_alloc_td (o);
|
cdata->td_head_virt = grub_ohci_alloc_td (o);
|
||||||
if (!cdata->td_head_virt)
|
if (!cdata->td_head_virt)
|
||||||
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */
|
{
|
||||||
|
grub_free (cdata);
|
||||||
|
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */
|
||||||
|
}
|
||||||
/* We can set td_head only when ED is not active, i.e.
|
/* We can set td_head only when ED is not active, i.e.
|
||||||
* when it is newly allocated. */
|
* when it is newly allocated. */
|
||||||
cdata->ed_virt->td_head
|
cdata->ed_virt->td_head
|
||||||
|
|
|
@ -311,8 +311,8 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
|
||||||
transfer->size + 1);
|
transfer->size + 1);
|
||||||
|
|
||||||
grub_free (transfer->transactions);
|
grub_free (transfer->transactions);
|
||||||
grub_free (transfer);
|
|
||||||
grub_dma_free (transfer->data_chunk);
|
grub_dma_free (transfer->data_chunk);
|
||||||
|
grub_free (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_usb_err_t
|
static grub_usb_err_t
|
||||||
|
|
|
@ -180,8 +180,10 @@ grub_acpi_create_ebda (void)
|
||||||
struct grub_acpi_rsdp_v20 *v2;
|
struct grub_acpi_rsdp_v20 *v2;
|
||||||
|
|
||||||
ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
|
ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
|
||||||
|
grub_dprintf ("acpi", "EBDA @%p\n", ebda);
|
||||||
if (ebda)
|
if (ebda)
|
||||||
ebda_kb_len = *(grub_uint16_t *) ebda;
|
ebda_kb_len = *(grub_uint16_t *) ebda;
|
||||||
|
grub_dprintf ("acpi", "EBDA length 0x%x\n", ebda_kb_len);
|
||||||
if (ebda_kb_len > 16)
|
if (ebda_kb_len > 16)
|
||||||
ebda_kb_len = 0;
|
ebda_kb_len = 0;
|
||||||
ctx.ebda_len = (ebda_kb_len + 1) << 10;
|
ctx.ebda_len = (ebda_kb_len + 1) << 10;
|
||||||
|
@ -495,6 +497,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||||
if (! rsdp)
|
if (! rsdp)
|
||||||
rsdp = grub_machine_acpi_get_rsdpv1 ();
|
rsdp = grub_machine_acpi_get_rsdpv1 ();
|
||||||
|
|
||||||
|
grub_dprintf ("acpi", "RSDP @%p\n", rsdp);
|
||||||
|
|
||||||
if (rsdp)
|
if (rsdp)
|
||||||
{
|
{
|
||||||
grub_uint32_t *entry_ptr;
|
grub_uint32_t *entry_ptr;
|
||||||
|
|
|
@ -39,9 +39,17 @@ static const char *descs[] = {
|
||||||
[2] = "before RAM init",
|
[2] = "before RAM init",
|
||||||
[3] = "after RAM init",
|
[3] = "after RAM init",
|
||||||
[4] = "end of romstage",
|
[4] = "end of romstage",
|
||||||
|
[5] = "start of verified boot",
|
||||||
|
[6] = "end of verified boot",
|
||||||
[8] = "start of RAM copy",
|
[8] = "start of RAM copy",
|
||||||
[9] = "end of RAM copy",
|
[9] = "end of RAM copy",
|
||||||
[10] = "start of ramstage",
|
[10] = "start of ramstage",
|
||||||
|
[11] = "start of bootblock",
|
||||||
|
[12] = "end of bootblock",
|
||||||
|
[13] = "starting to load romstage",
|
||||||
|
[14] = "finished loading romstage",
|
||||||
|
[15] = "starting LZMA decompress (ignore for x86)",
|
||||||
|
[16] = "finished LZMA decompress (ignore for x86)",
|
||||||
[30] = "device enumerate",
|
[30] = "device enumerate",
|
||||||
[40] = "device configure",
|
[40] = "device configure",
|
||||||
[50] = "device enable",
|
[50] = "device enable",
|
||||||
|
|
|
@ -29,14 +29,15 @@ grub_machine_acpi_get_rsdpv1 (void)
|
||||||
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
|
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
|
||||||
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
|
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
|
||||||
ebda_len = * (grub_uint16_t *) ebda;
|
ebda_len = * (grub_uint16_t *) ebda;
|
||||||
if (! ebda_len)
|
if (! ebda_len) /* FIXME do we really need this check? */
|
||||||
return 0;
|
goto scan_bios;
|
||||||
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
|
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
|
||||||
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
|
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
|
||||||
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
|
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
|
||||||
&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
|
&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
|
||||||
return (struct grub_acpi_rsdp_v10 *) ptr;
|
return (struct grub_acpi_rsdp_v10 *) ptr;
|
||||||
|
|
||||||
|
scan_bios:
|
||||||
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
|
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
|
||||||
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
|
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
|
||||||
ptr += 16)
|
ptr += 16)
|
||||||
|
@ -56,8 +57,8 @@ grub_machine_acpi_get_rsdpv2 (void)
|
||||||
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
|
grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
|
||||||
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
|
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
|
||||||
ebda_len = * (grub_uint16_t *) ebda;
|
ebda_len = * (grub_uint16_t *) ebda;
|
||||||
if (! ebda_len)
|
if (! ebda_len) /* FIXME do we really need this check? */
|
||||||
return 0;
|
goto scan_bios;
|
||||||
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
|
for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
|
||||||
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
|
if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
|
||||||
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
|
&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
|
||||||
|
@ -67,6 +68,7 @@ grub_machine_acpi_get_rsdpv2 (void)
|
||||||
== 0)
|
== 0)
|
||||||
return (struct grub_acpi_rsdp_v20 *) ptr;
|
return (struct grub_acpi_rsdp_v20 *) ptr;
|
||||||
|
|
||||||
|
scan_bios:
|
||||||
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
|
grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
|
||||||
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
|
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
|
||||||
ptr += 16)
|
ptr += 16)
|
||||||
|
|
|
@ -104,7 +104,10 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
pass->c = grub_strtoul (ptr, &ptr, 0);
|
pass->c = grub_strtoul (ptr, &ptr, 0);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
{
|
||||||
|
grub_free (pass);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
if (*ptr != '.')
|
if (*ptr != '.')
|
||||||
{
|
{
|
||||||
grub_free (pass);
|
grub_free (pass);
|
||||||
|
|
|
@ -251,10 +251,10 @@ try (struct search_ctx *ctx)
|
||||||
/* Cache entry was outdated. Remove it. */
|
/* Cache entry was outdated. Remove it. */
|
||||||
if (!ctx->count)
|
if (!ctx->count)
|
||||||
{
|
{
|
||||||
|
*prev = cache_ent->next;
|
||||||
grub_free (cache_ent->key);
|
grub_free (cache_ent->key);
|
||||||
grub_free (cache_ent->value);
|
grub_free (cache_ent->value);
|
||||||
grub_free (cache_ent);
|
grub_free (cache_ent);
|
||||||
*prev = cache_ent->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,10 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
var = "root";
|
var = "root";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (state[SEARCH_LABEL].set)
|
if (state[SEARCH_LABEL].set)
|
||||||
grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set,
|
grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||||
|
@ -199,8 +202,10 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
|
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||||
hints, nhints);
|
hints, nhints);
|
||||||
else
|
else
|
||||||
return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
|
grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
|
||||||
|
|
||||||
|
out:
|
||||||
|
grub_free (hints);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
|
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
||||||
grub_pci_write_word (addr, grub_pci_read_word (addr)
|
grub_pci_write_word (addr, grub_pci_read_word (addr)
|
||||||
| GRUB_PCI_COMMAND_MEM_ENABLED);
|
| GRUB_PCI_COMMAND_MEM_ENABLED | GRUB_PCI_COMMAND_BUS_MASTER);
|
||||||
|
|
||||||
hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK,
|
hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK,
|
||||||
sizeof (*hba));
|
sizeof (*hba));
|
||||||
|
@ -355,7 +355,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
if (adevs[i])
|
if (adevs[i])
|
||||||
{
|
{
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error = adevs[i]->hba->ports[adevs[i]->port].sata_error;
|
adevs[i]->hba->ports[adevs[i]->port].sata_error = adevs[i]->hba->ports[adevs[i]->port].sata_error;
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
adevs[i]->command_list_chunk = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head) * 32);
|
adevs[i]->command_list_chunk = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head) * 32);
|
||||||
|
@ -440,7 +440,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].intstatus = ~0;
|
adevs[i]->hba->ports[adevs[i]->port].intstatus = ~0;
|
||||||
// adevs[i]->hba->ports[adevs[i]->port].fbs = 0;
|
// adevs[i]->hba->ports[adevs[i]->port].fbs = 0;
|
||||||
|
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
adevs[i]->rfis = grub_memalign_dma32 (4096,
|
adevs[i]->rfis = grub_memalign_dma32 (4096,
|
||||||
|
@ -480,7 +480,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
for (i = 0; i < nports; i++)
|
for (i = 0; i < nports; i++)
|
||||||
if (adevs[i])
|
if (adevs[i])
|
||||||
{
|
{
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
fr_running |= (1 << i);
|
fr_running |= (1 << i);
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
|
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command |= 1 << 28;
|
adevs[i]->hba->ports[adevs[i]->port].command |= 1 << 28;
|
||||||
|
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,26 +515,26 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
for (i = 0; i < nports; i++)
|
for (i = 0; i < nports; i++)
|
||||||
if (adevs[i])
|
if (adevs[i])
|
||||||
{
|
{
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
|
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP;
|
adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP;
|
||||||
|
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error = ~0;
|
adevs[i]->hba->ports[adevs[i]->port].sata_error = ~0;
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
grub_dprintf ("ahci", "offset: %x, tfd:%x, CMD: %x\n",
|
grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port,
|
||||||
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
|
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
|
||||||
(char *) adevs[i]->hba),
|
(char *) adevs[i]->hba),
|
||||||
adevs[i]->hba->ports[adevs[i]->port].task_file_data,
|
adevs[i]->hba->ports[adevs[i]->port].task_file_data,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command);
|
adevs[i]->hba->ports[adevs[i]->port].command);
|
||||||
|
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,17 +542,19 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
for (i = 0; i < nports; i++)
|
for (i = 0; i < nports; i++)
|
||||||
if (adevs[i])
|
if (adevs[i])
|
||||||
{
|
{
|
||||||
grub_dprintf ("ahci", "offset: %x, tfd:%x, CMD: %x\n",
|
grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port,
|
||||||
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
|
(int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data -
|
||||||
(char *) adevs[i]->hba),
|
(char *) adevs[i]->hba),
|
||||||
adevs[i]->hba->ports[adevs[i]->port].task_file_data,
|
adevs[i]->hba->ports[adevs[i]->port].task_file_data,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command);
|
adevs[i]->hba->ports[adevs[i]->port].command);
|
||||||
|
|
||||||
grub_dprintf ("ahci", "err: %x\n",
|
grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port,
|
||||||
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
adevs[i]->hba->ports[adevs[i]->port].sata_error);
|
||||||
|
|
||||||
adevs[i]->hba->ports[adevs[i]->port].command
|
adevs[i]->hba->ports[adevs[i]->port].command
|
||||||
= (adevs[i]->hba->ports[adevs[i]->port].command & 0x0fffffff) | (1 << 28) | 2 | 4;
|
= (adevs[i]->hba->ports[adevs[i]->port].command & 0x0fffffff) | (1 << 28)
|
||||||
|
| GRUB_AHCI_HBA_PORT_CMD_SPIN_UP
|
||||||
|
| GRUB_AHCI_HBA_PORT_CMD_POWER_ON;
|
||||||
|
|
||||||
/* struct grub_disk_ata_pass_through_parms parms2;
|
/* struct grub_disk_ata_pass_through_parms parms2;
|
||||||
grub_memset (&parms2, 0, sizeof (parms2));
|
grub_memset (&parms2, 0, sizeof (parms2));
|
||||||
|
@ -565,14 +567,14 @@ grub_ahci_pciinit (grub_pci_device_t dev,
|
||||||
while (grub_get_time_ms () < endtime)
|
while (grub_get_time_ms () < endtime)
|
||||||
{
|
{
|
||||||
for (i = 0; i < nports; i++)
|
for (i = 0; i < nports; i++)
|
||||||
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & 0x88))
|
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ)))
|
||||||
break;
|
break;
|
||||||
if (i == nports)
|
if (i == nports)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nports; i++)
|
for (i = 0; i < nports; i++)
|
||||||
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & 0x88))
|
if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ)))
|
||||||
{
|
{
|
||||||
grub_dprintf ("ahci", "port %d is busy\n", i);
|
grub_dprintf ("ahci", "port %d is busy\n", i);
|
||||||
failed_adevs[i] = adevs[i];
|
failed_adevs[i] = adevs[i];
|
||||||
|
@ -1002,7 +1004,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
|
||||||
if (parms->write)
|
if (parms->write)
|
||||||
grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size);
|
grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size);
|
||||||
|
|
||||||
grub_dprintf ("ahci", "AHCI command schedulded\n");
|
grub_dprintf ("ahci", "AHCI command scheduled\n");
|
||||||
grub_dprintf ("ahci", "AHCI tfd = %x\n",
|
grub_dprintf ("ahci", "AHCI tfd = %x\n",
|
||||||
dev->hba->ports[dev->port].task_file_data);
|
dev->hba->ports[dev->port].task_file_data);
|
||||||
grub_dprintf ("ahci", "AHCI inten = %x\n",
|
grub_dprintf ("ahci", "AHCI inten = %x\n",
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
|
||||||
|
|
||||||
struct grub_diskfilter_vg *
|
struct grub_diskfilter_vg *
|
||||||
grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
char *name, grub_uint64_t disk_size,
|
const char *name, grub_uint64_t disk_size,
|
||||||
grub_uint64_t stripe_size,
|
grub_uint64_t stripe_size,
|
||||||
int layout, int level)
|
int layout, int level)
|
||||||
{
|
{
|
||||||
|
|
|
@ -172,7 +172,7 @@ grub_dmraid_nv_detect (grub_disk_t disk,
|
||||||
|
|
||||||
return grub_diskfilter_make_raid (sizeof (sb.array.signature),
|
return grub_diskfilter_make_raid (sizeof (sb.array.signature),
|
||||||
uuid, sb.array.total_volumes,
|
uuid, sb.array.total_volumes,
|
||||||
NULL, disk_size,
|
"nv", disk_size,
|
||||||
sb.array.stripe_block_size,
|
sb.array.stripe_block_size,
|
||||||
GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC,
|
GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC,
|
||||||
level);
|
level);
|
||||||
|
|
|
@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devices;
|
||||||
static struct grub_efidisk_data *hd_devices;
|
static struct grub_efidisk_data *hd_devices;
|
||||||
static struct grub_efidisk_data *cd_devices;
|
static struct grub_efidisk_data *cd_devices;
|
||||||
|
|
||||||
/* Duplicate a device path. */
|
|
||||||
static grub_efi_device_path_t *
|
|
||||||
duplicate_device_path (const grub_efi_device_path_t *dp)
|
|
||||||
{
|
|
||||||
grub_efi_device_path_t *p;
|
|
||||||
grub_size_t total_size = 0;
|
|
||||||
|
|
||||||
for (p = (grub_efi_device_path_t *) dp;
|
|
||||||
;
|
|
||||||
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
|
||||||
{
|
|
||||||
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
|
||||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = grub_malloc (total_size);
|
|
||||||
if (! p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
grub_memcpy (p, dp, total_size);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the device path node right before the end node. */
|
|
||||||
static grub_efi_device_path_t *
|
|
||||||
find_last_device_path (const grub_efi_device_path_t *dp)
|
|
||||||
{
|
|
||||||
grub_efi_device_path_t *next, *p;
|
|
||||||
|
|
||||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
|
|
||||||
! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
|
|
||||||
p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
|
|
||||||
;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grub_efidisk_data *
|
static struct grub_efidisk_data *
|
||||||
make_devices (void)
|
make_devices (void)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +69,7 @@ make_devices (void)
|
||||||
if (! dp)
|
if (! dp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ldp = find_last_device_path (dp);
|
ldp = grub_efi_find_last_device_path (dp);
|
||||||
if (! ldp)
|
if (! ldp)
|
||||||
/* This is empty. Why? */
|
/* This is empty. Why? */
|
||||||
continue;
|
continue;
|
||||||
|
@ -150,11 +109,11 @@ find_parent_device (struct grub_efidisk_data *devices,
|
||||||
grub_efi_device_path_t *dp, *ldp;
|
grub_efi_device_path_t *dp, *ldp;
|
||||||
struct grub_efidisk_data *parent;
|
struct grub_efidisk_data *parent;
|
||||||
|
|
||||||
dp = duplicate_device_path (d->device_path);
|
dp = grub_efi_duplicate_device_path (d->device_path);
|
||||||
if (! dp)
|
if (! dp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ldp = find_last_device_path (dp);
|
ldp = grub_efi_find_last_device_path (dp);
|
||||||
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
ldp->length = sizeof (*ldp);
|
ldp->length = sizeof (*ldp);
|
||||||
|
@ -180,11 +139,11 @@ is_child (struct grub_efidisk_data *child,
|
||||||
grub_efi_device_path_t *dp, *ldp;
|
grub_efi_device_path_t *dp, *ldp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dp = duplicate_device_path (child->device_path);
|
dp = grub_efi_duplicate_device_path (child->device_path);
|
||||||
if (! dp)
|
if (! dp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ldp = find_last_device_path (dp);
|
ldp = grub_efi_find_last_device_path (dp);
|
||||||
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
ldp->length = sizeof (*ldp);
|
ldp->length = sizeof (*ldp);
|
||||||
|
@ -207,8 +166,8 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
|
ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path),
|
||||||
find_last_device_path (d->device_path));
|
grub_efi_find_last_device_path (d->device_path));
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = grub_efi_compare_device_paths ((*p)->device_path,
|
ret = grub_efi_compare_device_paths ((*p)->device_path,
|
||||||
d->device_path);
|
d->device_path);
|
||||||
|
@ -795,7 +754,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
if (! dp)
|
if (! dp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ldp = find_last_device_path (dp);
|
ldp = grub_efi_find_last_device_path (dp);
|
||||||
if (! ldp)
|
if (! ldp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -810,14 +769,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
|
|
||||||
/* It is necessary to duplicate the device path so that GRUB
|
/* It is necessary to duplicate the device path so that GRUB
|
||||||
can overwrite it. */
|
can overwrite it. */
|
||||||
dup_dp = duplicate_device_path (dp);
|
dup_dp = grub_efi_duplicate_device_path (dp);
|
||||||
if (! dup_dp)
|
if (! dup_dp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
grub_efi_device_path_t *dup_ldp;
|
grub_efi_device_path_t *dup_ldp;
|
||||||
dup_ldp = find_last_device_path (dup_dp);
|
dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||||
if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
||||||
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|
||||||
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
|
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
|
||||||
|
|
|
@ -160,7 +160,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
"we don't support multiple LVM data areas");
|
"we don't support multiple LVM data areas");
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("we don't support multiple LVM data areas\n");
|
grub_util_info ("we don't support multiple LVM data areas");
|
||||||
#endif
|
#endif
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"unknown LVM metadata header");
|
"unknown LVM metadata header");
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown LVM metadata header\n");
|
grub_util_info ("unknown LVM metadata header");
|
||||||
#endif
|
#endif
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (q == metadatabuf + mda_size)
|
if (q == metadatabuf + mda_size)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("error parsing metadata\n");
|
grub_util_info ("error parsing metadata");
|
||||||
#endif
|
#endif
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("couldn't find ID\n");
|
grub_util_info ("couldn't find ID");
|
||||||
#endif
|
#endif
|
||||||
goto fail3;
|
goto fail3;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown extent size\n");
|
grub_util_info ("unknown extent size");
|
||||||
#endif
|
#endif
|
||||||
goto fail4;
|
goto fail4;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown pe_start\n");
|
grub_util_info ("unknown pe_start");
|
||||||
#endif
|
#endif
|
||||||
goto pvs_fail;
|
goto pvs_fail;
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("error parsing pe_start\n");
|
grub_util_info ("error parsing pe_start");
|
||||||
#endif
|
#endif
|
||||||
goto pvs_fail;
|
goto pvs_fail;
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("couldn't find ID\n");
|
grub_util_info ("couldn't find ID");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_fail;
|
goto lvs_fail;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown segment_count\n");
|
grub_util_info ("unknown segment_count");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_fail;
|
goto lvs_fail;
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown segment\n");
|
grub_util_info ("unknown segment");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown start_extent\n");
|
grub_util_info ("unknown start_extent");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown extent_count\n");
|
grub_util_info ("unknown extent_count");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +475,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown stripe_count\n");
|
grub_util_info ("unknown stripe_count");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -491,7 +491,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown stripes\n");
|
grub_util_info ("unknown stripes");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail2;
|
goto lvs_segment_fail2;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown mirror_count\n");
|
grub_util_info ("unknown mirror_count");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -545,7 +545,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown mirrors\n");
|
grub_util_info ("unknown mirrors");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail2;
|
goto lvs_segment_fail2;
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown device_count\n");
|
grub_util_info ("unknown device_count");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -618,7 +618,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown stripe_size\n");
|
grub_util_info ("unknown stripe_size");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail;
|
goto lvs_segment_fail;
|
||||||
}
|
}
|
||||||
|
@ -631,7 +631,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("unknown raids\n");
|
grub_util_info ("unknown raids");
|
||||||
#endif
|
#endif
|
||||||
goto lvs_segment_fail2;
|
goto lvs_segment_fail2;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
p2 = grub_strchr (p, '"');
|
p2 = grub_strchr (p, '"');
|
||||||
if (p2)
|
if (p2)
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
grub_util_info ("unknown LVM type %s\n", p);
|
grub_util_info ("unknown LVM type %s", p);
|
||||||
if (p2)
|
if (p2)
|
||||||
*p2 ='"';
|
*p2 ='"';
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -615,9 +615,10 @@ grub_scsi_open (const char *name, grub_disk_t disk)
|
||||||
|
|
||||||
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
|
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
|
||||||
{
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "invalid sector size %d",
|
||||||
|
scsi->blocksize);
|
||||||
grub_free (scsi);
|
grub_free (scsi);
|
||||||
return grub_error (GRUB_ERR_IO, "invalid sector size %d",
|
return grub_errno;
|
||||||
scsi->blocksize);
|
|
||||||
}
|
}
|
||||||
for (disk->log_sector_size = 0;
|
for (disk->log_sector_size = 0;
|
||||||
(1U << disk->log_sector_size) < scsi->blocksize;
|
(1U << disk->log_sector_size) < scsi->blocksize;
|
||||||
|
|
|
@ -34,12 +34,12 @@ canonicalize (char *name)
|
||||||
iptr++;
|
iptr++;
|
||||||
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
|
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
|
||||||
{
|
{
|
||||||
iptr += 2;
|
iptr++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
|
if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
|
||||||
{
|
{
|
||||||
iptr += 3;
|
iptr += 2;
|
||||||
if (optr == name)
|
if (optr == name)
|
||||||
continue;
|
continue;
|
||||||
for (optr -= 2; optr >= name && *optr != '/'; optr--);
|
for (optr -= 2; optr >= name && *optr != '/'; optr--);
|
||||||
|
@ -249,9 +249,10 @@ grub_archelp_open (struct grub_archelp_data *data,
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
grub_uint32_t mode;
|
grub_uint32_t mode;
|
||||||
|
grub_int32_t mtime;
|
||||||
int restart;
|
int restart;
|
||||||
|
|
||||||
if (arcops->find_file (data, &fn, NULL, &mode))
|
if (arcops->find_file (data, &fn, &mtime, &mode))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (mode == GRUB_ARCHELP_ATTR_END)
|
if (mode == GRUB_ARCHELP_ATTR_END)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/fshelp.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -561,10 +562,10 @@ iterate_in_b_tree (grub_disk_t disk,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bfs_strcmp (const char *a, const char *b, grub_size_t alen, grub_size_t blen)
|
bfs_strcmp (const char *a, const char *b, grub_size_t alen)
|
||||||
{
|
{
|
||||||
char ac, bc;
|
char ac, bc;
|
||||||
while (blen && alen)
|
while (*b && alen)
|
||||||
{
|
{
|
||||||
if (*a != *b)
|
if (*a != *b)
|
||||||
break;
|
break;
|
||||||
|
@ -572,11 +573,10 @@ bfs_strcmp (const char *a, const char *b, grub_size_t alen, grub_size_t blen)
|
||||||
a++;
|
a++;
|
||||||
b++;
|
b++;
|
||||||
alen--;
|
alen--;
|
||||||
blen--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ac = alen ? *a : 0;
|
ac = alen ? *a : 0;
|
||||||
bc = blen ? *b : 0;
|
bc = *b;
|
||||||
|
|
||||||
#ifdef MODE_AFS
|
#ifdef MODE_AFS
|
||||||
return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc;
|
return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc;
|
||||||
|
@ -589,7 +589,6 @@ static grub_err_t
|
||||||
find_in_b_tree (grub_disk_t disk,
|
find_in_b_tree (grub_disk_t disk,
|
||||||
const struct grub_bfs_superblock *sb,
|
const struct grub_bfs_superblock *sb,
|
||||||
const struct grub_bfs_inode *ino, const char *name,
|
const struct grub_bfs_inode *ino, const char *name,
|
||||||
grub_size_t name_len,
|
|
||||||
grub_uint64_t * res)
|
grub_uint64_t * res)
|
||||||
{
|
{
|
||||||
struct grub_bfs_btree_header head;
|
struct grub_bfs_btree_header head;
|
||||||
|
@ -637,7 +636,7 @@ find_in_b_tree (grub_disk_t disk,
|
||||||
end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]);
|
end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]);
|
||||||
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
|
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
|
||||||
end = grub_bfs_to_cpu_treehead (node->total_key_len);
|
end = grub_bfs_to_cpu_treehead (node->total_key_len);
|
||||||
cmp = bfs_strcmp (key_data + start, name, end - start, name_len);
|
cmp = bfs_strcmp (key_data + start, name, end - start);
|
||||||
if (cmp == 0 && level == 0)
|
if (cmp == 0 && level == 0)
|
||||||
{
|
{
|
||||||
*res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val);
|
*res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val);
|
||||||
|
@ -658,7 +657,7 @@ find_in_b_tree (grub_disk_t disk,
|
||||||
end = grub_bfs_to_cpu16 (keylen_idx[0]);
|
end = grub_bfs_to_cpu16 (keylen_idx[0]);
|
||||||
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
|
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
|
||||||
end = grub_bfs_to_cpu_treehead (node->total_key_len);
|
end = grub_bfs_to_cpu_treehead (node->total_key_len);
|
||||||
cmp = bfs_strcmp (key_data, name, end, name_len);
|
cmp = bfs_strcmp (key_data, name, end);
|
||||||
if (cmp == 0 && level == 0)
|
if (cmp == 0 && level == 0)
|
||||||
{
|
{
|
||||||
*res = grub_bfs_to_cpu64 (key_values[0].val);
|
*res = grub_bfs_to_cpu64 (key_values[0].val);
|
||||||
|
@ -707,127 +706,119 @@ find_in_b_tree (grub_disk_t disk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct grub_fshelp_node
|
||||||
|
{
|
||||||
|
grub_disk_t disk;
|
||||||
|
const struct grub_bfs_superblock *sb;
|
||||||
|
struct grub_bfs_inode ino;
|
||||||
|
};
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
hop_level (grub_disk_t disk,
|
lookup_file (grub_fshelp_node_t dir,
|
||||||
const struct grub_bfs_superblock *sb,
|
const char *name,
|
||||||
struct grub_bfs_inode *ino, const char *name,
|
grub_fshelp_node_t *foundnode,
|
||||||
const char *name_end)
|
enum grub_fshelp_filetype *foundtype)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
struct grub_bfs_inode *new_ino;
|
||||||
grub_uint64_t res = 0;
|
grub_uint64_t res = 0;
|
||||||
|
|
||||||
if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) != ATTR_DIR))
|
err = find_in_b_tree (dir->disk, dir->sb, &dir->ino, name, &res);
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
|
|
||||||
err = find_in_b_tree (disk, sb, ino, name, name_end - name, &res);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return grub_disk_read (disk, res
|
*foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||||
<< (grub_bfs_to_cpu32 (sb->log2_bsize)
|
if (!*foundnode)
|
||||||
- GRUB_DISK_SECTOR_BITS), 0,
|
return grub_errno;
|
||||||
sizeof (*ino), (char *) ino);
|
|
||||||
|
(*foundnode)->disk = dir->disk;
|
||||||
|
(*foundnode)->sb = dir->sb;
|
||||||
|
new_ino = &(*foundnode)->ino;
|
||||||
|
|
||||||
|
if (grub_disk_read (dir->disk, res
|
||||||
|
<< (grub_bfs_to_cpu32 (dir->sb->log2_bsize)
|
||||||
|
- GRUB_DISK_SECTOR_BITS), 0,
|
||||||
|
sizeof (*new_ino), (char *) new_ino))
|
||||||
|
{
|
||||||
|
grub_free (*foundnode);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
switch (grub_bfs_to_cpu32 (new_ino->mode) & ATTR_TYPE)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case ATTR_REG:
|
||||||
|
*foundtype = GRUB_FSHELP_REG;
|
||||||
|
break;
|
||||||
|
case ATTR_DIR:
|
||||||
|
*foundtype = GRUB_FSHELP_DIR;
|
||||||
|
break;
|
||||||
|
case ATTR_LNK:
|
||||||
|
*foundtype = GRUB_FSHELP_SYMLINK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_symlink (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
char *alloc = NULL;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
#ifndef MODE_AFS
|
||||||
|
if (!(grub_bfs_to_cpu32 (node->ino.flags) & LONG_SYMLINK))
|
||||||
|
{
|
||||||
|
alloc = grub_malloc (sizeof (node->ino.inplace_link) + 1);
|
||||||
|
if (!alloc)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
grub_memcpy (alloc, node->ino.inplace_link,
|
||||||
|
sizeof (node->ino.inplace_link));
|
||||||
|
alloc[sizeof (node->ino.inplace_link)] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
grub_size_t symsize = grub_bfs_to_cpu64 (node->ino.size);
|
||||||
|
alloc = grub_malloc (symsize + 1);
|
||||||
|
if (!alloc)
|
||||||
|
return NULL;
|
||||||
|
err = read_bfs_file (node->disk, node->sb, &node->ino, 0, alloc, symsize, 0, 0);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (alloc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
alloc[symsize] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
find_file (const char *path, grub_disk_t disk,
|
find_file (const char *path, grub_disk_t disk,
|
||||||
const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino)
|
const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino,
|
||||||
|
enum grub_fshelp_filetype exptype)
|
||||||
{
|
{
|
||||||
const char *ptr, *next = path;
|
|
||||||
char *alloc = NULL;
|
|
||||||
char *wptr;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
struct grub_bfs_inode old_ino;
|
struct grub_fshelp_node root = {
|
||||||
unsigned symlinks_max = 32;
|
.disk = disk,
|
||||||
|
.sb = sb,
|
||||||
|
};
|
||||||
|
struct grub_fshelp_node *found;
|
||||||
|
|
||||||
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino,
|
err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino,
|
||||||
sizeof (*ino));
|
sizeof (root.ino));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, read_symlink, exptype);
|
||||||
|
if (!err)
|
||||||
|
grub_memcpy (ino, &found->ino, sizeof (*ino));
|
||||||
|
|
||||||
while (1)
|
if (&root != found)
|
||||||
{
|
grub_free (found);
|
||||||
ptr = next;
|
return err;
|
||||||
while (*ptr == '/')
|
|
||||||
ptr++;
|
|
||||||
if (*ptr == 0)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
for (next = ptr; *next && *next != '/'; next++);
|
|
||||||
grub_memcpy (&old_ino, ino, sizeof (old_ino));
|
|
||||||
err = hop_level (disk, sb, ino, ptr, next);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) == ATTR_LNK))
|
|
||||||
{
|
|
||||||
char *old_alloc = alloc;
|
|
||||||
if (--symlinks_max == 0)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP,
|
|
||||||
N_("too deep nesting of symlinks"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MODE_AFS
|
|
||||||
if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
grub_size_t symsize = grub_bfs_to_cpu64 (ino->size);
|
|
||||||
alloc = grub_malloc (grub_strlen (next)
|
|
||||||
+ symsize + 1);
|
|
||||||
if (!alloc)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
grub_free (old_alloc);
|
|
||||||
err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0, 0);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
alloc[symsize] = 0;
|
|
||||||
}
|
|
||||||
#ifndef MODE_AFS
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alloc = grub_malloc (grub_strlen (next)
|
|
||||||
+ sizeof (ino->inplace_link) + 1);
|
|
||||||
if (!alloc)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
grub_free (old_alloc);
|
|
||||||
grub_memcpy (alloc, ino->inplace_link,
|
|
||||||
sizeof (ino->inplace_link));
|
|
||||||
alloc[sizeof (ino->inplace_link)] = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (alloc[0] == '/')
|
|
||||||
{
|
|
||||||
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino,
|
|
||||||
sizeof (*ino));
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
grub_free (alloc);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grub_memcpy (ino, &old_ino, sizeof (old_ino));
|
|
||||||
wptr = alloc + grub_strlen (alloc);
|
|
||||||
if (next)
|
|
||||||
wptr = grub_stpcpy (wptr, next);
|
|
||||||
*wptr = 0;
|
|
||||||
next = alloc;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -909,11 +900,9 @@ grub_bfs_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
{
|
{
|
||||||
struct grub_bfs_inode ino;
|
struct grub_bfs_inode ino;
|
||||||
err = find_file (path, device->disk, &ctx.sb, &ino);
|
err = find_file (path, device->disk, &ctx.sb, &ino, GRUB_FSHELP_DIR);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_DIR))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter,
|
iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter,
|
||||||
&ctx);
|
&ctx);
|
||||||
}
|
}
|
||||||
|
@ -934,11 +923,9 @@ grub_bfs_open (struct grub_file *file, const char *name)
|
||||||
{
|
{
|
||||||
struct grub_bfs_inode ino;
|
struct grub_bfs_inode ino;
|
||||||
struct grub_bfs_data *data;
|
struct grub_bfs_data *data;
|
||||||
err = find_file (name, file->device->disk, &sb, &ino);
|
err = find_file (name, file->device->disk, &sb, &ino, GRUB_FSHELP_REG);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_REG))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
|
|
||||||
|
|
||||||
data = grub_zalloc (sizeof (struct grub_bfs_data));
|
data = grub_zalloc (sizeof (struct grub_bfs_data));
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -1034,7 +1021,7 @@ read_bfs_attr (grub_disk_t disk,
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
err = find_in_b_tree (disk, sb, ino, name, grub_strlen (name), &res);
|
err = find_in_b_tree (disk, sb, ino, name, &res);
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
grub_disk_read (disk, res
|
grub_disk_read (disk, res
|
||||||
|
|
|
@ -538,8 +538,9 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
shift = 2;
|
shift = 2;
|
||||||
goto indirect;
|
goto indirect;
|
||||||
}
|
}
|
||||||
return grub_error (GRUB_ERR_BAD_FS,
|
grub_error (GRUB_ERR_BAD_FS,
|
||||||
"ext2fs doesn't support quadruple indirect blocks");
|
"ext2fs doesn't support quadruple indirect blocks");
|
||||||
|
return -1;
|
||||||
|
|
||||||
indirect:
|
indirect:
|
||||||
do {
|
do {
|
||||||
|
@ -554,7 +555,7 @@ indirect:
|
||||||
& ((1 << log_perblock) - 1))
|
& ((1 << log_perblock) - 1))
|
||||||
* sizeof (indir),
|
* sizeof (indir),
|
||||||
sizeof (indir), &indir))
|
sizeof (indir), &indir))
|
||||||
return grub_errno;
|
return -1;
|
||||||
} while (shift--);
|
} while (shift--);
|
||||||
|
|
||||||
return grub_le_to_cpu32 (indir);
|
return grub_le_to_cpu32 (indir);
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#else
|
#else
|
||||||
#include <grub/exfat.h>
|
#include <grub/exfat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <grub/fshelp.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
@ -173,8 +174,6 @@ struct grub_fat_data
|
||||||
#ifndef MODE_EXFAT
|
#ifndef MODE_EXFAT
|
||||||
grub_uint32_t root_sector;
|
grub_uint32_t root_sector;
|
||||||
grub_uint32_t num_root_sectors;
|
grub_uint32_t num_root_sectors;
|
||||||
#else
|
|
||||||
int is_contiguous;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int cluster_bits;
|
int cluster_bits;
|
||||||
|
@ -182,13 +181,22 @@ struct grub_fat_data
|
||||||
grub_uint32_t cluster_sector;
|
grub_uint32_t cluster_sector;
|
||||||
grub_uint32_t num_clusters;
|
grub_uint32_t num_clusters;
|
||||||
|
|
||||||
|
grub_uint32_t uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_fshelp_node {
|
||||||
|
grub_disk_t disk;
|
||||||
|
struct grub_fat_data *data;
|
||||||
|
|
||||||
grub_uint8_t attr;
|
grub_uint8_t attr;
|
||||||
grub_ssize_t file_size;
|
grub_ssize_t file_size;
|
||||||
grub_uint32_t file_cluster;
|
grub_uint32_t file_cluster;
|
||||||
grub_uint32_t cur_cluster_num;
|
grub_uint32_t cur_cluster_num;
|
||||||
grub_uint32_t cur_cluster;
|
grub_uint32_t cur_cluster;
|
||||||
|
|
||||||
grub_uint32_t uuid;
|
#ifdef MODE_EXFAT
|
||||||
|
int is_contiguous;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
@ -427,13 +435,6 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
(void) magic;
|
(void) magic;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start from the root directory. */
|
|
||||||
data->file_cluster = data->root_cluster;
|
|
||||||
data->cur_cluster_num = ~0U;
|
|
||||||
data->attr = GRUB_FAT_ATTR_DIRECTORY;
|
|
||||||
#ifdef MODE_EXFAT
|
|
||||||
data->is_contiguous = 0;
|
|
||||||
#endif
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -444,7 +445,7 @@ grub_fat_mount (grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_read_data (grub_disk_t disk, grub_fshelp_node_t node,
|
||||||
grub_disk_read_hook_t read_hook, void *read_hook_data,
|
grub_disk_read_hook_t read_hook, void *read_hook_data,
|
||||||
grub_off_t offset, grub_size_t len, char *buf)
|
grub_off_t offset, grub_size_t len, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -457,13 +458,13 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
#ifndef MODE_EXFAT
|
#ifndef MODE_EXFAT
|
||||||
/* This is a special case. FAT12 and FAT16 doesn't have the root directory
|
/* This is a special case. FAT12 and FAT16 doesn't have the root directory
|
||||||
in clusters. */
|
in clusters. */
|
||||||
if (data->file_cluster == ~0U)
|
if (node->file_cluster == ~0U)
|
||||||
{
|
{
|
||||||
size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
|
size = (node->data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
|
||||||
if (size > len)
|
if (size > len)
|
||||||
size = len;
|
size = len;
|
||||||
|
|
||||||
if (grub_disk_read (disk, data->root_sector, offset, size, buf))
|
if (grub_disk_read (disk, node->data->root_sector, offset, size, buf))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
@ -471,12 +472,12 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
if (data->is_contiguous)
|
if (node->is_contiguous)
|
||||||
{
|
{
|
||||||
/* Read the data here. */
|
/* Read the data here. */
|
||||||
sector = (data->cluster_sector
|
sector = (node->data->cluster_sector
|
||||||
+ ((data->file_cluster - 2)
|
+ ((node->file_cluster - 2)
|
||||||
<< data->cluster_bits));
|
<< node->data->cluster_bits));
|
||||||
|
|
||||||
disk->read_hook = read_hook;
|
disk->read_hook = read_hook;
|
||||||
disk->read_hook_data = read_hook_data;
|
disk->read_hook_data = read_hook_data;
|
||||||
|
@ -491,53 +492,53 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate the logical cluster number and offset. */
|
/* Calculate the logical cluster number and offset. */
|
||||||
logical_cluster_bits = (data->cluster_bits
|
logical_cluster_bits = (node->data->cluster_bits
|
||||||
+ GRUB_DISK_SECTOR_BITS);
|
+ GRUB_DISK_SECTOR_BITS);
|
||||||
logical_cluster = offset >> logical_cluster_bits;
|
logical_cluster = offset >> logical_cluster_bits;
|
||||||
offset &= (1ULL << logical_cluster_bits) - 1;
|
offset &= (1ULL << logical_cluster_bits) - 1;
|
||||||
|
|
||||||
if (logical_cluster < data->cur_cluster_num)
|
if (logical_cluster < node->cur_cluster_num)
|
||||||
{
|
{
|
||||||
data->cur_cluster_num = 0;
|
node->cur_cluster_num = 0;
|
||||||
data->cur_cluster = data->file_cluster;
|
node->cur_cluster = node->file_cluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
while (logical_cluster > data->cur_cluster_num)
|
while (logical_cluster > node->cur_cluster_num)
|
||||||
{
|
{
|
||||||
/* Find next cluster. */
|
/* Find next cluster. */
|
||||||
grub_uint32_t next_cluster;
|
grub_uint32_t next_cluster;
|
||||||
grub_uint32_t fat_offset;
|
grub_uint32_t fat_offset;
|
||||||
|
|
||||||
switch (data->fat_size)
|
switch (node->data->fat_size)
|
||||||
{
|
{
|
||||||
case 32:
|
case 32:
|
||||||
fat_offset = data->cur_cluster << 2;
|
fat_offset = node->cur_cluster << 2;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
fat_offset = data->cur_cluster << 1;
|
fat_offset = node->cur_cluster << 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* case 12: */
|
/* case 12: */
|
||||||
fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
|
fat_offset = node->cur_cluster + (node->cur_cluster >> 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the FAT. */
|
/* Read the FAT. */
|
||||||
if (grub_disk_read (disk, data->fat_sector, fat_offset,
|
if (grub_disk_read (disk, node->data->fat_sector, fat_offset,
|
||||||
(data->fat_size + 7) >> 3,
|
(node->data->fat_size + 7) >> 3,
|
||||||
(char *) &next_cluster))
|
(char *) &next_cluster))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
next_cluster = grub_le_to_cpu32 (next_cluster);
|
next_cluster = grub_le_to_cpu32 (next_cluster);
|
||||||
switch (data->fat_size)
|
switch (node->data->fat_size)
|
||||||
{
|
{
|
||||||
case 16:
|
case 16:
|
||||||
next_cluster &= 0xFFFF;
|
next_cluster &= 0xFFFF;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
if (data->cur_cluster & 1)
|
if (node->cur_cluster & 1)
|
||||||
next_cluster >>= 4;
|
next_cluster >>= 4;
|
||||||
|
|
||||||
next_cluster &= 0x0FFF;
|
next_cluster &= 0x0FFF;
|
||||||
|
@ -545,27 +546,27 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
|
grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
|
||||||
data->fat_size, next_cluster);
|
node->data->fat_size, next_cluster);
|
||||||
|
|
||||||
/* Check the end. */
|
/* Check the end. */
|
||||||
if (next_cluster >= data->cluster_eof_mark)
|
if (next_cluster >= node->data->cluster_eof_mark)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (next_cluster < 2 || next_cluster >= data->num_clusters)
|
if (next_cluster < 2 || next_cluster >= node->data->num_clusters)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
|
grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
|
||||||
next_cluster);
|
next_cluster);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->cur_cluster = next_cluster;
|
node->cur_cluster = next_cluster;
|
||||||
data->cur_cluster_num++;
|
node->cur_cluster_num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the data here. */
|
/* Read the data here. */
|
||||||
sector = (data->cluster_sector
|
sector = (node->data->cluster_sector
|
||||||
+ ((data->cur_cluster - 2)
|
+ ((node->cur_cluster - 2)
|
||||||
<< data->cluster_bits));
|
<< node->data->cluster_bits));
|
||||||
size = (1 << logical_cluster_bits) - offset;
|
size = (1 << logical_cluster_bits) - offset;
|
||||||
if (size > len)
|
if (size > len)
|
||||||
size = len;
|
size = len;
|
||||||
|
@ -631,7 +632,7 @@ grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt)
|
||||||
|
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
struct grub_fat_iterate_context *ctxt)
|
struct grub_fat_iterate_context *ctxt)
|
||||||
{
|
{
|
||||||
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
||||||
|
@ -641,7 +642,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
ctxt->offset += sizeof (dir);
|
ctxt->offset += sizeof (dir);
|
||||||
|
|
||||||
if (grub_fat_read_data (disk, data, 0, 0, ctxt->offset, sizeof (dir),
|
if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir),
|
||||||
(char *) &dir)
|
(char *) &dir)
|
||||||
!= sizeof (dir))
|
!= sizeof (dir))
|
||||||
break;
|
break;
|
||||||
|
@ -663,7 +664,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry sec;
|
struct grub_fat_dir_entry sec;
|
||||||
ctxt->offset += sizeof (sec);
|
ctxt->offset += sizeof (sec);
|
||||||
if (grub_fat_read_data (disk, data, 0, 0,
|
if (grub_fat_read_data (node->disk, node, 0, 0,
|
||||||
ctxt->offset, sizeof (sec), (char *) &sec)
|
ctxt->offset, sizeof (sec), (char *) &sec)
|
||||||
!= sizeof (sec))
|
!= sizeof (sec))
|
||||||
break;
|
break;
|
||||||
|
@ -727,7 +728,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
struct grub_fat_iterate_context *ctxt)
|
struct grub_fat_iterate_context *ctxt)
|
||||||
{
|
{
|
||||||
char *filep = 0;
|
char *filep = 0;
|
||||||
|
@ -742,7 +743,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
ctxt->offset += sizeof (ctxt->dir);
|
ctxt->offset += sizeof (ctxt->dir);
|
||||||
|
|
||||||
/* Read a directory entry. */
|
/* Read a directory entry. */
|
||||||
if (grub_fat_read_data (disk, data, 0, 0,
|
if (grub_fat_read_data (node->disk, node, 0, 0,
|
||||||
ctxt->offset, sizeof (ctxt->dir),
|
ctxt->offset, sizeof (ctxt->dir),
|
||||||
(char *) &ctxt->dir)
|
(char *) &ctxt->dir)
|
||||||
!= sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
|
!= sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
|
||||||
|
@ -829,7 +830,9 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
*filep++ = '.';
|
/* XXX should we check that dir position is 0 or 1? */
|
||||||
|
if (i > 2 || filep[0] != '.' || (i == 2 && filep[1] != '.'))
|
||||||
|
*filep++ = '.';
|
||||||
|
|
||||||
for (i = 8; i < 11 && ctxt->dir.name[i]; i++)
|
for (i = 8; i < 11 && ctxt->dir.name[i]; i++)
|
||||||
*filep++ = grub_tolower (ctxt->dir.name[i]);
|
*filep++ = grub_tolower (ctxt->dir.name[i]);
|
||||||
|
@ -851,62 +854,20 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find the underlying directory or file in PATH and return the
|
static grub_err_t lookup_file (grub_fshelp_node_t node,
|
||||||
next path. If there is no next path or an error occurs, return NULL.
|
const char *name,
|
||||||
If HOOK is specified, call it with each file name. */
|
grub_fshelp_node_t *foundnode,
|
||||||
static char *
|
enum grub_fshelp_filetype *foundtype)
|
||||||
grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
|
||||||
const char *path, const char *origpath,
|
|
||||||
grub_fs_dir_hook_t hook, void *hook_data)
|
|
||||||
{
|
{
|
||||||
char *dirname, *dirp;
|
|
||||||
int call_hook;
|
|
||||||
int found = 0;
|
|
||||||
struct grub_fat_iterate_context ctxt;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
struct grub_fat_iterate_context ctxt;
|
||||||
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract a directory name. */
|
|
||||||
while (*path == '/')
|
|
||||||
path++;
|
|
||||||
|
|
||||||
dirp = grub_strchr (path, '/');
|
|
||||||
if (dirp)
|
|
||||||
{
|
|
||||||
unsigned len = dirp - path;
|
|
||||||
|
|
||||||
dirname = grub_malloc (len + 1);
|
|
||||||
if (! dirname)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
grub_memcpy (dirname, path, len);
|
|
||||||
dirname[len] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* This is actually a file. */
|
|
||||||
dirname = grub_strdup (path);
|
|
||||||
|
|
||||||
call_hook = (! dirp && hook);
|
|
||||||
|
|
||||||
err = grub_fat_iterate_init (&ctxt);
|
err = grub_fat_iterate_init (&ctxt);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
return err;
|
||||||
grub_free (dirname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt)))
|
while (!(err = grub_fat_iterate_dir_next (node, &ctxt)))
|
||||||
{
|
{
|
||||||
struct grub_dirhook_info info;
|
|
||||||
grub_memset (&info, 0, sizeof (info));
|
|
||||||
|
|
||||||
info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
|
|
||||||
info.case_insensitive = 1;
|
|
||||||
|
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
if (!ctxt.dir.have_stream)
|
if (!ctxt.dir.have_stream)
|
||||||
|
@ -915,33 +876,33 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if (*dirname == '\0' && call_hook)
|
|
||||||
{
|
|
||||||
if (hook (ctxt.filename, &info, hook_data))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_strcasecmp (dirname, ctxt.filename) == 0)
|
if (grub_strcasecmp (name, ctxt.filename) == 0)
|
||||||
{
|
{
|
||||||
found = 1;
|
*foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||||
data->attr = ctxt.dir.attr;
|
if (!*foundnode)
|
||||||
|
return grub_errno;
|
||||||
|
(*foundnode)->attr = ctxt.dir.attr;
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
data->file_size = ctxt.dir.file_size;
|
(*foundnode)->file_size = ctxt.dir.file_size;
|
||||||
data->file_cluster = ctxt.dir.first_cluster;
|
(*foundnode)->file_cluster = ctxt.dir.first_cluster;
|
||||||
data->is_contiguous = ctxt.dir.is_contiguous;
|
(*foundnode)->is_contiguous = ctxt.dir.is_contiguous;
|
||||||
#else
|
#else
|
||||||
data->file_size = grub_le_to_cpu32 (ctxt.dir.file_size);
|
(*foundnode)->file_size = grub_le_to_cpu32 (ctxt.dir.file_size);
|
||||||
data->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16)
|
(*foundnode)->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16)
|
||||||
| grub_le_to_cpu16 (ctxt.dir.first_cluster_low));
|
| grub_le_to_cpu16 (ctxt.dir.first_cluster_low));
|
||||||
|
/* If directory points to root, starting cluster is 0 */
|
||||||
|
if (!(*foundnode)->file_cluster)
|
||||||
|
(*foundnode)->file_cluster = node->data->root_cluster;
|
||||||
#endif
|
#endif
|
||||||
data->cur_cluster_num = ~0U;
|
(*foundnode)->cur_cluster_num = ~0U;
|
||||||
|
(*foundnode)->data = node->data;
|
||||||
|
(*foundnode)->disk = node->disk;
|
||||||
|
|
||||||
if (call_hook)
|
*foundtype = ((*foundnode)->attr & GRUB_FAT_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
|
||||||
hook (ctxt.filename, &info, hook_data);
|
|
||||||
|
|
||||||
break;
|
grub_fat_iterate_fini (&ctxt);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,13 +910,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
|
||||||
if (err == GRUB_ERR_EOF)
|
if (err == GRUB_ERR_EOF)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
|
return err;
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_free (dirname);
|
|
||||||
|
|
||||||
return found ? dirp : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -964,9 +920,9 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||||
{
|
{
|
||||||
struct grub_fat_data *data = 0;
|
struct grub_fat_data *data = 0;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
grub_size_t len;
|
grub_fshelp_node_t found = NULL;
|
||||||
char *dirname = 0;
|
grub_err_t err;
|
||||||
char *p;
|
struct grub_fat_iterate_context ctxt;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -974,27 +930,53 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||||
if (! data)
|
if (! data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Make sure that DIRNAME terminates with '/'. */
|
struct grub_fshelp_node root = {
|
||||||
len = grub_strlen (path);
|
.data = data,
|
||||||
dirname = grub_malloc (len + 1 + 1);
|
.disk = disk,
|
||||||
if (! dirname)
|
.attr = GRUB_FAT_ATTR_DIRECTORY,
|
||||||
goto fail;
|
.file_size = 0,
|
||||||
grub_memcpy (dirname, path, len);
|
.file_cluster = data->root_cluster,
|
||||||
p = dirname + len;
|
.cur_cluster_num = ~0U,
|
||||||
if (path[len - 1] != '/')
|
.cur_cluster = 0,
|
||||||
*p++ = '/';
|
#ifdef MODE_EXFAT
|
||||||
*p = '\0';
|
.is_contiguous = 0,
|
||||||
p = dirname;
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
do
|
err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, NULL, GRUB_FSHELP_DIR);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
err = grub_fat_iterate_init (&ctxt);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
while (!(err = grub_fat_iterate_dir_next (found, &ctxt)))
|
||||||
{
|
{
|
||||||
p = grub_fat_find_dir (disk, data, p, path, hook, hook_data);
|
struct grub_dirhook_info info;
|
||||||
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
|
info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
|
||||||
|
info.case_insensitive = 1;
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
if (!ctxt.dir.have_stream)
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hook (ctxt.filename, &info, hook_data))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
while (p && grub_errno == GRUB_ERR_NONE);
|
grub_fat_iterate_fini (&ctxt);
|
||||||
|
if (err == GRUB_ERR_EOF)
|
||||||
|
err = 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (found != &root)
|
||||||
|
grub_free (found);
|
||||||
|
|
||||||
grub_free (dirname);
|
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
@ -1006,35 +988,43 @@ static grub_err_t
|
||||||
grub_fat_open (grub_file_t file, const char *name)
|
grub_fat_open (grub_file_t file, const char *name)
|
||||||
{
|
{
|
||||||
struct grub_fat_data *data = 0;
|
struct grub_fat_data *data = 0;
|
||||||
char *p = (char *) name;
|
grub_fshelp_node_t found = NULL;
|
||||||
|
grub_err_t err;
|
||||||
|
grub_disk_t disk = file->device->disk;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
data = grub_fat_mount (file->device->disk);
|
data = grub_fat_mount (disk);
|
||||||
if (! data)
|
if (! data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
do
|
struct grub_fshelp_node root = {
|
||||||
{
|
.data = data,
|
||||||
p = grub_fat_find_dir (file->device->disk, data, p, name, 0, 0);
|
.disk = disk,
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
.attr = GRUB_FAT_ATTR_DIRECTORY,
|
||||||
goto fail;
|
.file_size = 0,
|
||||||
}
|
.file_cluster = data->root_cluster,
|
||||||
while (p);
|
.cur_cluster_num = ~0U,
|
||||||
|
.cur_cluster = 0,
|
||||||
|
#ifdef MODE_EXFAT
|
||||||
|
.is_contiguous = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
if (data->attr & GRUB_FAT_ATTR_DIRECTORY)
|
err = grub_fshelp_find_file_lookup (name, &root, &found, lookup_file, NULL, GRUB_FSHELP_REG);
|
||||||
{
|
if (err)
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
|
goto fail;
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->data = data;
|
file->data = found;
|
||||||
file->size = data->file_size;
|
file->size = found->file_size;
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
|
if (found != &root)
|
||||||
|
grub_free (found);
|
||||||
|
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
@ -1053,7 +1043,10 @@ grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_close (grub_file_t file)
|
grub_fat_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
grub_fshelp_node_t node = file->data;
|
||||||
|
|
||||||
|
grub_free (node->data);
|
||||||
|
grub_free (node);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
@ -1066,20 +1059,29 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry dir;
|
struct grub_fat_dir_entry dir;
|
||||||
grub_ssize_t offset = -sizeof(dir);
|
grub_ssize_t offset = -sizeof(dir);
|
||||||
struct grub_fat_data *data;
|
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
struct grub_fshelp_node root = {
|
||||||
|
.disk = disk,
|
||||||
|
.attr = GRUB_FAT_ATTR_DIRECTORY,
|
||||||
|
.file_size = 0,
|
||||||
|
.cur_cluster_num = ~0U,
|
||||||
|
.cur_cluster = 0,
|
||||||
|
.is_contiguous = 0,
|
||||||
|
};
|
||||||
|
|
||||||
data = grub_fat_mount (disk);
|
root.data = grub_fat_mount (disk);
|
||||||
if (! data)
|
if (! root.data)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
root.file_cluster = root.data->root_cluster;
|
||||||
|
|
||||||
*label = NULL;
|
*label = NULL;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
offset += sizeof (dir);
|
offset += sizeof (dir);
|
||||||
|
|
||||||
if (grub_fat_read_data (disk, data, 0, 0,
|
if (grub_fat_read_data (disk, &root, 0, 0,
|
||||||
offset, sizeof (dir), (char *) &dir)
|
offset, sizeof (dir), (char *) &dir)
|
||||||
!= sizeof (dir))
|
!= sizeof (dir))
|
||||||
break;
|
break;
|
||||||
|
@ -1099,7 +1101,7 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (!*label)
|
if (!*label)
|
||||||
{
|
{
|
||||||
grub_free (data);
|
grub_free (root.data);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
chc = dir.type_specific.volume_label.character_count;
|
chc = dir.type_specific.volume_label.character_count;
|
||||||
|
@ -1111,7 +1113,7 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_free (data);
|
grub_free (root.data);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,30 +1122,32 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fat_label (grub_device_t device, char **label)
|
grub_fat_label (grub_device_t device, char **label)
|
||||||
{
|
{
|
||||||
struct grub_fat_data *data;
|
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
struct grub_fat_iterate_context ctxt;
|
struct grub_fat_iterate_context ctxt;
|
||||||
|
struct grub_fshelp_node root = {
|
||||||
|
.disk = disk,
|
||||||
|
.attr = GRUB_FAT_ATTR_DIRECTORY,
|
||||||
|
.file_size = 0,
|
||||||
|
.cur_cluster_num = ~0U,
|
||||||
|
.cur_cluster = 0,
|
||||||
|
};
|
||||||
|
|
||||||
*label = 0;
|
*label = 0;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
data = grub_fat_mount (disk);
|
root.data = grub_fat_mount (disk);
|
||||||
if (! data)
|
if (! root.data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
|
root.file_cluster = root.data->root_cluster;
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = grub_fat_iterate_init (&ctxt);
|
err = grub_fat_iterate_init (&ctxt);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
while (!(err = grub_fat_iterate_dir_next (disk, data, &ctxt)))
|
while (!(err = grub_fat_iterate_dir_next (&root, &ctxt)))
|
||||||
if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID)
|
if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
{
|
{
|
||||||
*label = grub_strdup (ctxt.filename);
|
*label = grub_strdup (ctxt.filename);
|
||||||
|
@ -1156,7 +1160,7 @@ grub_fat_label (grub_device_t device, char **label)
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
grub_free (data);
|
grub_free (root.data);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,169 +30,287 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
typedef int (*iterate_dir_func) (grub_fshelp_node_t dir,
|
typedef int (*iterate_dir_func) (grub_fshelp_node_t dir,
|
||||||
grub_fshelp_iterate_dir_hook_t hook,
|
grub_fshelp_iterate_dir_hook_t hook,
|
||||||
void *data);
|
void *data);
|
||||||
|
typedef grub_err_t (*lookup_file_func) (grub_fshelp_node_t dir,
|
||||||
|
const char *name,
|
||||||
|
grub_fshelp_node_t *foundnode,
|
||||||
|
enum grub_fshelp_filetype *foundtype);
|
||||||
typedef char *(*read_symlink_func) (grub_fshelp_node_t node);
|
typedef char *(*read_symlink_func) (grub_fshelp_node_t node);
|
||||||
|
|
||||||
|
struct stack_element {
|
||||||
|
struct stack_element *parent;
|
||||||
|
grub_fshelp_node_t node;
|
||||||
|
enum grub_fshelp_filetype type;
|
||||||
|
};
|
||||||
|
|
||||||
/* Context for grub_fshelp_find_file. */
|
/* Context for grub_fshelp_find_file. */
|
||||||
struct grub_fshelp_find_file_ctx
|
struct grub_fshelp_find_file_ctx
|
||||||
{
|
{
|
||||||
|
/* Inputs. */
|
||||||
const char *path;
|
const char *path;
|
||||||
grub_fshelp_node_t rootnode, currroot, currnode, oldnode;
|
grub_fshelp_node_t rootnode;
|
||||||
enum grub_fshelp_filetype foundtype;
|
|
||||||
|
/* Global options. */
|
||||||
int symlinknest;
|
int symlinknest;
|
||||||
const char *name;
|
|
||||||
const char *next;
|
/* Current file being traversed and its parents. */
|
||||||
enum grub_fshelp_filetype type;
|
struct stack_element *currnode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helper for find_file_iter. */
|
/* Helper for find_file_iter. */
|
||||||
static void
|
static void
|
||||||
free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx)
|
free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx)
|
||||||
{
|
{
|
||||||
if (node != ctx->rootnode && node != ctx->currroot)
|
if (node != ctx->rootnode)
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pop_element (struct grub_fshelp_find_file_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct stack_element *el;
|
||||||
|
el = ctx->currnode;
|
||||||
|
ctx->currnode = el->parent;
|
||||||
|
free_node (el->node, ctx);
|
||||||
|
grub_free (el);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_stack (struct grub_fshelp_find_file_ctx *ctx)
|
||||||
|
{
|
||||||
|
while (ctx->currnode)
|
||||||
|
pop_element (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
go_up_a_level (struct grub_fshelp_find_file_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (!ctx->currnode->parent)
|
||||||
|
return;
|
||||||
|
pop_element (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
push_node (struct grub_fshelp_find_file_ctx *ctx, grub_fshelp_node_t node, enum grub_fshelp_filetype filetype)
|
||||||
|
{
|
||||||
|
struct stack_element *nst;
|
||||||
|
nst = grub_malloc (sizeof (*nst));
|
||||||
|
if (!nst)
|
||||||
|
return grub_errno;
|
||||||
|
nst->node = node;
|
||||||
|
nst->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
|
||||||
|
nst->parent = ctx->currnode;
|
||||||
|
ctx->currnode = nst;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
go_to_root (struct grub_fshelp_find_file_ctx *ctx)
|
||||||
|
{
|
||||||
|
free_stack (ctx);
|
||||||
|
return push_node (ctx, ctx->rootnode, GRUB_FSHELP_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_fshelp_find_file_iter_ctx
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
grub_fshelp_node_t *foundnode;
|
||||||
|
enum grub_fshelp_filetype *foundtype;
|
||||||
|
};
|
||||||
|
|
||||||
/* Helper for grub_fshelp_find_file. */
|
/* Helper for grub_fshelp_find_file. */
|
||||||
static int
|
static int
|
||||||
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||||
grub_fshelp_node_t node, void *data)
|
grub_fshelp_node_t node, void *data)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_find_file_ctx *ctx = data;
|
struct grub_fshelp_find_file_iter_ctx *ctx = data;
|
||||||
|
|
||||||
if (filetype == GRUB_FSHELP_UNKNOWN ||
|
if (filetype == GRUB_FSHELP_UNKNOWN ||
|
||||||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
|
((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
|
||||||
? grub_strncasecmp (ctx->name, filename, ctx->next - ctx->name)
|
? grub_strcasecmp (ctx->name, filename)
|
||||||
: grub_strncmp (ctx->name, filename, ctx->next - ctx->name))
|
: grub_strcmp (ctx->name, filename)))
|
||||||
|| filename[ctx->next - ctx->name])
|
|
||||||
{
|
{
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The node is found, stop iterating over the nodes. */
|
/* The node is found, stop iterating over the nodes. */
|
||||||
ctx->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
|
*ctx->foundnode = node;
|
||||||
ctx->oldnode = ctx->currnode;
|
*ctx->foundtype = filetype;
|
||||||
ctx->currnode = node;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
find_file (const char *currpath, grub_fshelp_node_t currroot,
|
directory_find_file (grub_fshelp_node_t node, const char *name, grub_fshelp_node_t *foundnode,
|
||||||
grub_fshelp_node_t *currfound,
|
enum grub_fshelp_filetype *foundtype, iterate_dir_func iterate_dir)
|
||||||
iterate_dir_func iterate_dir, read_symlink_func read_symlink,
|
{
|
||||||
|
int found;
|
||||||
|
struct grub_fshelp_find_file_iter_ctx ctx = {
|
||||||
|
.foundnode = foundnode,
|
||||||
|
.foundtype = foundtype,
|
||||||
|
.name = name
|
||||||
|
};
|
||||||
|
found = iterate_dir (node, find_file_iter, &ctx);
|
||||||
|
if (! found)
|
||||||
|
{
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
find_file (char *currpath,
|
||||||
|
iterate_dir_func iterate_dir, lookup_file_func lookup_file,
|
||||||
|
read_symlink_func read_symlink,
|
||||||
struct grub_fshelp_find_file_ctx *ctx)
|
struct grub_fshelp_find_file_ctx *ctx)
|
||||||
{
|
{
|
||||||
ctx->currroot = currroot;
|
char *name, *next;
|
||||||
ctx->name = currpath;
|
grub_err_t err;
|
||||||
ctx->type = GRUB_FSHELP_DIR;
|
for (name = currpath; ; name = next)
|
||||||
ctx->currnode = currroot;
|
|
||||||
ctx->oldnode = currroot;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
int found;
|
char c;
|
||||||
|
grub_fshelp_node_t foundnode = NULL;
|
||||||
|
enum grub_fshelp_filetype foundtype = 0;
|
||||||
|
|
||||||
/* Remove all leading slashes. */
|
/* Remove all leading slashes. */
|
||||||
while (*ctx->name == '/')
|
while (*name == '/')
|
||||||
ctx->name++;
|
name++;
|
||||||
|
|
||||||
/* Found the node! */
|
/* Found the node! */
|
||||||
if (! *ctx->name)
|
if (! *name)
|
||||||
{
|
return 0;
|
||||||
*currfound = ctx->currnode;
|
|
||||||
ctx->foundtype = ctx->type;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract the actual part from the pathname. */
|
/* Extract the actual part from the pathname. */
|
||||||
for (ctx->next = ctx->name; *ctx->next && *ctx->next != '/'; ctx->next++);
|
for (next = name; *next && *next != '/'; next++);
|
||||||
|
|
||||||
/* At this point it is expected that the current node is a
|
/* At this point it is expected that the current node is a
|
||||||
directory, check if this is true. */
|
directory, check if this is true. */
|
||||||
if (ctx->type != GRUB_FSHELP_DIR)
|
if (ctx->currnode->type != GRUB_FSHELP_DIR)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
||||||
|
|
||||||
|
/* Don't rely on fs providing actual . in the listing. */
|
||||||
|
if (next - name == 1 && name[0] == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Don't rely on fs providing actual .. in the listing. */
|
||||||
|
if (next - name == 2 && name[0] == '.' && name[1] == '.')
|
||||||
{
|
{
|
||||||
free_node (ctx->currnode, ctx);
|
go_up_a_level (ctx);
|
||||||
ctx->currnode = 0;
|
continue;
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate over the directory. */
|
/* Iterate over the directory. */
|
||||||
found = iterate_dir (ctx->currnode, find_file_iter, ctx);
|
c = *next;
|
||||||
if (! found)
|
*next = '\0';
|
||||||
{
|
if (lookup_file)
|
||||||
free_node (ctx->currnode, ctx);
|
err = lookup_file (ctx->currnode->node, name, &foundnode, &foundtype);
|
||||||
ctx->currnode = 0;
|
else
|
||||||
if (grub_errno)
|
err = directory_find_file (ctx->currnode->node, name, &foundnode, &foundtype, iterate_dir);
|
||||||
return grub_errno;
|
*next = c;
|
||||||
|
|
||||||
break;
|
if (err)
|
||||||
}
|
return err;
|
||||||
|
|
||||||
|
if (!foundnode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
push_node (ctx, foundnode, foundtype);
|
||||||
|
|
||||||
/* Read in the symlink and follow it. */
|
/* Read in the symlink and follow it. */
|
||||||
if (ctx->type == GRUB_FSHELP_SYMLINK)
|
if (ctx->currnode->type == GRUB_FSHELP_SYMLINK)
|
||||||
{
|
{
|
||||||
char *symlink;
|
char *symlink;
|
||||||
const char *next;
|
|
||||||
|
|
||||||
/* Test if the symlink does not loop. */
|
/* Test if the symlink does not loop. */
|
||||||
if (++ctx->symlinknest == 8)
|
if (++ctx->symlinknest == 8)
|
||||||
{
|
return grub_error (GRUB_ERR_SYMLINK_LOOP,
|
||||||
free_node (ctx->currnode, ctx);
|
N_("too deep nesting of symlinks"));
|
||||||
free_node (ctx->oldnode, ctx);
|
|
||||||
ctx->currnode = 0;
|
|
||||||
ctx->oldnode = 0;
|
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP,
|
|
||||||
N_("too deep nesting of symlinks"));
|
|
||||||
}
|
|
||||||
|
|
||||||
symlink = read_symlink (ctx->currnode);
|
symlink = read_symlink (ctx->currnode->node);
|
||||||
free_node (ctx->currnode, ctx);
|
|
||||||
ctx->currnode = 0;
|
|
||||||
|
|
||||||
if (!symlink)
|
if (!symlink)
|
||||||
{
|
return grub_errno;
|
||||||
free_node (ctx->oldnode, ctx);
|
|
||||||
ctx->oldnode = 0;
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The symlink is an absolute path, go back to the root inode. */
|
/* The symlink is an absolute path, go back to the root inode. */
|
||||||
if (symlink[0] == '/')
|
if (symlink[0] == '/')
|
||||||
{
|
{
|
||||||
free_node (ctx->oldnode, ctx);
|
err = go_to_root (ctx);
|
||||||
ctx->oldnode = ctx->rootnode;
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get from symlink to containing directory. */
|
||||||
|
go_up_a_level (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Lookup the node the symlink points to. */
|
/* Lookup the node the symlink points to. */
|
||||||
next = ctx->next;
|
find_file (symlink, iterate_dir, lookup_file, read_symlink, ctx);
|
||||||
find_file (symlink, ctx->oldnode, &ctx->currnode,
|
|
||||||
iterate_dir, read_symlink, ctx);
|
|
||||||
ctx->next = next;
|
|
||||||
ctx->type = ctx->foundtype;
|
|
||||||
grub_free (symlink);
|
grub_free (symlink);
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
{
|
return grub_errno;
|
||||||
free_node (ctx->oldnode, ctx);
|
|
||||||
ctx->oldnode = 0;
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->oldnode != ctx->currnode)
|
|
||||||
{
|
|
||||||
free_node (ctx->oldnode, ctx);
|
|
||||||
ctx->oldnode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->name = ctx->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
|
||||||
ctx->path);
|
ctx->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_fshelp_find_file_real (const char *path, grub_fshelp_node_t rootnode,
|
||||||
|
grub_fshelp_node_t *foundnode,
|
||||||
|
iterate_dir_func iterate_dir,
|
||||||
|
lookup_file_func lookup_file,
|
||||||
|
read_symlink_func read_symlink,
|
||||||
|
enum grub_fshelp_filetype expecttype)
|
||||||
|
{
|
||||||
|
struct grub_fshelp_find_file_ctx ctx = {
|
||||||
|
.path = path,
|
||||||
|
.rootnode = rootnode,
|
||||||
|
.symlinknest = 0,
|
||||||
|
.currnode = 0
|
||||||
|
};
|
||||||
|
grub_err_t err;
|
||||||
|
enum grub_fshelp_filetype foundtype;
|
||||||
|
char *duppath;
|
||||||
|
|
||||||
|
if (!path || path[0] != '/')
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = go_to_root (&ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
duppath = grub_strdup (path);
|
||||||
|
if (!duppath)
|
||||||
|
return grub_errno;
|
||||||
|
err = find_file (duppath, iterate_dir, lookup_file, read_symlink, &ctx);
|
||||||
|
grub_free (duppath);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
free_stack (&ctx);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*foundnode = ctx.currnode->node;
|
||||||
|
foundtype = ctx.currnode->type;
|
||||||
|
/* Avoid the node being freed. */
|
||||||
|
ctx.currnode->node = 0;
|
||||||
|
free_stack (&ctx);
|
||||||
|
|
||||||
|
/* Check if the node that was found was of the expected type. */
|
||||||
|
if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
|
||||||
|
else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Lookup the node PATH. The node ROOTNODE describes the root of the
|
/* Lookup the node PATH. The node ROOTNODE describes the root of the
|
||||||
directory tree. The node found is returned in FOUNDNODE, which is
|
directory tree. The node found is returned in FOUNDNODE, which is
|
||||||
either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
|
either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
|
||||||
|
@ -207,31 +325,23 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
|
||||||
read_symlink_func read_symlink,
|
read_symlink_func read_symlink,
|
||||||
enum grub_fshelp_filetype expecttype)
|
enum grub_fshelp_filetype expecttype)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_find_file_ctx ctx = {
|
return grub_fshelp_find_file_real (path, rootnode, foundnode,
|
||||||
.path = path,
|
iterate_dir, NULL,
|
||||||
.rootnode = rootnode,
|
read_symlink, expecttype);
|
||||||
.foundtype = GRUB_FSHELP_DIR,
|
|
||||||
.symlinknest = 0
|
|
||||||
};
|
|
||||||
grub_err_t err;
|
|
||||||
|
|
||||||
if (!path || path[0] != '/')
|
}
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = find_file (path, rootnode, foundnode, iterate_dir, read_symlink, &ctx);
|
grub_err_t
|
||||||
if (err)
|
grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode,
|
||||||
return err;
|
grub_fshelp_node_t *foundnode,
|
||||||
|
lookup_file_func lookup_file,
|
||||||
|
read_symlink_func read_symlink,
|
||||||
|
enum grub_fshelp_filetype expecttype)
|
||||||
|
{
|
||||||
|
return grub_fshelp_find_file_real (path, rootnode, foundnode,
|
||||||
|
NULL, lookup_file,
|
||||||
|
read_symlink, expecttype);
|
||||||
|
|
||||||
/* Check if the node that was found was of the expected type. */
|
|
||||||
if (expecttype == GRUB_FSHELP_REG && ctx.foundtype != expecttype)
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
|
|
||||||
else if (expecttype == GRUB_FSHELP_DIR && ctx.foundtype != expecttype)
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
|
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/hfs.h>
|
#include <grub/hfs.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/fshelp.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -1125,90 +1126,81 @@ utf8_to_macroman (grub_uint8_t *to, const char *from)
|
||||||
return optr - to;
|
return optr - to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
union grub_hfs_anyrec {
|
||||||
|
struct grub_hfs_filerec frec;
|
||||||
|
struct grub_hfs_dirrec dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_fshelp_node
|
||||||
|
{
|
||||||
|
struct grub_hfs_data *data;
|
||||||
|
union grub_hfs_anyrec fdrec;
|
||||||
|
grub_uint32_t inode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
lookup_file (grub_fshelp_node_t dir,
|
||||||
|
const char *name,
|
||||||
|
grub_fshelp_node_t *foundnode,
|
||||||
|
enum grub_fshelp_filetype *foundtype)
|
||||||
|
{
|
||||||
|
struct grub_hfs_catalog_key key;
|
||||||
|
grub_ssize_t slen;
|
||||||
|
union grub_hfs_anyrec fdrec;
|
||||||
|
|
||||||
|
key.parent_dir = grub_cpu_to_be32 (dir->inode);
|
||||||
|
slen = utf8_to_macroman (key.str, name);
|
||||||
|
if (slen < 0)
|
||||||
|
/* Not found */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
key.strlen = slen;
|
||||||
|
|
||||||
|
/* Lookup this node. */
|
||||||
|
if (! grub_hfs_find_node (dir->data, (char *) &key, dir->data->cat_root,
|
||||||
|
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
|
||||||
|
/* Not found */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
*foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||||
|
if (!*foundnode)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
(*foundnode)->inode = grub_be_to_cpu32 (fdrec.dir.dirid);
|
||||||
|
(*foundnode)->fdrec = fdrec;
|
||||||
|
(*foundnode)->data = dir->data;
|
||||||
|
*foundtype = (fdrec.frec.type == GRUB_HFS_FILETYPE_DIR) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find a file or directory with the pathname PATH in the filesystem
|
/* Find a file or directory with the pathname PATH in the filesystem
|
||||||
DATA. Return the file record in RETDATA when it is non-zero.
|
DATA. Return the file record in RETDATA when it is non-zero.
|
||||||
Return the directory number in RETINODE when it is non-zero. */
|
Return the directory number in RETINODE when it is non-zero. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
|
grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
|
||||||
struct grub_hfs_filerec *retdata, int *retinode)
|
grub_fshelp_node_t *found,
|
||||||
|
enum grub_fshelp_filetype exptype)
|
||||||
{
|
{
|
||||||
int inode = data->rootdir;
|
struct grub_fshelp_node root = {
|
||||||
char *next;
|
.data = data,
|
||||||
char *origpath;
|
.inode = data->rootdir,
|
||||||
union {
|
.fdrec = {
|
||||||
struct grub_hfs_filerec frec;
|
.frec = {
|
||||||
struct grub_hfs_dirrec dir;
|
.type = GRUB_HFS_FILETYPE_DIR
|
||||||
} fdrec;
|
}
|
||||||
|
|
||||||
fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
|
|
||||||
|
|
||||||
if (path[0] != '/')
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
origpath = grub_strdup (path);
|
err = grub_fshelp_find_file_lookup (path, &root, found, lookup_file, NULL, exptype);
|
||||||
if (!origpath)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
path = origpath;
|
if (&root == *found)
|
||||||
while (*path == '/')
|
|
||||||
path++;
|
|
||||||
|
|
||||||
while (path && grub_strlen (path))
|
|
||||||
{
|
{
|
||||||
grub_ssize_t slen;
|
*found = grub_malloc (sizeof (root));
|
||||||
if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
|
if (!*found)
|
||||||
{
|
return grub_errno;
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
grub_memcpy (*found, &root, sizeof (root));
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Isolate a part of the path. */
|
|
||||||
next = grub_strchr (path, '/');
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
while (*next == '/')
|
|
||||||
*(next++) = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
struct grub_hfs_catalog_key key;
|
|
||||||
|
|
||||||
key.parent_dir = grub_cpu_to_be32 (inode);
|
|
||||||
slen = utf8_to_macroman (key.str, path);
|
|
||||||
if (slen < 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
key.strlen = slen;
|
|
||||||
|
|
||||||
/* Lookup this node. */
|
|
||||||
if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
|
|
||||||
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_errno)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
inode = grub_be_to_cpu32 (fdrec.dir.dirid);
|
|
||||||
path = next;
|
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
if (retdata)
|
|
||||||
grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
|
|
||||||
|
|
||||||
if (retinode)
|
|
||||||
*retinode = inode;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_free (origpath);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grub_hfs_dir_hook_ctx
|
struct grub_hfs_dir_hook_ctx
|
||||||
|
@ -1266,15 +1258,13 @@ static grub_err_t
|
||||||
grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||||
void *hook_data)
|
void *hook_data)
|
||||||
{
|
{
|
||||||
int inode;
|
|
||||||
|
|
||||||
struct grub_hfs_data *data;
|
struct grub_hfs_data *data;
|
||||||
struct grub_hfs_filerec frec;
|
|
||||||
struct grub_hfs_dir_hook_ctx ctx =
|
struct grub_hfs_dir_hook_ctx ctx =
|
||||||
{
|
{
|
||||||
.hook = hook,
|
.hook = hook,
|
||||||
.hook_data = hook_data
|
.hook_data = hook_data
|
||||||
};
|
};
|
||||||
|
grub_fshelp_node_t found = NULL;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -1283,18 +1273,13 @@ grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* First the directory ID for the directory. */
|
/* First the directory ID for the directory. */
|
||||||
if (grub_hfs_find_dir (data, path, &frec, &inode))
|
if (grub_hfs_find_dir (data, path, &found, GRUB_FSHELP_DIR))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (frec.type != GRUB_HFS_FILETYPE_DIR)
|
grub_hfs_iterate_dir (data, data->cat_root, found->inode, grub_hfs_dir_hook, &ctx);
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_hfs_iterate_dir (data, data->cat_root, inode, grub_hfs_dir_hook, &ctx);
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
grub_free (found);
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
@ -1308,7 +1293,7 @@ static grub_err_t
|
||||||
grub_hfs_open (struct grub_file *file, const char *name)
|
grub_hfs_open (struct grub_file *file, const char *name)
|
||||||
{
|
{
|
||||||
struct grub_hfs_data *data;
|
struct grub_hfs_data *data;
|
||||||
struct grub_hfs_filerec frec;
|
grub_fshelp_node_t found = NULL;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -1320,29 +1305,23 @@ grub_hfs_open (struct grub_file *file, const char *name)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_hfs_find_dir (data, name, &frec, 0))
|
if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG))
|
||||||
{
|
{
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frec.type != GRUB_HFS_FILETYPE_FILE)
|
grub_memcpy (data->extents, found->fdrec.frec.extents, sizeof (grub_hfs_datarecord_t));
|
||||||
{
|
file->size = grub_be_to_cpu32 (found->fdrec.frec.size);
|
||||||
grub_free (data);
|
data->size = grub_be_to_cpu32 (found->fdrec.frec.size);
|
||||||
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
|
data->fileid = grub_be_to_cpu32 (found->fdrec.frec.fileid);
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
|
|
||||||
file->size = grub_be_to_cpu32 (frec.size);
|
|
||||||
data->size = grub_be_to_cpu32 (frec.size);
|
|
||||||
data->fileid = grub_be_to_cpu32 (frec.fileid);
|
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
|
|
||||||
file->data = data;
|
file->data = data;
|
||||||
|
|
||||||
|
grub_free (found);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/archelp.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -74,6 +75,44 @@ grub_procdev_write (grub_disk_t disk __attribute ((unused)),
|
||||||
return GRUB_ERR_OUT_OF_RANGE;
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct grub_archelp_data
|
||||||
|
{
|
||||||
|
struct grub_procfs_entry *entry, *next_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_procfs_rewind (struct grub_archelp_data *data)
|
||||||
|
{
|
||||||
|
data->entry = NULL;
|
||||||
|
data->next_entry = grub_procfs_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_procfs_find_file (struct grub_archelp_data *data, char **name,
|
||||||
|
grub_int32_t *mtime,
|
||||||
|
grub_uint32_t *mode)
|
||||||
|
{
|
||||||
|
data->entry = data->next_entry;
|
||||||
|
if (!data->entry)
|
||||||
|
{
|
||||||
|
*mode = GRUB_ARCHELP_ATTR_END;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
data->next_entry = data->entry->next;
|
||||||
|
*mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;
|
||||||
|
*name = grub_strdup (data->entry->name);
|
||||||
|
*mtime = 0;
|
||||||
|
if (!*name)
|
||||||
|
return grub_errno;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_archelp_ops arcops =
|
||||||
|
{
|
||||||
|
.find_file = grub_procfs_find_file,
|
||||||
|
.rewind = grub_procfs_rewind
|
||||||
|
};
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
|
grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
|
@ -99,44 +138,35 @@ static grub_err_t
|
||||||
grub_procfs_dir (grub_device_t device, const char *path,
|
grub_procfs_dir (grub_device_t device, const char *path,
|
||||||
grub_fs_dir_hook_t hook, void *hook_data)
|
grub_fs_dir_hook_t hook, void *hook_data)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
struct grub_archelp_data data;
|
||||||
struct grub_dirhook_info info;
|
|
||||||
struct grub_procfs_entry *entry;
|
|
||||||
|
|
||||||
grub_memset (&info, 0, sizeof (info));
|
|
||||||
|
|
||||||
/* Check if the disk is our dummy disk. */
|
/* Check if the disk is our dummy disk. */
|
||||||
if (grub_strcmp (device->disk->name, "proc"))
|
if (grub_strcmp (device->disk->name, "proc"))
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
|
return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
|
||||||
for (ptr = path; *ptr == '/'; ptr++);
|
|
||||||
if (*ptr)
|
grub_procfs_rewind (&data);
|
||||||
return 0;
|
|
||||||
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
|
return grub_archelp_dir (&data, &arcops,
|
||||||
if (hook (entry->name, &info, hook_data))
|
path, hook, hook_data);
|
||||||
return 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_procfs_open (struct grub_file *file, const char *path)
|
grub_procfs_open (struct grub_file *file, const char *path)
|
||||||
{
|
{
|
||||||
const char *pathptr;
|
grub_err_t err;
|
||||||
struct grub_procfs_entry *entry;
|
struct grub_archelp_data data;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
for (pathptr = path; *pathptr == '/'; pathptr++);
|
grub_procfs_rewind (&data);
|
||||||
|
|
||||||
FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
|
err = grub_archelp_open (&data, &arcops, path);
|
||||||
if (grub_strcmp (pathptr, entry->name) == 0)
|
if (err)
|
||||||
{
|
return err;
|
||||||
grub_size_t sz;
|
file->data = data.entry->get_contents (&sz);
|
||||||
file->data = entry->get_contents (&sz);
|
if (!file->data)
|
||||||
if (!file->data)
|
return grub_errno;
|
||||||
return grub_errno;
|
file->size = sz;
|
||||||
file->size = sz;
|
return GRUB_ERR_NONE;
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_disk_dev grub_procfs_dev = {
|
static struct grub_disk_dev grub_procfs_dev = {
|
||||||
|
|
|
@ -783,12 +783,30 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
||||||
struct grub_reiserfs_key entry_key;
|
struct grub_reiserfs_key entry_key;
|
||||||
enum grub_fshelp_filetype entry_type;
|
enum grub_fshelp_filetype entry_type;
|
||||||
char *entry_name;
|
char *entry_name;
|
||||||
|
char *entry_name_end = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK))
|
if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entry_name = (((char *) directory_headers)
|
entry_name = (((char *) directory_headers)
|
||||||
+ grub_le_to_cpu16 (directory_header->location));
|
+ grub_le_to_cpu16 (directory_header->location));
|
||||||
|
if (entry_number == 0)
|
||||||
|
{
|
||||||
|
entry_name_end = (char *) block_header
|
||||||
|
+ grub_le_to_cpu16 (item_headers[block_position].item_location)
|
||||||
|
+ grub_le_to_cpu16 (item_headers[block_position].item_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry_name_end = (((char *) directory_headers)
|
||||||
|
+ grub_le_to_cpu16 (directory_headers[entry_number - 1].location));
|
||||||
|
}
|
||||||
|
if (entry_name_end < entry_name || entry_name_end > (char *) block_header + block_size)
|
||||||
|
{
|
||||||
|
entry_name_end = (char *) block_header + block_size;
|
||||||
|
}
|
||||||
|
|
||||||
entry_key.directory_id = directory_header->directory_id;
|
entry_key.directory_id = directory_header->directory_id;
|
||||||
entry_key.object_id = directory_header->object_id;
|
entry_key.object_id = directory_header->object_id;
|
||||||
entry_key.u.v2.offset_type = 0;
|
entry_key.u.v2.offset_type = 0;
|
||||||
|
@ -935,7 +953,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Pseudo file ".." never has stat block. */
|
/* Pseudo file ".." never has stat block. */
|
||||||
if (grub_strcmp (entry_name, ".."))
|
if (entry_name_end == entry_name + 2 && grub_memcmp (entry_name, "..", 2) != 0)
|
||||||
grub_dprintf ("reiserfs",
|
grub_dprintf ("reiserfs",
|
||||||
"Warning : %s has no stat block !\n",
|
"Warning : %s has no stat block !\n",
|
||||||
entry_name);
|
entry_name);
|
||||||
|
@ -943,18 +961,21 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = *entry_name_end;
|
||||||
|
*entry_name_end = 0;
|
||||||
if (hook (entry_name, entry_type, entry_item, hook_data))
|
if (hook (entry_name, entry_type, entry_item, hook_data))
|
||||||
{
|
{
|
||||||
|
*entry_name_end = c;
|
||||||
grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
|
grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
|
||||||
entry_name, entry_type);
|
entry_name, entry_type);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
*entry_name_end = c;
|
||||||
|
|
||||||
next:
|
next:
|
||||||
*entry_name = 0; /* Make sure next entry name (which is just
|
;
|
||||||
before this one in disk order) stops before
|
|
||||||
the current one. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_offset == 0)
|
if (next_offset == 0)
|
||||||
|
|
|
@ -34,6 +34,50 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
#define XFS_INODE_FORMAT_EXT 2
|
#define XFS_INODE_FORMAT_EXT 2
|
||||||
#define XFS_INODE_FORMAT_BTREE 3
|
#define XFS_INODE_FORMAT_BTREE 3
|
||||||
|
|
||||||
|
/* Superblock version field flags */
|
||||||
|
#define XFS_SB_VERSION_NUMBITS 0x000f
|
||||||
|
#define XFS_SB_VERSION_ATTRBIT 0x0010
|
||||||
|
#define XFS_SB_VERSION_NLINKBIT 0x0020
|
||||||
|
#define XFS_SB_VERSION_QUOTABIT 0x0040
|
||||||
|
#define XFS_SB_VERSION_ALIGNBIT 0x0080
|
||||||
|
#define XFS_SB_VERSION_DALIGNBIT 0x0100
|
||||||
|
#define XFS_SB_VERSION_LOGV2BIT 0x0400
|
||||||
|
#define XFS_SB_VERSION_SECTORBIT 0x0800
|
||||||
|
#define XFS_SB_VERSION_EXTFLGBIT 0x1000
|
||||||
|
#define XFS_SB_VERSION_DIRV2BIT 0x2000
|
||||||
|
#define XFS_SB_VERSION_MOREBITSBIT 0x8000
|
||||||
|
#define XFS_SB_VERSION_BITS_SUPPORTED \
|
||||||
|
(XFS_SB_VERSION_NUMBITS | \
|
||||||
|
XFS_SB_VERSION_ATTRBIT | \
|
||||||
|
XFS_SB_VERSION_NLINKBIT | \
|
||||||
|
XFS_SB_VERSION_QUOTABIT | \
|
||||||
|
XFS_SB_VERSION_ALIGNBIT | \
|
||||||
|
XFS_SB_VERSION_DALIGNBIT | \
|
||||||
|
XFS_SB_VERSION_LOGV2BIT | \
|
||||||
|
XFS_SB_VERSION_SECTORBIT | \
|
||||||
|
XFS_SB_VERSION_EXTFLGBIT | \
|
||||||
|
XFS_SB_VERSION_DIRV2BIT | \
|
||||||
|
XFS_SB_VERSION_MOREBITSBIT)
|
||||||
|
|
||||||
|
/* Recognized xfs format versions */
|
||||||
|
#define XFS_SB_VERSION_4 4 /* Good old XFS filesystem */
|
||||||
|
#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */
|
||||||
|
|
||||||
|
/* features2 field flags */
|
||||||
|
#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */
|
||||||
|
#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
|
||||||
|
#define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32-bit project ids */
|
||||||
|
#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */
|
||||||
|
#define XFS_SB_VERSION2_BITS_SUPPORTED \
|
||||||
|
(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
|
||||||
|
XFS_SB_VERSION2_ATTR2BIT | \
|
||||||
|
XFS_SB_VERSION2_PROJID32BIT | \
|
||||||
|
XFS_SB_VERSION2_FTYPE)
|
||||||
|
|
||||||
|
/* incompat feature flags */
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
|
||||||
|
(XFS_SB_FEAT_INCOMPAT_FTYPE)
|
||||||
|
|
||||||
struct grub_xfs_sblock
|
struct grub_xfs_sblock
|
||||||
{
|
{
|
||||||
|
@ -45,7 +89,9 @@ struct grub_xfs_sblock
|
||||||
grub_uint64_t rootino;
|
grub_uint64_t rootino;
|
||||||
grub_uint8_t unused3[20];
|
grub_uint8_t unused3[20];
|
||||||
grub_uint32_t agsize;
|
grub_uint32_t agsize;
|
||||||
grub_uint8_t unused4[20];
|
grub_uint8_t unused4[12];
|
||||||
|
grub_uint16_t version;
|
||||||
|
grub_uint8_t unused5[6];
|
||||||
grub_uint8_t label[12];
|
grub_uint8_t label[12];
|
||||||
grub_uint8_t log2_bsize;
|
grub_uint8_t log2_bsize;
|
||||||
grub_uint8_t log2_sect;
|
grub_uint8_t log2_sect;
|
||||||
|
@ -54,12 +100,19 @@ struct grub_xfs_sblock
|
||||||
grub_uint8_t log2_agblk;
|
grub_uint8_t log2_agblk;
|
||||||
grub_uint8_t unused6[67];
|
grub_uint8_t unused6[67];
|
||||||
grub_uint8_t log2_dirblk;
|
grub_uint8_t log2_dirblk;
|
||||||
|
grub_uint8_t unused7[7];
|
||||||
|
grub_uint32_t features2;
|
||||||
|
grub_uint8_t unused8[4];
|
||||||
|
grub_uint32_t sb_features_compat;
|
||||||
|
grub_uint32_t sb_features_ro_compat;
|
||||||
|
grub_uint32_t sb_features_incompat;
|
||||||
|
grub_uint32_t sb_features_log_incompat;
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
struct grub_xfs_dir_header
|
struct grub_xfs_dir_header
|
||||||
{
|
{
|
||||||
grub_uint8_t count;
|
grub_uint8_t count;
|
||||||
grub_uint8_t smallino;
|
grub_uint8_t largeino;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
grub_uint32_t i4;
|
grub_uint32_t i4;
|
||||||
|
@ -67,21 +120,29 @@ struct grub_xfs_dir_header
|
||||||
} GRUB_PACKED parent;
|
} GRUB_PACKED parent;
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
|
/* Structure for directory entry inlined in the inode */
|
||||||
struct grub_xfs_dir_entry
|
struct grub_xfs_dir_entry
|
||||||
{
|
{
|
||||||
grub_uint8_t len;
|
grub_uint8_t len;
|
||||||
grub_uint16_t offset;
|
grub_uint16_t offset;
|
||||||
char name[1];
|
char name[1];
|
||||||
/* Inode number follows, 32 bits. */
|
/* Inode number follows, 32 / 64 bits. */
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
|
/* Structure for directory entry in a block */
|
||||||
struct grub_xfs_dir2_entry
|
struct grub_xfs_dir2_entry
|
||||||
{
|
{
|
||||||
grub_uint64_t inode;
|
grub_uint64_t inode;
|
||||||
grub_uint8_t len;
|
grub_uint8_t len;
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
typedef grub_uint32_t grub_xfs_extent[4];
|
struct grub_xfs_extent
|
||||||
|
{
|
||||||
|
/* This should be a bitfield but bietfields are unportable, so just have
|
||||||
|
a raw array and functions extracting useful info from it.
|
||||||
|
*/
|
||||||
|
grub_uint32_t raw[4];
|
||||||
|
} GRUB_PACKED;
|
||||||
|
|
||||||
struct grub_xfs_btree_node
|
struct grub_xfs_btree_node
|
||||||
{
|
{
|
||||||
|
@ -90,21 +151,22 @@ struct grub_xfs_btree_node
|
||||||
grub_uint16_t numrecs;
|
grub_uint16_t numrecs;
|
||||||
grub_uint64_t left;
|
grub_uint64_t left;
|
||||||
grub_uint64_t right;
|
grub_uint64_t right;
|
||||||
grub_uint64_t keys[1];
|
/* In V5 here follow crc, uuid, etc. */
|
||||||
} GRUB_PACKED;
|
/* Then follow keys and block pointers */
|
||||||
|
} GRUB_PACKED;
|
||||||
|
|
||||||
struct grub_xfs_btree_root
|
struct grub_xfs_btree_root
|
||||||
{
|
{
|
||||||
grub_uint16_t level;
|
grub_uint16_t level;
|
||||||
grub_uint16_t numrecs;
|
grub_uint16_t numrecs;
|
||||||
grub_uint64_t keys[1];
|
grub_uint64_t keys[1];
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
struct grub_xfs_time
|
struct grub_xfs_time
|
||||||
{
|
{
|
||||||
grub_uint32_t sec;
|
grub_uint32_t sec;
|
||||||
grub_uint32_t nanosec;
|
grub_uint32_t nanosec;
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
struct grub_xfs_inode
|
struct grub_xfs_inode
|
||||||
{
|
{
|
||||||
|
@ -123,19 +185,11 @@ struct grub_xfs_inode
|
||||||
grub_uint16_t unused3;
|
grub_uint16_t unused3;
|
||||||
grub_uint8_t fork_offset;
|
grub_uint8_t fork_offset;
|
||||||
grub_uint8_t unused4[17];
|
grub_uint8_t unused4[17];
|
||||||
union
|
|
||||||
{
|
|
||||||
char raw[156];
|
|
||||||
struct dir
|
|
||||||
{
|
|
||||||
struct grub_xfs_dir_header dirhead;
|
|
||||||
struct grub_xfs_dir_entry direntry[1];
|
|
||||||
} dir;
|
|
||||||
grub_xfs_extent extents[XFS_INODE_EXTENTS];
|
|
||||||
struct grub_xfs_btree_root btree;
|
|
||||||
} GRUB_PACKED data;
|
|
||||||
} GRUB_PACKED;
|
} GRUB_PACKED;
|
||||||
|
|
||||||
|
#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
|
||||||
|
#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)
|
||||||
|
|
||||||
struct grub_xfs_dirblock_tail
|
struct grub_xfs_dirblock_tail
|
||||||
{
|
{
|
||||||
grub_uint32_t leaf_count;
|
grub_uint32_t leaf_count;
|
||||||
|
@ -157,6 +211,8 @@ struct grub_xfs_data
|
||||||
int pos;
|
int pos;
|
||||||
int bsize;
|
int bsize;
|
||||||
grub_uint32_t agsize;
|
grub_uint32_t agsize;
|
||||||
|
unsigned int hasftype:1;
|
||||||
|
unsigned int hascrc:1;
|
||||||
struct grub_fshelp_node diropen;
|
struct grub_fshelp_node diropen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,6 +220,71 @@ static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
|
||||||
|
{
|
||||||
|
return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
|
||||||
|
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int grub_xfs_sb_hasftype(struct grub_xfs_data *data)
|
||||||
|
{
|
||||||
|
if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
|
||||||
|
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) &&
|
||||||
|
data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE))
|
||||||
|
return 1;
|
||||||
|
if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
|
||||||
|
data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int grub_xfs_sb_valid(struct grub_xfs_data *data)
|
||||||
|
{
|
||||||
|
grub_dprintf("xfs", "Validating superblock\n");
|
||||||
|
if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
|
||||||
|
|| data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
|
||||||
|
|| ((int) data->sblock.log2_bsize
|
||||||
|
+ (int) data->sblock.log2_dirblk) >= 27)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
|
||||||
|
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5))
|
||||||
|
{
|
||||||
|
grub_dprintf("xfs", "XFS v5 superblock detected\n");
|
||||||
|
if (data->sblock.sb_features_incompat &
|
||||||
|
grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported "
|
||||||
|
"incompatible features");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
|
||||||
|
grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4))
|
||||||
|
{
|
||||||
|
grub_dprintf("xfs", "XFS v4 superblock detected\n");
|
||||||
|
if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT)))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories "
|
||||||
|
"is unsupported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) ||
|
||||||
|
(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
|
||||||
|
data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED)))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version "
|
||||||
|
"bits");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Filetype information as used in inodes. */
|
/* Filetype information as used in inodes. */
|
||||||
#define FILETYPE_INO_MASK 0170000
|
#define FILETYPE_INO_MASK 0170000
|
||||||
#define FILETYPE_INO_REG 0100000
|
#define FILETYPE_INO_REG 0100000
|
||||||
|
@ -180,14 +301,14 @@ static inline grub_uint64_t
|
||||||
GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
|
GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
|
||||||
grub_uint64_t ino)
|
grub_uint64_t ino)
|
||||||
{
|
{
|
||||||
return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
|
return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
GRUB_XFS_INO_AG (struct grub_xfs_data *data,
|
GRUB_XFS_INO_AG (struct grub_xfs_data *data,
|
||||||
grub_uint64_t ino)
|
grub_uint64_t ino)
|
||||||
{
|
{
|
||||||
return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data));
|
return (ino >> GRUB_XFS_INO_AGBITS (data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_disk_addr_t
|
static inline grub_disk_addr_t
|
||||||
|
@ -198,37 +319,25 @@ GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
GRUB_XFS_EXTENT_OFFSET (grub_xfs_extent *exts, int ex)
|
GRUB_XFS_EXTENT_OFFSET (struct grub_xfs_extent *exts, int ex)
|
||||||
{
|
{
|
||||||
return ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23
|
return ((grub_be_to_cpu32 (exts[ex].raw[0]) & ~(1 << 31)) << 23
|
||||||
| grub_be_to_cpu32 (exts[ex][1]) >> 9);
|
| grub_be_to_cpu32 (exts[ex].raw[1]) >> 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
GRUB_XFS_EXTENT_BLOCK (grub_xfs_extent *exts, int ex)
|
GRUB_XFS_EXTENT_BLOCK (struct grub_xfs_extent *exts, int ex)
|
||||||
{
|
{
|
||||||
return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1])
|
return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex].raw[1])
|
||||||
& (0x1ff)) << 43
|
& (0x1ff)) << 43
|
||||||
| (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11
|
| (grub_uint64_t) grub_be_to_cpu32 (exts[ex].raw[2]) << 11
|
||||||
| grub_be_to_cpu32 (exts[ex][3]) >> 21);
|
| grub_be_to_cpu32 (exts[ex].raw[3]) >> 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex)
|
GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex)
|
||||||
{
|
{
|
||||||
return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 21) - 1));
|
return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1));
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
GRUB_XFS_ROUND_TO_DIRENT (int pos)
|
|
||||||
{
|
|
||||||
return ((((pos) + 8 - 1) / 8) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
GRUB_XFS_NEXT_DIRENT (int pos, int len)
|
|
||||||
{
|
|
||||||
return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,6 +364,109 @@ grub_xfs_inode_offset (struct grub_xfs_data *data,
|
||||||
data->sblock.log2_inode);
|
data->sblock.log2_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline grub_size_t
|
||||||
|
grub_xfs_inode_size(struct grub_xfs_data *data)
|
||||||
|
{
|
||||||
|
return (grub_size_t)1 << data->sblock.log2_inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns size occupied by XFS inode stored in memory - we store struct
|
||||||
|
* grub_fshelp_node there but on disk inode size may be actually larger than
|
||||||
|
* struct grub_xfs_inode so we need to account for that so that we can read
|
||||||
|
* from disk directly into in-memory structure.
|
||||||
|
*/
|
||||||
|
static inline grub_size_t
|
||||||
|
grub_xfs_fshelp_size(struct grub_xfs_data *data)
|
||||||
|
{
|
||||||
|
return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode)
|
||||||
|
+ grub_xfs_inode_size(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should return void * but XFS code is error-prone with alignment, so
|
||||||
|
return char to retain cast-align.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
grub_xfs_inode_data(struct grub_xfs_inode *inode)
|
||||||
|
{
|
||||||
|
if (inode->version <= 2)
|
||||||
|
return ((char *)inode) + XFS_V2_INODE_SIZE;
|
||||||
|
return ((char *)inode) + XFS_V3_INODE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_xfs_dir_entry *
|
||||||
|
grub_xfs_inline_de(struct grub_xfs_dir_header *head)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
With small inode numbers the header is 4 bytes smaller because of
|
||||||
|
smaller parent pointer
|
||||||
|
*/
|
||||||
|
return (struct grub_xfs_dir_entry *)
|
||||||
|
(((char *) head) + sizeof(struct grub_xfs_dir_header) -
|
||||||
|
(head->largeino ? 0 : sizeof(grub_uint32_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_uint8_t *
|
||||||
|
grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
|
||||||
|
struct grub_xfs_dir_entry *de)
|
||||||
|
{
|
||||||
|
return ((grub_uint8_t *)(de + 1)) + de->len - 1 + (data->hasftype ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_xfs_dir_entry *
|
||||||
|
grub_xfs_inline_next_de(struct grub_xfs_data *data,
|
||||||
|
struct grub_xfs_dir_header *head,
|
||||||
|
struct grub_xfs_dir_entry *de)
|
||||||
|
{
|
||||||
|
char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;
|
||||||
|
|
||||||
|
p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
|
||||||
|
if (data->hasftype)
|
||||||
|
p++;
|
||||||
|
|
||||||
|
return (struct grub_xfs_dir_entry *)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_xfs_dirblock_tail *
|
||||||
|
grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
|
||||||
|
{
|
||||||
|
int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk);
|
||||||
|
|
||||||
|
return (struct grub_xfs_dirblock_tail *)
|
||||||
|
((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_xfs_dir2_entry *
|
||||||
|
grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
|
||||||
|
{
|
||||||
|
if (data->hascrc)
|
||||||
|
return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
|
||||||
|
return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_xfs_dir2_entry *
|
||||||
|
grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de)
|
||||||
|
{
|
||||||
|
int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;
|
||||||
|
|
||||||
|
if (data->hasftype)
|
||||||
|
size++; /* File type */
|
||||||
|
return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should return void * but XFS code is error-prone with alignment, so
|
||||||
|
return char to retain cast-align.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
grub_xfs_btree_keys(struct grub_xfs_data *data,
|
||||||
|
struct grub_xfs_btree_node *leaf)
|
||||||
|
{
|
||||||
|
char *keys = (char *)(leaf + 1);
|
||||||
|
|
||||||
|
if (data->hascrc)
|
||||||
|
keys += 48; /* skip crc, uuid, ... */
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
||||||
|
@ -263,9 +475,11 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
||||||
grub_uint64_t block = grub_xfs_inode_block (data, ino);
|
grub_uint64_t block = grub_xfs_inode_block (data, ino);
|
||||||
int offset = grub_xfs_inode_offset (data, ino);
|
int offset = grub_xfs_inode_offset (data, ino);
|
||||||
|
|
||||||
|
grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n",
|
||||||
|
ino, block, offset);
|
||||||
/* Read the inode. */
|
/* Read the inode. */
|
||||||
if (grub_disk_read (data->disk, block, offset,
|
if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
|
||||||
1 << data->sblock.log2_inode, inode))
|
inode))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_strncmp ((char *) inode->magic, "IN", 2))
|
if (grub_strncmp ((char *) inode->magic, "IN", 2))
|
||||||
|
@ -274,40 +488,47 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_uint64_t
|
||||||
|
get_fsb (const void *keys, int idx)
|
||||||
|
{
|
||||||
|
const char *p = (const char *) keys + sizeof(grub_uint64_t) * idx;
|
||||||
|
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
|
||||||
|
}
|
||||||
|
|
||||||
static grub_disk_addr_t
|
static grub_disk_addr_t
|
||||||
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
{
|
{
|
||||||
struct grub_xfs_btree_node *leaf = 0;
|
struct grub_xfs_btree_node *leaf = 0;
|
||||||
int ex, nrec;
|
int ex, nrec;
|
||||||
grub_xfs_extent *exts;
|
struct grub_xfs_extent *exts;
|
||||||
grub_uint64_t ret = 0;
|
grub_uint64_t ret = 0;
|
||||||
|
|
||||||
if (node->inode.format == XFS_INODE_FORMAT_BTREE)
|
if (node->inode.format == XFS_INODE_FORMAT_BTREE)
|
||||||
{
|
{
|
||||||
const grub_uint64_t *keys;
|
struct grub_xfs_btree_root *root;
|
||||||
|
const char *keys;
|
||||||
int recoffset;
|
int recoffset;
|
||||||
|
|
||||||
leaf = grub_malloc (node->data->bsize);
|
leaf = grub_malloc (node->data->bsize);
|
||||||
if (leaf == 0)
|
if (leaf == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
|
root = (struct grub_xfs_btree_root *) grub_xfs_inode_data(&node->inode);
|
||||||
keys = &node->inode.data.btree.keys[0];
|
nrec = grub_be_to_cpu16 (root->numrecs);
|
||||||
|
keys = (char *) &root->keys[0];
|
||||||
if (node->inode.fork_offset)
|
if (node->inode.fork_offset)
|
||||||
recoffset = (node->inode.fork_offset - 1) / 2;
|
recoffset = (node->inode.fork_offset - 1) / 2;
|
||||||
else
|
else
|
||||||
recoffset = ((1 << node->data->sblock.log2_inode)
|
recoffset = (grub_xfs_inode_size(node->data)
|
||||||
- ((char *) &node->inode.data.btree.keys
|
- ((char *) keys - (char *) &node->inode))
|
||||||
- (char *) &node->inode))
|
/ (2 * sizeof (grub_uint64_t));
|
||||||
/ (2 * sizeof (grub_uint64_t));
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < nrec; i++)
|
for (i = 0; i < nrec; i++)
|
||||||
{
|
{
|
||||||
if (fileblock < grub_be_to_cpu64 (keys[i]))
|
if (fileblock < get_fsb(keys, i))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,12 +538,16 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
grub_free (leaf);
|
grub_free (leaf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_disk_read (node->data->disk,
|
if (grub_disk_read (node->data->disk,
|
||||||
GRUB_XFS_FSB_TO_BLOCK (node->data, grub_be_to_cpu64 (keys[i - 1 + recoffset])) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
|
GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
|
||||||
0, node->data->bsize, leaf))
|
0, node->data->bsize, leaf))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
|
if ((!node->data->hascrc &&
|
||||||
|
grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
|
||||||
|
(node->data->hascrc &&
|
||||||
|
grub_strncmp ((char *) leaf->magic, "BMA3", 4)))
|
||||||
{
|
{
|
||||||
grub_free (leaf);
|
grub_free (leaf);
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
|
grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
|
||||||
|
@ -330,18 +555,18 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
}
|
}
|
||||||
|
|
||||||
nrec = grub_be_to_cpu16 (leaf->numrecs);
|
nrec = grub_be_to_cpu16 (leaf->numrecs);
|
||||||
keys = &leaf->keys[0];
|
keys = grub_xfs_btree_keys(node->data, leaf);
|
||||||
recoffset = ((node->data->bsize - ((char *) &leaf->keys
|
recoffset = ((node->data->bsize - ((char *) keys
|
||||||
- (char *) leaf))
|
- (char *) leaf))
|
||||||
/ (2 * sizeof (grub_uint64_t)));
|
/ (2 * sizeof (grub_uint64_t)));
|
||||||
}
|
}
|
||||||
while (leaf->level);
|
while (leaf->level);
|
||||||
exts = (grub_xfs_extent *) keys;
|
exts = (struct grub_xfs_extent *) keys;
|
||||||
}
|
}
|
||||||
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
|
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
|
||||||
{
|
{
|
||||||
nrec = grub_be_to_cpu32 (node->inode.nextents);
|
nrec = grub_be_to_cpu32 (node->inode.nextents);
|
||||||
exts = &node->inode.data.extents[0];
|
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -379,13 +604,13 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
POS. Return the amount of read bytes in READ. */
|
POS. Return the amount of read bytes in READ. */
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
grub_xfs_read_file (grub_fshelp_node_t node,
|
grub_xfs_read_file (grub_fshelp_node_t node,
|
||||||
grub_disk_read_hook_t read_hook, void *read_hook_data,
|
grub_disk_read_hook_t read_hook, void *read_hook_data,
|
||||||
grub_off_t pos, grub_size_t len, char *buf)
|
grub_off_t pos, grub_size_t len, char *buf, grub_uint32_t header_size)
|
||||||
{
|
{
|
||||||
return grub_fshelp_read_file (node->data->disk, node,
|
return grub_fshelp_read_file (node->data->disk, node,
|
||||||
read_hook, read_hook_data,
|
read_hook, read_hook_data,
|
||||||
pos, len, buf, grub_xfs_read_block,
|
pos, len, buf, grub_xfs_read_block,
|
||||||
grub_be_to_cpu64 (node->inode.size),
|
grub_be_to_cpu64 (node->inode.size) + header_size,
|
||||||
node->data->sblock.log2_bsize
|
node->data->sblock.log2_bsize
|
||||||
- GRUB_DISK_SECTOR_BITS, 0);
|
- GRUB_DISK_SECTOR_BITS, 0);
|
||||||
}
|
}
|
||||||
|
@ -394,23 +619,34 @@ grub_xfs_read_file (grub_fshelp_node_t node,
|
||||||
static char *
|
static char *
|
||||||
grub_xfs_read_symlink (grub_fshelp_node_t node)
|
grub_xfs_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
int size = grub_be_to_cpu64 (node->inode.size);
|
grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (node->inode.format)
|
switch (node->inode.format)
|
||||||
{
|
{
|
||||||
case XFS_INODE_FORMAT_INO:
|
case XFS_INODE_FORMAT_INO:
|
||||||
return grub_strndup (node->inode.data.raw, size);
|
return grub_strndup (grub_xfs_inode_data(&node->inode), size);
|
||||||
|
|
||||||
case XFS_INODE_FORMAT_EXT:
|
case XFS_INODE_FORMAT_EXT:
|
||||||
{
|
{
|
||||||
char *symlink;
|
char *symlink;
|
||||||
grub_ssize_t numread;
|
grub_ssize_t numread;
|
||||||
|
int off = 0;
|
||||||
|
|
||||||
|
if (node->data->hascrc)
|
||||||
|
off = 56;
|
||||||
|
|
||||||
symlink = grub_malloc (size + 1);
|
symlink = grub_malloc (size + 1);
|
||||||
if (!symlink)
|
if (!symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
numread = grub_xfs_read_file (node, 0, 0, 0, size, symlink);
|
node->inode.size = grub_be_to_cpu64 (size + off);
|
||||||
|
numread = grub_xfs_read_file (node, 0, 0, off, size, symlink, off);
|
||||||
if (numread != size)
|
if (numread != size)
|
||||||
{
|
{
|
||||||
grub_free (symlink);
|
grub_free (symlink);
|
||||||
|
@ -456,9 +692,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
|
||||||
struct grub_fshelp_node *fdiro;
|
struct grub_fshelp_node *fdiro;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
|
fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
|
||||||
- sizeof (struct grub_xfs_inode)
|
|
||||||
+ (1 << ctx->diro->data->sblock.log2_inode) + 1);
|
|
||||||
if (!fdiro)
|
if (!fdiro)
|
||||||
{
|
{
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
|
@ -496,24 +730,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
{
|
{
|
||||||
case XFS_INODE_FORMAT_INO:
|
case XFS_INODE_FORMAT_INO:
|
||||||
{
|
{
|
||||||
struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
|
struct grub_xfs_dir_header *head = (struct grub_xfs_dir_header *) grub_xfs_inode_data(&diro->inode);
|
||||||
int smallino = !diro->inode.data.dir.dirhead.smallino;
|
struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head);
|
||||||
|
int smallino = !head->largeino;
|
||||||
int i;
|
int i;
|
||||||
grub_uint64_t parent;
|
grub_uint64_t parent;
|
||||||
|
|
||||||
/* If small inode numbers are used to pack the direntry, the
|
/* If small inode numbers are used to pack the direntry, the
|
||||||
parent inode number is small too. */
|
parent inode number is small too. */
|
||||||
if (smallino)
|
if (smallino)
|
||||||
{
|
parent = grub_be_to_cpu32 (head->parent.i4);
|
||||||
parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
|
|
||||||
parent = grub_cpu_to_be64 (parent);
|
|
||||||
/* The header is a bit smaller than usual. */
|
|
||||||
de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
parent = grub_be_to_cpu64 (head->parent.i8);
|
||||||
parent = diro->inode.data.dir.dirhead.parent.i8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Synthesize the direntries for `.' and `..'. */
|
/* Synthesize the direntries for `.' and `..'. */
|
||||||
if (iterate_dir_call_hook (diro->ino, ".", &ctx))
|
if (iterate_dir_call_hook (diro->ino, ".", &ctx))
|
||||||
|
@ -522,12 +750,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (iterate_dir_call_hook (parent, "..", &ctx))
|
if (iterate_dir_call_hook (parent, "..", &ctx))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
|
for (i = 0; i < head->count; i++)
|
||||||
{
|
{
|
||||||
grub_uint64_t ino;
|
grub_uint64_t ino;
|
||||||
grub_uint8_t *inopos = (((grub_uint8_t *) de)
|
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
|
||||||
+ sizeof (struct grub_xfs_dir_entry)
|
|
||||||
+ de->len - 1);
|
|
||||||
grub_uint8_t c;
|
grub_uint8_t c;
|
||||||
|
|
||||||
/* inopos might be unaligned. */
|
/* inopos might be unaligned. */
|
||||||
|
@ -545,7 +771,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
| (((grub_uint64_t) inopos[5]) << 16)
|
| (((grub_uint64_t) inopos[5]) << 16)
|
||||||
| (((grub_uint64_t) inopos[6]) << 8)
|
| (((grub_uint64_t) inopos[6]) << 8)
|
||||||
| (((grub_uint64_t) inopos[7]) << 0);
|
| (((grub_uint64_t) inopos[7]) << 0);
|
||||||
ino = grub_cpu_to_be64 (ino);
|
|
||||||
|
|
||||||
c = de->name[de->len];
|
c = de->name[de->len];
|
||||||
de->name[de->len] = '\0';
|
de->name[de->len] = '\0';
|
||||||
|
@ -553,10 +778,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
de->name[de->len] = c;
|
de->name[de->len] = c;
|
||||||
|
|
||||||
de = ((struct grub_xfs_dir_entry *)
|
de = grub_xfs_inline_next_de(dir->data, head, de);
|
||||||
(((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
|
|
||||||
+ ((smallino ? sizeof (grub_uint32_t)
|
|
||||||
: sizeof (grub_uint64_t))) - 1));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -583,19 +805,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
>> dirblk_log2);
|
>> dirblk_log2);
|
||||||
blk++)
|
blk++)
|
||||||
{
|
{
|
||||||
/* The header is skipped, the first direntry is stored
|
struct grub_xfs_dir2_entry *direntry =
|
||||||
from byte 16. */
|
grub_xfs_first_de(dir->data, dirblock);
|
||||||
int pos = 16;
|
|
||||||
int entries;
|
int entries;
|
||||||
int tail_start = (dirblk_size
|
struct grub_xfs_dirblock_tail *tail =
|
||||||
- sizeof (struct grub_xfs_dirblock_tail));
|
grub_xfs_dir_tail(dir->data, dirblock);
|
||||||
|
|
||||||
struct grub_xfs_dirblock_tail *tail;
|
|
||||||
tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
|
|
||||||
|
|
||||||
numread = grub_xfs_read_file (dir, 0, 0,
|
numread = grub_xfs_read_file (dir, 0, 0,
|
||||||
blk << dirblk_log2,
|
blk << dirblk_log2,
|
||||||
dirblk_size, dirblock);
|
dirblk_size, dirblock, 0);
|
||||||
if (numread != dirblk_size)
|
if (numread != dirblk_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -603,14 +821,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
- grub_be_to_cpu32 (tail->leaf_stale));
|
- grub_be_to_cpu32 (tail->leaf_stale));
|
||||||
|
|
||||||
/* Iterate over all entries within this block. */
|
/* Iterate over all entries within this block. */
|
||||||
while (pos < (dirblk_size
|
while ((char *)direntry < (char *)tail)
|
||||||
- (int) sizeof (struct grub_xfs_dir2_entry)))
|
|
||||||
{
|
{
|
||||||
struct grub_xfs_dir2_entry *direntry;
|
|
||||||
grub_uint8_t *freetag;
|
grub_uint8_t *freetag;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
|
|
||||||
freetag = (grub_uint8_t *) direntry;
|
freetag = (grub_uint8_t *) direntry;
|
||||||
|
|
||||||
if (grub_get_unaligned16 (freetag) == 0XFFFF)
|
if (grub_get_unaligned16 (freetag) == 0XFFFF)
|
||||||
|
@ -618,17 +833,20 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));
|
grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));
|
||||||
|
|
||||||
/* This entry is not used, go to the next one. */
|
/* This entry is not used, go to the next one. */
|
||||||
pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip));
|
direntry = (struct grub_xfs_dir2_entry *)
|
||||||
|
(((char *)direntry) +
|
||||||
|
grub_be_to_cpu16 (grub_get_unaligned16 (skip)));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = &dirblock[pos + sizeof (*direntry)];
|
filename = (char *)(direntry + 1);
|
||||||
/* The byte after the filename is for the tag, which
|
/* The byte after the filename is for the filetype, padding, or
|
||||||
is not used by GRUB. So it can be overwritten. */
|
tag, which is not used by GRUB. So it can be overwritten. */
|
||||||
filename[direntry->len] = '\0';
|
filename[direntry->len] = '\0';
|
||||||
|
|
||||||
if (iterate_dir_call_hook (direntry->inode, filename, &ctx))
|
if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
|
||||||
|
filename, &ctx))
|
||||||
{
|
{
|
||||||
grub_free (dirblock);
|
grub_free (dirblock);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -641,8 +859,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Select the next directory entry. */
|
/* Select the next directory entry. */
|
||||||
pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
|
direntry = grub_xfs_next_de(dir->data, direntry);
|
||||||
pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grub_free (dirblock);
|
grub_free (dirblock);
|
||||||
|
@ -667,36 +884,35 @@ grub_xfs_mount (grub_disk_t disk)
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
grub_dprintf("xfs", "Reading sb\n");
|
||||||
/* Read the superblock. */
|
/* Read the superblock. */
|
||||||
if (grub_disk_read (disk, 0, 0,
|
if (grub_disk_read (disk, 0, 0,
|
||||||
sizeof (struct grub_xfs_sblock), &data->sblock))
|
sizeof (struct grub_xfs_sblock), &data->sblock))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
|
if (!grub_xfs_sb_valid(data))
|
||||||
|| data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
|
goto fail;
|
||||||
|| ((int) data->sblock.log2_bsize
|
|
||||||
+ (int) data->sblock.log2_dirblk) >= 27)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = grub_realloc (data,
|
data = grub_realloc (data,
|
||||||
sizeof (struct grub_xfs_data)
|
sizeof (struct grub_xfs_data)
|
||||||
- sizeof (struct grub_xfs_inode)
|
- sizeof (struct grub_xfs_inode)
|
||||||
+ (1 << data->sblock.log2_inode) + 1);
|
+ grub_xfs_inode_size(data) + 1);
|
||||||
|
|
||||||
if (! data)
|
if (! data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->diropen.data = data;
|
data->diropen.data = data;
|
||||||
data->diropen.ino = data->sblock.rootino;
|
data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
|
||||||
data->diropen.inode_read = 1;
|
data->diropen.inode_read = 1;
|
||||||
data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
|
data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
|
||||||
data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
|
data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
|
||||||
|
data->hasftype = grub_xfs_sb_hasftype(data);
|
||||||
|
data->hascrc = grub_xfs_sb_hascrc(data);
|
||||||
|
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
data->pos = 0;
|
data->pos = 0;
|
||||||
|
grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n",
|
||||||
|
grub_cpu_to_be64(data->sblock.rootino));
|
||||||
|
|
||||||
grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
|
grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
|
||||||
|
|
||||||
|
@ -799,10 +1015,7 @@ grub_xfs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
if (fdiro != &data->diropen)
|
if (fdiro != &data->diropen)
|
||||||
{
|
{
|
||||||
grub_memcpy (&data->diropen, fdiro,
|
grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data));
|
||||||
sizeof (struct grub_fshelp_node)
|
|
||||||
- sizeof (struct grub_xfs_inode)
|
|
||||||
+ (1 << data->sblock.log2_inode));
|
|
||||||
grub_free (fdiro);
|
grub_free (fdiro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +1045,7 @@ grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
|
||||||
return grub_xfs_read_file (&data->diropen,
|
return grub_xfs_read_file (&data->diropen,
|
||||||
file->read_hook, file->read_hook_data,
|
file->read_hook, file->read_hook_data,
|
||||||
file->offset, len, buf);
|
file->offset, len, buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,12 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key
|
||||||
*/
|
*/
|
||||||
#define MAX_SUPPORTED_FEATURE_STRLEN 50
|
#define MAX_SUPPORTED_FEATURE_STRLEN 50
|
||||||
static const char *spa_feature_names[] = {
|
static const char *spa_feature_names[] = {
|
||||||
"org.illumos:lz4_compress",NULL
|
"org.illumos:lz4_compress",
|
||||||
|
"com.delphix:hole_birth",
|
||||||
|
"com.delphix:embedded_data",
|
||||||
|
"com.delphix:extensible_dataset",
|
||||||
|
"org.open-zfs:large_blocks",
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1751,7 +1756,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf,
|
||||||
|
|
||||||
for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
|
for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
|
||||||
{
|
{
|
||||||
if (zio_gb->zg_blkptr[i].blk_birth == 0)
|
if (BP_IS_HOLE(&zio_gb->zg_blkptr[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
|
err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
|
||||||
|
@ -1800,6 +1805,39 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
|
||||||
|
* more than BPE_PAYLOAD_SIZE bytes).
|
||||||
|
*/
|
||||||
|
static grub_err_t
|
||||||
|
decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
|
||||||
|
{
|
||||||
|
grub_size_t psize, i;
|
||||||
|
grub_uint8_t *buf8 = buf;
|
||||||
|
grub_uint64_t w = 0;
|
||||||
|
const grub_uint64_t *bp64 = (const grub_uint64_t *)bp;
|
||||||
|
|
||||||
|
psize = BPE_GET_PSIZE(bp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the words of the block pointer into the byte array.
|
||||||
|
* Low bits of first word are the first byte (little endian).
|
||||||
|
*/
|
||||||
|
for (i = 0; i < psize; i++)
|
||||||
|
{
|
||||||
|
if (i % sizeof (w) == 0)
|
||||||
|
{
|
||||||
|
/* beginning of a word */
|
||||||
|
w = *bp64;
|
||||||
|
bp64++;
|
||||||
|
if (!BPE_IS_PAYLOADWORD(bp, bp64))
|
||||||
|
bp64++;
|
||||||
|
}
|
||||||
|
buf8[i] = BF64_GET(w, (i % sizeof (w)) * 8, 8);
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read in a block of data, verify its checksum, decompress if needed,
|
* Read in a block of data, verify its checksum, decompress if needed,
|
||||||
* and put the uncompressed data in buf.
|
* and put the uncompressed data in buf.
|
||||||
|
@ -1818,12 +1856,26 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
|
|
||||||
checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
|
checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
|
||||||
comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff;
|
comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
|
||||||
encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
|
encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
|
||||||
lsize = (BP_IS_HOLE(bp) ? 0 :
|
if (BP_IS_EMBEDDED(bp))
|
||||||
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
|
{
|
||||||
<< SPA_MINBLOCKSHIFT));
|
if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA)
|
||||||
psize = get_psize (bp, endian);
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
"unsupported embedded BP (type=%u)\n",
|
||||||
|
BPE_GET_ETYPE(bp));
|
||||||
|
lsize = BPE_GET_LSIZE(bp);
|
||||||
|
psize = BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), 25, 7, 0, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lsize = (BP_IS_HOLE(bp) ? 0 :
|
||||||
|
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
|
||||||
|
<< SPA_MINBLOCKSHIFT));
|
||||||
|
psize = get_psize (bp, endian);
|
||||||
|
}
|
||||||
|
grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%"
|
||||||
|
PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize);
|
||||||
|
|
||||||
if (size)
|
if (size)
|
||||||
*size = lsize;
|
*size = lsize;
|
||||||
|
@ -1837,33 +1889,41 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
|
||||||
"compression algorithm %s not supported\n", decomp_table[comp].name);
|
"compression algorithm %s not supported\n", decomp_table[comp].name);
|
||||||
|
|
||||||
if (comp != ZIO_COMPRESS_OFF)
|
if (comp != ZIO_COMPRESS_OFF)
|
||||||
{
|
/* It's not really necessary to align to 16, just for safety. */
|
||||||
/* It's not really necessary to align to 16, just for safety. */
|
compbuf = grub_malloc (ALIGN_UP (psize, 16));
|
||||||
compbuf = grub_malloc (ALIGN_UP (psize, 16));
|
|
||||||
if (! compbuf)
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
compbuf = *buf = grub_malloc (lsize);
|
compbuf = *buf = grub_malloc (lsize);
|
||||||
|
if (! compbuf)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
grub_dprintf ("zfs", "endian = %d\n", endian);
|
grub_dprintf ("zfs", "endian = %d\n", endian);
|
||||||
err = zio_read_data (bp, endian, compbuf, data);
|
if (BP_IS_EMBEDDED(bp))
|
||||||
|
err = decode_embedded_bp_compressed(bp, compbuf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = zio_read_data (bp, endian, compbuf, data);
|
||||||
|
/* FIXME is it really necessary? */
|
||||||
|
if (comp != ZIO_COMPRESS_OFF)
|
||||||
|
grub_memset (compbuf + psize, 0, ALIGN_UP (psize, 16) - psize);
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_free (compbuf);
|
grub_free (compbuf);
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
|
|
||||||
|
|
||||||
err = zio_checksum_verify (zc, checksum, endian,
|
if (!BP_IS_EMBEDDED(bp))
|
||||||
compbuf, psize);
|
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
grub_dprintf ("zfs", "incorrect checksum\n");
|
err = zio_checksum_verify (zc, checksum, endian,
|
||||||
grub_free (compbuf);
|
compbuf, psize);
|
||||||
*buf = NULL;
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_dprintf ("zfs", "incorrect checksum\n");
|
||||||
|
grub_free (compbuf);
|
||||||
|
*buf = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
|
@ -2013,10 +2073,10 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
|
||||||
*/
|
*/
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
|
mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
|
||||||
grub_uint16_t objsize, const char *name, grub_uint64_t * value,
|
grub_uint32_t objsize, const char *name, grub_uint64_t * value,
|
||||||
int case_insensitive)
|
int case_insensitive)
|
||||||
{
|
{
|
||||||
grub_uint16_t i, chunks;
|
grub_uint32_t i, chunks;
|
||||||
mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
|
mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
|
||||||
|
|
||||||
if (objsize < MZAP_ENT_LEN)
|
if (objsize < MZAP_ENT_LEN)
|
||||||
|
@ -2428,7 +2488,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
|
||||||
struct grub_zfs_data *data, int case_insensitive)
|
struct grub_zfs_data *data, int case_insensitive)
|
||||||
{
|
{
|
||||||
grub_uint64_t block_type;
|
grub_uint64_t block_type;
|
||||||
grub_uint16_t size;
|
grub_uint32_t size;
|
||||||
void *zapbuf;
|
void *zapbuf;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_zfs_endian_t endian;
|
grub_zfs_endian_t endian;
|
||||||
|
@ -2436,7 +2496,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
|
||||||
grub_dprintf ("zfs", "looking for '%s'\n", name);
|
grub_dprintf ("zfs", "looking for '%s'\n", name);
|
||||||
|
|
||||||
/* Read in the first block of the zap object data. */
|
/* Read in the first block of the zap object data. */
|
||||||
size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
|
size = (grub_uint32_t) grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
|
||||||
zap_dnode->endian) << SPA_MINBLOCKSHIFT;
|
zap_dnode->endian) << SPA_MINBLOCKSHIFT;
|
||||||
err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
|
err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -2822,7 +2882,10 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
|
||||||
|
|
||||||
err = dmu_read (&(dnode_path->dn), block, &t, 0, data);
|
err = dmu_read (&(dnode_path->dn), block, &t, 0, data);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_free (sym_value);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
movesize = sym_sz - block * blksz;
|
movesize = sym_sz - block * blksz;
|
||||||
if (movesize > blksz)
|
if (movesize > blksz)
|
||||||
|
@ -3022,7 +3085,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
|
||||||
|
|
||||||
grub_dprintf ("zfs", "alive\n");
|
grub_dprintf ("zfs", "alive\n");
|
||||||
|
|
||||||
err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
|
err = dnode_get (mosmdn, objnum, 0, mdn, data);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -3055,7 +3118,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
|
err = dnode_get (mosmdn, objnum, 0, mdn, data);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -3210,8 +3273,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
|
||||||
|
|
||||||
grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
|
grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
|
||||||
|
|
||||||
err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &subvol->mdn,
|
err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data);
|
||||||
data);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_free (fsname);
|
grub_free (fsname);
|
||||||
|
@ -3607,7 +3669,12 @@ zfs_mount (grub_device_t dev)
|
||||||
if (ub->ub_version >= SPA_VERSION_FEATURES &&
|
if (ub->ub_version >= SPA_VERSION_FEATURES &&
|
||||||
check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian,
|
check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian,
|
||||||
data) != 0)
|
data) != 0)
|
||||||
return NULL;
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool");
|
||||||
|
grub_free (osp);
|
||||||
|
zfs_unmount (data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Got the MOS. Save it at the memory addr MOS. */
|
/* Got the MOS. Save it at the memory addr MOS. */
|
||||||
grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode,
|
grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode,
|
||||||
|
@ -3905,7 +3972,7 @@ fill_fs_info (struct grub_dirhook_info *info,
|
||||||
{
|
{
|
||||||
headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian);
|
headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian);
|
||||||
|
|
||||||
err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &mdn, data);
|
err = dnode_get (&(data->mos), headobj, 0, &mdn, data);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_dprintf ("zfs", "failed here\n");
|
grub_dprintf ("zfs", "failed here\n");
|
||||||
|
|
|
@ -67,7 +67,7 @@ grub_machine_fini (int flags)
|
||||||
|
|
||||||
b = grub_efi_system_table->boot_services;
|
b = grub_efi_system_table->boot_services;
|
||||||
|
|
||||||
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 0);
|
efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0);
|
||||||
efi_call_1 (b->close_event, tmr_evt);
|
efi_call_1 (b->close_event, tmr_evt);
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
|
@ -381,9 +381,24 @@ __aeabi_idiv (grub_int32_t a, grub_int32_t b)
|
||||||
__attribute__ ((alias ("__divsi3")));
|
__attribute__ ((alias ("__divsi3")));
|
||||||
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
|
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
|
||||||
__attribute__ ((alias ("grub_memcpy")));
|
__attribute__ ((alias ("grub_memcpy")));
|
||||||
|
void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
|
||||||
|
__attribute__ ((alias ("grub_memcpy")));
|
||||||
|
void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
|
||||||
|
__attribute__ ((alias ("grub_memcpy")));
|
||||||
void *__aeabi_memset (void *s, int c, grub_size_t n)
|
void *__aeabi_memset (void *s, int c, grub_size_t n)
|
||||||
__attribute__ ((alias ("memset")));
|
__attribute__ ((alias ("memset")));
|
||||||
|
|
||||||
|
void
|
||||||
|
__aeabi_memclr (void *s, grub_size_t n)
|
||||||
|
{
|
||||||
|
grub_memset (s, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __aeabi_memclr4 (void *s, grub_size_t n)
|
||||||
|
__attribute__ ((alias ("__aeabi_memclr")));
|
||||||
|
void __aeabi_memclr8 (void *s, grub_size_t n)
|
||||||
|
__attribute__ ((alias ("__aeabi_memclr")));
|
||||||
|
|
||||||
int
|
int
|
||||||
__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
|
__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/kernel.h>
|
#include <grub/kernel.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
|
||||||
/* The handle of GRUB itself. Filled in by the startup code. */
|
/* The handle of GRUB itself. Filled in by the startup code. */
|
||||||
grub_efi_handle_t grub_efi_image_handle;
|
grub_efi_handle_t grub_efi_image_handle;
|
||||||
|
@ -156,7 +157,7 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
|
||||||
void
|
void
|
||||||
grub_exit (void)
|
grub_exit (void)
|
||||||
{
|
{
|
||||||
grub_efi_fini ();
|
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||||
efi_call_4 (grub_efi_system_table->boot_services->exit,
|
efi_call_4 (grub_efi_system_table->boot_services->exit,
|
||||||
grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
|
grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
|
||||||
for (;;) ;
|
for (;;) ;
|
||||||
|
@ -205,6 +206,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||||
| GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
|
| GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
| GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
|
| GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
|
||||||
datasize, data);
|
datasize, data);
|
||||||
|
grub_free (var16);
|
||||||
if (status == GRUB_EFI_SUCCESS)
|
if (status == GRUB_EFI_SUCCESS)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
@ -236,8 +238,11 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||||
|
|
||||||
status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL);
|
status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL);
|
||||||
|
|
||||||
if (!datasize)
|
if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
|
||||||
return NULL;
|
{
|
||||||
|
grub_free (var16);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
data = grub_malloc (datasize);
|
data = grub_malloc (datasize);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -422,6 +427,47 @@ grub_efi_get_device_path (grub_efi_handle_t handle)
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the device path node right before the end node. */
|
||||||
|
grub_efi_device_path_t *
|
||||||
|
grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
|
||||||
|
{
|
||||||
|
grub_efi_device_path_t *next, *p;
|
||||||
|
|
||||||
|
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
|
||||||
|
! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
|
||||||
|
p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
|
||||||
|
;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Duplicate a device path. */
|
||||||
|
grub_efi_device_path_t *
|
||||||
|
grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
|
||||||
|
{
|
||||||
|
grub_efi_device_path_t *p;
|
||||||
|
grub_size_t total_size = 0;
|
||||||
|
|
||||||
|
for (p = (grub_efi_device_path_t *) dp;
|
||||||
|
;
|
||||||
|
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
||||||
|
{
|
||||||
|
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
||||||
|
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = grub_malloc (total_size);
|
||||||
|
if (! p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
grub_memcpy (p, dp, total_size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
||||||
{
|
{
|
||||||
|
|
|
@ -422,7 +422,7 @@ read_device_map (const char *dev_map)
|
||||||
char buf[1024]; /* XXX */
|
char buf[1024]; /* XXX */
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
|
|
||||||
if (dev_map[0] == '\0')
|
if (!dev_map || dev_map[0] == '\0')
|
||||||
{
|
{
|
||||||
grub_util_info ("no device.map");
|
grub_util_info ("no device.map");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/cpu/kernel.h>
|
|
||||||
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
mips_attributes
|
|
||||||
|
|
||||||
FUNCTION (grub_arch_sync_caches)
|
FUNCTION (grub_arch_sync_caches)
|
||||||
#include "cache_flush.S"
|
#include "cache_flush.S"
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/cpu/kernel.h>
|
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
#define BASE_ADDR 8
|
#define BASE_ADDR 8
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
.globl __start, _start, start
|
.globl __start, _start, start
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
mips_attributes
|
|
||||||
__start:
|
__start:
|
||||||
_start:
|
_start:
|
||||||
start:
|
start:
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
|
||||||
.file "setjmp.S"
|
.file "setjmp.S"
|
||||||
|
GRUB_MOD_LICENSE "GPLv3+"
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -64,7 +64,6 @@ extern grub_uint64_t grub_relocator64_rbx;
|
||||||
extern grub_uint64_t grub_relocator64_rcx;
|
extern grub_uint64_t grub_relocator64_rcx;
|
||||||
extern grub_uint64_t grub_relocator64_rdx;
|
extern grub_uint64_t grub_relocator64_rdx;
|
||||||
extern grub_uint64_t grub_relocator64_rip;
|
extern grub_uint64_t grub_relocator64_rip;
|
||||||
extern grub_uint64_t grub_relocator64_rip_addr;
|
|
||||||
extern grub_uint64_t grub_relocator64_rsp;
|
extern grub_uint64_t grub_relocator64_rsp;
|
||||||
extern grub_uint64_t grub_relocator64_rsi;
|
extern grub_uint64_t grub_relocator64_rsi;
|
||||||
extern grub_addr_t grub_relocator64_cr3;
|
extern grub_addr_t grub_relocator64_cr3;
|
||||||
|
|
|
@ -17,13 +17,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/cpu/kernel.h>
|
|
||||||
|
|
||||||
.p2align 4 /* force 16-byte alignment */
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
mips_attributes
|
|
||||||
|
|
||||||
VARIABLE (grub_relocator_forward_start)
|
VARIABLE (grub_relocator_forward_start)
|
||||||
move $a0, $9
|
move $a0, $9
|
||||||
|
|
|
@ -362,7 +362,7 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
|
||||||
|
|
||||||
/* Nothing to do. */
|
/* Nothing to do. */
|
||||||
if (!rs)
|
if (!rs)
|
||||||
return;
|
goto exit;
|
||||||
|
|
||||||
init_powx ();
|
init_powx ();
|
||||||
|
|
||||||
|
@ -388,6 +388,7 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
|
||||||
#ifndef TEST
|
#ifndef TEST
|
||||||
assert (grub_memcmp (tmp, buffer, data_size) == 0);
|
assert (grub_memcmp (tmp, buffer, data_size) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
exit:
|
||||||
free (tmp);
|
free (tmp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -772,7 +772,7 @@ print_escaped (struct output_buffer *outbuf,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
outbuf->buf[outbuf->ptr++] = '\'';
|
outbuf->buf[outbuf->ptr++] = '\'';
|
||||||
for (ptr = from; *ptr; ptr++)
|
for (ptr = from; *ptr && ptr < to; ptr++)
|
||||||
{
|
{
|
||||||
if (*ptr == '\'')
|
if (*ptr == '\'')
|
||||||
{
|
{
|
||||||
|
@ -874,7 +874,9 @@ print_config (struct output_buffer *outbuf,
|
||||||
print_string ("#");
|
print_string ("#");
|
||||||
print_file (outbuf, menu, filename, NULL);
|
print_file (outbuf, menu, filename, NULL);
|
||||||
print_string (" ");
|
print_string (" ");
|
||||||
print (outbuf, newname, grub_strlen (newname));
|
err = print (outbuf, newname, grub_strlen (newname));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
print_string (":\n");
|
print_string (":\n");
|
||||||
|
|
||||||
for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++)
|
for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++)
|
||||||
|
@ -944,8 +946,8 @@ write_entry (struct output_buffer *outbuf,
|
||||||
{
|
{
|
||||||
case KERNEL_LINUX:
|
case KERNEL_LINUX:
|
||||||
{
|
{
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
char *initrd = NULL;
|
const char *initrd = NULL, *initrde= NULL;
|
||||||
for (ptr = curentry->append; ptr && *ptr; ptr++)
|
for (ptr = curentry->append; ptr && *ptr; ptr++)
|
||||||
if ((ptr == curentry->append || grub_isspace (ptr[-1]))
|
if ((ptr == curentry->append || grub_isspace (ptr[-1]))
|
||||||
&& grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1)
|
&& grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1)
|
||||||
|
@ -953,12 +955,8 @@ write_entry (struct output_buffer *outbuf,
|
||||||
break;
|
break;
|
||||||
if (ptr && *ptr)
|
if (ptr && *ptr)
|
||||||
{
|
{
|
||||||
char *ptr2;
|
initrd = ptr + sizeof ("initrd=") - 1;
|
||||||
initrd = grub_strdup(ptr + sizeof ("initrd=") - 1);
|
for (initrde = initrd; *initrde && !grub_isspace (*initrde); initrde++);
|
||||||
if (!initrd)
|
|
||||||
return grub_errno;
|
|
||||||
for (ptr2 = initrd; *ptr2 && !grub_isspace (*ptr2); ptr2++);
|
|
||||||
*ptr2 = 0;
|
|
||||||
}
|
}
|
||||||
print_string (" if test x$grub_platform = xpc; then "
|
print_string (" if test x$grub_platform = xpc; then "
|
||||||
"linux_suffix=16; else linux_suffix= ; fi\n");
|
"linux_suffix=16; else linux_suffix= ; fi\n");
|
||||||
|
@ -966,7 +964,11 @@ write_entry (struct output_buffer *outbuf,
|
||||||
print_file (outbuf, menu, curentry->kernel_file, NULL);
|
print_file (outbuf, menu, curentry->kernel_file, NULL);
|
||||||
print_string (" ");
|
print_string (" ");
|
||||||
if (curentry->append)
|
if (curentry->append)
|
||||||
print (outbuf, curentry->append, grub_strlen (curentry->append));
|
{
|
||||||
|
err = print (outbuf, curentry->append, grub_strlen (curentry->append));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
print_string ("\n");
|
print_string ("\n");
|
||||||
if (initrd || curentry->initrds)
|
if (initrd || curentry->initrds)
|
||||||
{
|
{
|
||||||
|
@ -974,7 +976,7 @@ write_entry (struct output_buffer *outbuf,
|
||||||
print_string (" initrd$linux_suffix ");
|
print_string (" initrd$linux_suffix ");
|
||||||
if (initrd)
|
if (initrd)
|
||||||
{
|
{
|
||||||
print_file (outbuf, menu, initrd, NULL);
|
print_file (outbuf, menu, initrd, initrde);
|
||||||
print_string (" ");
|
print_string (" ");
|
||||||
}
|
}
|
||||||
for (lst = curentry->initrds; lst; lst = lst->next)
|
for (lst = curentry->initrds; lst; lst = lst->next)
|
||||||
|
@ -985,7 +987,6 @@ write_entry (struct output_buffer *outbuf,
|
||||||
|
|
||||||
print_string ("\n");
|
print_string ("\n");
|
||||||
}
|
}
|
||||||
grub_free (initrd);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KERNEL_CHAINLOADER:
|
case KERNEL_CHAINLOADER:
|
||||||
|
@ -1197,8 +1198,7 @@ write_entry (struct output_buffer *outbuf,
|
||||||
ptr++;
|
ptr++;
|
||||||
i386e = ptr;
|
i386e = ptr;
|
||||||
}
|
}
|
||||||
if (lme)
|
*lme = '\0';
|
||||||
*lme = '\0';
|
|
||||||
if (paee)
|
if (paee)
|
||||||
*paee = '\0';
|
*paee = '\0';
|
||||||
if (i386e)
|
if (i386e)
|
||||||
|
|
|
@ -33,12 +33,6 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_EFI_PAGE_SHIFT 12
|
|
||||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT)
|
|
||||||
#define GRUB_EFI_PE_MAGIC 0x5A4D
|
|
||||||
|
|
||||||
static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
static int loaded;
|
static int loaded;
|
||||||
|
|
||||||
|
@ -58,6 +52,7 @@ static void *
|
||||||
get_firmware_fdt (void)
|
get_firmware_fdt (void)
|
||||||
{
|
{
|
||||||
grub_efi_configuration_table_t *tables;
|
grub_efi_configuration_table_t *tables;
|
||||||
|
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||||
void *firmware_fdt = NULL;
|
void *firmware_fdt = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -75,8 +70,8 @@ get_firmware_fdt (void)
|
||||||
return firmware_fdt;
|
return firmware_fdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void *
|
||||||
get_fdt (void)
|
grub_linux_get_fdt (void)
|
||||||
{
|
{
|
||||||
void *raw_fdt;
|
void *raw_fdt;
|
||||||
grub_size_t size;
|
grub_size_t size;
|
||||||
|
@ -99,7 +94,7 @@ get_fdt (void)
|
||||||
grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size);
|
grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size);
|
||||||
fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size));
|
fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size));
|
||||||
if (!fdt)
|
if (!fdt)
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
if (raw_fdt)
|
if (raw_fdt)
|
||||||
{
|
{
|
||||||
|
@ -110,10 +105,11 @@ get_fdt (void)
|
||||||
{
|
{
|
||||||
grub_fdt_create_empty_tree (fdt, size);
|
grub_fdt_create_empty_tree (fdt, size);
|
||||||
}
|
}
|
||||||
|
return fdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
check_kernel (struct grub_arm64_linux_kernel_header *lh)
|
grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header * lh)
|
||||||
{
|
{
|
||||||
if (lh->magic != GRUB_ARM64_LINUX_MAGIC)
|
if (lh->magic != GRUB_ARM64_LINUX_MAGIC)
|
||||||
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
||||||
|
@ -131,14 +127,14 @@ check_kernel (struct grub_arm64_linux_kernel_header *lh)
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
finalize_params (void)
|
finalize_params_linux (void)
|
||||||
{
|
{
|
||||||
grub_efi_boot_services_t *b;
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||||
grub_efi_status_t status;
|
grub_efi_status_t status;
|
||||||
int node, retval;
|
int node, retval;
|
||||||
|
|
||||||
get_fdt ();
|
if (!grub_linux_get_fdt ())
|
||||||
if (!fdt)
|
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||||
|
@ -240,21 +236,16 @@ out:
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
grub_linux_boot (void)
|
grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||||
{
|
{
|
||||||
grub_efi_memory_mapped_device_path_t *mempath;
|
grub_efi_memory_mapped_device_path_t *mempath;
|
||||||
grub_efi_handle_t image_handle;
|
grub_efi_handle_t image_handle;
|
||||||
grub_efi_boot_services_t *b;
|
grub_efi_boot_services_t *b;
|
||||||
grub_efi_status_t status;
|
grub_efi_status_t status;
|
||||||
grub_err_t retval;
|
|
||||||
grub_efi_loaded_image_t *loaded_image;
|
grub_efi_loaded_image_t *loaded_image;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
retval = finalize_params();
|
|
||||||
if (retval != GRUB_ERR_NONE)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
||||||
if (!mempath)
|
if (!mempath)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -263,8 +254,8 @@ grub_linux_boot (void)
|
||||||
mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
||||||
mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
||||||
mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
||||||
mempath[0].start_address = (grub_addr_t) kernel_addr;
|
mempath[0].start_address = addr;
|
||||||
mempath[0].end_address = (grub_addr_t) kernel_addr + kernel_size;
|
mempath[0].end_address = addr + size;
|
||||||
|
|
||||||
mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
@ -273,16 +264,16 @@ grub_linux_boot (void)
|
||||||
b = grub_efi_system_table->boot_services;
|
b = grub_efi_system_table->boot_services;
|
||||||
status = b->load_image (0, grub_efi_image_handle,
|
status = b->load_image (0, grub_efi_image_handle,
|
||||||
(grub_efi_device_path_t *) mempath,
|
(grub_efi_device_path_t *) mempath,
|
||||||
kernel_addr, kernel_size, &image_handle);
|
(void *) addr, size, &image_handle);
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||||
|
|
||||||
grub_dprintf ("linux", "linux command line: '%s'\n", linux_args);
|
grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||||
|
|
||||||
/* Convert command line to UCS-2 */
|
/* Convert command line to UCS-2 */
|
||||||
loaded_image = grub_efi_get_loaded_image (image_handle);
|
loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||||
loaded_image->load_options_size = len =
|
loaded_image->load_options_size = len =
|
||||||
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
(grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
|
||||||
loaded_image->load_options =
|
loaded_image->load_options =
|
||||||
grub_efi_allocate_pages (0,
|
grub_efi_allocate_pages (0,
|
||||||
BYTES_TO_PAGES (loaded_image->load_options_size));
|
BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||||
|
@ -291,9 +282,9 @@ grub_linux_boot (void)
|
||||||
|
|
||||||
loaded_image->load_options_size =
|
loaded_image->load_options_size =
|
||||||
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||||
(grub_uint8_t *) linux_args, len, NULL);
|
(grub_uint8_t *) args, len, NULL);
|
||||||
|
|
||||||
grub_dprintf("linux", "starting image %p\n", image_handle);
|
grub_dprintf ("linux", "starting image %p\n", image_handle);
|
||||||
status = b->start_image (image_handle, 0, NULL);
|
status = b->start_image (image_handle, 0, NULL);
|
||||||
|
|
||||||
/* When successful, not reached */
|
/* When successful, not reached */
|
||||||
|
@ -304,6 +295,16 @@ grub_linux_boot (void)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_boot (void)
|
||||||
|
{
|
||||||
|
if (finalize_params_linux () != GRUB_ERR_NONE)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr,
|
||||||
|
kernel_size, linux_args));
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_unload (void)
|
grub_linux_unload (void)
|
||||||
{
|
{
|
||||||
|
@ -400,7 +401,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (check_kernel (&lh) != GRUB_ERR_NONE)
|
if (grub_arm64_uefi_check_image (&lh) != GRUB_ERR_NONE)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_loader_unset();
|
grub_loader_unset();
|
||||||
|
|
|
@ -350,8 +350,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
loaded_image->device_handle = dev_handle;
|
loaded_image->device_handle = dev_handle;
|
||||||
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
|
@ -381,6 +379,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
loaded_image->load_options_size = len;
|
loaded_image->load_options_size = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_device_close (dev);
|
||||||
|
|
||||||
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -84,11 +84,11 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
|
||||||
grub_size_t chunk_size = 0;
|
grub_size_t chunk_size = 0;
|
||||||
void *chunk_src;
|
void *chunk_src;
|
||||||
|
|
||||||
|
curload = module = ALIGN_PAGE (*kern_end);
|
||||||
|
|
||||||
err = read_headers (file, argv[0], &e, &shdr);
|
err = read_headers (file, argv[0], &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
curload = module = ALIGN_PAGE (*kern_end);
|
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
@ -109,7 +109,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
|
||||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
module, chunk_size);
|
module, chunk_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
chunk_src = get_virtual_current_address (ch);
|
chunk_src = get_virtual_current_address (ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
|
||||||
err = load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end,
|
err = load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end,
|
||||||
s->sh_offset, s->sh_size);
|
s->sh_offset, s->sh_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
break;
|
break;
|
||||||
case SHT_NOBITS:
|
case SHT_NOBITS:
|
||||||
grub_memset ((grub_uint8_t *) chunk_src + curload - *kern_end, 0,
|
grub_memset ((grub_uint8_t *) chunk_src + curload - *kern_end, 0,
|
||||||
|
@ -159,6 +159,8 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
|
||||||
| FREEBSD_MODINFOMD_SHDR,
|
| FREEBSD_MODINFOMD_SHDR,
|
||||||
shdr, e.e_shnum * e.e_shentsize);
|
shdr, e.e_shnum * e.e_shentsize);
|
||||||
|
|
||||||
|
out:
|
||||||
|
grub_free (shdr);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,11 +179,11 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||||
grub_size_t chunk_size = 0;
|
grub_size_t chunk_size = 0;
|
||||||
void *chunk_src;
|
void *chunk_src;
|
||||||
|
|
||||||
|
curload = module = ALIGN_PAGE (*kern_end);
|
||||||
|
|
||||||
err = read_headers (file, argv[0], &e, &shdr);
|
err = read_headers (file, argv[0], &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
curload = module = ALIGN_PAGE (*kern_end);
|
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
@ -207,7 +209,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
module, chunk_size);
|
module, chunk_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
chunk_src = get_virtual_current_address (ch);
|
chunk_src = get_virtual_current_address (ch);
|
||||||
}
|
}
|
||||||
|
@ -235,7 +237,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||||
+ s->sh_addr - *kern_end,
|
+ s->sh_addr - *kern_end,
|
||||||
s->sh_offset, s->sh_size);
|
s->sh_offset, s->sh_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
break;
|
break;
|
||||||
case SHT_NOBITS:
|
case SHT_NOBITS:
|
||||||
grub_memset ((grub_uint8_t *) chunk_src + module
|
grub_memset ((grub_uint8_t *) chunk_src + module
|
||||||
|
@ -265,6 +267,10 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||||
grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
|
grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
|
||||||
argc - 1, argv + 1, module,
|
argc - 1, argv + 1, module,
|
||||||
curload - module);
|
curload - module);
|
||||||
|
out:
|
||||||
|
grub_free (shdr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
return SUFFIX (grub_freebsd_load_elf_meta) (relocator, file, argv[0], kern_end);
|
return SUFFIX (grub_freebsd_load_elf_meta) (relocator, file, argv[0], kern_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,13 +298,13 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
|
|
||||||
err = read_headers (file, filename, &e, &shdr);
|
err = read_headers (file, filename, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_ELFHDR, &e,
|
FREEBSD_MODINFOMD_ELFHDR, &e,
|
||||||
sizeof (e));
|
sizeof (e));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
@ -307,7 +313,10 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
break;
|
break;
|
||||||
if (s >= (Elf_Shdr *) ((char *) shdr
|
if (s >= (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize))
|
+ e.e_shnum * e.e_shentsize))
|
||||||
return grub_error (GRUB_ERR_BAD_OS, N_("no symbol table"));
|
{
|
||||||
|
err = grub_error (GRUB_ERR_BAD_OS, N_("no symbol table"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
symoff = s->sh_offset;
|
symoff = s->sh_offset;
|
||||||
symsize = s->sh_size;
|
symsize = s->sh_size;
|
||||||
symentsize = s->sh_entsize;
|
symentsize = s->sh_entsize;
|
||||||
|
@ -325,7 +334,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
symtarget, chunk_size);
|
symtarget, chunk_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
sym_chunk = get_virtual_current_address (ch);
|
sym_chunk = get_virtual_current_address (ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,28 +346,38 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
curload += sizeof (grub_freebsd_addr_t);
|
curload += sizeof (grub_freebsd_addr_t);
|
||||||
|
|
||||||
if (grub_file_seek (file, symoff) == (grub_off_t) -1)
|
if (grub_file_seek (file, symoff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
sym = (Elf_Sym *) curload;
|
sym = (Elf_Sym *) curload;
|
||||||
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
filename);
|
filename);
|
||||||
return grub_errno;
|
else
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
curload += symsize;
|
curload += symsize;
|
||||||
|
|
||||||
*((grub_freebsd_addr_t *) curload) = strsize;
|
*((grub_freebsd_addr_t *) curload) = strsize;
|
||||||
curload += sizeof (grub_freebsd_addr_t);
|
curload += sizeof (grub_freebsd_addr_t);
|
||||||
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
str = (char *) curload;
|
str = (char *) curload;
|
||||||
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
filename);
|
filename);
|
||||||
return grub_errno;
|
else
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
|
@ -378,18 +397,20 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
|
FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
|
||||||
sizeof (dynamic));
|
sizeof (dynamic));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_SSYM, &symstart,
|
FREEBSD_MODINFOMD_SSYM, &symstart,
|
||||||
sizeof (symstart));
|
sizeof (symstart));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_ESYM, &symend,
|
FREEBSD_MODINFOMD_ESYM, &symend,
|
||||||
sizeof (symend));
|
sizeof (symend));
|
||||||
|
out:
|
||||||
|
grub_free (shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -417,7 +438,10 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
|
|
||||||
err = read_headers (file, filename, &e, &shdr);
|
err = read_headers (file, filename, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_free (shdr);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
@ -426,7 +450,10 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
break;
|
break;
|
||||||
if (s >= (Elf_Shdr *) ((char *) shdr
|
if (s >= (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize))
|
+ e.e_shnum * e.e_shentsize))
|
||||||
return GRUB_ERR_NONE;
|
{
|
||||||
|
grub_free (shdr);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
symsize = s->sh_size;
|
symsize = s->sh_size;
|
||||||
symsh = s;
|
symsh = s;
|
||||||
s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
|
s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
|
||||||
|
@ -443,7 +470,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
symtarget, chunk_size);
|
symtarget, chunk_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
sym_chunk = get_virtual_current_address (ch);
|
sym_chunk = get_virtual_current_address (ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,29 +509,41 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_file_seek (file, symsh->sh_offset) == (grub_off_t) -1)
|
if (grub_file_seek (file, symsh->sh_offset) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
filename);
|
filename);
|
||||||
return grub_errno;
|
else
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
curload += ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t));
|
curload += ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t));
|
||||||
|
|
||||||
if (grub_file_seek (file, strsh->sh_offset) == (grub_off_t) -1)
|
if (grub_file_seek (file, strsh->sh_offset) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
filename);
|
filename);
|
||||||
return grub_errno;
|
else
|
||||||
|
err = grub_errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB,
|
err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB,
|
||||||
&symtab,
|
&symtab,
|
||||||
sizeof (symtab));
|
sizeof (symtab));
|
||||||
|
out:
|
||||||
|
grub_free (shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -530,7 +569,10 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
|
||||||
|
|
||||||
err = read_headers (file, filename, &e, &shdr);
|
err = read_headers (file, filename, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
grub_free (shdr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
@ -583,7 +625,11 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
grub_free (strs);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize)
|
if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize)
|
||||||
{
|
{
|
||||||
grub_free (syms);
|
grub_free (syms);
|
||||||
|
|
|
@ -70,7 +70,6 @@ static grub_addr_t prot_mode_target;
|
||||||
static void *initrd_mem;
|
static void *initrd_mem;
|
||||||
static grub_addr_t initrd_mem_target;
|
static grub_addr_t initrd_mem_target;
|
||||||
static grub_size_t prot_init_space;
|
static grub_size_t prot_init_space;
|
||||||
static grub_uint32_t initrd_pages;
|
|
||||||
static struct grub_relocator *relocator = NULL;
|
static struct grub_relocator *relocator = NULL;
|
||||||
static void *efi_mmap_buf;
|
static void *efi_mmap_buf;
|
||||||
static grub_size_t maximal_cmdline_size;
|
static grub_size_t maximal_cmdline_size;
|
||||||
|
@ -1048,7 +1047,7 @@ static grub_err_t
|
||||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
grub_size_t size = 0;
|
grub_size_t size = 0, aligned_size = 0;
|
||||||
grub_addr_t addr_min, addr_max;
|
grub_addr_t addr_min, addr_max;
|
||||||
grub_addr_t addr;
|
grub_addr_t addr;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -1070,8 +1069,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
size = grub_get_initrd_size (&initrd_ctx);
|
size = grub_get_initrd_size (&initrd_ctx);
|
||||||
|
aligned_size = ALIGN_UP (size, 4096);
|
||||||
initrd_pages = (page_align (size) >> 12);
|
|
||||||
|
|
||||||
/* Get the highest address available for the initrd. */
|
/* Get the highest address available for the initrd. */
|
||||||
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
|
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
|
||||||
|
@ -1099,7 +1097,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
|
addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
|
||||||
|
|
||||||
/* Put the initrd as high as possible, 4KiB aligned. */
|
/* Put the initrd as high as possible, 4KiB aligned. */
|
||||||
addr = (addr_max - size) & ~0xFFF;
|
addr = (addr_max - aligned_size) & ~0xFFF;
|
||||||
|
|
||||||
if (addr < addr_min)
|
if (addr < addr_min)
|
||||||
{
|
{
|
||||||
|
@ -1110,7 +1108,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
addr_min, addr, size, 0x1000,
|
addr_min, addr, aligned_size,
|
||||||
|
0x1000,
|
||||||
GRUB_RELOCATOR_PREFERENCE_HIGH,
|
GRUB_RELOCATOR_PREFERENCE_HIGH,
|
||||||
1);
|
1);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -269,9 +269,9 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
|
||||||
prop->data = grub_malloc (prop->length);
|
prop->data = grub_malloc (prop->length);
|
||||||
if (!prop->data)
|
if (!prop->data)
|
||||||
{
|
{
|
||||||
grub_free (prop);
|
|
||||||
grub_free (prop->name);
|
grub_free (prop->name);
|
||||||
grub_free (prop->name16);
|
grub_free (prop->name16);
|
||||||
|
grub_free (prop);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
grub_memcpy (prop->data, data, prop->length);
|
grub_memcpy (prop->data, data, prop->length);
|
||||||
|
|
|
@ -161,6 +161,9 @@ grub_initrd_init (int argc, char *argv[],
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
const char *fname = argv[i];
|
const char *fname = argv[i];
|
||||||
|
|
||||||
|
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||||
|
|
||||||
if (grub_memcmp (argv[i], "newc:", 5) == 0)
|
if (grub_memcmp (argv[i], "newc:", 5) == 0)
|
||||||
{
|
{
|
||||||
const char *ptr, *eptr;
|
const char *ptr, *eptr;
|
||||||
|
@ -205,11 +208,12 @@ grub_initrd_init (int argc, char *argv[],
|
||||||
initrd_ctx->nfiles++;
|
initrd_ctx->nfiles++;
|
||||||
initrd_ctx->components[i].size
|
initrd_ctx->components[i].size
|
||||||
= grub_file_size (initrd_ctx->components[i].file);
|
= grub_file_size (initrd_ctx->components[i].file);
|
||||||
initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
|
initrd_ctx->size += initrd_ctx->components[i].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newc)
|
if (newc)
|
||||||
{
|
{
|
||||||
|
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||||
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
||||||
+ sizeof ("TRAILER!!!") - 1, 4);
|
+ sizeof ("TRAILER!!!") - 1, 4);
|
||||||
free_dir (root);
|
free_dir (root);
|
||||||
|
@ -248,10 +252,12 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||||
int i;
|
int i;
|
||||||
int newc = 0;
|
int newc = 0;
|
||||||
struct dir *root = 0;
|
struct dir *root = 0;
|
||||||
|
grub_ssize_t cursize = 0;
|
||||||
|
|
||||||
for (i = 0; i < initrd_ctx->nfiles; i++)
|
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||||
{
|
{
|
||||||
grub_ssize_t cursize;
|
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||||
|
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||||
|
|
||||||
if (initrd_ctx->components[i].newc_name)
|
if (initrd_ctx->components[i].newc_name)
|
||||||
{
|
{
|
||||||
|
@ -283,11 +289,13 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
ptr += cursize;
|
ptr += cursize;
|
||||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
|
||||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
|
||||||
}
|
}
|
||||||
if (newc)
|
if (newc)
|
||||||
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
|
{
|
||||||
|
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||||
|
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||||
|
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
|
||||||
|
}
|
||||||
free_dir (root);
|
free_dir (root);
|
||||||
root = 0;
|
root = 0;
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
|
@ -333,6 +333,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
#ifndef GRUB_USE_MULTIBOOT2
|
#ifndef GRUB_USE_MULTIBOOT2
|
||||||
|
lowest_addr = 0x100000;
|
||||||
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL)
|
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL)
|
||||||
lowest_addr = ALIGN_UP (highest_load + 1048576, 4096);
|
lowest_addr = ALIGN_UP (highest_load + 1048576, 4096);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -169,7 +169,10 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
{
|
||||||
|
grub_free (shdr);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
|
|
|
@ -157,6 +157,12 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
||||||
|
|
||||||
inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
|
inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
|
||||||
|
#if 0
|
||||||
|
/* This is likely based on misunderstanding. gateway_ip refers to
|
||||||
|
address of BOOTP relay and should not be used after BOOTP transaction
|
||||||
|
is complete.
|
||||||
|
See RFC1542, 3.4 Interpretation of the 'giaddr' field
|
||||||
|
*/
|
||||||
if (bp->gateway_ip)
|
if (bp->gateway_ip)
|
||||||
{
|
{
|
||||||
grub_net_network_level_netaddress_t target;
|
grub_net_network_level_netaddress_t target;
|
||||||
|
@ -178,6 +184,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
target.ipv4.masksize = 32;
|
target.ipv4.masksize = 32;
|
||||||
grub_net_add_route (name, target, inter);
|
grub_net_add_route (name, target, inter);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (size > OFFSET_OF (boot_file, bp))
|
if (size > OFFSET_OF (boot_file, bp))
|
||||||
grub_env_set_net_property (name, "boot_file", bp->boot_file,
|
grub_env_set_net_property (name, "boot_file", bp->boot_file,
|
||||||
|
|
|
@ -262,7 +262,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||||
grub_netbuff_free (nb);
|
grub_netbuff_free (nb);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
for (i = 0; i < grub_cpu_to_be16 (head->qdcount); i++)
|
for (i = 0; i < grub_be_to_cpu16 (head->qdcount); i++)
|
||||||
{
|
{
|
||||||
if (ptr >= nb->tail)
|
if (ptr >= nb->tail)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +277,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
*data->addresses = grub_malloc (sizeof ((*data->addresses)[0])
|
*data->addresses = grub_malloc (sizeof ((*data->addresses)[0])
|
||||||
* grub_cpu_to_be16 (head->ancount));
|
* grub_be_to_cpu16 (head->ancount));
|
||||||
if (!*data->addresses)
|
if (!*data->addresses)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -286,7 +286,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
reparse_ptr = ptr;
|
reparse_ptr = ptr;
|
||||||
reparse:
|
reparse:
|
||||||
for (i = 0, ptr = reparse_ptr; i < grub_cpu_to_be16 (head->ancount); i++)
|
for (i = 0, ptr = reparse_ptr; i < grub_be_to_cpu16 (head->ancount); i++)
|
||||||
{
|
{
|
||||||
int ignored = 0;
|
int ignored = 0;
|
||||||
grub_uint8_t class;
|
grub_uint8_t class;
|
||||||
|
|
|
@ -142,9 +142,80 @@ get_card_packet (struct grub_net_card *dev)
|
||||||
return nb;
|
return nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
open_card (struct grub_net_card *dev)
|
||||||
|
{
|
||||||
|
grub_efi_simple_network_t *net;
|
||||||
|
|
||||||
|
/* Try to reopen SNP exlusively to close any active MNP protocol instance
|
||||||
|
that may compete for packet polling
|
||||||
|
*/
|
||||||
|
net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid,
|
||||||
|
GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE);
|
||||||
|
if (net)
|
||||||
|
{
|
||||||
|
if (net->mode->state == GRUB_EFI_NETWORK_STOPPED
|
||||||
|
&& efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS)
|
||||||
|
return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed",
|
||||||
|
dev->name);
|
||||||
|
|
||||||
|
if (net->mode->state == GRUB_EFI_NETWORK_STOPPED)
|
||||||
|
return grub_error (GRUB_ERR_NET_NO_CARD, "%s: card stopped",
|
||||||
|
dev->name);
|
||||||
|
|
||||||
|
if (net->mode->state == GRUB_EFI_NETWORK_STARTED
|
||||||
|
&& efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS)
|
||||||
|
return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed",
|
||||||
|
dev->name);
|
||||||
|
|
||||||
|
/* Enable hardware receive filters if driver declares support for it.
|
||||||
|
We need unicast and broadcast and additionaly all nodes and
|
||||||
|
solicited multicast for IPv6. Solicited multicast is per-IPv6
|
||||||
|
address and we currently do not have API to do it so simply
|
||||||
|
try to enable receive of all multicast packets or evertyhing in
|
||||||
|
the worst case (i386 PXE driver always enables promiscuous too).
|
||||||
|
|
||||||
|
This does trust firmware to do what it claims to do.
|
||||||
|
*/
|
||||||
|
if (net->mode->receive_filter_mask)
|
||||||
|
{
|
||||||
|
grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
|
||||||
|
|
||||||
|
filters &= net->mode->receive_filter_mask;
|
||||||
|
if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST))
|
||||||
|
filters |= (net->mode->receive_filter_mask &
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS);
|
||||||
|
|
||||||
|
efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
|
||||||
|
dev->efi_net, &net_io_guid,
|
||||||
|
grub_efi_image_handle, dev->efi_handle);
|
||||||
|
dev->efi_net = net;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it failed we just try to run as best as we can */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_card (struct grub_net_card *dev)
|
||||||
|
{
|
||||||
|
efi_call_1 (dev->efi_net->shutdown, dev->efi_net);
|
||||||
|
efi_call_1 (dev->efi_net->stop, dev->efi_net);
|
||||||
|
efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
|
||||||
|
dev->efi_net, &net_io_guid,
|
||||||
|
grub_efi_image_handle, dev->efi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
static struct grub_net_card_driver efidriver =
|
static struct grub_net_card_driver efidriver =
|
||||||
{
|
{
|
||||||
.name = "efinet",
|
.name = "efinet",
|
||||||
|
.open = open_card,
|
||||||
|
.close = close_card,
|
||||||
.send = send_card_buffer,
|
.send = send_card_buffer,
|
||||||
.recv = get_card_packet
|
.recv = get_card_packet
|
||||||
};
|
};
|
||||||
|
@ -174,6 +245,29 @@ grub_efinet_findcards (void)
|
||||||
{
|
{
|
||||||
grub_efi_simple_network_t *net;
|
grub_efi_simple_network_t *net;
|
||||||
struct grub_net_card *card;
|
struct grub_net_card *card;
|
||||||
|
grub_efi_device_path_t *dp, *parent = NULL, *child = NULL;
|
||||||
|
|
||||||
|
/* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as
|
||||||
|
children of main MAC messaging device. We only need one device with
|
||||||
|
bound SNP per physical card, otherwise they compete with each other
|
||||||
|
when polling for incoming packets.
|
||||||
|
*/
|
||||||
|
dp = grub_efi_get_device_path (*handle);
|
||||||
|
if (!dp)
|
||||||
|
continue;
|
||||||
|
for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp))
|
||||||
|
{
|
||||||
|
parent = child;
|
||||||
|
child = dp;
|
||||||
|
}
|
||||||
|
if (child
|
||||||
|
&& GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||||
|
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||||
|
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
|
||||||
|
&& parent
|
||||||
|
&& GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||||
|
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
|
||||||
|
continue;
|
||||||
|
|
||||||
net = grub_efi_open_protocol (*handle, &net_io_guid,
|
net = grub_efi_open_protocol (*handle, &net_io_guid,
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
@ -251,7 +345,33 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||||
if (! cdp)
|
if (! cdp)
|
||||||
continue;
|
continue;
|
||||||
if (grub_efi_compare_device_paths (dp, cdp) != 0)
|
if (grub_efi_compare_device_paths (dp, cdp) != 0)
|
||||||
continue;
|
{
|
||||||
|
grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp;
|
||||||
|
int match;
|
||||||
|
|
||||||
|
/* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6
|
||||||
|
as children of Ethernet card and binds PXE and Load File protocols
|
||||||
|
to it. Loaded Image Device Path protocol will point to these pseudo
|
||||||
|
devices. We skip them when enumerating cards, so here we need to
|
||||||
|
find matching MAC device.
|
||||||
|
*/
|
||||||
|
ldp = grub_efi_find_last_device_path (dp);
|
||||||
|
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||||
|
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||||
|
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
|
||||||
|
continue;
|
||||||
|
dup_dp = grub_efi_duplicate_device_path (dp);
|
||||||
|
if (!dup_dp)
|
||||||
|
continue;
|
||||||
|
dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||||
|
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
|
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
dup_ldp->length = sizeof (*dup_ldp);
|
||||||
|
match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
|
||||||
|
grub_free (dup_dp);
|
||||||
|
if (!match)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
|
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
if (! pxe)
|
if (! pxe)
|
||||||
|
|
|
@ -389,6 +389,7 @@ grub_cmdline_get (const char *prompt_translated)
|
||||||
if (!unicode_msg)
|
if (!unicode_msg)
|
||||||
{
|
{
|
||||||
grub_free (buf);
|
grub_free (buf);
|
||||||
|
grub_free (cl_terms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len - 1,
|
msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len - 1,
|
||||||
|
|
|
@ -64,7 +64,10 @@ grub_env_new_context (int export_all)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
menu = grub_zalloc (sizeof (*menu));
|
menu = grub_zalloc (sizeof (*menu));
|
||||||
if (! menu)
|
if (! menu)
|
||||||
return grub_errno;
|
{
|
||||||
|
grub_free (context);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
context->prev = grub_current_context;
|
context->prev = grub_current_context;
|
||||||
grub_current_context = context;
|
grub_current_context = context;
|
||||||
|
|
|
@ -316,9 +316,9 @@ get_btrfs_fs_prefix (const char *mount_path)
|
||||||
|
|
||||||
tree_id = sargs.buf[2];
|
tree_id = sargs.buf[2];
|
||||||
br = (struct grub_btrfs_root_backref *) (sargs.buf + 4);
|
br = (struct grub_btrfs_root_backref *) (sargs.buf + 4);
|
||||||
inode_id = br->inode_id;
|
inode_id = grub_le_to_cpu64 (br->inode_id);
|
||||||
name = br->name;
|
name = br->name;
|
||||||
namelen = br->n;
|
namelen = grub_le_to_cpu16 (br->n);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -345,7 +345,7 @@ get_btrfs_fs_prefix (const char *mount_path)
|
||||||
|
|
||||||
ir = (struct grub_btrfs_inode_ref *) (sargs.buf + 4);
|
ir = (struct grub_btrfs_inode_ref *) (sargs.buf + 4);
|
||||||
name = ir->name;
|
name = ir->name;
|
||||||
namelen = ir->n;
|
namelen = grub_le_to_cpu16 (ir->n);
|
||||||
}
|
}
|
||||||
old = ret;
|
old = ret;
|
||||||
ret = xmalloc (namelen + (old ? strlen (old) : 0) + 2);
|
ret = xmalloc (namelen + (old ? strlen (old) : 0) + 2);
|
||||||
|
|
|
@ -539,7 +539,7 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||||
ofpath = xstrdup ("floppy");
|
ofpath = xstrdup ("floppy");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
grub_util_warn (_("unknown device type %s\n"), device);
|
grub_util_warn (_("unknown device type %s"), device);
|
||||||
ofpath = NULL;
|
ofpath = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -544,6 +544,7 @@ grub_guess_root_devices (const char *dir_in)
|
||||||
|
|
||||||
if (stat (dir, &st) < 0)
|
if (stat (dir, &st) < 0)
|
||||||
grub_util_error (_("cannot stat `%s': %s"), dir, strerror (errno));
|
grub_util_error (_("cannot stat `%s': %s"), dir, strerror (errno));
|
||||||
|
free (dir);
|
||||||
|
|
||||||
dev = st.st_dev;
|
dev = st.st_dev;
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,10 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
ret = grub_make_system_path_relative_to_its_root_os (p);
|
ret = grub_make_system_path_relative_to_its_root_os (p);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
{
|
||||||
|
free (p);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For ZFS sub-pool filesystems. */
|
/* For ZFS sub-pool filesystems. */
|
||||||
|
|
|
@ -173,7 +173,10 @@ grub_efiserial_init (void)
|
||||||
|
|
||||||
port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX"));
|
port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX"));
|
||||||
if (!port->name)
|
if (!port->name)
|
||||||
return;
|
{
|
||||||
|
grub_free (port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"),
|
grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"),
|
||||||
"efi%d", num_serial++);
|
"efi%d", num_serial++);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
|
|
||||||
#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
|
#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
|
||||||
|
|
||||||
|
#define GRUB_EFI_PAGE_SHIFT 12
|
||||||
|
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT)
|
||||||
|
#define GRUB_EFI_PE_MAGIC 0x5A4D
|
||||||
|
|
||||||
/* From linux/Documentation/arm64/booting.txt */
|
/* From linux/Documentation/arm64/booting.txt */
|
||||||
struct grub_arm64_linux_kernel_header
|
struct grub_arm64_linux_kernel_header
|
||||||
{
|
{
|
||||||
|
@ -38,4 +42,11 @@ struct grub_arm64_linux_kernel_header
|
||||||
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Declare the functions for getting dtb and checking/booting image */
|
||||||
|
void *grub_linux_get_fdt (void);
|
||||||
|
grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header
|
||||||
|
*lh);
|
||||||
|
grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size,
|
||||||
|
char *args);
|
||||||
|
|
||||||
#endif /* ! GRUB_LINUX_CPU_HEADER */
|
#endif /* ! GRUB_LINUX_CPU_HEADER */
|
||||||
|
|
|
@ -115,11 +115,36 @@ void *
|
||||||
EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n);
|
EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___AEABI_MEMCPY4
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC (__aeabi_memcpy4) (void *dest, const void *src, grub_size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___AEABI_MEMCPY8
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC (__aeabi_memcpy8) (void *dest, const void *src, grub_size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE___AEABI_MEMSET
|
#ifdef HAVE___AEABI_MEMSET
|
||||||
void *
|
void *
|
||||||
EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n);
|
EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___AEABI_MEMCLR
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC(__aeabi_memclr) (void *s, grub_size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___AEABI_MEMCLR4
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC(__aeabi_memclr4) (void *s, grub_size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___AEABI_MEMCLR8
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC(__aeabi_memclr8) (void *s, grub_size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE___AEABI_LASR
|
#ifdef HAVE___AEABI_LASR
|
||||||
grub_uint64_t
|
grub_uint64_t
|
||||||
EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b);
|
EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b);
|
||||||
|
|
|
@ -88,7 +88,14 @@ EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b);
|
||||||
void *
|
void *
|
||||||
EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n);
|
EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n);
|
||||||
void *
|
void *
|
||||||
|
EXPORT_FUNC (__aeabi_memcpy4) (void *dest, const void *src, grub_size_t n);
|
||||||
|
void *
|
||||||
|
EXPORT_FUNC (__aeabi_memcpy8) (void *dest, const void *src, grub_size_t n);
|
||||||
|
void *
|
||||||
EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n);
|
EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n);
|
||||||
|
void EXPORT_FUNC(__aeabi_memclr) (void *s, grub_size_t n);
|
||||||
|
void EXPORT_FUNC(__aeabi_memclr4) (void *s, grub_size_t n);
|
||||||
|
void EXPORT_FUNC(__aeabi_memclr8) (void *s, grub_size_t n);
|
||||||
|
|
||||||
grub_uint64_t
|
grub_uint64_t
|
||||||
EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b);
|
EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b);
|
||||||
|
|
|
@ -172,7 +172,7 @@ grub_diskfilter_unregister (grub_diskfilter_t diskfilter)
|
||||||
|
|
||||||
struct grub_diskfilter_vg *
|
struct grub_diskfilter_vg *
|
||||||
grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
char *name, grub_uint64_t disk_size,
|
const char *name, grub_uint64_t disk_size,
|
||||||
grub_uint64_t stripe_size,
|
grub_uint64_t stripe_size,
|
||||||
int layout, int level);
|
int layout, int level);
|
||||||
|
|
||||||
|
|
|
@ -1501,17 +1501,31 @@ enum
|
||||||
GRUB_EFI_NETWORK_INITIALIZED,
|
GRUB_EFI_NETWORK_INITIALIZED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01,
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02,
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04,
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08,
|
||||||
|
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
struct grub_efi_simple_network
|
struct grub_efi_simple_network
|
||||||
{
|
{
|
||||||
grub_uint64_t revision;
|
grub_uint64_t revision;
|
||||||
grub_efi_status_t (*start) (struct grub_efi_simple_network *this);
|
grub_efi_status_t (*start) (struct grub_efi_simple_network *this);
|
||||||
void (*stop) (void);
|
grub_efi_status_t (*stop) (struct grub_efi_simple_network *this);
|
||||||
grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this,
|
grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this,
|
||||||
grub_efi_uintn_t extra_rx,
|
grub_efi_uintn_t extra_rx,
|
||||||
grub_efi_uintn_t extra_tx);
|
grub_efi_uintn_t extra_tx);
|
||||||
void (*reset) (void);
|
void (*reset) (void);
|
||||||
void (*shutdown) (void);
|
grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this);
|
||||||
void (*receive_filters) (void);
|
grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this,
|
||||||
|
grub_uint32_t enable,
|
||||||
|
grub_uint32_t disable,
|
||||||
|
grub_efi_boolean_t reset_mcast_filter,
|
||||||
|
grub_efi_uintn_t mcast_filter_count,
|
||||||
|
grub_efi_mac_address_t *mcast_filter);
|
||||||
void (*station_address) (void);
|
void (*station_address) (void);
|
||||||
void (*statistics) (void);
|
void (*statistics) (void);
|
||||||
void (*mcastiptomac) (void);
|
void (*mcastiptomac) (void);
|
||||||
|
|
|
@ -56,6 +56,10 @@ void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
|
||||||
char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
|
char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
|
||||||
grub_efi_device_path_t *
|
grub_efi_device_path_t *
|
||||||
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
|
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
|
||||||
|
grub_efi_device_path_t *
|
||||||
|
EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp);
|
||||||
|
grub_efi_device_path_t *
|
||||||
|
EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp);
|
||||||
grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf,
|
grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf,
|
||||||
grub_efi_uintn_t *map_key,
|
grub_efi_uintn_t *map_key,
|
||||||
grub_efi_uintn_t *efi_desc_size,
|
grub_efi_uintn_t *efi_desc_size,
|
||||||
|
|
|
@ -117,4 +117,16 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name,
|
||||||
grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \
|
grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* Setup "reg" property for
|
||||||
|
* #address-cells = <0x2>
|
||||||
|
* #size-cells = <0x2>
|
||||||
|
*/
|
||||||
|
#define grub_fdt_set_reg64(fdt, nodeoffset, addr, size) \
|
||||||
|
({ \
|
||||||
|
grub_uint64_t reg_64[2]; \
|
||||||
|
reg_64[0] = grub_cpu_to_be64(addr); \
|
||||||
|
reg_64[1] = grub_cpu_to_be64(size); \
|
||||||
|
grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \
|
||||||
|
})
|
||||||
|
|
||||||
#endif /* ! GRUB_FDT_HEADER */
|
#endif /* ! GRUB_FDT_HEADER */
|
||||||
|
|
|
@ -62,6 +62,17 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
|
||||||
enum grub_fshelp_filetype expect);
|
enum grub_fshelp_filetype expect);
|
||||||
|
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
EXPORT_FUNC(grub_fshelp_find_file_lookup) (const char *path,
|
||||||
|
grub_fshelp_node_t rootnode,
|
||||||
|
grub_fshelp_node_t *foundnode,
|
||||||
|
grub_err_t (*lookup_file) (grub_fshelp_node_t dir,
|
||||||
|
const char *name,
|
||||||
|
grub_fshelp_node_t *foundnode,
|
||||||
|
enum grub_fshelp_filetype *foundtype),
|
||||||
|
char *(*read_symlink) (grub_fshelp_node_t node),
|
||||||
|
enum grub_fshelp_filetype expect);
|
||||||
|
|
||||||
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
|
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
|
||||||
beginning with the block POS. READ_HOOK should be set before
|
beginning with the block POS. READ_HOOK should be set before
|
||||||
reading a block from the file. GET_BLOCK is used to translate file
|
reading a block from the file. GET_BLOCK is used to translate file
|
||||||
|
|
|
@ -21,8 +21,4 @@
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
|
|
||||||
#ifdef ASM_FILE
|
|
||||||
#define mips_attributes .gnu_attribute 4, 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
|
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
|
||||||
|
|
|
@ -126,7 +126,7 @@ typedef struct zio_cksum {
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* 5 |G| offset3 |
|
* 5 |G| offset3 |
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE |
|
* 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* 7 | padding |
|
* 7 | padding |
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
|
@ -160,7 +160,8 @@ typedef struct zio_cksum {
|
||||||
* G gang block indicator
|
* G gang block indicator
|
||||||
* B byteorder (endianness)
|
* B byteorder (endianness)
|
||||||
* D dedup
|
* D dedup
|
||||||
* X unused
|
* X encryption
|
||||||
|
* E blkptr_t contains embedded data
|
||||||
* lvl level of indirection
|
* lvl level of indirection
|
||||||
* type DMU object type
|
* type DMU object type
|
||||||
* phys birth txg of block allocation; zero if same as logical birth txg
|
* phys birth txg of block allocation; zero if same as logical birth txg
|
||||||
|
@ -203,8 +204,8 @@ typedef struct blkptr {
|
||||||
#define BP_SET_LSIZE(bp, x) \
|
#define BP_SET_LSIZE(bp, x) \
|
||||||
BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
|
BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
|
||||||
|
|
||||||
#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8)
|
#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7)
|
||||||
#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x)
|
#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x)
|
||||||
|
|
||||||
#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
|
#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
|
||||||
#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
|
#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
|
||||||
|
@ -215,6 +216,8 @@ typedef struct blkptr {
|
||||||
#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
|
#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
|
||||||
#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
|
#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
|
||||||
|
|
||||||
|
#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1)
|
||||||
|
|
||||||
#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1)
|
#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1)
|
||||||
#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x)
|
#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x)
|
||||||
|
|
||||||
|
@ -277,9 +280,27 @@ typedef struct blkptr {
|
||||||
(zcp)->zc_word[3] = w3; \
|
(zcp)->zc_word[3] = w3; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BPE_GET_ETYPE(bp) BP_GET_CHECKSUM(bp)
|
||||||
|
#define BPE_GET_LSIZE(bp) \
|
||||||
|
BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1)
|
||||||
|
#define BPE_GET_PSIZE(bp) \
|
||||||
|
BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1)
|
||||||
|
|
||||||
|
typedef enum bp_embedded_type {
|
||||||
|
BP_EMBEDDED_TYPE_DATA,
|
||||||
|
NUM_BP_EMBEDDED_TYPES
|
||||||
|
} bp_embedded_type_t;
|
||||||
|
|
||||||
|
#define BPE_NUM_WORDS 14
|
||||||
|
#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof(grub_uint64_t))
|
||||||
|
#define BPE_IS_PAYLOADWORD(bp, wp) \
|
||||||
|
((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
|
||||||
|
|
||||||
#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
|
#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
|
||||||
#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
|
#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
|
||||||
#define BP_IS_HOLE(bp) ((bp)->blk_birth == 0)
|
#define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] == 0ULL && \
|
||||||
|
(dva)->dva_word[1] == 0ULL)
|
||||||
|
#define BP_IS_HOLE(bp) DVA_IS_EMPTY(BP_IDENTITY(bp))
|
||||||
|
|
||||||
/* BP_IS_RAIDZ(bp) assumes no block compression */
|
/* BP_IS_RAIDZ(bp) assumes no block compression */
|
||||||
#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
|
#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
|
||||||
|
|
|
@ -156,9 +156,6 @@ struct multiboot_header_tag_module_align
|
||||||
multiboot_uint16_t type;
|
multiboot_uint16_t type;
|
||||||
multiboot_uint16_t flags;
|
multiboot_uint16_t flags;
|
||||||
multiboot_uint32_t size;
|
multiboot_uint32_t size;
|
||||||
multiboot_uint32_t width;
|
|
||||||
multiboot_uint32_t height;
|
|
||||||
multiboot_uint32_t depth;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct multiboot_color
|
struct multiboot_color
|
||||||
|
|
BIN
po/exclude.pot
BIN
po/exclude.pot
Binary file not shown.
|
@ -40,6 +40,10 @@ case x"$fs" in
|
||||||
MINLOGSECSIZE=9
|
MINLOGSECSIZE=9
|
||||||
# OS LIMITATION: GNU/Linux doesn't accept > 4096
|
# OS LIMITATION: GNU/Linux doesn't accept > 4096
|
||||||
MAXLOGSECSIZE=12;;
|
MAXLOGSECSIZE=12;;
|
||||||
|
xxfs_crc)
|
||||||
|
MINLOGSECSIZE=9
|
||||||
|
# OS LIMITATION: GNU/Linux doesn't accept > 1024
|
||||||
|
MAXLOGSECSIZE=10;;
|
||||||
xzfs*)
|
xzfs*)
|
||||||
# OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B.
|
# OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B.
|
||||||
MINLOGSECSIZE=9
|
MINLOGSECSIZE=9
|
||||||
|
@ -142,6 +146,10 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
MINBLKSIZE=$SECSIZE
|
MINBLKSIZE=$SECSIZE
|
||||||
# OS Limitation: GNU/Linux doesn't accept > 4096
|
# OS Limitation: GNU/Linux doesn't accept > 4096
|
||||||
MAXBLKSIZE=4096;;
|
MAXBLKSIZE=4096;;
|
||||||
|
xxfs_crc)
|
||||||
|
# OS Limitation: GNU/Linux doesn't accept != 1024
|
||||||
|
MINBLKSIZE=1024
|
||||||
|
MAXBLKSIZE=1024;;
|
||||||
xudf)
|
xudf)
|
||||||
MINBLKSIZE=1024
|
MINBLKSIZE=1024
|
||||||
MAXBLKSIZE=4096;;
|
MAXBLKSIZE=4096;;
|
||||||
|
@ -289,7 +297,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
x"ufs1" | x"ufs1_sun" | x"ufs2")
|
x"ufs1" | x"ufs1_sun" | x"ufs2")
|
||||||
FSLABEL="grubtest""ieurrucnenreeiurueurewf";;
|
FSLABEL="grubtest""ieurrucnenreeiurueurewf";;
|
||||||
# FS LIMITATION: XFS label is at most 12 UTF-8 characters
|
# FS LIMITATION: XFS label is at most 12 UTF-8 characters
|
||||||
x"xfs")
|
x"xfs"|x"xfs_crc")
|
||||||
FSLABEL="géт 😁к";;
|
FSLABEL="géт 😁к";;
|
||||||
# FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase
|
# FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase
|
||||||
x"vfat"* | xmsdos*)
|
x"vfat"* | xmsdos*)
|
||||||
|
@ -467,7 +475,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
case x"$fs" in
|
case x"$fs" in
|
||||||
# FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it.
|
# FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it.
|
||||||
# FS LIMITATION: as far as I know those FS don't store their last modification date.
|
# FS LIMITATION: as far as I know those FS don't store their last modification date.
|
||||||
x"jfs_caseins" | x"jfs" | x"xfs"| x"btrfs"* | x"reiserfs_old" | x"reiserfs" \
|
x"jfs_caseins" | x"jfs" | x"xfs" | x"xfs_crc" | x"btrfs"* | x"reiserfs_old" | x"reiserfs" \
|
||||||
| x"bfs" | x"afs" \
|
| x"bfs" | x"afs" \
|
||||||
| x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \
|
| x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \
|
||||||
| x"minix3" | x"ntfs"* | x"udf" | x"sfs"*)
|
| x"minix3" | x"ntfs"* | x"udf" | x"sfs"*)
|
||||||
|
@ -760,7 +768,10 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
xext*)
|
xext*)
|
||||||
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
||||||
xxfs)
|
xxfs)
|
||||||
"mkfs.xfs" -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
"mkfs.xfs" -m crc=0 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
||||||
|
xxfs_crc)
|
||||||
|
MOUNTFS="xfs"
|
||||||
|
"mkfs.xfs" -m crc=1 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${LODEVICES[0]}" ;;
|
||||||
*)
|
*)
|
||||||
echo "Add appropriate mkfs command here"
|
echo "Add appropriate mkfs command here"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -1123,6 +1134,37 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case x"$fs" in
|
||||||
|
x"zfs"*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/.");;
|
||||||
|
*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/.");;
|
||||||
|
esac
|
||||||
|
if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo DOT IN ROOTDIR FAIL
|
||||||
|
echo "$LSROUT"
|
||||||
|
TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case x"$fs" in
|
||||||
|
x"zfs"*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/..");
|
||||||
|
if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo DOTDOT IN ROOTDIR FAIL
|
||||||
|
echo "$LSROUT"
|
||||||
|
TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case x"$fs" in
|
case x"$fs" in
|
||||||
x"zfs"*)
|
x"zfs"*)
|
||||||
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/////sdir");;
|
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/////sdir");;
|
||||||
|
@ -1153,6 +1195,36 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case x"$fs" in
|
||||||
|
x"zfs"*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/.");;
|
||||||
|
*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/.");;
|
||||||
|
esac
|
||||||
|
if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo DOT IN SUBDIR FAIL
|
||||||
|
echo "$LSROUT"
|
||||||
|
TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$OSDIR/sdir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case x"$fs" in
|
||||||
|
x"zfs"*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/sdir/../sdir");;
|
||||||
|
*)
|
||||||
|
LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/sdir/../sdir");;
|
||||||
|
esac
|
||||||
|
if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo DOTDOT IN SUBDIR FAIL
|
||||||
|
echo "$LSROUT"
|
||||||
|
TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$OSDIR/ssdir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
LSOUT=`run_grubfstest ls -- -l "($GRUBDEVICE)"`
|
LSOUT=`run_grubfstest ls -- -l "($GRUBDEVICE)"`
|
||||||
if [ x"$NOFSLABEL" = xy ]; then
|
if [ x"$NOFSLABEL" = xy ]; then
|
||||||
:
|
:
|
||||||
|
|
|
@ -16,4 +16,5 @@ if ! which mkfs.xfs >/dev/null 2>&1; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
"@builddir@/grub-fs-tester" xfs_crc
|
||||||
"@builddir@/grub-fs-tester" xfs
|
"@builddir@/grub-fs-tester" xfs
|
||||||
|
|
|
@ -494,7 +494,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||||
|
|
||||||
tgt = grub_install_get_image_target (mkimage_target);
|
tgt = grub_install_get_image_target (mkimage_target);
|
||||||
if (!tgt)
|
if (!tgt)
|
||||||
grub_util_error (_("unknown target format %s\n"), mkimage_target);
|
grub_util_error (_("unknown target format %s"), mkimage_target);
|
||||||
|
|
||||||
grub_install_generate_image (dir, prefix, fp, outname,
|
grub_install_generate_image (dir, prefix, fp, outname,
|
||||||
modules.entries, memdisk_path,
|
modules.entries, memdisk_path,
|
||||||
|
@ -902,7 +902,7 @@ grub_install_get_target (const char *src)
|
||||||
{
|
{
|
||||||
char *fn;
|
char *fn;
|
||||||
grub_util_fd_t f;
|
grub_util_fd_t f;
|
||||||
char buf[2048];
|
char buf[8192];
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
char *c, *pl, *p;
|
char *c, *pl, *p;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
|
@ -773,7 +773,7 @@ bless (grub_device_t dev, const char *path, int x86)
|
||||||
err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
|
err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
|
||||||
if (err)
|
if (err)
|
||||||
grub_util_error ("%s", grub_errmsg);
|
grub_util_error ("%s", grub_errmsg);
|
||||||
grub_util_info ("blessed\n");
|
grub_util_info ("blessed");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1070,7 +1070,7 @@ main (int argc, char *argv[])
|
||||||
efidir_is_mac = 1;
|
efidir_is_mac = 1;
|
||||||
|
|
||||||
if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
|
if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
|
||||||
grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir);
|
grub_util_error (_("%s doesn't look like an EFI partition"), efidir);
|
||||||
|
|
||||||
/* The EFI specification requires that an EFI System Partition must
|
/* The EFI specification requires that an EFI System Partition must
|
||||||
contain an "EFI" subdirectory, and that OS loaders are stored in
|
contain an "EFI" subdirectory, and that OS loaders are stored in
|
||||||
|
@ -1271,7 +1271,7 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
if (!config.is_cryptodisk_enabled && have_cryptodisk)
|
if (!config.is_cryptodisk_enabled && have_cryptodisk)
|
||||||
grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. "
|
grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. "
|
||||||
"Set `%s' in file `%s'."), "GRUB_ENABLE_CRYPTODISK=y",
|
"Set `%s' in file `%s'"), "GRUB_ENABLE_CRYPTODISK=y",
|
||||||
grub_util_get_config_filename ());
|
grub_util_get_config_filename ());
|
||||||
|
|
||||||
if (disk_module && grub_strcmp (disk_module, "ata") == 0)
|
if (disk_module && grub_strcmp (disk_module, "ata") == 0)
|
||||||
|
@ -1727,7 +1727,7 @@ main (int argc, char *argv[])
|
||||||
grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
|
grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
|
||||||
grub_install_copy_file (imgfile, grub_elf, 1);
|
grub_install_copy_file (imgfile, grub_elf, 1);
|
||||||
|
|
||||||
f = grub_util_fopen (mach_kernel, "r+");
|
f = grub_util_fopen (mach_kernel, "a+");
|
||||||
if (!f)
|
if (!f)
|
||||||
grub_util_error (_("Can't create file: %s"), strerror (errno));
|
grub_util_error (_("Can't create file: %s"), strerror (errno));
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
|
|
@ -140,7 +140,7 @@ process_input_dir (const char *input_dir, enum grub_install_plat platform)
|
||||||
|
|
||||||
prefix = xasprintf ("/%s", subdir);
|
prefix = xasprintf ("/%s", subdir);
|
||||||
if (!targets[platform].mkimage_target)
|
if (!targets[platform].mkimage_target)
|
||||||
grub_util_error (_("unsupported platform %s\n"), platsub);
|
grub_util_error (_("unsupported platform %s"), platsub);
|
||||||
|
|
||||||
grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
|
grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
|
||||||
cfg = grub_util_fopen (grub_cfg, "wb");
|
cfg = grub_util_fopen (grub_cfg, "wb");
|
||||||
|
|
|
@ -451,6 +451,12 @@ main (int argc, char *argv[])
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
if (strcmp (argv[i], "-output") == 0) {
|
||||||
|
argp_argv[argp_argc++] = (char *) "--output";
|
||||||
|
i++;
|
||||||
|
argp_argv[argp_argc++] = argv[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (args_to_eat (argv[i]))
|
switch (args_to_eat (argv[i]))
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
@ -279,7 +279,7 @@ write_reloc_section (FILE* fp, const char *name, char *image,
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
grub_util_error ("unknown pe relocation type %d\n", pe_rel->type);
|
grub_util_error ("unknown pe relocation type %d", pe_rel->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type ==
|
if (type ==
|
||||||
|
|
|
@ -429,7 +429,7 @@ probe (const char *path, char **device_names, char delim)
|
||||||
if (print == PRINT_HINT_STR)
|
if (print == PRINT_HINT_STR)
|
||||||
{
|
{
|
||||||
const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
|
const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
|
||||||
const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
|
char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
|
||||||
char *biosname, *bare, *efi;
|
char *biosname, *bare, *efi;
|
||||||
const char *map;
|
const char *map;
|
||||||
|
|
||||||
|
@ -443,6 +443,7 @@ probe (const char *path, char **device_names, char delim)
|
||||||
grub_util_fprint_full_disk_name (stdout, tmp, dev);
|
grub_util_fprint_full_disk_name (stdout, tmp, dev);
|
||||||
printf ("' ");
|
printf ("' ");
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
free (ofpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
biosname = grub_util_guess_bios_drive (*curdev);
|
biosname = grub_util_guess_bios_drive (*curdev);
|
||||||
|
@ -485,23 +486,18 @@ probe (const char *path, char **device_names, char delim)
|
||||||
printf (" ");
|
printf (" ");
|
||||||
else
|
else
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
|
else if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
|
||||||
|| print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
|
|| print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
|
||||||
|| print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
|
|| print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
|
||||||
&& dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
|
&& dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
|
||||||
{
|
{
|
||||||
grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev);
|
grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_COMPATIBILITY_HINT)
|
else if (print == PRINT_COMPATIBILITY_HINT)
|
||||||
{
|
{
|
||||||
const char *map;
|
const char *map;
|
||||||
char *biosname;
|
char *biosname;
|
||||||
|
@ -519,16 +515,14 @@ probe (const char *path, char **device_names, char delim)
|
||||||
{
|
{
|
||||||
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
|
free (biosname);
|
||||||
|
/* Compatibility hint is one device only. */
|
||||||
|
grub_device_close (dev);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free (biosname);
|
|
||||||
grub_device_close (dev);
|
|
||||||
/* Compatibility hint is one device only. */
|
|
||||||
if (biosname)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_BIOS_HINT)
|
else if (print == PRINT_BIOS_HINT)
|
||||||
{
|
{
|
||||||
char *biosname;
|
char *biosname;
|
||||||
biosname = grub_util_guess_bios_drive (*curdev);
|
biosname = grub_util_guess_bios_drive (*curdev);
|
||||||
|
@ -536,12 +530,10 @@ probe (const char *path, char **device_names, char delim)
|
||||||
{
|
{
|
||||||
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
|
free (biosname);
|
||||||
}
|
}
|
||||||
free (biosname);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (print == PRINT_IEEE1275_HINT)
|
else if (print == PRINT_IEEE1275_HINT)
|
||||||
{
|
{
|
||||||
const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
|
const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
|
||||||
char *ofpath = grub_util_devname_to_ofpath (osdev);
|
char *ofpath = grub_util_devname_to_ofpath (osdev);
|
||||||
|
@ -565,11 +557,8 @@ probe (const char *path, char **device_names, char delim)
|
||||||
free (ofpath);
|
free (ofpath);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (print == PRINT_EFI_HINT)
|
else if (print == PRINT_EFI_HINT)
|
||||||
{
|
{
|
||||||
char *biosname;
|
char *biosname;
|
||||||
const char *map;
|
const char *map;
|
||||||
|
@ -585,14 +574,11 @@ probe (const char *path, char **device_names, char delim)
|
||||||
{
|
{
|
||||||
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
|
free (biosname);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (biosname);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_BAREMETAL_HINT)
|
else if (print == PRINT_BAREMETAL_HINT)
|
||||||
{
|
{
|
||||||
char *biosname;
|
char *biosname;
|
||||||
const char *map;
|
const char *map;
|
||||||
|
@ -609,14 +595,11 @@ probe (const char *path, char **device_names, char delim)
|
||||||
{
|
{
|
||||||
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
grub_util_fprint_full_disk_name (stdout, biosname, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
|
free (biosname);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (biosname);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_ARC_HINT)
|
else if (print == PRINT_ARC_HINT)
|
||||||
{
|
{
|
||||||
const char *map;
|
const char *map;
|
||||||
|
|
||||||
|
@ -626,46 +609,28 @@ probe (const char *path, char **device_names, char delim)
|
||||||
grub_util_fprint_full_disk_name (stdout, map, dev);
|
grub_util_fprint_full_disk_name (stdout, map, dev);
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME */
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_ABSTRACTION)
|
else if (print == PRINT_ABSTRACTION)
|
||||||
{
|
probe_abstraction (dev->disk, delim);
|
||||||
probe_abstraction (dev->disk, delim);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print == PRINT_CRYPTODISK_UUID)
|
else if (print == PRINT_CRYPTODISK_UUID)
|
||||||
{
|
probe_cryptodisk_uuid (dev->disk, delim);
|
||||||
probe_cryptodisk_uuid (dev->disk, delim);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print == PRINT_PARTMAP)
|
else if (print == PRINT_PARTMAP)
|
||||||
{
|
/* Check if dev->disk itself is contained in a partmap. */
|
||||||
/* Check if dev->disk itself is contained in a partmap. */
|
probe_partmap (dev->disk, delim);
|
||||||
probe_partmap (dev->disk, delim);
|
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print == PRINT_MSDOS_PARTTYPE)
|
else if (print == PRINT_MSDOS_PARTTYPE)
|
||||||
{
|
{
|
||||||
if (dev->disk->partition
|
if (dev->disk->partition
|
||||||
&& strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
|
&& strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
|
||||||
printf ("%02x", dev->disk->partition->msdostype);
|
printf ("%02x", dev->disk->partition->msdostype);
|
||||||
|
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print == PRINT_GPT_PARTTYPE)
|
else if (print == PRINT_GPT_PARTTYPE)
|
||||||
{
|
{
|
||||||
if (dev->disk->partition
|
if (dev->disk->partition
|
||||||
&& strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
|
&& strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
|
||||||
|
@ -694,9 +659,9 @@ probe (const char *path, char **device_names, char delim)
|
||||||
dev->disk->partition = p;
|
dev->disk->partition = p;
|
||||||
}
|
}
|
||||||
putchar (delim);
|
putchar (delim);
|
||||||
grub_device_close (dev);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_device_close (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
|
@ -823,7 +823,7 @@ compress_kernel (const struct grub_install_image_target_desc *image_target, char
|
||||||
|
|
||||||
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
|
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
|
||||||
&& (comp != GRUB_COMPRESSION_NONE))
|
&& (comp != GRUB_COMPRESSION_NONE))
|
||||||
grub_util_error (_("unknown compression %d\n"), comp);
|
grub_util_error (_("unknown compression %d"), comp);
|
||||||
|
|
||||||
*core_img = xmalloc (kernel_size);
|
*core_img = xmalloc (kernel_size);
|
||||||
memcpy (*core_img, kernel_img, kernel_size);
|
memcpy (*core_img, kernel_img, kernel_size);
|
||||||
|
@ -1234,7 +1234,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||||
name = "none_decompress.img";
|
name = "none_decompress.img";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
grub_util_error (_("unknown compression %d\n"), comp);
|
grub_util_error (_("unknown compression %d"), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
decompress_path = grub_util_get_path (dir, name);
|
decompress_path = grub_util_get_path (dir, name);
|
||||||
|
|
Loading…
Reference in a new issue