grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 7/7] Add support for ARM UEFI ("EFI") platforms
@ 2013-03-24 17:01 Leif Lindholm
  2013-04-01  2:31 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-01 16:24 ` Francesco Lavra
  0 siblings, 2 replies; 16+ messages in thread
From: Leif Lindholm @ 2013-03-24 17:01 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0007-uefi-support.patch --]
[-- Type: application/octet-stream, Size: 21885 bytes --]

=== modified file 'configure.ac'
--- configure.ac	2013-03-24 14:49:04 +0000
+++ configure.ac	2013-03-24 15:32:46 +0000
@@ -153,6 +153,7 @@
   mipsel-fuloong) platform=loongson ;;
   mipsel-loongson) ;;
   arm-uboot) ;;
+  arm-efi) ;;
   *-emu) ;;
   *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
 esac
@@ -1159,6 +1160,7 @@
 AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
 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_efi], [test x$target_cpu = xarm -a x$platform = xefi])
 
 AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
 AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])

=== modified file 'gentpl.py'
--- gentpl.py	2013-03-24 14:49:04 +0000
+++ gentpl.py	2013-03-24 15:32:46 +0000
@@ -23,7 +23,7 @@
                    "i386_multiboot", "i386_ieee1275", "x86_64_efi",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
-                   "mips_qemu_mips", "arm_uboot" ]
+                   "mips_qemu_mips", "arm_uboot", "arm_efi" ]
 
 GROUPS = {}
 
@@ -36,10 +36,10 @@
 GROUPS["mips"]     = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
 GROUPS["sparc64"]  = [ "sparc64_ieee1275" ]
 GROUPS["powerpc"]  = [ "powerpc_ieee1275" ]
-GROUPS["arm"]      = [ "arm_uboot" ]
+GROUPS["arm"]      = [ "arm_uboot", "arm_efi" ]
 
 # Groups based on firmware
-GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi" ]
+GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
 GROUPS["uboot"] = [ "arm_uboot" ]
 
@@ -64,7 +64,7 @@
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
 # Flattened Device Trees (FDT)
-GROUPS["fdt"] = [ "arm_uboot" ]
+GROUPS["fdt"] = [ "arm_uboot", "arm_efi" ]
 
 # Miscelaneous groups schedulded to disappear in future
 GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]

=== modified file 'grub-core/Makefile.am'
--- grub-core/Makefile.am	2013-03-24 14:49:04 +0000
+++ grub-core/Makefile.am	2013-03-24 15:32:46 +0000
@@ -218,6 +218,12 @@
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
 endif
 
+if COND_arm_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+endif
+
 if COND_emu
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h

=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def	2013-03-24 14:49:04 +0000
+++ grub-core/Makefile.core.def	2013-03-24 15:32:46 +0000
@@ -45,6 +45,9 @@
   ia64_efi_ldflags = '-Wl,-r,-d';
   ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
 
+  arm_efi_ldflags          = '-Wl,-r,-d';
+  arm_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_BASE_LDOPT),0x9000';
 
@@ -80,6 +83,7 @@
   sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
   powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
   arm_uboot_startup = kern/arm/uboot/startup.S;
+  arm_efi_startup = kern/arm/efi/startup.S;
 
   common = kern/command.c;
   common = kern/corecmd.c;
@@ -152,6 +156,9 @@
   ia64_efi = kern/ia64/dl.c;
   ia64_efi = kern/ia64/dl_helper.c;
 
+  arm_efi = kern/arm/efi/init.c;
+  arm_efi = kern/arm/efi/misc.c;
+
   i386_pc = kern/i386/pc/init.c;
   i386_pc = kern/i386/pc/mmap.c;
   i386_pc = kern/i386/tsc.c;
@@ -714,6 +721,7 @@
   i386 = lib/i386/reboot_trampoline.S;
   ia64_efi = lib/efi/reboot.c;
   x86_64_efi = lib/efi/reboot.c;
+  arm_efi = lib/efi/reboot.c;
   powerpc_ieee1275 = lib/ieee1275/reboot.c;
   sparc64_ieee1275 = lib/ieee1275/reboot.c;
   mips_arc = lib/mips/arc/reboot.c;
@@ -1526,6 +1534,7 @@
 
   enable = x86;
   enable = ia64_efi;
+  enable = arm_efi;
   enable = mips;
 };
 

=== added directory 'grub-core/kern/arm/efi'
=== added file 'grub-core/kern/arm/efi/init.c'
--- grub-core/kern/arm/efi/init.c	1970-01-01 00:00:00 +0000
+++ grub-core/kern/arm/efi/init.c	2013-03-24 15:32:46 +0000
@@ -0,0 +1,68 @@
+/* init.c - initialize an arm-based EFI system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/efi/efi.h>
+
+/*
+ * A bit ugly, but functional - and should be completely portable.
+ */
+static grub_uint64_t
+grub_efi_get_time_ms(void)
+{
+  grub_efi_time_t now;
+  grub_uint64_t retval;
+  grub_efi_status_t status;
+
+  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
+		       &now, NULL);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_printf("No time!\n");
+      return 0;
+    }
+  retval = now.year * 365 * 24 * 60 * 60 * 1000;
+  retval += now.month * 30 * 24 * 60 * 60 * 1000;
+  retval += now.day * 24 * 60 * 60 * 1000;
+  retval += now.hour * 60 * 60 * 1000;
+  retval += now.minute * 60 * 1000;
+  retval += now.second * 1000;
+  retval += now.nanosecond / 1000;
+ 
+  grub_dprintf("timer", "timestamp: 0x%llx\n", retval);
+
+  return retval;
+}
+
+void
+grub_machine_init (void)
+{
+  grub_efi_init ();
+  grub_install_get_time_ms (grub_efi_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_efi_fini ();
+}

=== added file 'grub-core/kern/arm/efi/misc.c'
--- grub-core/kern/arm/efi/misc.c	1970-01-01 00:00:00 +0000
+++ grub-core/kern/arm/efi/misc.c	2013-03-24 15:43:19 +0000
@@ -0,0 +1,203 @@
+/* misc.c - various system functions for an arm-based EFI system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/system.h>
+#include <grub/efi/efi.h>
+#include <grub/machine/loader.h>
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+   move this code to efi/mm.c?  */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+  static grub_efi_uintn_t mmap_size = 0;
+
+  if (mmap_size != 0)
+    return mmap_size;
+  
+  mmap_size = (1 << 12);
+  while (1)
+    {
+      int ret;
+      grub_efi_memory_descriptor_t *mmap;
+      grub_efi_uintn_t desc_size;
+      
+      mmap = grub_malloc (mmap_size);
+      if (! mmap)
+	return 0;
+
+      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      grub_free (mmap);
+      
+      if (ret < 0)
+	{
+	  grub_error (GRUB_ERR_IO, "cannot get memory map");
+	  return 0;
+	}
+      else if (ret > 0)
+	break;
+
+      mmap_size += (1 << 12);
+    }
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later, and EFI itself may allocate more.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+#define PAGE_SHIFT 12
+
+void *
+grub_efi_allocate_loader_memory (grub_uint32_t min_offset, grub_uint32_t size)
+{
+  grub_efi_uintn_t desc_size;
+  grub_efi_memory_descriptor_t *mmap, *mmap_end;
+  grub_efi_uintn_t mmap_size, tmp_mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  void *mem = NULL;
+  grub_addr_t min_start = 0;
+
+  mmap_size = find_mmap_size();
+  if (!mmap_size)
+    return NULL;
+
+  mmap = grub_malloc(mmap_size);
+  if (!mmap)
+    return NULL;
+
+  tmp_mmap_size = mmap_size;
+  if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+    {
+      grub_error (GRUB_ERR_IO, "cannot get memory map");
+      goto fail;
+    }
+
+  mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
+  /* Find lowest accessible RAM location */
+  {
+    int found = 0;
+    for (desc = mmap ; !found && (desc < mmap_end) ;
+	 desc = NEXT_MEMORY_DESCRIPTOR(desc, desc_size))
+      {
+	switch (desc->type)
+	  {
+	  case GRUB_EFI_CONVENTIONAL_MEMORY:
+	  case GRUB_EFI_LOADER_CODE:
+	  case GRUB_EFI_LOADER_DATA:
+	    min_start = desc->physical_start + min_offset;
+	    found = 1;
+	    break;
+	  default:
+	    break;
+	  }
+      }
+  }
+
+  /* First, find free pages for the real mode code
+     and the memory map buffer.  */
+  for (desc = mmap ; desc < mmap_end ;
+       desc = NEXT_MEMORY_DESCRIPTOR(desc, desc_size))
+    {
+      grub_uint64_t start, end;
+
+      grub_dprintf("mm", "%s: 0x%08x bytes @ 0x%08x\n",
+		   __FUNCTION__,
+		   (grub_uint32_t) (desc->num_pages << PAGE_SHIFT),
+		   (grub_uint32_t) (desc->physical_start));
+
+      if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
+	continue;
+
+      start = desc->physical_start;
+      end = start + (desc->num_pages << PAGE_SHIFT);
+      grub_dprintf("mm", "%s: start=0x%016llx, end=0x%016llx\n",
+		  __FUNCTION__, start, end);
+      start = start < min_start ? min_start : start;
+      if (start + size > end)
+	continue;
+      grub_dprintf("mm", "%s: let's allocate some (0x%x) pages @ 0x%08x...\n",
+		  __FUNCTION__, (size >> PAGE_SHIFT), (grub_addr_t) start);
+      mem = grub_efi_allocate_pages (start, (size >> PAGE_SHIFT) + 1);
+      grub_dprintf("mm", "%s: retval=0x%08x\n",
+		   __FUNCTION__, (grub_addr_t) mem);
+      if (! mem)
+	{
+	  grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory");
+	  goto fail;
+	}
+      break;
+    }
+
+  if (! mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory");
+      goto fail;
+    }
+
+  grub_free (mmap);
+  return mem;
+
+ fail:
+  grub_free (mmap);
+  return NULL;
+}
+
+grub_err_t
+grub_efi_prepare_platform (void)
+{
+  grub_efi_uintn_t mmap_size;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  grub_efi_memory_descriptor_t *mmap_buf;
+  grub_err_t err;
+
+  /*
+   * Cloned from IA64
+   * Must be done after grub_machine_fini because map_key is used by
+   *exit_boot_services.
+   */
+  mmap_size = find_mmap_size ();
+  if (! mmap_size)
+    return GRUB_ERR_OUT_OF_MEMORY;
+  mmap_buf = grub_efi_allocate_pages (0, page_align (mmap_size) >> 12);
+  if (! mmap_buf)
+    return GRUB_ERR_OUT_OF_MEMORY;
+
+  err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key,
+				       &desc_size, &desc_version);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  grub_arm_disable_caches_mmu();
+  return GRUB_ERR_NONE;
+}

=== added file 'grub-core/kern/arm/efi/startup.S'
--- grub-core/kern/arm/efi/startup.S	1970-01-01 00:00:00 +0000
+++ grub-core/kern/arm/efi/startup.S	2013-03-24 15:32:46 +0000
@@ -0,0 +1,38 @@
+/*
+ * (C) Copyright 2013 Free Software Foundation
+ *
+ * This program 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 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <grub/symbol.h>
+
+	.file 	"startup.S"
+	.text
+	.arm
+FUNCTION(_start)
+	/*
+	 *  EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0.
+	 */
+	ldr	ip, =EXT_C(grub_efi_image_handle)
+	str	r0, [ip]
+	ldr	ip, =EXT_C(grub_efi_system_table)
+	str	r1, [ip]
+	ldr	ip, =EXT_C(grub_main)
+	bx	ip
+	.thumb		@ For relocation debugging
+	blx	_start
+	.end

=== modified file 'grub-core/lib/efi/halt.c'
--- grub-core/lib/efi/halt.c	2011-01-03 01:28:14 +0000
+++ grub-core/lib/efi/halt.c	2013-03-24 15:32:46 +0000
@@ -28,7 +28,7 @@
 grub_halt (void)
 {
   grub_machine_fini ();
-#ifndef __ia64__
+#if !defined(__ia64__) && !defined(__arm__)
   grub_acpi_halt ();
 #endif
   efi_call_4 (grub_efi_system_table->runtime_services->reset_system,

=== added directory 'include/grub/arm/efi'
=== added file 'include/grub/arm/efi/loader.h'
--- include/grub/arm/efi/loader.h	1970-01-01 00:00:00 +0000
+++ include/grub/arm/efi/loader.h	2013-03-24 15:32:46 +0000
@@ -0,0 +1,26 @@
+/*
+ *  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_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+grub_err_t EXPORT_FUNC (grub_efi_prepare_platform) (void);
+void * EXPORT_FUNC (grub_efi_allocate_loader_memory) (grub_uint32_t min_offset,
+						      grub_uint32_t size);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */

=== added file 'include/grub/arm/efi/memory.h'
--- include/grub/arm/efi/memory.h	1970-01-01 00:00:00 +0000
+++ include/grub/arm/efi/memory.h	2013-03-24 15:32:46 +0000
@@ -0,0 +1,1 @@
+#include <grub/efi/memory.h>

=== modified file 'include/grub/efi/pe32.h'
--- include/grub/efi/pe32.h	2011-01-03 12:46:36 +0000
+++ include/grub/efi/pe32.h	2013-03-24 15:32:46 +0000
@@ -63,9 +63,10 @@
   grub_uint16_t characteristics;
 };
 
-#define GRUB_PE32_MACHINE_I386		0x14c
-#define GRUB_PE32_MACHINE_IA64		0x200
-#define GRUB_PE32_MACHINE_X86_64	0x8664
+#define GRUB_PE32_MACHINE_I386			0x14c
+#define GRUB_PE32_MACHINE_IA64			0x200
+#define GRUB_PE32_MACHINE_X86_64		0x8664
+#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED	0x01c2
 
 #define GRUB_PE32_RELOCS_STRIPPED		0x0001
 #define GRUB_PE32_EXECUTABLE_IMAGE		0x0002
@@ -276,8 +277,10 @@
 #define GRUB_PE32_REL_BASED_HIGHLOW	3
 #define GRUB_PE32_REL_BASED_HIGHADJ	4
 #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
+#define GRUB_PE32_REL_BASED_ARM_MOV32A  5
 #define GRUB_PE32_REL_BASED_SECTION	6
 #define GRUB_PE32_REL_BASED_REL		7
+#define GRUB_PE32_REL_BASED_ARM_MOV32T  7
 #define GRUB_PE32_REL_BASED_IA64_IMM64	9
 #define GRUB_PE32_REL_BASED_DIR64	10
 #define GRUB_PE32_REL_BASED_HIGH3ADJ	11

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2013-03-24 14:49:04 +0000
+++ util/grub-install.in	2013-03-24 15:32:46 +0000
@@ -469,6 +469,8 @@
 	    # expansion.
 		ia64)
 		    efi_file=BOOTIA64.EFI ;;
+		arm)
+		    efi_file=BOOTARM.EFI ;;
 	    esac
 	else
 	    # It is convenient for each architecture to have a different
@@ -483,6 +485,8 @@
 	 # expansion.
 		ia64)
 		    efi_file=grubia64.efi ;;
+		arm)
+		    efi_file=grubarm.efi ;;
 		*)
 		    efi_file=grub.efi ;;
 	    esac

=== modified file 'util/grub-mkimage.c'
--- util/grub-mkimage.c	2013-03-24 14:49:04 +0000
+++ util/grub-mkimage.c	2013-03-24 15:32:46 +0000
@@ -472,6 +472,27 @@
       .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
       .link_align = 4
     },
+    {
+      .dirname = "arm-efi",
+      .names = { "arm-efi", NULL },
+      .voidp_sizeof = 4,
+      .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 = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE
+                                + GRUB_PE32_SIGNATURE_SIZE
+                                + sizeof (struct grub_pe32_coff_header)
+                                + sizeof (struct grub_pe32_optional_header)
+                                + 4 * sizeof (struct grub_pe32_section_table),
+                                GRUB_PE32_SECTION_ALIGNMENT),
+      .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
+      .elf_target = EM_ARM,
+    },
   };
 
 #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))

=== modified file 'util/grub-mkimagexx.c'
--- util/grub-mkimagexx.c	2012-02-29 17:57:43 +0000
+++ util/grub-mkimagexx.c	2013-03-24 15:32:46 +0000
@@ -58,6 +58,11 @@
 #error "I'm confused"
 #endif
 
+static Elf_Addr SUFFIX (entry_point);
+
+grub_err_t reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
+grub_err_t reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
+
 /* Relocate symbols; note that this function overwrites the symbol table.
    Return the address of a start symbol.  */
 static Elf_Addr
@@ -528,6 +533,48 @@
 		}
 	       break;
 #endif
+#if defined(MKIMAGE_ELF32)
+	     case EM_ARM:
+	       {
+		 sym_addr += addend;
+		 sym_addr -= SUFFIX (entry_point);
+		 switch (ELF_R_TYPE (info))
+		   {
+		   case R_ARM_ABS32:
+		     {
+		       grub_util_info ("  ABS32:\toffset=%d\t(0x%08x)",
+				       (int) sym_addr, (int) sym_addr);
+		       /* Data will be naturally aligned */
+		       //      sym_addr -= offset;
+		       sym_addr += 0x400;
+		       *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr);
+		     }
+		     break;
+		   case R_ARM_THM_CALL:
+		   case R_ARM_THM_JUMP24:
+		     {
+		       grub_util_info ("  THM_JUMP24:\ttarget=0x%08x\toffset=(0x%08x)",	(unsigned int) target, sym_addr);
+		       sym_addr -= offset;
+		       /* Thumb instructions can be 16-bit aligned */
+		       reloc_thm_call ((grub_uint16_t *) target, sym_addr);
+		     }
+		     break;
+		   case R_ARM_THM_JUMP19:
+		     {
+		       grub_util_info ("  THM_JUMP19:\toffset=%d\t(0x%08x)",
+				       sym_addr, sym_addr);
+		       sym_addr -= offset;
+		       /* Thumb instructions can be 16-bit aligned */
+		       reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+		     }
+		     break;
+		   default:
+		     grub_util_error (_("relocation 0x%x is not implemented yet!"), ELF_R_TYPE (info));
+		     break;
+		   }
+		 break;
+	       }
+#endif /* MKIMAGE_ELF32 */
 	     default:
 	       grub_util_error ("unknown architecture type %d",
 				image_target->elf_target);
@@ -755,6 +802,46 @@
 		  break;
 		}
 		break;
+#if defined(MKIMAGE_ELF32)
+	      case EM_ARM:
+		switch (ELF_R_TYPE (info))
+		  {
+		    /* Relative relocations do not require fixup entries. */
+		  case R_ARM_JUMP24:
+		  case R_ARM_THM_CALL:
+		  case R_ARM_THM_JUMP19:
+		  case R_ARM_THM_JUMP24:
+		    {
+		      Elf_Addr addr;
+
+		      addr = section_address + offset;
+		      grub_util_info ("  %s:  not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) current_address);
+		    }
+		    break;
+		    /* Create fixup entry for PE/COFF loader */
+		  case R_ARM_ABS32:
+		    {      
+		      Elf_Addr addr;
+
+		      addr = section_address + offset;
+#if 0
+		      grub_util_info ("  %s:  add_fixup: 0x%08x : 0x%08x",
+				      __FUNCTION__, (unsigned int) addr,
+				      (unsigned int) current_address);
+#endif
+		      current_address
+			= SUFFIX (add_fixup_entry) (&lst,
+						    GRUB_PE32_REL_BASED_HIGHLOW,
+						    addr, 0, current_address,
+						    image_target);
+		    }
+		    break;
+		  default:
+		    grub_util_error (_("relocation 0x%x is not implemented yet2"), ELF_R_TYPE (info));
+		    break;
+		  }
+		break;
+#endif /* defined(MKIMAGE_ELF32) */
 	      default:
 		grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
 	      }
@@ -1065,6 +1152,8 @@
       if (*start == 0)
 	grub_util_error ("start symbol is not defined");
       
+      SUFFIX (entry_point) = (Elf_Addr) *start;
+
       /* Resolve addresses in the virtual address space.  */
       SUFFIX (relocate_addresses) (e, sections, section_addresses, 
 				   section_entsize,


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-05-11 17:58 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-24 17:01 [PATCH 7/7] Add support for ARM UEFI ("EFI") platforms Leif Lindholm
2013-04-01  2:31 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01 10:41   ` Francesco Lavra
2013-04-01 11:23     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01 14:10       ` Francesco Lavra
2013-04-01 14:16         ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01 14:49           ` Francesco Lavra
2013-04-03 17:50   ` Leif Lindholm
2013-04-01 16:24 ` Francesco Lavra
2013-04-03 18:07   ` Leif Lindholm
2013-04-03 20:01     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-04 12:54       ` Leif Lindholm
2013-04-09 17:30         ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-05-09 18:08           ` Leif Lindholm
2013-05-11  8:42             ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-05-11 18:00             ` Francesco Lavra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).