mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-29 02:31:05 +00:00
Compare commits
44
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ffd8219c5 | ||
|
|
79fc008935 | ||
|
|
bf9c561670 | ||
|
|
afa9dda37e | ||
|
|
cde63a3bb0 | ||
|
|
bf0e59cebf | ||
|
|
a2932fbe8a | ||
|
|
972765fe82 | ||
|
|
07662af7ae | ||
|
|
562c406763 | ||
|
|
ce95549cc5 | ||
|
|
a3e9da054d | ||
|
|
130234bc78 | ||
|
|
7b4c54c4ad | ||
|
|
0d2345774d | ||
|
|
c9a8d037a8 | ||
|
|
f8c3af3b61 | ||
|
|
0af7539bd2 | ||
|
|
0d663b50b9 | ||
|
|
28511b0da9 | ||
|
|
e1b099fb69 | ||
|
|
fbca374105 | ||
|
|
5f311e86d2 | ||
|
|
0de3eeb623 | ||
|
|
b67a95ecad | ||
|
|
5500cefccd | ||
|
|
d73976fdff | ||
|
|
1fbb2b4b39 | ||
|
|
c221ea06b5 | ||
|
|
72c28509fa | ||
|
|
7e5fcb0b34 | ||
|
|
6ae55ce103 | ||
|
|
c69d1858f1 | ||
|
|
4231927e44 | ||
|
|
a620876e3b | ||
|
|
f2b6c20a25 | ||
|
|
ba89c19f49 | ||
|
|
9862b24121 | ||
|
|
e563928ba4 | ||
|
|
a0bf403f66 | ||
|
|
4e0f8f66e3 | ||
|
|
c831d2073b | ||
|
|
52408aa946 | ||
|
|
58590cb2ef |
No files matched your search
@@ -246,3 +246,4 @@ build-aux/test-driver
|
||||
/garbage-gen
|
||||
/garbage-gen.exe
|
||||
/grub-fs-tester
|
||||
grub-core/build-grub-module-verifier
|
||||
@@ -51,6 +51,8 @@ New in 2.02:
|
||||
* Parse `nd' disk names in GRUB Legacy configuration files.
|
||||
* Issue separate DNS queries for IPv4 and IPv6.
|
||||
* Support IPv6 Router Advertisement to configure default router.
|
||||
* New variable net_<interface>_next_server containing next server
|
||||
from BOOTP reply.
|
||||
|
||||
* Coreboot improvements:
|
||||
* CBFS support both in on-disk images (loopback) and flash.
|
||||
@@ -171,6 +173,7 @@ New in 2.02:
|
||||
* Use fixed timestamp when generating GRUB image for reproducible builds.
|
||||
* Verify at build time that modules contain only supported relocations and their
|
||||
structure matches what boot-time module loader expects.
|
||||
* Do not require fonts on powerpc-ieee1275.
|
||||
|
||||
* Revision control moved to git.
|
||||
|
||||
|
||||
@@ -390,6 +390,24 @@ else
|
||||
[fi]
|
||||
])
|
||||
|
||||
dnl Check if the Linker supports `-no-pie'.
|
||||
AC_DEFUN([grub_CHECK_NO_PIE],
|
||||
[AC_MSG_CHECKING([whether linker accepts -no-pie])
|
||||
AC_CACHE_VAL(grub_cv_cc_ld_no_pie,
|
||||
[save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -no-pie"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_cc_ld_no_pie=yes],
|
||||
[grub_cv_cc_ld_no_pie=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
])
|
||||
AC_MSG_RESULT([$grub_cv_cc_ld_no_pie])
|
||||
nopie_possible=no
|
||||
if test "x$grub_cv_cc_ld_no_pie" = xyes ; then
|
||||
nopie_possible=yes
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Check if the C compiler supports `-fPIC'.
|
||||
AC_DEFUN([grub_CHECK_PIC],[
|
||||
[# Position independent executable.
|
||||
|
||||
+5
-1
@@ -1,12 +1,16 @@
|
||||
/* on x86 old clang doesn't support .code16
|
||||
newer clang supports it but creates 6-byte jumps instead of 3-byte ones
|
||||
which makes us go over boot sector size. */
|
||||
which makes us go over boot sector size.
|
||||
Starting with 3.9 clang emits 3-byte jumps but still creates 8-bytes movl
|
||||
instead of 5-bytes, so code overflows into data. */
|
||||
|
||||
.code16
|
||||
jmp far
|
||||
.org 4
|
||||
jmp nearer
|
||||
.org 6
|
||||
movl nearer, %ebx
|
||||
.org 11
|
||||
.space 100
|
||||
nearer:
|
||||
.space 200
|
||||
|
||||
+26
-13
@@ -389,7 +389,14 @@ fi
|
||||
# Check for functions and headers.
|
||||
AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
|
||||
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
|
||||
|
||||
# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation
|
||||
# warning which causes compilation failure later with -Werror. So use -Werror here
|
||||
# as well to force proper sys/sysmacros.h detection.
|
||||
SAVED_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$HOST_CFLAGS -Werror"
|
||||
AC_HEADER_MAJOR
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
|
||||
#include <sys/param.h>
|
||||
@@ -1145,14 +1152,15 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then
|
||||
fi
|
||||
|
||||
if test "x$target_cpu" = xarm; then
|
||||
AC_CACHE_CHECK([whether option -mlong-calls works], grub_cv_cc_mlong_calls, [
|
||||
CFLAGS="$TARGET_CFLAGS -mlong-calls -Werror"
|
||||
AC_CACHE_CHECK([whether option -mllvm -arm-use-movt=0 works], grub_cv_cc_mllvm_arm_use_movt, [
|
||||
CPPFLAGS="$TARGET_CPPFLAGS -mllvm -arm-use-movt=0 -Werror"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_cc_mlong_calls=yes],
|
||||
[grub_cv_cc_mlong_calls=no])
|
||||
[grub_cv_cc_mllvm_arm_use_movt=yes],
|
||||
[grub_cv_cc_mllvm_arm_use_movt=no])
|
||||
])
|
||||
if test "x$grub_cv_cc_mlong_calls" = xyes; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -mlong-calls"
|
||||
if test "x$grub_cv_cc_mllvm_arm_use_movt" = xyes; then
|
||||
# A trick so that clang doesn't see it on link stage
|
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -mllvm -arm-use-movt=0"
|
||||
fi
|
||||
AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [
|
||||
CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror"
|
||||
@@ -1185,13 +1193,18 @@ CFLAGS="$TARGET_CFLAGS"
|
||||
|
||||
# Position independent executable.
|
||||
grub_CHECK_PIE
|
||||
grub_CHECK_NO_PIE
|
||||
[# Need that, because some distributions ship compilers that include
|
||||
# `-fPIE' or '-fpie' in the default specs.
|
||||
# `-fPIE' or '-fpie' and '-pie' in the default specs.
|
||||
if [ x"$pie_possible" = xyes ]; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
|
||||
fi
|
||||
if [ x"$nopie_possible" = xyes ] && [ x"$pie_possible" = xyes ]; then
|
||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie"
|
||||
fi]
|
||||
|
||||
CFLAGS="$TARGET_CFLAGS"
|
||||
LDFLAGS="$TARGET_LDFLAGS"
|
||||
|
||||
# Position independent executable.
|
||||
grub_CHECK_PIC
|
||||
@@ -1555,11 +1568,11 @@ if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
else
|
||||
enable_build_grub_mkfont=no
|
||||
fi
|
||||
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
|
||||
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
|
||||
if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont])
|
||||
else
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont ($grub_build_mkfont_excuse)])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)])
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1629,11 +1642,11 @@ if test x"$enable_build_grub_mkfont" = xno ; then
|
||||
FONT_SOURCE=
|
||||
fi
|
||||
|
||||
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
|
||||
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
|
||||
if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont])
|
||||
else
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -2446,6 +2446,10 @@ The boot file name provided by DHCP. Read-only.
|
||||
The name of the DHCP server responsible for these boot parameters.
|
||||
Read-only.
|
||||
|
||||
@item net_@var{<interface>}_next_server
|
||||
The IP address of the next (usually, TFTP) server provided by DHCP.
|
||||
Read-only.
|
||||
|
||||
@item net_default_interface
|
||||
Initially set to name of network interface that was used to load grub.
|
||||
Read-write, although setting it affects only interpretation of
|
||||
@@ -3062,6 +3066,7 @@ These variables have special meaning to GRUB.
|
||||
* net_@var{<interface>}_hostname::
|
||||
* net_@var{<interface>}_ip::
|
||||
* net_@var{<interface>}_mac::
|
||||
* net_@var{<interface>}_next_server::
|
||||
* net_@var{<interface>}_rootpath::
|
||||
* net_default_interface::
|
||||
* net_default_ip::
|
||||
@@ -3422,6 +3427,12 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
@node net_@var{<interface>}_next_server
|
||||
@subsection net_@var{<interface>}_next_server
|
||||
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
@node net_@var{<interface>}_rootpath
|
||||
@subsection net_@var{<interface>}_rootpath
|
||||
|
||||
|
||||
@@ -212,8 +212,10 @@ kernel = {
|
||||
|
||||
arm_efi = kern/arm/efi/init.c;
|
||||
arm_efi = kern/arm/efi/misc.c;
|
||||
arm_efi = kern/efi/fdt.c;
|
||||
|
||||
arm64_efi = kern/arm64/efi/init.c;
|
||||
arm64_efi = kern/efi/fdt.c;
|
||||
|
||||
i386_pc = kern/i386/pc/init.c;
|
||||
i386_pc = kern/i386/pc/mmap.c;
|
||||
@@ -1531,6 +1533,7 @@ module = {
|
||||
i386_xen = lib/i386/xen/relocator.S;
|
||||
x86_64_xen = lib/x86_64/xen/relocator.S;
|
||||
xen = lib/i386/relocator_common_c.c;
|
||||
x86_64_efi = lib/x86_64/efi/relocator.c;
|
||||
|
||||
extra_dist = lib/i386/relocator_common.S;
|
||||
extra_dist = kern/powerpc/cache_flush.S;
|
||||
|
||||
+42
-221
@@ -89,9 +89,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
|
||||
#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
|
||||
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
|
||||
#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
|
||||
#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
|
||||
#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
|
||||
/* Superblock filesystem feature flags (back-incompatible)
|
||||
* A filesystem with any of these enabled should not be attempted to be read
|
||||
* by a driver that does not understand them, since they usually indicate
|
||||
@@ -105,11 +102,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
|
||||
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
||||
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
||||
#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 /* EA in inode */
|
||||
#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 /* data in dirent */
|
||||
#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
|
||||
#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */
|
||||
#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */
|
||||
|
||||
/* The set of back-incompatible features this driver DOES support. Add (OR)
|
||||
* flags here as the related features are implemented into the driver. */
|
||||
@@ -117,8 +109,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
| EXT4_FEATURE_INCOMPAT_EXTENTS \
|
||||
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
|
||||
| EXT2_FEATURE_INCOMPAT_META_BG \
|
||||
| EXT4_FEATURE_INCOMPAT_64BIT \
|
||||
| EXT4_FEATURE_INCOMPAT_INLINE_DATA)
|
||||
| EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
/* List of rationales for the ignored "incompatible" features:
|
||||
* needs_recovery: Not really back-incompatible - was added as such to forbid
|
||||
* ext2 drivers from mounting an ext3 volume with a dirty
|
||||
@@ -325,40 +316,12 @@ struct grub_ext4_extent_idx
|
||||
grub_uint16_t unused;
|
||||
};
|
||||
|
||||
#define EXT4_XATTR_MAGIC 0xEA020000
|
||||
#define EXT4_XATTR_INDEX_SYSTEM 7
|
||||
#define EXT4_XATTR_SYSTEM_DATA "data"
|
||||
#define EXT4_INLINE_DOTDOT_SIZE 4
|
||||
|
||||
struct grub_ext4_xattr_entry
|
||||
{
|
||||
grub_uint8_t name_len; /* length of name */
|
||||
grub_uint8_t name_index; /* attribute name index */
|
||||
grub_uint16_t value_offs; /* offset in disk block of value */
|
||||
grub_uint32_t value_block; /* disk block attribute is stored on */
|
||||
grub_uint32_t value_size; /* size of attribute value */
|
||||
grub_uint32_t hash; /* hash value of name and value */
|
||||
char name[0]; /* attribute name */
|
||||
} GRUB_PACKED;
|
||||
|
||||
#define EXT4_XATTR_LEN(name_len) \
|
||||
(ALIGN_UP((name_len) + sizeof(struct grub_ext4_xattr_entry), 4))
|
||||
#define EXT4_XATTR_NEXT(entry) \
|
||||
((struct grub_ext4_xattr_entry *)( \
|
||||
(char *)(entry) + EXT4_XATTR_LEN((entry)->name_len)))
|
||||
#define IS_LAST_ENTRY(entry) (grub_get_unaligned32 (entry) == 0)
|
||||
|
||||
|
||||
struct grub_fshelp_node
|
||||
{
|
||||
struct grub_ext2_data *data;
|
||||
struct grub_ext2_inode inode;
|
||||
grub_uint32_t ino;
|
||||
int ino;
|
||||
int inode_read;
|
||||
grub_disk_addr_t inode_base; /* Inode filesystem block */
|
||||
grub_off_t inode_offs; /* Inode offset in filesystem block */
|
||||
grub_off_t inline_offs; /* Offset of inline data from start of inode */
|
||||
grub_size_t inline_size; /* Size of inline data */
|
||||
};
|
||||
|
||||
/* Information about a "mounted" ext2 filesystem. */
|
||||
@@ -404,66 +367,6 @@ group_has_super_block (struct grub_ext2_data *data, grub_uint64_t group)
|
||||
is_power_of(group, 3));
|
||||
}
|
||||
|
||||
/* Inline data is stored using inline extended attributes. Attributes consist
|
||||
of entry and value. Entries start after inode proper, following 4 bytes
|
||||
magic header. Each entry is 4 bytes aligned, end of list is marked with
|
||||
4 bytes zero. Values are stored after entries.
|
||||
|
||||
Inline data is stored as system attribute with name "data". First part of
|
||||
data is kept in space reserved for block pointers, so it is valid for value
|
||||
size to be zero. Offset is apparently non-zero even in this case.
|
||||
*/
|
||||
inline static void
|
||||
grub_ext2_find_inline_data (struct grub_fshelp_node *node, grub_size_t isize,
|
||||
struct grub_ext2_inode *inode)
|
||||
{
|
||||
grub_size_t extra;
|
||||
grub_uint8_t *ihdr;
|
||||
struct grub_ext4_xattr_entry *entry;
|
||||
grub_uint8_t *iend = (grub_uint8_t *) inode + isize - sizeof (grub_uint32_t);
|
||||
|
||||
node->inline_offs = 0;
|
||||
|
||||
if (isize < EXT2_GOOD_OLD_INODE_SIZE + sizeof (grub_uint16_t))
|
||||
return;
|
||||
extra = grub_le_to_cpu16 (*((grub_uint16_t *) inode
|
||||
+ (EXT2_GOOD_OLD_INODE_SIZE / 2)));
|
||||
if (EXT2_GOOD_OLD_INODE_SIZE + extra + 4 > isize)
|
||||
return;
|
||||
ihdr = ((grub_uint8_t *) inode
|
||||
+ EXT2_GOOD_OLD_INODE_SIZE + extra);
|
||||
if (grub_get_unaligned32 (ihdr)
|
||||
!= grub_cpu_to_le32_compile_time (EXT4_XATTR_MAGIC))
|
||||
return;
|
||||
entry = (struct grub_ext4_xattr_entry *) (ihdr + 4);
|
||||
for (; (grub_uint8_t *) entry < iend && !IS_LAST_ENTRY(entry);
|
||||
entry = EXT4_XATTR_NEXT(entry))
|
||||
{
|
||||
grub_size_t value_size;
|
||||
grub_off_t value_offs;
|
||||
|
||||
if (entry->value_block)
|
||||
continue;
|
||||
if (entry->name_index != EXT4_XATTR_INDEX_SYSTEM)
|
||||
continue;
|
||||
if (entry->name_len != sizeof (EXT4_XATTR_SYSTEM_DATA) - 1)
|
||||
continue;
|
||||
if (grub_memcmp (entry->name, EXT4_XATTR_SYSTEM_DATA, sizeof (EXT4_XATTR_SYSTEM_DATA) - 1))
|
||||
continue;
|
||||
value_size = grub_le_to_cpu32 (entry->value_size);
|
||||
value_offs = grub_le_to_cpu16 (entry->value_offs);
|
||||
/* extra is additional size of base inode. Extended attributes start
|
||||
after base inode, offset is calculated from the end of extended
|
||||
attributes header.
|
||||
*/
|
||||
if (EXT2_GOOD_OLD_INODE_SIZE + extra + 4 + value_offs + value_size > isize)
|
||||
continue;
|
||||
node->inline_offs = EXT2_GOOD_OLD_INODE_SIZE + extra + 4 + value_offs;
|
||||
node->inline_size = value_size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
|
||||
the mounted filesystem DATA. */
|
||||
inline static grub_err_t
|
||||
@@ -665,52 +568,6 @@ grub_ext2_read_file (grub_fshelp_node_t node,
|
||||
grub_disk_read_hook_t read_hook, void *read_hook_data,
|
||||
grub_off_t pos, grub_size_t len, char *buf)
|
||||
{
|
||||
/* Does inode have inine data? */
|
||||
if (node->inline_offs)
|
||||
{
|
||||
grub_size_t cp_len;
|
||||
grub_off_t cp_pos;
|
||||
grub_ssize_t total = 0;
|
||||
|
||||
if (pos < 60)
|
||||
{
|
||||
cp_pos = node->inode_offs + ((char *)&node->inode.blocks - (char *)&node->inode) + pos;
|
||||
cp_len = 60 - pos;
|
||||
if (cp_len > len)
|
||||
cp_len = len;
|
||||
|
||||
node->data->disk->read_hook = read_hook;
|
||||
node->data->disk->read_hook_data = read_hook_data;
|
||||
grub_disk_read (node->data->disk, node->inode_base, cp_pos,
|
||||
cp_len, buf);
|
||||
node->data->disk->read_hook = 0;
|
||||
if (grub_errno)
|
||||
return -1;
|
||||
pos += cp_len;
|
||||
buf += cp_len;
|
||||
len -= cp_len;
|
||||
total = cp_len;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
pos -= 60;
|
||||
if (pos >= node->inline_size)
|
||||
return 0;
|
||||
if (pos + len > node->inline_size)
|
||||
len = node->inline_size - pos;
|
||||
cp_pos = node->inode_offs + node->inline_offs + pos;
|
||||
node->data->disk->read_hook = read_hook;
|
||||
node->data->disk->read_hook_data = read_hook_data;
|
||||
grub_disk_read (node->data->disk, node->inode_base, cp_pos,
|
||||
len, buf);
|
||||
node->data->disk->read_hook = 0;
|
||||
if (!grub_errno)
|
||||
total += len;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
return grub_fshelp_read_file (node->data->disk, node,
|
||||
read_hook, read_hook_data,
|
||||
pos, len, buf, grub_ext2_read_block,
|
||||
@@ -721,28 +578,17 @@ grub_ext2_read_file (grub_fshelp_node_t node,
|
||||
}
|
||||
|
||||
|
||||
/* Read the inode NODE->INO for the file described by NODE->DATA into NODE->INODE. */
|
||||
/* Read the inode INO for the file described by DATA into INODE. */
|
||||
static grub_err_t
|
||||
grub_ext2_read_inode (struct grub_fshelp_node *node)
|
||||
grub_ext2_read_inode (struct grub_ext2_data *data,
|
||||
int ino, struct grub_ext2_inode *inode)
|
||||
{
|
||||
struct grub_ext2_data *data = node->data;
|
||||
grub_uint32_t ino = node->ino;
|
||||
struct grub_ext2_block_group blkgrp;
|
||||
struct grub_ext2_sblock *sblock = &data->sblock;
|
||||
int inodes_per_block;
|
||||
unsigned int blkno;
|
||||
unsigned int blkoff;
|
||||
grub_disk_addr_t base;
|
||||
struct grub_ext2_inode *full_inode;
|
||||
grub_size_t full_isize;
|
||||
|
||||
if (node->inode_read)
|
||||
return 0;
|
||||
|
||||
full_isize = EXT2_INODE_SIZE (data);
|
||||
full_inode = grub_malloc (full_isize);
|
||||
if (!full_inode)
|
||||
return 0;
|
||||
|
||||
/* It is easier to calculate if the first inode is 0. */
|
||||
ino--;
|
||||
@@ -751,12 +597,9 @@ grub_ext2_read_inode (struct grub_fshelp_node *node)
|
||||
ino / grub_le_to_cpu32 (sblock->inodes_per_group),
|
||||
&blkgrp);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_free (full_inode);
|
||||
return grub_errno;
|
||||
}
|
||||
return grub_errno;
|
||||
|
||||
inodes_per_block = EXT2_BLOCK_SIZE (data) / full_isize;
|
||||
inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data);
|
||||
blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
|
||||
/ inodes_per_block;
|
||||
blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
|
||||
@@ -768,19 +611,12 @@ grub_ext2_read_inode (struct grub_fshelp_node *node)
|
||||
<< 32);
|
||||
|
||||
/* Read the inode. */
|
||||
node->inode_base = (base + blkno) << LOG2_EXT2_BLOCK_SIZE (data);
|
||||
node->inode_offs = full_isize * blkoff;
|
||||
if (grub_disk_read (data->disk, node->inode_base, node->inode_offs,
|
||||
full_isize, full_inode))
|
||||
{
|
||||
grub_free (full_inode);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (&node->inode, full_inode, sizeof (struct grub_ext2_inode));
|
||||
if (grub_disk_read (data->disk,
|
||||
((base + blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
|
||||
EXT2_INODE_SIZE (data) * blkoff,
|
||||
sizeof (struct grub_ext2_inode), inode))
|
||||
return grub_errno;
|
||||
|
||||
node->inode_read = 1;
|
||||
grub_ext2_find_inline_data (node, full_isize, full_inode);
|
||||
grub_free (full_inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -841,9 +677,11 @@ grub_ext2_mount (grub_disk_t disk)
|
||||
|
||||
data->diropen.data = data;
|
||||
data->diropen.ino = 2;
|
||||
data->diropen.inode_read = 1;
|
||||
|
||||
data->inode = &data->diropen.inode;
|
||||
|
||||
grub_ext2_read_inode (&data->diropen);
|
||||
grub_ext2_read_inode (data, 2, data->inode);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
@@ -863,9 +701,12 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||
char *symlink;
|
||||
struct grub_fshelp_node *diro = node;
|
||||
|
||||
grub_ext2_read_inode (diro);
|
||||
if (grub_errno)
|
||||
return 0;
|
||||
if (! diro->inode_read)
|
||||
{
|
||||
grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
|
||||
if (grub_errno)
|
||||
return 0;
|
||||
}
|
||||
|
||||
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
|
||||
if (! symlink)
|
||||
@@ -901,42 +742,11 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
|
||||
unsigned int fpos = 0;
|
||||
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
|
||||
|
||||
grub_ext2_read_inode (diro);
|
||||
if (grub_errno)
|
||||
return 0;
|
||||
|
||||
/* Inline directory has only parent inode number and no explicit entries
|
||||
for . or ..; simulate them */
|
||||
if (diro->inline_offs)
|
||||
if (! diro->inode_read)
|
||||
{
|
||||
struct grub_fshelp_node *dot, *dotdot;
|
||||
grub_uint32_t inum;
|
||||
|
||||
dot = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||
if (!dot)
|
||||
return 0;
|
||||
|
||||
dot->inode_read = 0;
|
||||
dot->ino = dir->ino;
|
||||
dot->data = diro->data;
|
||||
if (hook (".", FILETYPE_DIRECTORY, dot, hook_data))
|
||||
return 1;
|
||||
|
||||
/* First 4 bytes of inline directory data is parent inode number */
|
||||
grub_ext2_read_file (diro, 0, 0, 0, EXT4_INLINE_DOTDOT_SIZE, (char *) &inum);
|
||||
grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
|
||||
if (grub_errno)
|
||||
return 0;
|
||||
dotdot = grub_malloc (sizeof (struct grub_fshelp_node));
|
||||
if (!dotdot)
|
||||
return 0;
|
||||
|
||||
dotdot->inode_read = 0;
|
||||
dotdot->ino = grub_le_to_cpu32 (inum);
|
||||
dotdot->data = diro->data;
|
||||
if (hook ("..", FILETYPE_DIRECTORY, dotdot, hook_data))
|
||||
return 1;
|
||||
|
||||
fpos = EXT4_INLINE_DOTDOT_SIZE;
|
||||
}
|
||||
|
||||
/* Search the file. */
|
||||
@@ -987,13 +797,17 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
/* The filetype can not be read from the dirent, read
|
||||
the inode to get more information. */
|
||||
grub_ext2_read_inode (fdiro);
|
||||
grub_ext2_read_inode (diro->data,
|
||||
grub_le_to_cpu32 (dirent.inode),
|
||||
&fdiro->inode);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_free (fdiro);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fdiro->inode_read = 1;
|
||||
|
||||
if ((grub_le_to_cpu16 (fdiro->inode.mode)
|
||||
& FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
|
||||
type = GRUB_FSHELP_DIR;
|
||||
@@ -1038,11 +852,14 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = grub_ext2_read_inode (fdiro);
|
||||
if (err)
|
||||
goto fail;
|
||||
if (! fdiro->inode_read)
|
||||
{
|
||||
err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
|
||||
if (err)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_memcpy (&data->diropen, fdiro, sizeof (struct grub_fshelp_node));
|
||||
grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
|
||||
grub_free (fdiro);
|
||||
|
||||
file->size = grub_le_to_cpu32 (data->inode->size);
|
||||
@@ -1101,9 +918,13 @@ grub_ext2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
struct grub_dirhook_info info;
|
||||
|
||||
grub_memset (&info, 0, sizeof (info));
|
||||
grub_ext2_read_inode (node);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
if (! node->inode_read)
|
||||
{
|
||||
grub_ext2_read_inode (ctx->data, node->ino, &node->inode);
|
||||
if (!grub_errno)
|
||||
node->inode_read = 1;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (node->inode_read)
|
||||
{
|
||||
info.mtimeset = 1;
|
||||
|
||||
+6
-1
@@ -76,8 +76,13 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* incompat feature flags */
|
||||
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
|
||||
/* We do not currently verify metadata UUID so it is safe to read such filesystem */
|
||||
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE)
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* fdt.c - EFI Flattened Device Tree interaction */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
void *
|
||||
grub_efi_get_firmware_fdt (void)
|
||||
{
|
||||
grub_efi_configuration_table_t *tables;
|
||||
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||
void *firmware_fdt = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Look for FDT in UEFI config tables. */
|
||||
tables = grub_efi_system_table->configuration_table;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
|
||||
{
|
||||
firmware_fdt = tables[i].vendor_table;
|
||||
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
|
||||
break;
|
||||
}
|
||||
|
||||
return firmware_fdt;
|
||||
}
|
||||
@@ -59,10 +59,13 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||
if (!image)
|
||||
return;
|
||||
*device = grub_efidisk_get_device_name (image->device_handle);
|
||||
*path = grub_efi_get_filename (image->file_path);
|
||||
if (!*device && grub_efi_net_config)
|
||||
grub_efi_net_config (image->device_handle, device, path);
|
||||
{
|
||||
grub_efi_net_config (image->device_handle, device, path);
|
||||
return;
|
||||
}
|
||||
|
||||
*path = grub_efi_get_filename (image->file_path);
|
||||
if (*path)
|
||||
{
|
||||
/* Get the directory. */
|
||||
|
||||
@@ -127,6 +127,7 @@ xasprintf (const char *fmt, ...)
|
||||
|
||||
va_start (ap, fmt);
|
||||
result = grub_xvasprintf (fmt, ap);
|
||||
va_end (ap);
|
||||
if (!result)
|
||||
grub_util_error ("%s", _("out of memory"));
|
||||
|
||||
|
||||
@@ -73,6 +73,14 @@ VARIABLE(grub_relocator64_rsp)
|
||||
|
||||
movq %rax, %rsp
|
||||
|
||||
/*
|
||||
* Here is grub_relocator64_efi_start() entry point.
|
||||
* Following code is shared between grub_relocator64_efi_start()
|
||||
* and grub_relocator64_start().
|
||||
*
|
||||
* Think twice before changing anything below!!!
|
||||
*/
|
||||
VARIABLE(grub_relocator64_efi_start)
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
@@ -120,6 +128,9 @@ LOCAL(jump_addr):
|
||||
VARIABLE(grub_relocator64_rip)
|
||||
.quad 0
|
||||
|
||||
/* Here grub_relocator64_efi_start() ends. Ufff... */
|
||||
VARIABLE(grub_relocator64_efi_end)
|
||||
|
||||
#ifndef __x86_64__
|
||||
.p2align 4
|
||||
LOCAL(gdt):
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/i386/memory.h>
|
||||
#include <grub/i386/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/xen.h>
|
||||
|
||||
@@ -23,78 +25,86 @@
|
||||
|
||||
VARIABLE(grub_relocator_xen_remap_start)
|
||||
LOCAL(base):
|
||||
/* mov imm32, %ebx */
|
||||
/* Remap the remapper to it's new address. */
|
||||
/* mov imm32, %ebx - %ebx: new virtual address of remapper */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_remapper_virt)
|
||||
.long 0
|
||||
|
||||
/* mov imm32, %ecx */
|
||||
/* mov imm32, %ecx - %ecx: low part of page table entry */
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_remapper_map)
|
||||
.long 0
|
||||
|
||||
/* mov imm32, %edx */
|
||||
/* mov imm32, %edx - %edx: high part of page table entry */
|
||||
.byte 0xba
|
||||
VARIABLE(grub_relocator_xen_remapper_map_high)
|
||||
.long 0
|
||||
|
||||
movl %ebx, %ebp
|
||||
movl %ebx, %ebp /* %ebx is clobbered by hypercall */
|
||||
|
||||
movl $2, %esi
|
||||
movl $UVMF_INVLPG, %esi /* esi: flags (inv. single entry) */
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
|
||||
movl %ebp, %ebx
|
||||
addl $(LOCAL(cont) - LOCAL(base)), %ebx
|
||||
|
||||
jmp *%ebx
|
||||
jmp *%ebx /* Continue with new virtual address */
|
||||
|
||||
LOCAL(cont):
|
||||
xorl %eax, %eax
|
||||
movl %eax, %ebp
|
||||
/* Modify mappings of new page tables to be read-only. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_paging_areas_addr)
|
||||
.long 0
|
||||
movl %eax, %ebx
|
||||
1:
|
||||
movl 0(%ebx), %ebp /* Get start pfn of the current area */
|
||||
movl GRUB_TARGET_SIZEOF_LONG(%ebx), %ecx /* Get # of pg tables */
|
||||
testl %ecx, %ecx /* 0 -> last area reached */
|
||||
jz 3f
|
||||
addl $(2 * GRUB_TARGET_SIZEOF_LONG), %ebx
|
||||
movl %ebx, %esp /* Save current area pointer */
|
||||
|
||||
2:
|
||||
movl %ecx, %edi
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_mfn_list)
|
||||
.long 0
|
||||
movl %eax, %edi
|
||||
movl %ebp, %eax
|
||||
movl 0(%edi, %eax, 4), %ecx
|
||||
|
||||
/* mov imm32, %ebx */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_paging_start)
|
||||
.long 0
|
||||
shll $12, %eax
|
||||
addl %eax, %ebx
|
||||
movl 0(%eax, %ebp, 4), %ecx /* mfn */
|
||||
movl %ebp, %ebx
|
||||
shll $PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */
|
||||
movl %ecx, %edx
|
||||
shll $12, %ecx
|
||||
shrl $20, %edx
|
||||
orl $5, %ecx
|
||||
movl $2, %esi
|
||||
shll $PAGE_SHIFT, %ecx /* prepare pte low part */
|
||||
shrl $(32 - PAGE_SHIFT), %edx /* pte high part */
|
||||
orl $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %ecx /* pte low */
|
||||
movl $UVMF_INVLPG, %esi
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
int $0x82 /* parameters: eax, ebx, ecx, edx, esi */
|
||||
|
||||
incl %ebp
|
||||
/* mov imm32, %ecx */
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_paging_size)
|
||||
.long 0
|
||||
cmpl %ebp, %ecx
|
||||
incl %ebp /* next pfn */
|
||||
movl %edi, %ecx
|
||||
|
||||
ja 1b
|
||||
loop 2b
|
||||
|
||||
mov %esp, %ebx /* restore area poniter */
|
||||
jmp 1b
|
||||
|
||||
3:
|
||||
/* Switch page tables: pin new L3 pt, load cr3, unpin old L3. */
|
||||
/* mov imm32, %ebx */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_mmu_op_addr)
|
||||
.long 0
|
||||
movl $3, %ecx
|
||||
movl $0, %edx
|
||||
movl $0x7FF0, %esi
|
||||
movl $3, %ecx /* 3 mmu ops */
|
||||
movl $0, %edx /* pdone (not used) */
|
||||
movl $DOMID_SELF, %esi
|
||||
movl $__HYPERVISOR_mmuext_op, %eax
|
||||
int $0x82
|
||||
|
||||
/* Continue in virtual kernel mapping. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remap_continue)
|
||||
@@ -102,6 +112,9 @@ VARIABLE(grub_relocator_xen_remap_continue)
|
||||
|
||||
jmp *%eax
|
||||
|
||||
VARIABLE(grub_relocator_xen_paging_areas)
|
||||
.long 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
VARIABLE(grub_relocator_xen_mmu_op)
|
||||
.space 256
|
||||
|
||||
@@ -109,6 +122,7 @@ VARIABLE(grub_relocator_xen_remap_end)
|
||||
|
||||
|
||||
VARIABLE(grub_relocator_xen_start)
|
||||
/* Unmap old remapper area. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt2)
|
||||
@@ -116,14 +130,14 @@ VARIABLE(grub_relocator_xen_remapper_virt2)
|
||||
|
||||
movl %eax, %edi
|
||||
|
||||
xorl %ecx, %ecx
|
||||
xorl %ecx, %ecx /* Invalid pte */
|
||||
xorl %edx, %edx
|
||||
|
||||
movl $2, %esi
|
||||
movl $UVMF_INVLPG, %esi
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
|
||||
|
||||
/* Prepare registers for starting kernel. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_stack)
|
||||
@@ -145,6 +159,7 @@ VARIABLE(grub_relocator_xen_start_info)
|
||||
VARIABLE(grub_relocator_xen_entry_point)
|
||||
.long 0
|
||||
|
||||
/* Now start the new kernel. */
|
||||
jmp *%eax
|
||||
|
||||
VARIABLE(grub_relocator_xen_end)
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
#include <grub/i386/relocator.h>
|
||||
#include <grub/relocator_private.h>
|
||||
|
||||
extern grub_uint64_t grub_relocator64_rax;
|
||||
extern grub_uint64_t grub_relocator64_rbx;
|
||||
extern grub_uint64_t grub_relocator64_rcx;
|
||||
extern grub_uint64_t grub_relocator64_rdx;
|
||||
extern grub_uint64_t grub_relocator64_rip;
|
||||
extern grub_uint64_t grub_relocator64_rsi;
|
||||
|
||||
extern grub_uint8_t grub_relocator64_efi_start;
|
||||
extern grub_uint8_t grub_relocator64_efi_end;
|
||||
|
||||
#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start)
|
||||
|
||||
grub_err_t
|
||||
grub_relocator64_efi_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator64_efi_state state)
|
||||
{
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
/*
|
||||
* 64-bit relocator code may live above 4 GiB quite well.
|
||||
* However, I do not want ask for problems. Just in case.
|
||||
*/
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||
0x100000000 - RELOCATOR_SIZEOF (64_efi),
|
||||
RELOCATOR_SIZEOF (64_efi), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Do not touch %rsp! It points to EFI created stack. */
|
||||
grub_relocator64_rax = state.rax;
|
||||
grub_relocator64_rbx = state.rbx;
|
||||
grub_relocator64_rcx = state.rcx;
|
||||
grub_relocator64_rdx = state.rdx;
|
||||
grub_relocator64_rip = state.rip;
|
||||
grub_relocator64_rsi = state.rsi;
|
||||
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_efi_start,
|
||||
RELOCATOR_SIZEOF (64_efi));
|
||||
|
||||
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||
&relst, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
((void (*) (void)) relst) ();
|
||||
|
||||
/* Not reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -16,95 +16,85 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/x86_64/memory.h>
|
||||
#include <grub/x86_64/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/xen.h>
|
||||
|
||||
/* Macro to load an imm64 value stored by the C-part into %rax: */
|
||||
#define MOV_IMM64_RAX(var) .byte 0x48, 0xb8; VARIABLE(var); .quad 0
|
||||
|
||||
.p2align 4 /* force 16-byte alignment */
|
||||
|
||||
VARIABLE(grub_relocator_xen_remap_start)
|
||||
LOCAL(base):
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt)
|
||||
.quad 0
|
||||
/* Remap the remapper to it's new address. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt)
|
||||
|
||||
movq %rax, %rdi
|
||||
movq %rax, %rbx
|
||||
movq %rax, %rdi /* %rdi: new virtual address of remapper */
|
||||
movq %rax, %rbx /* Remember new virtual address */
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_map)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_map)
|
||||
|
||||
movq %rax, %rsi
|
||||
movq %rax, %rsi /* %rsi: page table entry */
|
||||
|
||||
movq $2, %rdx
|
||||
movq $UVMF_INVLPG, %rdx /* %rdx: flags (inv. single entry) */
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
syscall /* Do the remap operation */
|
||||
|
||||
addq $(LOCAL(cont) - LOCAL(base)), %rbx
|
||||
|
||||
jmp *%rbx
|
||||
jmp *%rbx /* Continue with new virtual address */
|
||||
|
||||
LOCAL(cont):
|
||||
|
||||
/* mov imm64, %rcx */
|
||||
.byte 0x48
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_paging_size)
|
||||
.quad 0
|
||||
/* Modify mappings of new page tables to be read-only. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_mfn_list)
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_paging_start)
|
||||
.quad 0
|
||||
movq %rax, %rbx /* %rbx is the base of the p2m list */
|
||||
leaq EXT_C(grub_relocator_xen_paging_areas) (%rip), %r8
|
||||
|
||||
movq %rax, %r12
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_mfn_list)
|
||||
.quad 0
|
||||
|
||||
movq %rax, %rsi
|
||||
1:
|
||||
movq 0(%r8), %r12 /* Get start pfn of the current area */
|
||||
movq GRUB_TARGET_SIZEOF_LONG(%r8), %rcx /* Get # of pg tables */
|
||||
testq %rcx, %rcx /* 0 -> last area reached */
|
||||
jz 3f
|
||||
2:
|
||||
movq %r12, %rdi
|
||||
movq %rsi, %rbx
|
||||
movq 0(%rsi), %rsi
|
||||
shlq $12, %rsi
|
||||
orq $5, %rsi
|
||||
movq $2, %rdx
|
||||
movq %rcx, %r9
|
||||
shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */
|
||||
movq (%rbx, %r12, 8), %rsi /* mfn */
|
||||
shlq $PAGE_SHIFT, %rsi
|
||||
orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */
|
||||
movq $UVMF_INVLPG, %rdx
|
||||
movq %rcx, %r9 /* %rcx clobbered by hypercall */
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
|
||||
movq %r9, %rcx
|
||||
addq $8, %rbx
|
||||
addq $4096, %r12
|
||||
movq %rbx, %rsi
|
||||
incq %r12 /* next pfn */
|
||||
|
||||
loop 1b
|
||||
loop 2b
|
||||
|
||||
leaq LOCAL(mmu_op) (%rip), %rdi
|
||||
movq $3, %rsi
|
||||
movq $0, %rdx
|
||||
movq $0x7FF0, %r10
|
||||
addq $(2 * GRUB_TARGET_SIZEOF_LONG), %r8 /* next pg table area */
|
||||
jmp 1b
|
||||
|
||||
3:
|
||||
/* Switch page tables: pin new L4 pt, load cr3, unpin old L4. */
|
||||
leaq EXT_C(grub_relocator_xen_mmu_op) (%rip), %rdi
|
||||
movq $3, %rsi /* 3 mmu ops */
|
||||
movq $0, %rdx /* pdone (not used) */
|
||||
movq $DOMID_SELF, %r10
|
||||
movq $__HYPERVISOR_mmuext_op, %rax
|
||||
syscall
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remap_continue)
|
||||
.quad 0
|
||||
/* Continue in virtual kernel mapping. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remap_continue)
|
||||
|
||||
jmp *%rax
|
||||
|
||||
LOCAL(mmu_op):
|
||||
VARIABLE(grub_relocator_xen_paging_areas)
|
||||
/* array of start, size pairs, size 0 is end marker */
|
||||
.quad 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
VARIABLE(grub_relocator_xen_mmu_op)
|
||||
.space 256
|
||||
|
||||
@@ -112,46 +102,32 @@ VARIABLE(grub_relocator_xen_remap_end)
|
||||
|
||||
|
||||
VARIABLE(grub_relocator_xen_start)
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt2)
|
||||
.quad 0
|
||||
/* Unmap old remapper area. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt2)
|
||||
|
||||
movq %rax, %rdi
|
||||
|
||||
xorq %rax, %rax
|
||||
xorq %rax, %rax /* Invalid pte */
|
||||
movq %rax, %rsi
|
||||
|
||||
movq $2, %rdx
|
||||
movq $UVMF_INVLPG, %rdx
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_stack)
|
||||
.quad 0
|
||||
/* Prepare registers for starting kernel. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_stack)
|
||||
|
||||
movq %rax, %rsp
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_start_info)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_start_info)
|
||||
|
||||
movq %rax, %rsi
|
||||
|
||||
cld
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_entry_point)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_entry_point)
|
||||
|
||||
/* Now start the new kernel. */
|
||||
jmp *%rax
|
||||
|
||||
VARIABLE(grub_relocator_xen_end)
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
typedef grub_addr_t grub_xen_reg_t;
|
||||
|
||||
struct grub_relocator_xen_paging_area {
|
||||
grub_xen_reg_t start;
|
||||
grub_xen_reg_t size;
|
||||
} GRUB_PACKED;
|
||||
|
||||
extern grub_uint8_t grub_relocator_xen_start;
|
||||
extern grub_uint8_t grub_relocator_xen_end;
|
||||
extern grub_uint8_t grub_relocator_xen_remap_start;
|
||||
@@ -36,15 +41,16 @@ extern grub_uint8_t grub_relocator_xen_remap_end;
|
||||
extern grub_xen_reg_t grub_relocator_xen_stack;
|
||||
extern grub_xen_reg_t grub_relocator_xen_start_info;
|
||||
extern grub_xen_reg_t grub_relocator_xen_entry_point;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_start;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_size;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_virt;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_virt2;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_map;
|
||||
extern grub_xen_reg_t grub_relocator_xen_mfn_list;
|
||||
extern struct grub_relocator_xen_paging_area
|
||||
grub_relocator_xen_paging_areas[XEN_MAX_MAPPINGS];
|
||||
extern grub_xen_reg_t grub_relocator_xen_remap_continue;
|
||||
#ifdef __i386__
|
||||
extern grub_xen_reg_t grub_relocator_xen_mmu_op_addr;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_areas_addr;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_map_high;
|
||||
#endif
|
||||
extern mmuext_op_t grub_relocator_xen_mmu_op[3];
|
||||
@@ -61,6 +67,7 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
{
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
int i;
|
||||
grub_relocator_chunk_t ch, ch_tramp;
|
||||
grub_xen_mfn_t *mfn_list =
|
||||
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
|
||||
@@ -77,8 +84,11 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
grub_relocator_xen_stack = state.stack;
|
||||
grub_relocator_xen_start_info = state.start_info;
|
||||
grub_relocator_xen_entry_point = state.entry_point;
|
||||
grub_relocator_xen_paging_start = state.paging_start << 12;
|
||||
grub_relocator_xen_paging_size = state.paging_size;
|
||||
for (i = 0; i < XEN_MAX_MAPPINGS; i++)
|
||||
{
|
||||
grub_relocator_xen_paging_areas[i].start = state.paging_start[i];
|
||||
grub_relocator_xen_paging_areas[i].size = state.paging_size[i];
|
||||
}
|
||||
grub_relocator_xen_remapper_virt = remapper_virt;
|
||||
grub_relocator_xen_remapper_virt2 = remapper_virt;
|
||||
grub_relocator_xen_remap_continue = trampoline_virt;
|
||||
@@ -88,10 +98,12 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
grub_relocator_xen_remapper_map_high = (mfn_list[remapper_pfn] >> 20);
|
||||
grub_relocator_xen_mmu_op_addr = (char *) &grub_relocator_xen_mmu_op
|
||||
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
|
||||
grub_relocator_xen_paging_areas_addr =
|
||||
(char *) &grub_relocator_xen_paging_areas
|
||||
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
|
||||
#endif
|
||||
|
||||
grub_relocator_xen_mfn_list = state.mfn_list
|
||||
+ state.paging_start * sizeof (grub_addr_t);
|
||||
grub_relocator_xen_mfn_list = state.mfn_list;
|
||||
|
||||
grub_memset (grub_relocator_xen_mmu_op, 0,
|
||||
sizeof (grub_relocator_xen_mmu_op));
|
||||
@@ -100,9 +112,9 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
#else
|
||||
grub_relocator_xen_mmu_op[0].cmd = MMUEXT_PIN_L4_TABLE;
|
||||
#endif
|
||||
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start];
|
||||
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start[0]];
|
||||
grub_relocator_xen_mmu_op[1].cmd = MMUEXT_NEW_BASEPTR;
|
||||
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start];
|
||||
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start[0]];
|
||||
grub_relocator_xen_mmu_op[2].cmd = MMUEXT_UNPIN_TABLE;
|
||||
grub_relocator_xen_mmu_op[2].arg1.mfn =
|
||||
mfn_list[grub_xen_start_page_addr->pt_base >> 12];
|
||||
|
||||
@@ -28,28 +28,6 @@
|
||||
static void *loaded_fdt;
|
||||
static void *fdt;
|
||||
|
||||
static void *
|
||||
get_firmware_fdt (void)
|
||||
{
|
||||
grub_efi_configuration_table_t *tables;
|
||||
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||
void *firmware_fdt = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Look for FDT in UEFI config tables. */
|
||||
tables = grub_efi_system_table->configuration_table;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
|
||||
{
|
||||
firmware_fdt = tables[i].vendor_table;
|
||||
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
|
||||
break;
|
||||
}
|
||||
|
||||
return firmware_fdt;
|
||||
}
|
||||
|
||||
void *
|
||||
grub_fdt_load (grub_size_t additional_size)
|
||||
{
|
||||
@@ -65,7 +43,7 @@ grub_fdt_load (grub_size_t additional_size)
|
||||
if (loaded_fdt)
|
||||
raw_fdt = loaded_fdt;
|
||||
else
|
||||
raw_fdt = get_firmware_fdt();
|
||||
raw_fdt = grub_efi_get_firmware_fdt();
|
||||
|
||||
size =
|
||||
raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ;
|
||||
|
||||
@@ -122,6 +122,8 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
if (*p == '/')
|
||||
*p = '\\';
|
||||
|
||||
/* File Path is NULL terminated */
|
||||
fp->path_name[size++] = '\0';
|
||||
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
|
||||
}
|
||||
|
||||
@@ -156,8 +158,10 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
|
||||
}
|
||||
|
||||
/* File Path is NULL terminated. Allocate space for 2 extra characters */
|
||||
/* FIXME why we split path in two components? */
|
||||
file_path = grub_malloc (size
|
||||
+ ((grub_strlen (dir_start) + 1)
|
||||
+ ((grub_strlen (dir_start) + 2)
|
||||
* GRUB_MAX_UTF16_PER_UTF8
|
||||
* sizeof (grub_efi_char16_t))
|
||||
+ sizeof (grub_efi_file_path_device_path_t) * 2);
|
||||
|
||||
@@ -915,8 +915,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@@ -925,8 +925,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
default:
|
||||
/* Ignore invalid values. */
|
||||
|
||||
@@ -70,9 +70,18 @@ load_kernel (grub_file_t file, const char *filename,
|
||||
char *buffer, struct multiboot_header *header)
|
||||
{
|
||||
grub_err_t err;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.buffer = buffer;
|
||||
mld.mbi_ver = 1;
|
||||
mld.relocatable = 0;
|
||||
mld.avoid_efi_boot_services = 0;
|
||||
|
||||
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE)
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err == GRUB_ERR_NONE) {
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -121,7 +130,7 @@ load_kernel (grub_file_t file, const char *filename,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
return grub_multiboot_load_elf (file, filename, buffer);
|
||||
return grub_multiboot_load_elf (&mld);
|
||||
}
|
||||
|
||||
static struct multiboot_header *
|
||||
|
||||
+520
-258
File diff suppressed because it is too large.
Load diff
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <grub/xen_file.h>
|
||||
#include <grub/misc.h>
|
||||
#include <xen/elfnote.h>
|
||||
|
||||
static grub_err_t
|
||||
parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
@@ -26,6 +27,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
char *buf;
|
||||
char *ptr;
|
||||
int has_paddr = 0;
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (grub_file_seek (elf->file, off) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
buf = grub_malloc (sz);
|
||||
@@ -35,7 +38,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz)
|
||||
{
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
grub_free (buf);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
elf->file->name);
|
||||
}
|
||||
@@ -123,14 +127,14 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
{
|
||||
xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0)
|
||||
{
|
||||
xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0)
|
||||
@@ -138,7 +142,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16);
|
||||
xi->has_hypercall_page = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0)
|
||||
@@ -146,7 +150,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16);
|
||||
has_paddr = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +158,11 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base;
|
||||
if (!has_paddr)
|
||||
xi->paddr_offset = xi->virt_base;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
out:
|
||||
grub_free (buf);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
@@ -196,35 +204,35 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->has_note = 1;
|
||||
switch (nh->n_type)
|
||||
{
|
||||
case 1:
|
||||
case XEN_ELFNOTE_ENTRY:
|
||||
xi->entry_point = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 2:
|
||||
case XEN_ELFNOTE_HYPERCALL_PAGE:
|
||||
xi->hypercall_page = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_hypercall_page = 1;
|
||||
break;
|
||||
case 3:
|
||||
case XEN_ELFNOTE_VIRT_BASE:
|
||||
xi->virt_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 4:
|
||||
case XEN_ELFNOTE_PADDR_OFFSET:
|
||||
xi->paddr_offset = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 5:
|
||||
case XEN_ELFNOTE_XEN_VERSION:
|
||||
grub_dprintf ("xen", "xenversion = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 6:
|
||||
case XEN_ELFNOTE_GUEST_OS:
|
||||
grub_dprintf ("xen", "name = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 7:
|
||||
case XEN_ELFNOTE_GUEST_VERSION:
|
||||
grub_dprintf ("xen", "version = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 8:
|
||||
case XEN_ELFNOTE_LOADER:
|
||||
if (descsz < 7
|
||||
|| grub_memcmp (desc, "generic", descsz == 7 ? 7 : 8) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid loader");
|
||||
break;
|
||||
/* PAE */
|
||||
case 9:
|
||||
case XEN_ELFNOTE_PAE_MODE:
|
||||
grub_dprintf ("xen", "pae = `%s', %d, %d\n", (char *) desc,
|
||||
xi->arch, descsz);
|
||||
if (xi->arch != GRUB_XEN_FILE_I386
|
||||
@@ -253,6 +261,13 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
descsz == 2 ? 2 : 3) == 0)
|
||||
xi->arch = GRUB_XEN_FILE_I386;
|
||||
break;
|
||||
case XEN_ELFNOTE_INIT_P2M:
|
||||
xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_p2m_base = 1;
|
||||
break;
|
||||
case XEN_ELFNOTE_MOD_START_PFN:
|
||||
xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc);
|
||||
break;
|
||||
default:
|
||||
grub_dprintf ("xen", "unknown note type %d\n", nh->n_type);
|
||||
break;
|
||||
|
||||
@@ -118,6 +118,48 @@ grub_multiboot_set_video_mode (void)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
#define grub_relocator_efi_boot grub_relocator64_efi_boot
|
||||
#define grub_relocator_efi_state grub_relocator64_efi_state
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef grub_relocator_efi_boot
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel,
|
||||
grub_uint32_t target)
|
||||
{
|
||||
struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE;
|
||||
|
||||
state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip;
|
||||
state_efi.MULTIBOOT_EFI_MBI_REGISTER = target;
|
||||
|
||||
grub_relocator_efi_boot (rel, state_efi);
|
||||
}
|
||||
#else
|
||||
#define grub_efi_is_finished 1
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
|
||||
grub_uint32_t target __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state, 0);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state);
|
||||
}
|
||||
#endif
|
||||
|
||||
static grub_err_t
|
||||
grub_multiboot_boot (void)
|
||||
{
|
||||
@@ -131,11 +173,10 @@ grub_multiboot_boot (void)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
|
||||
#else
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state);
|
||||
#endif
|
||||
if (grub_efi_is_finished)
|
||||
normal_boot (grub_multiboot_relocator, state);
|
||||
else
|
||||
efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER);
|
||||
|
||||
/* Not reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -166,13 +207,12 @@ static grub_uint64_t highest_load;
|
||||
|
||||
/* Load ELF32 or ELF64. */
|
||||
grub_err_t
|
||||
grub_multiboot_load_elf (grub_file_t file, const char *filename,
|
||||
void *buffer)
|
||||
grub_multiboot_load_elf (mbi_load_data_t *mld)
|
||||
{
|
||||
if (grub_multiboot_is_elf32 (buffer))
|
||||
return grub_multiboot_load_elf32 (file, filename, buffer);
|
||||
else if (grub_multiboot_is_elf64 (buffer))
|
||||
return grub_multiboot_load_elf64 (file, filename, buffer);
|
||||
if (grub_multiboot_is_elf32 (mld->buffer))
|
||||
return grub_multiboot_load_elf32 (mld);
|
||||
else if (grub_multiboot_is_elf64 (mld->buffer))
|
||||
return grub_multiboot_load_elf64 (mld);
|
||||
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic"));
|
||||
}
|
||||
|
||||
@@ -51,11 +51,15 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, void *buffer)
|
||||
CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer;
|
||||
char *phdr_base;
|
||||
grub_err_t err;
|
||||
grub_relocator_chunk_t ch;
|
||||
grub_uint32_t load_offset, load_size;
|
||||
int i;
|
||||
void *source;
|
||||
|
||||
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
|
||||
@@ -75,54 +79,86 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
|
||||
|
||||
phdr_base = (char *) buffer + ehdr->e_phoff;
|
||||
phdr_base = (char *) mld->buffer + ehdr->e_phoff;
|
||||
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
|
||||
|
||||
mld->link_base_addr = ~0;
|
||||
|
||||
/* Calculate lowest and highest load address. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr);
|
||||
highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz);
|
||||
}
|
||||
|
||||
#ifdef MULTIBOOT_LOAD_ELF64
|
||||
if (highest_load >= 0x100000000)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
|
||||
#endif
|
||||
|
||||
load_size = highest_load - mld->link_base_addr;
|
||||
|
||||
if (mld->relocatable)
|
||||
{
|
||||
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld->min_addr, mld->max_addr - load_size,
|
||||
load_size, mld->align ? mld->align : 1,
|
||||
mld->preference, mld->avoid_efi_boot_services);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch,
|
||||
mld->link_base_addr, load_size);
|
||||
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
mld->load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
|
||||
mld->load_base_addr, load_size, mld->relocatable);
|
||||
|
||||
if (mld->relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld->align, mld->preference, mld->avoid_efi_boot_services);
|
||||
|
||||
/* Load every loadable segment in memory. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
grub_err_t err;
|
||||
void *source;
|
||||
|
||||
if (phdr(i)->p_paddr + phdr(i)->p_memsz > highest_load)
|
||||
highest_load = phdr(i)->p_paddr + phdr(i)->p_memsz;
|
||||
|
||||
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
|
||||
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, phdr(i)->p_paddr,
|
||||
phdr(i)->p_memsz);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
source = get_virtual_current_address (ch);
|
||||
}
|
||||
load_offset = phdr(i)->p_paddr - mld->link_base_addr;
|
||||
|
||||
if (phdr(i)->p_filesz != 0)
|
||||
{
|
||||
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
|
||||
if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset)
|
||||
== (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, source, phdr(i)->p_filesz)
|
||||
if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz)
|
||||
!= (grub_ssize_t) phdr(i)->p_filesz)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
|
||||
grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
|
||||
grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0,
|
||||
phdr(i)->p_memsz - phdr(i)->p_filesz);
|
||||
}
|
||||
}
|
||||
@@ -168,18 +204,18 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
if (!shdr)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (shdr);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_file_read (file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -189,7 +225,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
|
||||
void *src;
|
||||
grub_addr_t target;
|
||||
grub_err_t err;
|
||||
|
||||
if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA))
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet");
|
||||
|
||||
/* This section is a loaded section,
|
||||
so we don't care. */
|
||||
@@ -200,33 +238,28 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
if (sh->sh_size == 0)
|
||||
continue;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||
&ch, 0,
|
||||
(0xffffffff - sh->sh_size)
|
||||
+ 1, sh->sh_size,
|
||||
sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
0);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
}
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0,
|
||||
(0xffffffff - sh->sh_size) + 1,
|
||||
sh->sh_size, sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
mld->avoid_efi_boot_services);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
|
||||
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, src, sh->sh_size)
|
||||
if (grub_file_read (mld->file, src, sh->sh_size)
|
||||
!= (grub_ssize_t) sh->sh_size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
sh->sh_addr = target;
|
||||
|
||||
@@ -68,6 +68,7 @@ static grub_size_t elf_sec_num, elf_sec_entsize;
|
||||
static unsigned elf_sec_shstrndx;
|
||||
static void *elf_sections;
|
||||
static int keep_bs = 0;
|
||||
static grub_uint32_t load_base_addr;
|
||||
|
||||
void
|
||||
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||
@@ -101,36 +102,40 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
|
||||
grub_err_t
|
||||
grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
{
|
||||
grub_properly_aligned_t *buffer;
|
||||
grub_ssize_t len;
|
||||
struct multiboot_header *header;
|
||||
grub_err_t err;
|
||||
struct multiboot_header_tag *tag;
|
||||
struct multiboot_header_tag_address *addr_tag = NULL;
|
||||
int entry_specified = 0;
|
||||
grub_addr_t entry = 0;
|
||||
struct multiboot_header_tag_relocatable *rel_tag;
|
||||
int entry_specified = 0, efi_entry_specified = 0;
|
||||
grub_addr_t entry = 0, efi_entry = 0;
|
||||
grub_uint32_t console_required = 0;
|
||||
struct multiboot_header_tag_framebuffer *fbtag = NULL;
|
||||
int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!buffer)
|
||||
mld.mbi_ver = 2;
|
||||
mld.relocatable = 0;
|
||||
|
||||
mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!mld.buffer)
|
||||
return grub_errno;
|
||||
|
||||
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
|
||||
len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
|
||||
if (len < 32)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
|
||||
}
|
||||
|
||||
COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
|
||||
|
||||
header = find_header (buffer, len);
|
||||
header = find_header (mld.buffer, len);
|
||||
|
||||
if (header == 0)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
|
||||
}
|
||||
|
||||
@@ -172,10 +177,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
case MULTIBOOT_TAG_TYPE_NETWORK:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_BS:
|
||||
case MULTIBOOT_TAG_TYPE_EFI32_IH:
|
||||
case MULTIBOOT_TAG_TYPE_EFI64_IH:
|
||||
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
|
||||
break;
|
||||
|
||||
default:
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported information tag: 0x%x",
|
||||
request_tag->requests[i]);
|
||||
@@ -192,6 +200,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
|
||||
#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
|
||||
efi_entry_specified = 1;
|
||||
efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
|
||||
if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
|
||||
& MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
|
||||
@@ -206,27 +221,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_RELOCATABLE:
|
||||
mld.relocatable = 1;
|
||||
rel_tag = (struct multiboot_header_tag_relocatable *) tag;
|
||||
mld.min_addr = rel_tag->min_addr;
|
||||
mld.max_addr = rel_tag->max_addr;
|
||||
mld.align = rel_tag->align;
|
||||
switch (rel_tag->preference)
|
||||
{
|
||||
case MULTIBOOT_LOAD_PREFERENCE_LOW:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_LOAD_PREFERENCE_HIGH:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
|
||||
break;
|
||||
|
||||
default:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* GRUB always page-aligns modules. */
|
||||
case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_EFI_BS:
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
keep_bs = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported tag: 0x%x", tag->type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr_tag && !entry_specified)
|
||||
if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"load address tag without entry address tag");
|
||||
}
|
||||
@@ -235,8 +273,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
{
|
||||
grub_uint64_t load_addr = (addr_tag->load_addr + 1)
|
||||
? addr_tag->load_addr : (addr_tag->header_addr
|
||||
- ((char *) header - (char *) buffer));
|
||||
int offset = ((char *) header - (char *) buffer -
|
||||
- ((char *) header - (char *) mld.buffer));
|
||||
int offset = ((char *) header - (char *) mld.buffer -
|
||||
(addr_tag->header_addr - load_addr));
|
||||
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
|
||||
addr_tag->load_end_addr - addr_tag->load_addr);
|
||||
@@ -249,27 +287,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
else
|
||||
code_size = load_size;
|
||||
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr,
|
||||
code_size);
|
||||
if (mld.relocatable)
|
||||
{
|
||||
if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
|
||||
{
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
}
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld.min_addr, mld.max_addr - code_size,
|
||||
code_size, mld.align ? mld.align : 1,
|
||||
mld.preference, keep_bs);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr, code_size);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
mld.link_base_addr = load_addr;
|
||||
mld.load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
|
||||
mld.load_base_addr, (long) code_size, mld.relocatable);
|
||||
|
||||
if (mld.relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld.align, mld.preference, keep_bs);
|
||||
|
||||
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_file_read (file, source, load_size);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -279,17 +340,41 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.avoid_efi_boot_services = keep_bs;
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry_specified)
|
||||
load_base_addr = mld.load_base_addr;
|
||||
|
||||
if (keep_bs && efi_entry_specified)
|
||||
grub_multiboot_payload_eip = efi_entry;
|
||||
else if (entry_specified)
|
||||
grub_multiboot_payload_eip = entry;
|
||||
|
||||
if (mld.relocatable)
|
||||
{
|
||||
/*
|
||||
* Both branches are mathematically equivalent. However, it looks
|
||||
* that real life (C?) is more complicated. I am trying to avoid
|
||||
* wrap around here if mld.load_base_addr < mld.link_base_addr.
|
||||
* If you look at C operator precedence then everything should work.
|
||||
* However, I am not 100% sure that a given compiler will not
|
||||
* optimize/break this stuff. So, maybe we should use signed
|
||||
* 64-bit int here.
|
||||
*/
|
||||
if (mld.load_base_addr >= mld.link_base_addr)
|
||||
grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr;
|
||||
else
|
||||
grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr;
|
||||
}
|
||||
|
||||
if (fbtag)
|
||||
err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
|
||||
accepted_consoles,
|
||||
@@ -377,7 +462,7 @@ static grub_size_t
|
||||
grub_multiboot_get_mbi_size (void)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
if (!efi_mmap_size)
|
||||
if (!keep_bs && !efi_mmap_size)
|
||||
find_efi_mmap_size ();
|
||||
#endif
|
||||
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||
@@ -396,13 +481,16 @@ grub_multiboot_get_mbi_size (void)
|
||||
+ grub_get_multiboot_mmap_count ()
|
||||
* sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
|
||||
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
|
||||
+ acpiv2_size ()
|
||||
+ net_size ()
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
|
||||
+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
|
||||
#endif
|
||||
@@ -678,6 +766,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
% sizeof (grub_properly_aligned_t) == 0);
|
||||
ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
|
||||
|
||||
{
|
||||
struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
|
||||
tag->size = sizeof (struct multiboot_tag_load_base_addr);
|
||||
tag->load_base_addr = load_base_addr;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
|
||||
@@ -740,12 +837,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_elf_sections *tag
|
||||
@@ -761,18 +859,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct grub_net_network_level_interface *net;
|
||||
@@ -871,36 +970,57 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
grub_efi_uintn_t efi_desc_size;
|
||||
grub_efi_uint32_t efi_desc_version;
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
if (!keep_bs)
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
else
|
||||
{
|
||||
if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
|
||||
NULL,
|
||||
&efi_desc_size, &efi_desc_version) <= 0)
|
||||
err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_bs)
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
{
|
||||
struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi32_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
{
|
||||
struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi64_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+14
-10
@@ -142,6 +142,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||
grub_net_link_level_address_t hwaddr;
|
||||
struct grub_net_network_level_interface *inter;
|
||||
int mask = -1;
|
||||
char server_ip[sizeof ("xxx.xxx.xxx.xxx")];
|
||||
|
||||
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
||||
addr.ipv4 = bp->your_ip;
|
||||
@@ -192,15 +193,22 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||
if (size > OFFSET_OF (boot_file, bp))
|
||||
grub_env_set_net_property (name, "boot_file", bp->boot_file,
|
||||
sizeof (bp->boot_file));
|
||||
if (bp->server_ip)
|
||||
{
|
||||
grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d",
|
||||
((grub_uint8_t *) &bp->server_ip)[0],
|
||||
((grub_uint8_t *) &bp->server_ip)[1],
|
||||
((grub_uint8_t *) &bp->server_ip)[2],
|
||||
((grub_uint8_t *) &bp->server_ip)[3]);
|
||||
grub_env_set_net_property (name, "next_server", server_ip, sizeof (server_ip));
|
||||
grub_print_error ();
|
||||
}
|
||||
|
||||
if (is_def)
|
||||
grub_net_default_server = 0;
|
||||
if (is_def && !grub_net_default_server && bp->server_ip)
|
||||
{
|
||||
grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d",
|
||||
((grub_uint8_t *) &bp->server_ip)[0],
|
||||
((grub_uint8_t *) &bp->server_ip)[1],
|
||||
((grub_uint8_t *) &bp->server_ip)[2],
|
||||
((grub_uint8_t *) &bp->server_ip)[3]);
|
||||
grub_net_default_server = grub_strdup (server_ip);
|
||||
grub_print_error ();
|
||||
}
|
||||
|
||||
@@ -212,11 +220,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||
|
||||
if (device && !*device && bp->server_ip)
|
||||
{
|
||||
*device = grub_xasprintf ("tftp,%d.%d.%d.%d",
|
||||
((grub_uint8_t *) &bp->server_ip)[0],
|
||||
((grub_uint8_t *) &bp->server_ip)[1],
|
||||
((grub_uint8_t *) &bp->server_ip)[2],
|
||||
((grub_uint8_t *) &bp->server_ip)[3]);
|
||||
*device = grub_xasprintf ("tftp,%s", server_ip);
|
||||
grub_print_error ();
|
||||
}
|
||||
if (size > OFFSET_OF (server_name, bp)
|
||||
|
||||
@@ -238,6 +238,15 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||
char *redirect_save = NULL;
|
||||
grub_uint32_t ttl_all = ~0U;
|
||||
|
||||
/* Code apparently assumed that only one packet is received as response.
|
||||
We may get multiple responses due to network condition, so check here
|
||||
and quit early. */
|
||||
if (*data->addresses)
|
||||
{
|
||||
grub_netbuff_free (nb);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
head = (struct dns_header *) nb->data;
|
||||
ptr = (grub_uint8_t *) (head + 1);
|
||||
if (ptr >= nb->tail)
|
||||
|
||||
@@ -85,24 +85,30 @@ get_card_packet (struct grub_net_card *dev)
|
||||
grub_uint64_t start_time;
|
||||
struct grub_net_buff *nb;
|
||||
|
||||
nb = grub_netbuff_alloc (dev->mtu + 64 + 2);
|
||||
start_time = grub_get_time_ms ();
|
||||
do
|
||||
rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
|
||||
while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
|
||||
|
||||
if (actual <= 0)
|
||||
return NULL;
|
||||
|
||||
nb = grub_netbuff_alloc (actual + 2);
|
||||
if (!nb)
|
||||
return NULL;
|
||||
/* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible
|
||||
by 4. So that IP header is aligned on 4 bytes. */
|
||||
grub_netbuff_reserve (nb, 2);
|
||||
|
||||
start_time = grub_get_time_ms ();
|
||||
do
|
||||
rc = grub_ieee1275_read (data->handle, nb->data, dev->mtu + 64, &actual);
|
||||
while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
|
||||
if (actual > 0)
|
||||
grub_memcpy (nb->data, dev->rcvbuf, actual);
|
||||
|
||||
if (grub_netbuff_put (nb, actual))
|
||||
{
|
||||
grub_netbuff_put (nb, actual);
|
||||
return nb;
|
||||
grub_netbuff_free (nb);
|
||||
return NULL;
|
||||
}
|
||||
grub_netbuff_free (nb);
|
||||
return NULL;
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
static struct grub_net_card_driver ofdriver =
|
||||
@@ -294,6 +300,91 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path,
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory with alloc-mem */
|
||||
static void *
|
||||
grub_ieee1275_alloc_mem (grub_size_t len)
|
||||
{
|
||||
struct alloc_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
grub_ieee1275_cell_t method;
|
||||
grub_ieee1275_cell_t len;
|
||||
grub_ieee1275_cell_t catch;
|
||||
grub_ieee1275_cell_t result;
|
||||
}
|
||||
args;
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2);
|
||||
args.len = len;
|
||||
args.method = (grub_ieee1275_cell_t) "alloc-mem";
|
||||
|
||||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch)
|
||||
{
|
||||
grub_error (GRUB_ERR_INVALID_COMMAND, N_("alloc-mem failed"));
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return (void *)args.result;
|
||||
}
|
||||
|
||||
/* Free memory allocated by alloc-mem */
|
||||
static grub_err_t
|
||||
grub_ieee1275_free_mem (void *addr, grub_size_t len)
|
||||
{
|
||||
struct free_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
grub_ieee1275_cell_t method;
|
||||
grub_ieee1275_cell_t len;
|
||||
grub_ieee1275_cell_t addr;
|
||||
grub_ieee1275_cell_t catch;
|
||||
}
|
||||
args;
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported"));
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "interpret", 3, 1);
|
||||
args.addr = (grub_ieee1275_cell_t)addr;
|
||||
args.len = len;
|
||||
args.method = (grub_ieee1275_cell_t) "free-mem";
|
||||
|
||||
if (IEEE1275_CALL_ENTRY_FN(&args) == -1 || args.catch)
|
||||
{
|
||||
grub_error (GRUB_ERR_INVALID_COMMAND, N_("free-mem failed"));
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void *
|
||||
ofnet_alloc_netbuf (grub_size_t len)
|
||||
{
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
|
||||
return grub_ieee1275_alloc_mem (len);
|
||||
else
|
||||
return grub_zalloc (len);
|
||||
}
|
||||
|
||||
static void
|
||||
ofnet_free_netbuf (void *addr, grub_size_t len)
|
||||
{
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
|
||||
grub_ieee1275_free_mem (addr, len);
|
||||
else
|
||||
grub_free (addr);
|
||||
}
|
||||
|
||||
static int
|
||||
search_net_devices (struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
@@ -409,40 +500,19 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
|
||||
card->default_address = lla;
|
||||
|
||||
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256;
|
||||
card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256;
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
|
||||
{
|
||||
struct alloc_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
grub_ieee1275_cell_t method;
|
||||
grub_ieee1275_cell_t len;
|
||||
grub_ieee1275_cell_t catch;
|
||||
grub_ieee1275_cell_t result;
|
||||
}
|
||||
args;
|
||||
INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2);
|
||||
args.len = card->txbufsize;
|
||||
args.method = (grub_ieee1275_cell_t) "alloc-mem";
|
||||
|
||||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1
|
||||
|| args.catch)
|
||||
{
|
||||
card->txbuf = 0;
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
}
|
||||
else
|
||||
card->txbuf = (void *) args.result;
|
||||
}
|
||||
else
|
||||
card->txbuf = grub_zalloc (card->txbufsize);
|
||||
card->txbuf = ofnet_alloc_netbuf (card->txbufsize);
|
||||
if (!card->txbuf)
|
||||
goto fail_netbuf;
|
||||
|
||||
card->rcvbuf = ofnet_alloc_netbuf (card->rcvbufsize);
|
||||
if (!card->rcvbuf)
|
||||
{
|
||||
grub_free (ofdata->path);
|
||||
grub_free (ofdata);
|
||||
grub_free (card);
|
||||
grub_print_error ();
|
||||
return 0;
|
||||
grub_error_push ();
|
||||
ofnet_free_netbuf (card->txbuf, card->txbufsize);
|
||||
grub_error_pop ();
|
||||
goto fail_netbuf;
|
||||
}
|
||||
card->driver = NULL;
|
||||
card->data = ofdata;
|
||||
@@ -455,6 +525,13 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
|
||||
card->driver = &ofdriver;
|
||||
grub_net_card_register (card);
|
||||
return 0;
|
||||
|
||||
fail_netbuf:
|
||||
grub_free (ofdata->path);
|
||||
grub_free (ofdata);
|
||||
grub_free (card);
|
||||
grub_print_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+3
-1
@@ -363,7 +363,9 @@ static void
|
||||
free_old_fragments (void)
|
||||
{
|
||||
struct reassemble *rsm, **prev;
|
||||
grub_uint64_t limit_time = grub_get_time_ms () - 90000;
|
||||
grub_uint64_t limit_time = grub_get_time_ms ();
|
||||
|
||||
limit_time = (limit_time > 90000) ? limit_time - 90000 : 0;
|
||||
|
||||
for (prev = &reassembles, rsm = *prev; rsm; rsm = *prev)
|
||||
if (rsm->last_time < limit_time)
|
||||
|
||||
@@ -143,7 +143,7 @@ grub_util_get_dm_abstraction (const char *os_dev)
|
||||
grub_free (uuid);
|
||||
return GRUB_DEV_ABSTRACTION_LVM;
|
||||
}
|
||||
if (strncmp (uuid, "CRYPT-LUKS1-", 4) == 0)
|
||||
if (strncmp (uuid, "CRYPT-LUKS1-", 12) == 0)
|
||||
{
|
||||
grub_free (uuid);
|
||||
return GRUB_DEV_ABSTRACTION_LUKS;
|
||||
|
||||
@@ -380,24 +380,30 @@ get_btrfs_fs_prefix (const char *mount_path)
|
||||
char **
|
||||
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||
{
|
||||
FILE *fp;
|
||||
FILE *fp = NULL;
|
||||
char *buf = NULL;
|
||||
size_t len = 0;
|
||||
grub_size_t entry_len = 0, entry_max = 4;
|
||||
grub_size_t entry_len, entry_max = 4;
|
||||
struct mountinfo_entry *entries;
|
||||
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
|
||||
int i;
|
||||
int retry = 0;
|
||||
int dir_fd = -1;
|
||||
char **ret = NULL;
|
||||
|
||||
if (! *dir)
|
||||
dir = "/";
|
||||
if (relroot)
|
||||
*relroot = NULL;
|
||||
|
||||
entries = xmalloc (entry_max * sizeof (*entries));
|
||||
|
||||
again:
|
||||
fp = grub_util_fopen ("/proc/self/mountinfo", "r");
|
||||
if (! fp)
|
||||
return NULL; /* fall through to other methods */
|
||||
goto out; /* fall through to other methods */
|
||||
|
||||
entries = xmalloc (entry_max * sizeof (*entries));
|
||||
entry_len = 0;
|
||||
|
||||
/* First, build a list of relevant visible mounts. */
|
||||
while (getline (&buf, &len, fp) > 0)
|
||||
@@ -484,7 +490,6 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||
/* Now scan visible mounts for the ones we're interested in. */
|
||||
for (i = entry_len - 1; i >= 0; i--)
|
||||
{
|
||||
char **ret = NULL;
|
||||
char *fs_prefix = NULL;
|
||||
if (!*entries[i].device)
|
||||
continue;
|
||||
@@ -515,6 +520,23 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||
ret = grub_find_root_devices_from_btrfs (dir);
|
||||
fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path);
|
||||
}
|
||||
else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0)
|
||||
{
|
||||
/* If the best match is automounted, try to trigger mount. We cannot
|
||||
simply return here because stat() on automounted directory does not
|
||||
trigger mount and returns bogus (pseudo)device number instead.
|
||||
We keep mountpoint open until end of scan to prevent timeout. */
|
||||
|
||||
int flags = O_RDONLY|O_DIRECTORY;
|
||||
|
||||
fclose (fp);
|
||||
#ifdef O_LARGEFILE
|
||||
flags |= O_LARGEFILE;
|
||||
#endif
|
||||
dir_fd = open (entries[i].enc_path, flags);
|
||||
retry = 1;
|
||||
goto again;
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
ret = xmalloc (2 * sizeof (ret[0]));
|
||||
@@ -544,16 +566,17 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||
}
|
||||
if (fs_prefix != entries[i].enc_root)
|
||||
free (fs_prefix);
|
||||
free (buf);
|
||||
free (entries);
|
||||
fclose (fp);
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
free (buf);
|
||||
free (entries);
|
||||
fclose (fp);
|
||||
return NULL;
|
||||
if (fp)
|
||||
fclose (fp);
|
||||
if (dir_fd != -1)
|
||||
close (dir_fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -88,7 +88,7 @@ static const grub_uint8_t set1_mapping[128] =
|
||||
/* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6,
|
||||
/* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1,
|
||||
/* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3,
|
||||
/* 0x52 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT,
|
||||
/* 0x52 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT,
|
||||
/* 0x54 */ 0, 0,
|
||||
/* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11,
|
||||
/* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0,
|
||||
@@ -193,7 +193,7 @@ static const grub_uint8_t set2_mapping[256] =
|
||||
/* 0x6a */ GRUB_KEYBOARD_KEY_JP_YEN, GRUB_KEYBOARD_KEY_NUM4,
|
||||
/* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, GRUB_KEYBOARD_KEY_KPCOMMA,
|
||||
/* 0x6e */ 0, 0,
|
||||
/* 0x70 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUM0,
|
||||
/* 0x70 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT,
|
||||
/* 0x72 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM5,
|
||||
/* 0x74 */ GRUB_KEYBOARD_KEY_NUM6, GRUB_KEYBOARD_KEY_NUM8,
|
||||
/* 0x76 */ GRUB_KEYBOARD_KEY_ESCAPE, GRUB_KEYBOARD_KEY_NUM_LOCK,
|
||||
|
||||
@@ -40,11 +40,7 @@
|
||||
# define LINUX_PHYS_OFFSET (0x00008000)
|
||||
# define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x02000000)
|
||||
# define LINUX_FDT_PHYS_OFFSET (LINUX_INITRD_PHYS_OFFSET - 0x10000)
|
||||
static inline grub_addr_t
|
||||
grub_arm_firmware_get_boot_data (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
# define grub_arm_firmware_get_boot_data (grub_addr_t)grub_efi_get_firmware_fdt
|
||||
static inline grub_uint32_t
|
||||
grub_arm_firmware_get_machine_type (void)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,10 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
|
||||
char **device,
|
||||
char **path);
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
|
||||
#endif
|
||||
|
||||
grub_addr_t grub_efi_modules_addr (void);
|
||||
|
||||
void grub_efi_mm_init (void);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef GRUB_MEMORY_CPU_HEADER
|
||||
#define GRUB_MEMORY_CPU_HEADER 1
|
||||
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
/* The flag for protected mode. */
|
||||
#define GRUB_MEMORY_CPU_CR0_PE_ON 0x1
|
||||
#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000020
|
||||
@@ -31,6 +33,11 @@
|
||||
#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */
|
||||
#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START
|
||||
|
||||
/* Some PTE definitions. */
|
||||
#define GRUB_PAGE_PRESENT 0x00000001
|
||||
#define GRUB_PAGE_RW 0x00000002
|
||||
#define GRUB_PAGE_USER 0x00000004
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
#define GRUB_MMAP_MALLOC_LOW 1
|
||||
|
||||
@@ -30,6 +30,17 @@
|
||||
#define MULTIBOOT_MBI_REGISTER ebx
|
||||
#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
#define MULTIBOOT_EFI_INITIAL_STATE { .rax = MULTIBOOT_BOOTLOADER_MAGIC, \
|
||||
.rcx = 0, \
|
||||
.rdx = 0, \
|
||||
}
|
||||
#define MULTIBOOT_EFI_ENTRY_REGISTER rip
|
||||
#define MULTIBOOT_EFI_MBI_REGISTER rbx
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MULTIBOOT_ELF32_MACHINE EM_386
|
||||
#define MULTIBOOT_ELF64_MACHINE EM_X86_64
|
||||
|
||||
|
||||
@@ -65,6 +65,20 @@ struct grub_relocator64_state
|
||||
grub_addr_t cr3;
|
||||
};
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
struct grub_relocator64_efi_state
|
||||
{
|
||||
grub_uint64_t rax;
|
||||
grub_uint64_t rbx;
|
||||
grub_uint64_t rcx;
|
||||
grub_uint64_t rdx;
|
||||
grub_uint64_t rip;
|
||||
grub_uint64_t rsi;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
grub_err_t grub_relocator16_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator16_state state);
|
||||
|
||||
@@ -76,4 +90,11 @@ grub_err_t grub_relocator64_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator64_state state,
|
||||
grub_addr_t min_addr, grub_addr_t max_addr);
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
grub_err_t grub_relocator64_efi_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator64_efi_state state);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
|
||||
@@ -91,10 +91,28 @@ grub_multiboot_set_console (int console_type, int accepted_consoles,
|
||||
int console_required);
|
||||
grub_err_t
|
||||
grub_multiboot_load (grub_file_t file, const char *filename);
|
||||
|
||||
struct mbi_load_data
|
||||
{
|
||||
grub_file_t file;
|
||||
const char *filename;
|
||||
void *buffer;
|
||||
unsigned int mbi_ver;
|
||||
int relocatable;
|
||||
grub_uint32_t min_addr;
|
||||
grub_uint32_t max_addr;
|
||||
grub_size_t align;
|
||||
grub_uint32_t preference;
|
||||
grub_uint32_t link_base_addr;
|
||||
grub_uint32_t load_base_addr;
|
||||
int avoid_efi_boot_services;
|
||||
};
|
||||
typedef struct mbi_load_data mbi_load_data_t;
|
||||
|
||||
/* Load ELF32 or ELF64. */
|
||||
grub_err_t
|
||||
grub_multiboot_load_elf (grub_file_t file, const char *filename,
|
||||
void *buffer);
|
||||
grub_multiboot_load_elf (mbi_load_data_t *mld);
|
||||
|
||||
extern grub_size_t grub_multiboot_pure_size;
|
||||
extern grub_size_t grub_multiboot_alloc_mbi;
|
||||
extern grub_uint32_t grub_multiboot_payload_eip;
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
#include <grub/err.h>
|
||||
#include <grub/relocator.h>
|
||||
|
||||
#define XEN_MAX_MAPPINGS 3
|
||||
|
||||
struct grub_relocator_xen_state
|
||||
{
|
||||
grub_addr_t start_info;
|
||||
grub_addr_t paging_start;
|
||||
grub_addr_t paging_size;
|
||||
grub_addr_t paging_start[XEN_MAX_MAPPINGS];
|
||||
grub_addr_t paging_size[XEN_MAX_MAPPINGS];
|
||||
grub_addr_t mfn_list;
|
||||
grub_addr_t stack;
|
||||
grub_addr_t entry_point;
|
||||
|
||||
@@ -32,10 +32,13 @@ struct grub_xen_file_info
|
||||
grub_uint64_t entry_point;
|
||||
grub_uint64_t hypercall_page;
|
||||
grub_uint64_t paddr_offset;
|
||||
grub_uint64_t p2m_base;
|
||||
int has_hypercall_page;
|
||||
int has_note;
|
||||
int has_xen_guest;
|
||||
int has_p2m_base;
|
||||
int extended_cr3;
|
||||
int unmapped_initrd;
|
||||
enum
|
||||
{
|
||||
GRUB_XEN_FILE_I386 = 1,
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
|
||||
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
|
||||
|
||||
#define MULTIBOOT_HEADER_TAG_END 0
|
||||
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
||||
@@ -69,11 +72,17 @@
|
||||
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
|
||||
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
|
||||
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
|
||||
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
|
||||
|
||||
#define MULTIBOOT_ARCHITECTURE_I386 0
|
||||
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
|
||||
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
|
||||
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
|
||||
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
|
||||
|
||||
@@ -158,6 +167,17 @@ struct multiboot_header_tag_module_align
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_relocatable
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t min_addr;
|
||||
multiboot_uint32_t max_addr;
|
||||
multiboot_uint32_t align;
|
||||
multiboot_uint32_t preference;
|
||||
};
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
@@ -370,6 +390,27 @@ struct multiboot_tag_efi_mmap
|
||||
multiboot_uint8_t efi_mmap[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_load_base_addr
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t load_base_addr;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||
@@ -58,34 +58,31 @@
|
||||
#define __HYPERVISOR_VIRT_START_PAE 0xF5800000
|
||||
#define __MACH2PHYS_VIRT_START_PAE 0xF5800000
|
||||
#define __MACH2PHYS_VIRT_END_PAE 0xF6800000
|
||||
#define HYPERVISOR_VIRT_START_PAE \
|
||||
mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_START_PAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_END_PAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE)
|
||||
#define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_PAE)
|
||||
|
||||
/* Non-PAE bounds are obsolete. */
|
||||
#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000
|
||||
#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000
|
||||
#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000
|
||||
#define HYPERVISOR_VIRT_START_NONPAE \
|
||||
mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE)
|
||||
xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE)
|
||||
#define MACH2PHYS_VIRT_START_NONPAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE)
|
||||
xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE)
|
||||
#define MACH2PHYS_VIRT_END_NONPAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE)
|
||||
xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE)
|
||||
|
||||
#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE
|
||||
#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE
|
||||
#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2)
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
|
||||
@@ -104,6 +101,7 @@
|
||||
do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \
|
||||
(hnd).p = val; \
|
||||
} while ( 0 )
|
||||
#define int64_aligned_t int64_t __attribute__((aligned(8)))
|
||||
#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
|
||||
#define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
|
||||
#define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name)
|
||||
|
||||
@@ -76,12 +76,12 @@
|
||||
#define __MACH2PHYS_VIRT_END 0xFFFF804000000000
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
|
||||
#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_END xen_mk_ulong(__HYPERVISOR_VIRT_END)
|
||||
#endif
|
||||
|
||||
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/******************************************************************************
|
||||
* elfnote.h
|
||||
*
|
||||
* Definitions used for the Xen ELF notes.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Copyright (c) 2006, Ian Campbell, XenSource Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_ELFNOTE_H__
|
||||
#define __XEN_PUBLIC_ELFNOTE_H__
|
||||
|
||||
/*
|
||||
* `incontents 200 elfnotes ELF notes
|
||||
*
|
||||
* The notes should live in a PT_NOTE segment and have "Xen" in the
|
||||
* name field.
|
||||
*
|
||||
* Numeric types are either 4 or 8 bytes depending on the content of
|
||||
* the desc field.
|
||||
*
|
||||
* LEGACY indicated the fields in the legacy __xen_guest string which
|
||||
* this a note type replaces.
|
||||
*
|
||||
* String values (for non-legacy) are NULL terminated ASCII, also known
|
||||
* as ASCIZ type.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NAME=VALUE pair (string).
|
||||
*/
|
||||
#define XEN_ELFNOTE_INFO 0
|
||||
|
||||
/*
|
||||
* The virtual address of the entry point (numeric).
|
||||
*
|
||||
* LEGACY: VIRT_ENTRY
|
||||
*/
|
||||
#define XEN_ELFNOTE_ENTRY 1
|
||||
|
||||
/* The virtual address of the hypercall transfer page (numeric).
|
||||
*
|
||||
* LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page
|
||||
* number not a virtual address)
|
||||
*/
|
||||
#define XEN_ELFNOTE_HYPERCALL_PAGE 2
|
||||
|
||||
/* The virtual address where the kernel image should be mapped (numeric).
|
||||
*
|
||||
* Defaults to 0.
|
||||
*
|
||||
* LEGACY: VIRT_BASE
|
||||
*/
|
||||
#define XEN_ELFNOTE_VIRT_BASE 3
|
||||
|
||||
/*
|
||||
* The offset of the ELF paddr field from the actual required
|
||||
* pseudo-physical address (numeric).
|
||||
*
|
||||
* This is used to maintain backwards compatibility with older kernels
|
||||
* which wrote __PAGE_OFFSET into that field. This field defaults to 0
|
||||
* if not present.
|
||||
*
|
||||
* LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE)
|
||||
*/
|
||||
#define XEN_ELFNOTE_PADDR_OFFSET 4
|
||||
|
||||
/*
|
||||
* The version of Xen that we work with (string).
|
||||
*
|
||||
* LEGACY: XEN_VER
|
||||
*/
|
||||
#define XEN_ELFNOTE_XEN_VERSION 5
|
||||
|
||||
/*
|
||||
* The name of the guest operating system (string).
|
||||
*
|
||||
* LEGACY: GUEST_OS
|
||||
*/
|
||||
#define XEN_ELFNOTE_GUEST_OS 6
|
||||
|
||||
/*
|
||||
* The version of the guest operating system (string).
|
||||
*
|
||||
* LEGACY: GUEST_VER
|
||||
*/
|
||||
#define XEN_ELFNOTE_GUEST_VERSION 7
|
||||
|
||||
/*
|
||||
* The loader type (string).
|
||||
*
|
||||
* LEGACY: LOADER
|
||||
*/
|
||||
#define XEN_ELFNOTE_LOADER 8
|
||||
|
||||
/*
|
||||
* The kernel supports PAE (x86/32 only, string = "yes", "no" or
|
||||
* "bimodal").
|
||||
*
|
||||
* For compatibility with Xen 3.0.3 and earlier the "bimodal" setting
|
||||
* may be given as "yes,bimodal" which will cause older Xen to treat
|
||||
* this kernel as PAE.
|
||||
*
|
||||
* LEGACY: PAE (n.b. The legacy interface included a provision to
|
||||
* indicate 'extended-cr3' support allowing L3 page tables to be
|
||||
* placed above 4G. It is assumed that any kernel new enough to use
|
||||
* these ELF notes will include this and therefore "yes" here is
|
||||
* equivalent to "yes[entended-cr3]" in the __xen_guest interface.
|
||||
*/
|
||||
#define XEN_ELFNOTE_PAE_MODE 9
|
||||
|
||||
/*
|
||||
* The features supported/required by this kernel (string).
|
||||
*
|
||||
* The string must consist of a list of feature names (as given in
|
||||
* features.h, without the "XENFEAT_" prefix) separated by '|'
|
||||
* characters. If a feature is required for the kernel to function
|
||||
* then the feature name must be preceded by a '!' character.
|
||||
*
|
||||
* LEGACY: FEATURES
|
||||
*/
|
||||
#define XEN_ELFNOTE_FEATURES 10
|
||||
|
||||
/*
|
||||
* The kernel requires the symbol table to be loaded (string = "yes" or "no")
|
||||
* LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence
|
||||
* of this string as a boolean flag rather than requiring "yes" or
|
||||
* "no".
|
||||
*/
|
||||
#define XEN_ELFNOTE_BSD_SYMTAB 11
|
||||
|
||||
/*
|
||||
* The lowest address the hypervisor hole can begin at (numeric).
|
||||
*
|
||||
* This must not be set higher than HYPERVISOR_VIRT_START. Its presence
|
||||
* also indicates to the hypervisor that the kernel can deal with the
|
||||
* hole starting at a higher address.
|
||||
*/
|
||||
#define XEN_ELFNOTE_HV_START_LOW 12
|
||||
|
||||
/*
|
||||
* List of maddr_t-sized mask/value pairs describing how to recognize
|
||||
* (non-present) L1 page table entries carrying valid MFNs (numeric).
|
||||
*/
|
||||
#define XEN_ELFNOTE_L1_MFN_VALID 13
|
||||
|
||||
/*
|
||||
* Whether or not the guest supports cooperative suspend cancellation.
|
||||
* This is a numeric value.
|
||||
*
|
||||
* Default is 0
|
||||
*/
|
||||
#define XEN_ELFNOTE_SUSPEND_CANCEL 14
|
||||
|
||||
/*
|
||||
* The (non-default) location the initial phys-to-machine map should be
|
||||
* placed at by the hypervisor (Dom0) or the tools (DomU).
|
||||
* The kernel must be prepared for this mapping to be established using
|
||||
* large pages, despite such otherwise not being available to guests.
|
||||
* The kernel must also be able to handle the page table pages used for
|
||||
* this mapping not being accessible through the initial mapping.
|
||||
* (Only x86-64 supports this at present.)
|
||||
*/
|
||||
#define XEN_ELFNOTE_INIT_P2M 15
|
||||
|
||||
/*
|
||||
* Whether or not the guest can deal with being passed an initrd not
|
||||
* mapped through its initial page tables.
|
||||
*/
|
||||
#define XEN_ELFNOTE_MOD_START_PFN 16
|
||||
|
||||
/*
|
||||
* The features supported by this kernel (numeric).
|
||||
*
|
||||
* Other than XEN_ELFNOTE_FEATURES on pre-4.2 Xen, this note allows a
|
||||
* kernel to specify support for features that older hypervisors don't
|
||||
* know about. The set of features 4.2 and newer hypervisors will
|
||||
* consider supported by the kernel is the combination of the sets
|
||||
* specified through this and the string note.
|
||||
*
|
||||
* LEGACY: FEATURES
|
||||
*/
|
||||
#define XEN_ELFNOTE_SUPPORTED_FEATURES 17
|
||||
|
||||
/*
|
||||
* Physical entry point into the kernel.
|
||||
*
|
||||
* 32bit entry point into the kernel. When requested to launch the
|
||||
* guest kernel in a HVM container, Xen will use this entry point to
|
||||
* launch the guest in 32bit protected mode with paging disabled.
|
||||
* Ignored otherwise.
|
||||
*/
|
||||
#define XEN_ELFNOTE_PHYS32_ENTRY 18
|
||||
|
||||
/*
|
||||
* The number of the highest elfnote defined.
|
||||
*/
|
||||
#define XEN_ELFNOTE_MAX XEN_ELFNOTE_PHYS32_ENTRY
|
||||
|
||||
/*
|
||||
* System information exported through crash notes.
|
||||
*
|
||||
* The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO
|
||||
* note in case of a system crash. This note will contain various
|
||||
* information about the system, see xen/include/xen/elfcore.h.
|
||||
*/
|
||||
#define XEN_ELFNOTE_CRASH_INFO 0x1000001
|
||||
|
||||
/*
|
||||
* System registers exported through crash notes.
|
||||
*
|
||||
* The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS
|
||||
* note per cpu in case of a system crash. This note is architecture
|
||||
* specific and will contain registers not saved in the "CORE" note.
|
||||
* See xen/include/xen/elfcore.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_CRASH_REGS 0x1000002
|
||||
|
||||
|
||||
/*
|
||||
* xen dump-core none note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE
|
||||
* in its dump file to indicate that the file is xen dump-core
|
||||
* file. This note doesn't have any other information.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000
|
||||
|
||||
/*
|
||||
* xen dump-core header note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER
|
||||
* in its dump file.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001
|
||||
|
||||
/*
|
||||
* xen dump-core xen version note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION
|
||||
* in its dump file. It contains the xen version obtained via the
|
||||
* XENVER hypercall.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002
|
||||
|
||||
/*
|
||||
* xen dump-core format version note.
|
||||
* xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION
|
||||
* in its dump file. It contains a format version identifier.
|
||||
* See tools/libxc/xc_core.h for more information.
|
||||
*/
|
||||
#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003
|
||||
|
||||
#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-file-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
+91
-34
@@ -52,6 +52,19 @@ DEFINE_XEN_GUEST_HANDLE(void);
|
||||
DEFINE_XEN_GUEST_HANDLE(uint64_t);
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
|
||||
|
||||
/* Turn a plain number into a C unsigned (long) constant. */
|
||||
#define __xen_mk_uint(x) x ## U
|
||||
#define __xen_mk_ulong(x) x ## UL
|
||||
#define xen_mk_uint(x) __xen_mk_uint(x)
|
||||
#define xen_mk_ulong(x) __xen_mk_ulong(x)
|
||||
|
||||
#else
|
||||
|
||||
/* In assembly code we cannot use C numeric constant suffixes. */
|
||||
#define xen_mk_uint(x) x
|
||||
#define xen_mk_ulong(x) x
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -101,6 +114,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
|
||||
#define __HYPERVISOR_kexec_op 37
|
||||
#define __HYPERVISOR_tmem_op 38
|
||||
#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
|
||||
#define __HYPERVISOR_xenpmu_op 40
|
||||
|
||||
/* Architecture-specific hypercall definitions. */
|
||||
#define __HYPERVISOR_arch_0 48
|
||||
@@ -160,6 +174,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
|
||||
#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occured */
|
||||
#define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient */
|
||||
#define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */
|
||||
#define VIRQ_XENPMU 13 /* V. PMC interrupt */
|
||||
|
||||
/* Architecture-specific VIRQ definitions. */
|
||||
#define VIRQ_ARCH_0 16
|
||||
@@ -449,13 +464,13 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
|
||||
/* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap. */
|
||||
/* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer. */
|
||||
/* ` enum uvm_flags { */
|
||||
#define UVMF_NONE (0UL<<0) /* No flushing at all. */
|
||||
#define UVMF_TLB_FLUSH (1UL<<0) /* Flush entire TLB(s). */
|
||||
#define UVMF_INVLPG (2UL<<0) /* Flush only one entry. */
|
||||
#define UVMF_FLUSHTYPE_MASK (3UL<<0)
|
||||
#define UVMF_MULTI (0UL<<2) /* Flush subset of TLBs. */
|
||||
#define UVMF_LOCAL (0UL<<2) /* Flush local TLB. */
|
||||
#define UVMF_ALL (1UL<<2) /* Flush all TLBs. */
|
||||
#define UVMF_NONE (xen_mk_ulong(0)<<0) /* No flushing at all. */
|
||||
#define UVMF_TLB_FLUSH (xen_mk_ulong(1)<<0) /* Flush entire TLB(s). */
|
||||
#define UVMF_INVLPG (xen_mk_ulong(2)<<0) /* Flush only one entry. */
|
||||
#define UVMF_FLUSHTYPE_MASK (xen_mk_ulong(3)<<0)
|
||||
#define UVMF_MULTI (xen_mk_ulong(0)<<2) /* Flush subset of TLBs. */
|
||||
#define UVMF_LOCAL (xen_mk_ulong(0)<<2) /* Flush local TLB. */
|
||||
#define UVMF_ALL (xen_mk_ulong(1)<<2) /* Flush all TLBs. */
|
||||
/* ` } */
|
||||
|
||||
/*
|
||||
@@ -486,17 +501,27 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
|
||||
/* x86/PAE guests: support PDPTs above 4GB. */
|
||||
#define VMASST_TYPE_pae_extended_cr3 3
|
||||
|
||||
/*
|
||||
* x86/64 guests: strictly hide M2P from user mode.
|
||||
* This allows the guest to control respective hypervisor behavior:
|
||||
* - when not set, L4 tables get created with the respective slot blank,
|
||||
* and whenever the L4 table gets used as a kernel one the missing
|
||||
* mapping gets inserted,
|
||||
* - when set, L4 tables get created with the respective slot initialized
|
||||
* as before, and whenever the L4 table gets used as a user one the
|
||||
* mapping gets zapped.
|
||||
*/
|
||||
#define VMASST_TYPE_m2p_strict 32
|
||||
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00040600
|
||||
#define MAX_VMASST_TYPE 3
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef uint16_t domid_t;
|
||||
#endif
|
||||
|
||||
/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
|
||||
#define DOMID_FIRST_RESERVED (0x7FF0U)
|
||||
#define DOMID_FIRST_RESERVED xen_mk_uint(0x7FF0)
|
||||
|
||||
/* DOMID_SELF is used in certain contexts to refer to oneself. */
|
||||
#define DOMID_SELF (0x7FF0U)
|
||||
#define DOMID_SELF xen_mk_uint(0x7FF0)
|
||||
|
||||
/*
|
||||
* DOMID_IO is used to restrict page-table updates to mapping I/O memory.
|
||||
@@ -507,7 +532,7 @@ typedef uint16_t domid_t;
|
||||
* This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
|
||||
* be specified by any calling domain.
|
||||
*/
|
||||
#define DOMID_IO (0x7FF1U)
|
||||
#define DOMID_IO xen_mk_uint(0x7FF1)
|
||||
|
||||
/*
|
||||
* DOMID_XEN is used to allow privileged domains to map restricted parts of
|
||||
@@ -515,17 +540,21 @@ typedef uint16_t domid_t;
|
||||
* This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
|
||||
* the caller is privileged.
|
||||
*/
|
||||
#define DOMID_XEN (0x7FF2U)
|
||||
#define DOMID_XEN xen_mk_uint(0x7FF2)
|
||||
|
||||
/*
|
||||
* DOMID_COW is used as the owner of sharable pages */
|
||||
#define DOMID_COW (0x7FF3U)
|
||||
#define DOMID_COW xen_mk_uint(0x7FF3)
|
||||
|
||||
/* DOMID_INVALID is used to identify pages with unknown owner. */
|
||||
#define DOMID_INVALID (0x7FF4U)
|
||||
#define DOMID_INVALID xen_mk_uint(0x7FF4)
|
||||
|
||||
/* Idle domain. */
|
||||
#define DOMID_IDLE (0x7FFFU)
|
||||
#define DOMID_IDLE xen_mk_uint(0x7FFF)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef uint16_t domid_t;
|
||||
|
||||
/*
|
||||
* Send an array of these to HYPERVISOR_mmu_update().
|
||||
@@ -682,6 +711,12 @@ struct shared_info {
|
||||
uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */
|
||||
uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
|
||||
uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */
|
||||
#if !defined(__i386__)
|
||||
uint32_t wc_sec_hi;
|
||||
# define xen_wc_sec_hi wc_sec_hi
|
||||
#elif !defined(__XEN__) && !defined(__XEN_TOOLS__)
|
||||
# define xen_wc_sec_hi arch.wc_sec_hi
|
||||
#endif
|
||||
|
||||
struct arch_shared_info arch;
|
||||
|
||||
@@ -698,24 +733,27 @@ typedef struct shared_info shared_info_t;
|
||||
* 3. This the order of bootstrap elements in the initial virtual region:
|
||||
* a. relocated kernel image
|
||||
* b. initial ram disk [mod_start, mod_len]
|
||||
* (may be omitted)
|
||||
* c. list of allocated page frames [mfn_list, nr_pages]
|
||||
* (unless relocated due to XEN_ELFNOTE_INIT_P2M)
|
||||
* d. start_info_t structure [register ESI (x86)]
|
||||
* e. bootstrap page tables [pt_base and CR3 (x86)]
|
||||
* f. bootstrap stack [register ESP (x86)]
|
||||
* in case of dom0 this page contains the console info, too
|
||||
* e. unless dom0: xenstore ring page
|
||||
* f. unless dom0: console ring page
|
||||
* g. bootstrap page tables [pt_base and CR3 (x86)]
|
||||
* h. bootstrap stack [register ESP (x86)]
|
||||
* 4. Bootstrap elements are packed together, but each is 4kB-aligned.
|
||||
* 5. The initial ram disk may be omitted.
|
||||
* 6. The list of page frames forms a contiguous 'pseudo-physical' memory
|
||||
* 5. The list of page frames forms a contiguous 'pseudo-physical' memory
|
||||
* layout for the domain. In particular, the bootstrap virtual-memory
|
||||
* region is a 1:1 mapping to the first section of the pseudo-physical map.
|
||||
* 7. All bootstrap elements are mapped read-writable for the guest OS. The
|
||||
* 6. All bootstrap elements are mapped read-writable for the guest OS. The
|
||||
* only exception is the bootstrap page table, which is mapped read-only.
|
||||
* 8. There is guaranteed to be at least 512kB padding after the final
|
||||
* 7. There is guaranteed to be at least 512kB padding after the final
|
||||
* bootstrap element. If necessary, the bootstrap virtual region is
|
||||
* extended by an extra 4MB to ensure this.
|
||||
*
|
||||
* Note: Prior to 25833:bb85bbccb1c9. ("x86/32-on-64 adjust Dom0 initial page
|
||||
* table layout") a bug caused the pt_base (3.e above) and cr3 to not point
|
||||
* table layout") a bug caused the pt_base (3.g above) and cr3 to not point
|
||||
* to the start of the guest page tables (it was offset by two pages).
|
||||
* This only manifested itself on 32-on-64 dom0 kernels and not 32-on-64 domU
|
||||
* or 64-bit kernels of any colour. The page tables for a 32-on-64 dom0 got
|
||||
@@ -759,6 +797,29 @@ struct start_info {
|
||||
};
|
||||
typedef struct start_info start_info_t;
|
||||
|
||||
/*
|
||||
* Start of day structure passed to PVH guests in %ebx.
|
||||
*
|
||||
* NOTE: nothing will be loaded at physical address 0, so
|
||||
* a 0 value in any of the address fields should be treated
|
||||
* as not present.
|
||||
*/
|
||||
struct hvm_start_info {
|
||||
#define HVM_START_MAGIC_VALUE 0x336ec578
|
||||
uint32_t magic; /* Contains the magic value 0x336ec578 */
|
||||
/* ("xEn3" with the 0x80 bit of the "E" set).*/
|
||||
uint32_t flags; /* SIF_xxx flags. */
|
||||
uint32_t cmdline_paddr; /* Physical address of the command line. */
|
||||
uint32_t nr_modules; /* Number of modules passed to the kernel. */
|
||||
uint32_t modlist_paddr; /* Physical address of an array of */
|
||||
/* hvm_modlist_entry. */
|
||||
};
|
||||
|
||||
struct hvm_modlist_entry {
|
||||
uint32_t paddr; /* Physical address of the module. */
|
||||
uint32_t size; /* Size of the module in bytes. */
|
||||
};
|
||||
|
||||
/* New console union for dom0 introduced in 0x00030203. */
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00030203
|
||||
#define console_mfn console.domU.mfn
|
||||
@@ -771,6 +832,8 @@ typedef struct start_info start_info_t;
|
||||
#define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */
|
||||
#define SIF_MULTIBOOT_MOD (1<<2) /* Is mod_start a multiboot module? */
|
||||
#define SIF_MOD_START_PFN (1<<3) /* Is mod_start a PFN? */
|
||||
#define SIF_VIRT_P2M_4TOOLS (1<<4) /* Do Xen tools understand a virt. mapped */
|
||||
/* P->M making the 3 level tree obsolete? */
|
||||
#define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */
|
||||
|
||||
/*
|
||||
@@ -851,25 +914,19 @@ typedef struct dom0_vga_console_info {
|
||||
|
||||
typedef uint8_t xen_domain_handle_t[16];
|
||||
|
||||
/* Turn a plain number into a C unsigned long constant. */
|
||||
#define __mk_unsigned_long(x) x ## UL
|
||||
#define mk_unsigned_long(x) __mk_unsigned_long(x)
|
||||
|
||||
__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t);
|
||||
__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t);
|
||||
__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t);
|
||||
__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
/* In assembly code we cannot use C numeric constant suffixes. */
|
||||
#define mk_unsigned_long(x) x
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/* Default definitions for macros used by domctl/sysctl. */
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
|
||||
#ifndef int64_aligned_t
|
||||
#define int64_aligned_t int64_t
|
||||
#endif
|
||||
#ifndef uint64_aligned_t
|
||||
#define uint64_aligned_t uint64_t
|
||||
#endif
|
||||
|
||||
@@ -251,7 +251,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
CFILES[0]="american-english";;
|
||||
esac
|
||||
# OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux
|
||||
LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoirewoifoiwqwoieqfrqwioerijewr"
|
||||
LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoi"
|
||||
rm -rf "$MASTER"
|
||||
|
||||
case x"$fs" in
|
||||
@@ -435,7 +435,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
| xiso9660 | xjoliet| xiso9660_1999 | xjoliet_1999)
|
||||
NOSYMLINK=y;;
|
||||
esac
|
||||
NOHARDLINK=n
|
||||
NOHARDLINK=y ###
|
||||
case x"$fs" in
|
||||
# FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS
|
||||
xbfs | xexfat | x"vfat"* | xmsdos* | xhfs | xsfs | xsfs_caseins)
|
||||
@@ -498,8 +498,8 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
NOFSLABEL=y;;
|
||||
esac
|
||||
|
||||
PDIRCOMPNUM=220
|
||||
PDIR2COMPNUM=220
|
||||
PDIRCOMPNUM=210
|
||||
PDIR2COMPNUM=210
|
||||
|
||||
case x$fs in
|
||||
# OS LIMITATION: bfs_fuse bugs beyond that
|
||||
@@ -514,7 +514,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
# FS LIMITATION: at most 255 on path length
|
||||
# FS LIMITATION: at most 100 on symlink length
|
||||
xcpio_ustar)
|
||||
PDIRCOMPNUM=85
|
||||
PDIRCOMPNUM=84
|
||||
PDIR2COMPNUM=30;;
|
||||
# OS LIMITATION: Linux supports only symlink at most one block long on reiserfs
|
||||
xreiserfs | xreiserfs_old)
|
||||
@@ -1304,10 +1304,11 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
# is not precise. Account for small difference here.
|
||||
FSTIMEM1="$(date -d "$FSTIME UTC -1 second" -u "+%Y-%m-%d %H:%M:%S")"
|
||||
FSTIMEM2="$(date -d "$FSTIME UTC -2 second" -u "+%Y-%m-%d %H:%M:%S")"
|
||||
FSTIMEM3="$(date -d "$FSTIME UTC -3 second" -u "+%Y-%m-%d %H:%M:%S")"
|
||||
|
||||
if [ x$NOFSTIME = xy ]; then
|
||||
:
|
||||
elif echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" > /dev/null; then
|
||||
elif echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM3" > /dev/null; then
|
||||
:
|
||||
else
|
||||
echo FSTIME FAIL
|
||||
@@ -1515,3 +1516,4 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE +
|
||||
done
|
||||
done
|
||||
done
|
||||
rmdir "${tempdir}"
|
||||
@@ -106,7 +106,8 @@ static const struct
|
||||
[GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }
|
||||
[GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
Reference in new issue
Block a user