New port arm64-efi

This commit is contained in:
Leif Lindholm 2013-11-30 16:49:05 +01:00 committed by Vladimir Serbinenko
commit b29b77fee2
28 changed files with 746 additions and 17 deletions

View file

@ -18,6 +18,8 @@ configuring the GRUB.
earlier versions not tested earlier versions not tested
Note: clang 3.2 or later works for arm Note: clang 3.2 or later works for arm
earlier versions not tested earlier versions not tested
Note: clang 3.3 or later works for arm64
earlier versions have no arm64 support
Note: clang 3.3 or later works for mips(el) Note: clang 3.3 or later works for mips(el)
earlier versions fail to generate .reginfo and hence gprel relocations earlier versions fail to generate .reginfo and hence gprel relocations
fail. fail.

View file

@ -156,6 +156,8 @@ library = {
common = grub-core/io/gzio.c; common = grub-core/io/gzio.c;
common = grub-core/io/lzopio.c; common = grub-core/io/lzopio.c;
common = grub-core/kern/ia64/dl_helper.c; common = grub-core/kern/ia64/dl_helper.c;
common = grub-core/kern/arm/dl_helper.c;
common = grub-core/kern/arm64/dl_helper.c;
common = grub-core/lib/minilzo/minilzo.c; common = grub-core/lib/minilzo/minilzo.c;
common = grub-core/lib/xzembed/xz_dec_bcj.c; common = grub-core/lib/xzembed/xz_dec_bcj.c;
common = grub-core/lib/xzembed/xz_dec_lzma2.c; common = grub-core/lib/xzembed/xz_dec_lzma2.c;
@ -177,8 +179,6 @@ program = {
extra_dist = grub-core/osdep/unix/config.c; extra_dist = grub-core/osdep/unix/config.c;
common = util/config.c; common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
extra_dist = util/grub-mkimagexx.c; extra_dist = util/grub-mkimagexx.c;
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
@ -512,8 +512,6 @@ program = {
common = grub-core/kern/emu/hostfs.c; common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c; common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c; common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
@ -558,8 +556,6 @@ program = {
common = grub-core/kern/emu/hostfs.c; common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c; common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c; common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
@ -595,8 +591,6 @@ program = {
common = grub-core/osdep/config.c; common = grub-core/osdep/config.c;
common = util/config.c; common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c; common = util/resolve.c;
enable = noemu; enable = noemu;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
@ -632,8 +626,6 @@ program = {
common = grub-core/osdep/config.c; common = grub-core/osdep/config.c;
common = util/config.c; common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c; common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c; common = grub-core/osdep/init.c;

View file

@ -15,6 +15,9 @@ if COND_arm
CCASFLAGS_PLATFORM = -mthumb-interwork CCASFLAGS_PLATFORM = -mthumb-interwork
LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
endif endif
if COND_arm64
CFLAGS_PLATFORM += -mcmodel=large
endif
#FIXME: discover and check XEN headers #FIXME: discover and check XEN headers
CPPFLAGS_XEN = -I/usr/include CPPFLAGS_XEN = -I/usr/include

View file

@ -99,6 +99,9 @@ case "$target_cpu" in
arm*) arm*)
target_cpu=arm; target_cpu=arm;
;; ;;
aarch64*)
target_cpu=arm64;
;;
esac esac
# Specify the platform (such as firmware). # Specify the platform (such as firmware).
@ -120,6 +123,7 @@ if test "x$with_platform" = x; then
mips-*) platform=arc ;; mips-*) platform=arc ;;
ia64-*) platform=efi ;; ia64-*) platform=efi ;;
arm-*) platform=uboot ;; arm-*) platform=uboot ;;
arm64-*) platform=efi ;;
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
esac esac
else else
@ -160,6 +164,7 @@ case "$target_cpu"-"$platform" in
mipsel-loongson) ;; mipsel-loongson) ;;
arm-uboot) ;; arm-uboot) ;;
arm-efi) ;; arm-efi) ;;
arm64-efi) ;;
*-emu) ;; *-emu) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
esac esac
@ -210,6 +215,7 @@ case "$platform" in
esac esac
case "$target_cpu" in case "$target_cpu" in
arm) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM=1" ;; arm) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM=1" ;;
arm64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM64=1" ;;
mips |mipsel) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; mips |mipsel) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;; sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
esac esac
@ -1498,6 +1504,8 @@ AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ]) AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot]) AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi]) AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])

View file

@ -29,7 +29,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_xen", "x86_64_xen", "i386_xen", "x86_64_xen",
"mips_loongson", "sparc64_ieee1275", "mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi", "powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi" ] "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ]
GROUPS = {} GROUPS = {}
@ -43,9 +43,10 @@ GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
GROUPS["powerpc"] = [ "powerpc_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi" ] GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
GROUPS["arm64"] = [ "arm64_efi" ]
# Groups based on firmware # Groups based on firmware
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ] GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ]
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
GROUPS["uboot"] = [ "arm_uboot" ] GROUPS["uboot"] = [ "arm_uboot" ]
GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
@ -71,7 +72,7 @@ GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
# Flattened Device Trees (FDT) # Flattened Device Trees (FDT)
GROUPS["fdt"] = [ "arm_uboot", "arm_efi" ] GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ]
# Miscelaneous groups schedulded to disappear in future # Miscelaneous groups schedulded to disappear in future
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]

View file

@ -234,6 +234,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif endif
if COND_arm64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
if COND_emu if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h

View file

@ -67,6 +67,9 @@ kernel = {
arm_efi_ldflags = '-Wl,-r,-d'; arm_efi_ldflags = '-Wl,-r,-d';
arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
arm64_efi_ldflags = '-Wl,-r,-d';
arm64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
@ -106,6 +109,7 @@ kernel = {
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
arm_uboot_startup = kern/arm/uboot/startup.S; arm_uboot_startup = kern/arm/uboot/startup.S;
arm_efi_startup = kern/arm/efi/startup.S; arm_efi_startup = kern/arm/efi/startup.S;
arm64_efi_startup = kern/arm64/efi/startup.S;
common = kern/command.c; common = kern/command.c;
common = kern/corecmd.c; common = kern/corecmd.c;
@ -194,6 +198,8 @@ kernel = {
arm_efi = kern/arm/efi/init.c; arm_efi = kern/arm/efi/init.c;
arm_efi = kern/arm/efi/misc.c; arm_efi = kern/arm/efi/misc.c;
arm64_efi = kern/arm/efi/init.c;
i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c; i386_pc = kern/i386/pc/mmap.c;
i386_pc = term/i386/pc/console.c; i386_pc = term/i386/pc/console.c;
@ -254,6 +260,11 @@ kernel = {
arm = kern/arm/cache.c; arm = kern/arm/cache.c;
arm = kern/arm/misc.S; arm = kern/arm/misc.S;
arm64 = kern/arm64/cache.c;
arm64 = kern/arm64/cache_flush.S;
arm64 = kern/arm64/dl.c;
arm64 = kern/arm64/dl_helper.c;
emu = disk/host.c; emu = disk/host.c;
emu = kern/emu/cache_s.S; emu = kern/emu/cache_s.S;
emu = kern/emu/hostdisk.c; emu = kern/emu/hostdisk.c;
@ -743,6 +754,7 @@ module = {
enable = mips_arc; enable = mips_arc;
enable = ia64_efi; enable = ia64_efi;
enable = arm_efi; enable = arm_efi;
enable = arm64_efi;
enable = arm_uboot; enable = arm_uboot;
}; };
@ -838,6 +850,7 @@ module = {
ia64_efi = lib/efi/reboot.c; ia64_efi = lib/efi/reboot.c;
x86_64_efi = lib/efi/reboot.c; x86_64_efi = lib/efi/reboot.c;
arm_efi = lib/efi/reboot.c; arm_efi = lib/efi/reboot.c;
arm64_efi = lib/efi/reboot.c;
powerpc_ieee1275 = lib/ieee1275/reboot.c; powerpc_ieee1275 = lib/ieee1275/reboot.c;
sparc64_ieee1275 = lib/ieee1275/reboot.c; sparc64_ieee1275 = lib/ieee1275/reboot.c;
mips_arc = lib/mips/arc/reboot.c; mips_arc = lib/mips/arc/reboot.c;
@ -1700,6 +1713,7 @@ module = {
enable = x86; enable = x86;
enable = ia64_efi; enable = ia64_efi;
enable = arm_efi; enable = arm_efi;
enable = arm64_efi;
enable = mips; enable = mips;
}; };

View file

@ -0,0 +1,63 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/cache.h>
#include <grub/misc.h>
static grub_int64_t dlinesz;
static grub_int64_t ilinesz;
/* Prototypes for asm functions. */
void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
grub_uint64_t line_size);
void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end,
grub_uint64_t line_size);
static void
probe_caches (void)
{
grub_uint64_t cache_type;
/* Read Cache Type Register */
asm volatile ("mrs %0, ctr_el0": "=r"(cache_type));
dlinesz = 4 << ((cache_type >> 16) & 0xf);
ilinesz = 4 << (cache_type & 0xf);
grub_dprintf("cache", "D$ line size: %lld\n", (long long) dlinesz);
grub_dprintf("cache", "I$ line size: %lld\n", (long long) ilinesz);
}
void
grub_arch_sync_caches (void *address, grub_size_t len)
{
grub_uint64_t start, end, max_align;
if (dlinesz == 0)
probe_caches();
if (dlinesz == 0)
grub_fatal ("Unknown cache line size!");
max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
start = ALIGN_DOWN ((grub_uint64_t) address, max_align);
end = ALIGN_UP ((grub_uint64_t) address + len, max_align);
grub_arch_clean_dcache_range (start, end, dlinesz);
grub_arch_invalidate_icache_range (start, end, ilinesz);
}

View file

@ -0,0 +1,55 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/symbol.h>
.file "cache_flush.S"
.text
/*
* Simple cache maintenance functions
*/
// x0 - *beg (inclusive)
// x1 - *end (exclusive)
// x2 - line size
FUNCTION(grub_arch_clean_dcache_range)
// Clean data cache for range to point-of-unification
1: cmp x0, x1
b.ge 2f
dc cvau, x0 // Clean Virtual Address to PoU
add x0, x0, x2 // Next line
b 1b
2: dsb ish
isb
ret
// x0 - *beg (inclusive)
// x1 - *end (exclusive)
// x2 - line size
FUNCTION(grub_arch_invalidate_icache_range)
// Invalidate instruction cache for range to point-of-unification
1: cmp x0, x1
b.ge 2f
ic ivau, x0 // Invalidate Virtual Address to PoU
add x0, x0, x2 // Next line
b 1b
// Branch predictor invalidation not needed on AArch64
2: dsb ish
isb
ret

199
grub-core/kern/arm64/dl.c Normal file
View file

@ -0,0 +1,199 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/cpu/reloc.h>
/*
* Check if EHDR is a valid ELF header.
*/
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
if (e->e_ident[EI_CLASS] != ELFCLASS64
|| e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_AARCH64)
return grub_error (GRUB_ERR_BAD_OS,
N_("invalid arch-dependent ELF magic"));
return GRUB_ERR_NONE;
}
/*
* Unified function for both REL and RELA
*/
static grub_err_t
do_relX (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
{
grub_err_t retval;
grub_dl_segment_t segment;
Elf_Rel *rel;
Elf_Rela *rela;
Elf_Sym *symbol;
int i, entnum;
unsigned long long entsize;
/* Find the target segment for this relocation section. */
for (segment = mod->segment ; segment != 0 ; segment = segment->next)
if (segment->section == relhdr->sh_info)
break;
if (!segment)
return grub_error (GRUB_ERR_EOF, N_("relocation segment not found"));
rel = (Elf_Rel *) ((grub_addr_t) e + relhdr->sh_offset);
rela = (Elf_Rela *) rel;
if (relhdr->sh_type == SHT_RELA)
entsize = sizeof (Elf_Rela);
else
entsize = sizeof (Elf_Rel);
entnum = relhdr->sh_size / entsize;
retval = GRUB_ERR_NONE;
grub_dprintf("dl", "Processing %d relocation entries.\n", entnum);
/* Step through all relocations */
for (i = 0, symbol = mod->symtab; i < entnum; i++)
{
void *place;
grub_uint64_t sym_addr, symidx, reltype;
if (rel->r_offset >= segment->size)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
symidx = ELF_R_SYM (rel->r_info);
reltype = ELF_R_TYPE (rel->r_info);
sym_addr = symbol[symidx].st_value;
if (relhdr->sh_type == SHT_RELA)
sym_addr += rela->r_addend;
place = (void *) ((grub_addr_t) segment->addr + rel->r_offset);
switch (reltype)
{
case R_AARCH64_ABS64:
{
grub_uint64_t *abs_place = place;
grub_dprintf ("dl", " reloc_abs64 %p => 0x%016llx\n",
place, (unsigned long long) sym_addr);
*abs_place = (grub_uint64_t) sym_addr;
}
break;
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
retval = grub_arm64_reloc_xxxx26 (place, sym_addr);
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
reltype);
}
if (retval != GRUB_ERR_NONE)
break;
rel = (Elf_Rel *) ((grub_addr_t) rel + entsize);
rela++;
}
return retval;
}
/*
* Verify that provided ELF header contains reference to a symbol table
*/
static int
has_symtab (Elf_Ehdr * e)
{
int i;
Elf_Shdr *s;
for (i = 0, s = (Elf_Shdr *) ((grub_addr_t) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
return 1;
return 0;
}
/*
* grub_arch_dl_relocate_symbols():
* Locates the relocations section of the ELF object, and calls
* do_relX() to deal with it.
*/
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
unsigned i;
if (!has_symtab (e))
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
#define FIRST_SHDR(x) ((Elf_Shdr *) ((grub_addr_t)(x) + (x)->e_shoff))
#define NEXT_SHDR(x, y) ((Elf_Shdr *) ((grub_addr_t)(y) + (x)->e_shentsize))
for (i = 0, s = FIRST_SHDR (e); i < e->e_shnum; i++, s = NEXT_SHDR (e, s))
{
grub_err_t ret;
switch (s->sh_type)
{
case SHT_REL:
case SHT_RELA:
{
ret = do_relX (s, e, mod);
if (ret != GRUB_ERR_NONE)
return ret;
}
break;
case SHT_ARM_ATTRIBUTES:
case SHT_NOBITS:
case SHT_NULL:
case SHT_PROGBITS:
case SHT_SYMTAB:
case SHT_STRTAB:
break;
default:
{
grub_dprintf ("dl", "unhandled section_type: %d (0x%08x)\n",
s->sh_type, s->sh_type);
return GRUB_ERR_NOT_IMPLEMENTED_YET;
};
}
}
#undef FIRST_SHDR
#undef NEXT_SHDR
return GRUB_ERR_NONE;
}

View file

@ -0,0 +1,70 @@
/* dl_helper.c - relocation helper functions for modules and grub-mkimage */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/cpu/reloc.h>
static grub_ssize_t
sign_compress_offset (grub_ssize_t offset, int bitpos)
{
return offset & ((1LL << (bitpos + 1)) - 1);
}
/*
* grub_arm64_reloc_xxxx26():
*
* JUMP26/CALL26 relocations for B and BL instructions.
*/
grub_err_t
grub_arm64_reloc_xxxx26 (grub_uint32_t *place, Elf64_Addr adjust)
{
grub_uint32_t insword, insmask;
grub_ssize_t offset;
const grub_ssize_t offset_low = -(1 << 27), offset_high = (1 << 27) - 1;
insword = grub_le_to_cpu32 (*place);
insmask = 0xfc000000;
offset = adjust;
#ifndef GRUB_UTIL
offset -= (grub_addr_t) place;
#endif
if ((offset < offset_low) || (offset > offset_high))
{
return grub_error (GRUB_ERR_BAD_MODULE,
N_("CALL26 Relocation out of range"));
}
grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%llx\n",
place, offset > 0 ? '+' : '-',
offset < 0 ? (long long) -(unsigned long long) offset : offset);
offset = sign_compress_offset (offset, 27) >> 2;
*place = grub_cpu_to_le32 ((insword & insmask) | offset);
return GRUB_ERR_NONE;
}

View file

@ -0,0 +1,39 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/symbol.h>
.file "startup.S"
.text
FUNCTION(_start)
/*
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0.
*/
ldr x2, efi_image_handle_val
str x0, [x2]
ldr x2, efi_system_table_val
str x1, [x2]
ldr x2, grub_main_val
br x2
grub_main_val:
.quad EXT_C(grub_main)
efi_system_table_val:
.quad EXT_C(grub_efi_system_table)
efi_image_handle_val:
.quad EXT_C(grub_efi_image_handle)

View file

@ -0,0 +1,53 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/symbol.h>
.file "setjmp.S"
.text
/*
* int grub_setjmp (grub_jmp_buf env)
*/
FUNCTION(grub_setjmp)
stp x19, x20, [x0], #16
stp x21, x22, [x0], #16
stp x23, x24, [x0], #16
stp x25, x26, [x0], #16
stp x27, x28, [x0], #16
stp x29, x30, [x0], #16
mov x1, sp
str x1, [x0]
mov x0, #0
ret
/*
* int grub_longjmp (grub_jmp_buf env, int val)
*/
FUNCTION(grub_longjmp)
ldp x19, x20, [x0], #16
ldp x21, x22, [x0], #16
ldp x23, x24, [x0], #16
ldp x25, x26, [x0], #16
ldp x27, x28, [x0], #16
ldp x29, x30, [x0], #16
ldr x2, [x0]
mov sp, x2
cmp x1, #0
csel x0, x1, x0, ne
ret

View file

@ -29,7 +29,7 @@ void
grub_halt (void) grub_halt (void)
{ {
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
#if !defined(__ia64__) && !defined(__arm__) #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__)
grub_acpi_halt (); grub_acpi_halt ();
#endif #endif
efi_call_4 (grub_efi_system_table->runtime_services->reset_system, efi_call_4 (grub_efi_system_table->runtime_services->reset_system,

View file

@ -13,6 +13,8 @@
#include "./ia64/longjmp.S" #include "./ia64/longjmp.S"
#elif defined(__arm__) #elif defined(__arm__)
#include "./arm/setjmp.S" #include "./arm/setjmp.S"
#elif defined(__aarch64__)
#include "./arm64/setjmp.S"
#else #else
#error "Unknown target cpu type" #error "Unknown target cpu type"
#endif #endif

View file

@ -0,0 +1 @@
#include <grub/efi/memory.h>

View file

@ -0,0 +1,24 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_ARM64_RELOC_H
#define GRUB_ARM64_RELOC_H 1
grub_err_t grub_arm64_reloc_xxxx26 (grub_uint32_t *target, Elf64_Addr sym_addr);
#endif

View file

@ -0,0 +1,27 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_SETJMP_CPU_HEADER
#define GRUB_SETJMP_CPU_HEADER 1
typedef unsigned long long grub_jmp_buf[13];
int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;
void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
#endif /* ! GRUB_SETJMP_CPU_HEADER */

29
include/grub/arm64/time.h Normal file
View file

@ -0,0 +1,29 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KERNEL_CPU_TIME_HEADER
#define KERNEL_CPU_TIME_HEADER 1
static __inline void
grub_cpu_idle (void)
{
/* FIXME: this can't work until we handle interrupts. */
/* __asm__ __volatile__ ("wfi"); */
}
#endif /* ! KERNEL_CPU_TIME_HEADER */

View file

@ -0,0 +1,34 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_TYPES_CPU_HEADER
#define GRUB_TYPES_CPU_HEADER 1
/* The size of void *. */
#define GRUB_TARGET_SIZEOF_VOID_P 8
/* The size of long. */
#define GRUB_TARGET_SIZEOF_LONG 8
/* currently only support little-endian. */
#undef GRUB_TARGET_WORDS_BIGENDIAN
/* Unaligned accesses only supported if MMU enabled */
#undef GRUB_HAVE_UNALIGNED_ACCESS
#endif /* ! GRUB_TYPES_CPU_HEADER */

View file

@ -1534,7 +1534,8 @@ struct grub_efi_block_io
}; };
typedef struct grub_efi_block_io grub_efi_block_io_t; typedef struct grub_efi_block_io grub_efi_block_io_t;
#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
|| defined (__aarch64__)
#define efi_call_0(func) func() #define efi_call_0(func) func()
#define efi_call_1(func, a) func(a) #define efi_call_1(func, a) func(a)

View file

@ -67,6 +67,7 @@ struct grub_pe32_coff_header
#define GRUB_PE32_MACHINE_IA64 0x200 #define GRUB_PE32_MACHINE_IA64 0x200
#define GRUB_PE32_MACHINE_X86_64 0x8664 #define GRUB_PE32_MACHINE_X86_64 0x8664
#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
#define GRUB_PE32_MACHINE_ARM64 0xAA64
#define GRUB_PE32_RELOCS_STRIPPED 0x0001 #define GRUB_PE32_RELOCS_STRIPPED 0x0001
#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002

View file

@ -246,6 +246,7 @@ typedef struct
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
#define EM_NUM 95 #define EM_NUM 95
#define EM_AARCH64 183 /* ARM 64-bit architecture */
/* If it is necessary to assign new unofficial EM_* values, please /* If it is necessary to assign new unofficial EM_* values, please
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@ -2062,6 +2063,21 @@ typedef Elf32_Addr Elf32_Conflict;
#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ #define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
/* AArch64 relocs. */
#define R_AARCH64_NONE 0 /* No relocation. */
#define R_AARCH64_ABS64 257 /* Direct 64 bit. */
#define R_AARCH64_ABS32 258 /* Direct 32 bit. */
#define R_AARCH64_JUMP26 282 /* 26-bit relative. */
#define R_AARCH64_CALL26 283 /* 26-bit relative. */
#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */
#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */
#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
/* ARM relocs. */ /* ARM relocs. */
#define R_ARM_NONE 0 /* No reloc */ #define R_ARM_NONE 0 /* No reloc */
#define R_ARM_PC24 1 /* PC relative 26 bit branch */ #define R_ARM_PC24 1 /* PC relative 26 bit branch */

View file

@ -92,6 +92,7 @@ enum grub_install_plat
GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
GRUB_INSTALL_PLATFORM_I386_XEN, GRUB_INSTALL_PLATFORM_I386_XEN,
GRUB_INSTALL_PLATFORM_X86_64_XEN, GRUB_INSTALL_PLATFORM_X86_64_XEN,
GRUB_INSTALL_PLATFORM_ARM64_EFI,
GRUB_INSTALL_PLATFORM_MAX GRUB_INSTALL_PLATFORM_MAX
}; };

View file

@ -636,6 +636,7 @@ static struct
[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" },
[GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" },
[GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" },
[GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" },
[GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" },
}; };

View file

@ -267,6 +267,8 @@ get_default_platform (void)
return "ia64-efi"; return "ia64-efi";
#elif defined (__arm__) #elif defined (__arm__)
return "arm-uboot"; return "arm-uboot";
#elif defined (__aarch64__)
return "arm64-efi";
#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
return grub_install_get_default_x86_platform (); return grub_install_get_default_x86_platform ();
#else #else
@ -400,6 +402,7 @@ have_bootdev (enum grub_install_plat pl)
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
@ -750,6 +753,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_EFI: case GRUB_INSTALL_PLATFORM_I386_EFI:
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
@ -789,6 +793,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_EFI: case GRUB_INSTALL_PLATFORM_I386_EFI:
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
@ -836,6 +841,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_EFI: case GRUB_INSTALL_PLATFORM_I386_EFI:
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
is_efi = 1; is_efi = 1;
break; break;
@ -940,6 +946,9 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
efi_file = "BOOTARM.EFI"; efi_file = "BOOTARM.EFI";
break; break;
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
efi_file = "BOOTAARCH64.EFI";
break;
default: default:
grub_util_error ("%s", _("You've found a bug")); grub_util_error ("%s", _("You've found a bug"));
break; break;
@ -964,6 +973,9 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
efi_file = "grubarm.efi"; efi_file = "grubarm.efi";
break; break;
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
efi_file = "grubarm64.efi";
break;
default: default:
efi_file = "grub.efi"; efi_file = "grub.efi";
break; break;
@ -1189,6 +1201,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_EFI: case GRUB_INSTALL_PLATFORM_I386_EFI:
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
g = grub_util_guess_efi_drive (*curdev); g = grub_util_guess_efi_drive (*curdev);
break; break;
@ -1278,6 +1291,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_EFI: case GRUB_INSTALL_PLATFORM_I386_EFI:
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
core_name = "core.efi"; core_name = "core.efi";
snprintf (mkimage_target, sizeof (mkimage_target), snprintf (mkimage_target, sizeof (mkimage_target),
@ -1380,6 +1394,7 @@ main (int argc, char *argv[])
} }
break; break;
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
@ -1516,6 +1531,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_X86_64_EFI:
case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI:
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
{ {
char *dst = grub_util_path_concat (2, efidir, efi_file); char *dst = grub_util_path_concat (2, efidir, efi_file);

View file

@ -718,6 +718,35 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
break; break;
} }
break; break;
case EM_AARCH64:
{
sym_addr += addend;
switch (ELF_R_TYPE (info))
{
case R_AARCH64_ABS64:
{
*target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
}
break;
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
{
grub_err_t err;
sym_addr -= offset;
sym_addr -= SUFFIX (entry_point);
err = grub_arm64_reloc_xxxx26((grub_uint32_t *)target,
sym_addr);
if (err)
grub_util_error ("%s", grub_errmsg);
}
break;
default:
grub_util_error (_("relocation %d is not implemented yet"),
(unsigned long long) ELF_R_TYPE (info));
break;
}
break;
}
#endif #endif
#if defined(MKIMAGE_ELF32) #if defined(MKIMAGE_ELF32)
case EM_ARM: case EM_ARM:
@ -995,6 +1024,32 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out,
break; break;
} }
break; break;
case EM_AARCH64:
switch (ELF_R_TYPE (info))
{
case R_AARCH64_ABS64:
{
Elf_Addr addr;
addr = section_address + offset;
current_address
= SUFFIX (add_fixup_entry) (&lst,
GRUB_PE32_REL_BASED_DIR64,
addr, 0, current_address,
image_target);
}
break;
/* Relative relocations do not require fixup entries. */
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
break;
default:
grub_util_error (_("fixup for relocation %d is not implemented yet"),
(unsigned long long) ELF_R_TYPE (info));
break;
}
break;
break;
#if defined(MKIMAGE_ELF32) #if defined(MKIMAGE_ELF32)
case EM_ARM: case EM_ARM:
switch (ELF_R_TYPE (info)) switch (ELF_R_TYPE (info))
@ -1357,7 +1412,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
image_target); image_target);
if (*start == 0) if (*start == 0)
grub_util_error ("start symbol is not defined"); grub_util_error ("start symbol is not defined");
SUFFIX (entry_point) = (Elf_Addr) *start; SUFFIX (entry_point) = (Elf_Addr) *start;
/* Resolve addresses in the virtual address space. */ /* Resolve addresses in the virtual address space. */
@ -1366,7 +1421,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
num_sections, strtab, num_sections, strtab,
out_img, ia64_toff, ia64_got_off, out_img, ia64_toff, ia64_got_off,
image_target); image_target);
*reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
section_vaddresses, sections, section_vaddresses, sections,
section_entsize, num_sections, section_entsize, num_sections,

View file

@ -42,6 +42,7 @@
#include <grub/efi/pe32.h> #include <grub/efi/pe32.h>
#include <grub/uboot/image.h> #include <grub/uboot/image.h>
#include <grub/arm/reloc.h> #include <grub/arm/reloc.h>
#include <grub/arm64/reloc.h>
#include <grub/ia64/reloc.h> #include <grub/ia64/reloc.h>
#include <grub/osdep/hostfile.h> #include <grub/osdep/hostfile.h>
#include <grub/util/install.h> #include <grub/util/install.h>
@ -578,6 +579,22 @@ static const struct grub_install_image_target_desc image_targets[] =
.pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED, .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
.elf_target = EM_ARM, .elf_target = EM_ARM,
}, },
{
.dirname = "arm64-efi",
.names = { "arm64-efi", NULL },
.voidp_sizeof = 8,
.bigendian = 0,
.id = IMAGE_EFI,
.flags = PLATFORM_FLAGS_NONE,
.total_module_size = TARGET_NO_FIELD,
.decompressor_compressed_size = TARGET_NO_FIELD,
.decompressor_uncompressed_size = TARGET_NO_FIELD,
.decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = GRUB_PE32_SECTION_ALIGNMENT,
.vaddr_offset = EFI64_HEADER_SIZE,
.pe_target = GRUB_PE32_MACHINE_ARM64,
.elf_target = EM_AARCH64,
},
}; };
#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))