Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Apr 2015 15:50:21 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r281156 - in head/sys: arm/include boot/efi boot/efi/boot1 boot/efi/include/arm boot/efi/loader boot/efi/loader/arch/arm
Message-ID:  <201504061550.t36FoLN1005813@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Mon Apr  6 15:50:20 2015
New Revision: 281156
URL: https://svnweb.freebsd.org/changeset/base/281156

Log:
  Add support to the efi boot1 and loader for 32-bit ARM. This will be used
  by the future qemu virt support.
  
  Differential Revision:	https://reviews.freebsd.org/D2238
  Reviewed by:	emaste

Added:
  head/sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu
     - copied, changed from r281154, head/sys/boot/efi/boot1/fat.tmpl.bz2.uu
  head/sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu   (contents, props changed)
  head/sys/boot/efi/include/arm/
  head/sys/boot/efi/include/arm/efibind.h   (contents, props changed)
  head/sys/boot/efi/loader/arch/arm/
  head/sys/boot/efi/loader/arch/arm/Makefile.inc   (contents, props changed)
  head/sys/boot/efi/loader/arch/arm/exec.c   (contents, props changed)
  head/sys/boot/efi/loader/arch/arm/ldscript.arm   (contents, props changed)
  head/sys/boot/efi/loader/arch/arm/reloc.c   (contents, props changed)
  head/sys/boot/efi/loader/arch/arm/start.S   (contents, props changed)
Deleted:
  head/sys/boot/efi/boot1/fat.tmpl.bz2.uu
Modified:
  head/sys/arm/include/metadata.h
  head/sys/boot/efi/Makefile
  head/sys/boot/efi/boot1/Makefile
  head/sys/boot/efi/boot1/generate-fat.sh
  head/sys/boot/efi/loader/Makefile
  head/sys/boot/efi/loader/bootinfo.c
  head/sys/boot/efi/loader/copy.c

Modified: head/sys/arm/include/metadata.h
==============================================================================
--- head/sys/arm/include/metadata.h	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/arm/include/metadata.h	Mon Apr  6 15:50:20 2015	(r281156)
@@ -31,5 +31,12 @@
 
 #define	MODINFOMD_BOOTINFO	0x1001
 #define	MODINFOMD_DTBP		0x1002
+#define	MODINFOMD_EFI_MAP	0x1003
+
+struct efi_map_header {
+	uint64_t	memory_size;
+	uint64_t	descriptor_size;
+	uint32_t	descriptor_version;
+};
 
 #endif /* !_MACHINE_METADATA_H_ */

Modified: head/sys/boot/efi/Makefile
==============================================================================
--- head/sys/boot/efi/Makefile	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/Makefile	Mon Apr  6 15:50:20 2015	(r281156)
@@ -10,7 +10,7 @@ SUBDIR+=	fdt
 .endif
 .endif
 
-.if ${MACHINE_CPUARCH} == "amd64"
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "arm"
 SUBDIR+=	loader boot1
 .endif
 

Modified: head/sys/boot/efi/boot1/Makefile
==============================================================================
--- head/sys/boot/efi/boot1/Makefile	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/boot1/Makefile	Mon Apr  6 15:50:20 2015	(r281156)
@@ -36,6 +36,14 @@ LDFLAGS=	-Wl,-T${LDSCRIPT} -Wl,-Bsymboli
 LDFLAGS+=	-Wl,-znocombreloc
 .endif
 
+.if ${MACHINE_CPUARCH} == "arm"
+#
+# Add libstand for the __aeabi_* functions used by the compiler
+#
+DPADD+=		${LIBSTAND}
+LDADD+=		-lstand
+.endif
+
 ${PROG}:	${LDSCRIPT}
 
 OBJCOPY?=	objcopy
@@ -45,6 +53,8 @@ OBJDUMP?=	objdump
 EFI_TARGET=	efi-app-x86_64
 .elif ${MACHINE_CPUARCH} == "i386"
 EFI_TARGET=	efi-app-ia32
+.else
+EFI_TARGET=	binary
 .endif
 
 boot1.efi: loader.sym
@@ -52,7 +62,7 @@ boot1.efi: loader.sym
 		${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
 		exit 1; \
 	fi
-	${OBJCOPY} -j .text -j .sdata -j .data \
+	${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \
 		-j .dynamic -j .dynsym -j .rel.dyn \
 		-j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
 		--output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
@@ -66,8 +76,8 @@ boot1.o: ${.CURDIR}/../../common/ufsread
 
 boot1.efifat: boot1.efi
 	echo ${.OBJDIR}
-	uudecode ${.CURDIR}/fat.tmpl.bz2.uu
-	mv fat.tmpl.bz2 ${.TARGET}.bz2
+	uudecode ${.CURDIR}/fat-${MACHINE_CPUARCH}.tmpl.bz2.uu
+	mv fat-${MACHINE_CPUARCH}.tmpl.bz2 ${.TARGET}.bz2
 	bzip2 -f -d ${.TARGET}.bz2
 	dd if=boot1.efi of=${.TARGET} seek=${BOOT1_OFFSET} conv=notrunc
 

Copied and modified: head/sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu (from r281154, head/sys/boot/efi/boot1/fat.tmpl.bz2.uu)
==============================================================================
--- head/sys/boot/efi/boot1/fat.tmpl.bz2.uu	Mon Apr  6 15:44:09 2015	(r281154, copy source)
+++ head/sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu	Mon Apr  6 15:50:20 2015	(r281156)
@@ -1,7 +1,7 @@
 FAT template boot filesystem created by generate-fat.sh
 DO NOT EDIT
 $FreeBSD$
-begin 644 fat.tmpl.bz2
+begin 644 fat-amd64.tmpl.bz2
 M0EIH.3%!629362AK*D(`&I+____[ZZKJZ_^N_ZO^Z_Z_OJ[L`4`!7I0$#&$"
 M0$!$3&(<P`(;J*C:0E0E#30&AH`T````9#0```9````#)ZF0:,-3U/409,`)
 M@`"8`C3",````$R:8F@P`C`````"24U,D>I-DTU,)ZAZ0VA-!M0T'J`>H#"9

Added: head/sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,26 @@
+FAT template boot filesystem created by generate-fat.sh
+DO NOT EDIT
+$FreeBSD$
+begin 644 fat-arm.tmpl.bz2
+M0EIH.3%!629365NH-?4`&T!_____ZZ[J[_ZN_ZO^J_Z[OJ_^J^J[^KZNKNNJ
+MZNKNZOJ^P`+\#$``0`&AD:,@TTTT-&C30#$R&FF1H:!B&)D&F@```-&AB::#
+M1HP0-,AD`T8F(TTP2JII&?^I5/]4`@TTT-&(T8FAB:&@T:8F(Q!@!`9,1DR9
+M`-,$:,FC)B&FC"8"#3"#(-,0`&AD:,@TTTT-&C30#$R&FF1H:!B&)D&F@```
+M-&AB::#1HP0-,AD`T8F(TTP*HI)D\DFDVC0AIIH]3(:-``80>HTTR!IH::#$
+M-`Q`:`/2:::&)IDP"/0$T:>IFD]$R8---3HUK2<PNK%<6\J]BA",-*(A%:0B
+M(B#G5%F8B$$(68C_:!`A#OL<HAB+JZ6UHRRU>*K9].C:!IWS-2UK9M<WC]W[
+M+]QW,9%V2,?<"ZEO9B("$,I.0ZFE66K/,<N6+8ITS$J3))F2I4HJ5*E2I74J
+M:$J5*E2I4JE5*I*I-2I4J5.;84I4J5*E2I6ZU4Q*E2I4J5+X<SOK,65E965D
+MT:($(0A"$(0A"$(0C>.3@8,&#!@P8(0A"$(0@0A"$(0[;_L-&C1HT:-&B+YP
+M,&#!@P8,$"$(0A"-?NW$*YY:V9IQ,:B93+AX^A7B),5HN_4JV=2\Y,:-+W'Q
+MKQKVU7KA+YR'.:*V#48N-"7<`%:TT4D`/;N;SZM9X,V(@!D'=P==+O)9*\H8
+MI8W<L9:.AU[N;G"QEHLZBWB/2B.SKCGRM):%ZK3-2U3ZV1;%MUZX:^?X_Y@N
+MM=0SN1R7Z\&PN,I8VVWKMS$1-X41%"V)-;+V9:MI5;.+M*TMZ]K7HQ-ALY1\
+M4LG)\#5/I7#7-D_1<KUPE\OW)<YEW=.GMJ%$MUF)TE9N)8[M[6LIEXF@H6?S
+MW%U89M5M+:LW6(\?7Z6I:U4F>IM*Q<2E)KFG;%M&U;INV]<)Q%^P'*<]T6R;
+M^7`P.+I+N(HA%=#(^Q0WVV0]=$2=5)>-XWKW7!95E7$<5QW)<IS6"PF@7&+H
+M&<ETI.`9F48V7/E&??ROG%<9FU^Y#E.8W+GL%]#L7+U=^CY91Q\+`K'-WPF4
+M.2S[EM@S38.8YKG.@P6_83I,-<G1DPY84N-)VMWK,/!;AIJ&3E%&7B`0A,`&
+3'65I7J6`B^?^+N2*<*$@MU!KZ@``
+`
+end

Modified: head/sys/boot/efi/boot1/generate-fat.sh
==============================================================================
--- head/sys/boot/efi/boot1/generate-fat.sh	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/boot1/generate-fat.sh	Mon Apr  6 15:50:20 2015	(r281156)
@@ -17,18 +17,20 @@ BOOT1_SIZE=128k
 
 #
 # Known filenames
-# amd64: BOOTx64.efi
-# arm64: BOOTaa64.efi
+# amd64:   BOOTx64.efi
+# aarch64: BOOTaa64.efi
+# arm:     BOOTarm.efi
 #
-if [ -z "$1" ]; then
-	echo "Usage: $0 filename"
+if [ -z "$2" ]; then
+	echo "Usage: $0 arch boot-filename"
 	exit 1
 fi
 
-FILENAME=$1
+ARCH=$1
+FILENAME=$2
 
 # Generate 800K FAT image
-OUTPUT_FILE=fat.tmpl
+OUTPUT_FILE=fat-${ARCH}.tmpl
 
 dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=$FAT_SIZE
 DEVICE=`mdconfig -a -f $OUTPUT_FILE`

Added: head/sys/boot/efi/include/arm/efibind.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/include/arm/efibind.h	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,165 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+  EfiBind.h
+
+Abstract:
+
+  Processor or Compiler specific defines and types for IA-32.
+  We are using the ANSI C 2000 _t type definitions for basic types.
+  This it technically a violation of the coding standard, but they
+  are used to make EfiTypes.h portable. Code other than EfiTypes.h
+  should never use any ANSI C 2000 _t integer types.
+
+--*/
+
+#ifndef _EFI_BIND_H_
+#define _EFI_BIND_H_
+
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction)
+#define EFI_APPLICATION_ENTRY_POINT EFI_DRIVER_ENTRY_POINT
+
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#else
+//
+// Assume standard IA-32 alignment.
+// BugBug: Need to check portability of long long
+//
+typedef unsigned long long  uint64_t;
+typedef long long           int64_t;
+typedef unsigned int        uint32_t;
+typedef int                 int32_t;
+typedef unsigned short      uint16_t;
+typedef short               int16_t;
+typedef unsigned char       uint8_t;
+typedef signed char         int8_t;
+#endif
+
+typedef uint64_t   UINT64;
+typedef int64_t    INT64;
+typedef uint32_t   UINT32;
+typedef int32_t    INT32;
+typedef uint16_t   UINT16;
+typedef int16_t    INT16;
+typedef uint8_t    UINT8;
+typedef int8_t     INT8;
+
+#undef VOID
+#define VOID    void
+
+//
+// Native integer size in stdint.h
+//
+typedef uint32_t  UINTN;
+typedef int32_t   INTN;
+
+#define EFIERR(a)           (0x80000000 | a)
+#define EFI_ERROR_MASK      0x80000000
+#define EFIERR_OEM(a)       (0xc0000000 | a)
+
+//
+// Processor specific defines
+//
+#define EFI_MAX_BIT       0x80000000
+#define MAX_2_BITS        0xC0000000
+
+//
+// Maximum legal IA-32 address
+//
+#define EFI_MAX_ADDRESS   0xFFFFFFFF
+
+//
+//  Bad pointer value to use in check builds.
+//  if you see this value you are using uninitialized or free'ed data
+//
+#define EFI_BAD_POINTER          0xAFAFAFAF
+#define EFI_BAD_POINTER_AS_BYTE  0xAF
+
+#define EFI_DEADLOOP()    { volatile UINTN __iii; __iii = 1; while (__iii); }
+
+//
+// Inject a break point in the code to assist debugging for NT Emulation Environment
+// For real hardware, just put in a halt loop. Don't do a while(1) because the
+// compiler will optimize away the rest of the function following, so that you run out in
+// the weeds if you skip over it with a debugger.
+//
+#define EFI_BREAKPOINT EFI_DEADLOOP()
+
+
+//
+// Memory Fence forces serialization, and is needed to support out of order
+//  memory transactions. The Memory Fence is mainly used to make sure IO
+//  transactions complete in a deterministic sequence, and to syncronize locks
+//  an other MP code. Currently no memory fencing is required.
+//
+#define MEMORY_FENCE()
+
+//
+// Some compilers don't support the forward reference construct:
+//  typedef struct XXXXX. The forward reference is required for
+//  ANSI compatibility.
+//
+// The following macro provide a workaround for such cases.
+//
+
+
+#ifdef EFI_NO_INTERFACE_DECL
+  #define EFI_FORWARD_DECLARATION(x)
+#else
+  #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+#endif
+
+
+//
+// Some C compilers optimize the calling conventions to increase performance.
+// EFIAPI is used to make all public APIs follow the standard C calling
+// convention.
+//
+#define EFIAPI
+
+
+
+//
+// For symbol name in GNU assembly code, an extra "_" is necessary
+//
+#if defined(__GNUC__)
+  ///
+  /// Private worker functions for ASM_PFX()
+  ///
+  #define _CONCATENATE(a, b)  __CONCATENATE(a, b)
+  #define __CONCATENATE(a, b) a ## b
+
+  ///
+  /// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix
+  /// on symbols in assembly language.
+  ///
+  #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
+
+#endif
+
+#define INTERFACE_DECL(x) struct x
+
+#endif

Modified: head/sys/boot/efi/loader/Makefile
==============================================================================
--- head/sys/boot/efi/loader/Makefile	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/loader/Makefile	Mon Apr  6 15:50:20 2015	(r281156)
@@ -87,6 +87,8 @@ OBJDUMP?=	objdump
 EFI_TARGET=	efi-app-x86_64
 .elif ${MACHINE_CPUARCH} == "i386"
 EFI_TARGET=	efi-app-ia32
+.else
+EFI_TARGET=	binary
 .endif
 
 loader.efi: loader.sym
@@ -94,7 +96,7 @@ loader.efi: loader.sym
 		${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
 		exit 1; \
 	fi
-	${OBJCOPY} -j .text -j .sdata -j .data \
+	${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \
 		-j .dynamic -j .dynsym -j .rel.dyn \
 		-j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
 		--output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}

Added: head/sys/boot/efi/loader/arch/arm/Makefile.inc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/arm/Makefile.inc	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SRCS+=	exec.c \
+	start.S \
+	reloc.c

Added: head/sys/boot/efi/loader/arch/arm/exec.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/arm/exec.c	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "loader_efi.h"
+
+extern vm_offset_t md_load(char *, vm_offset_t *);
+
+int
+__elfN(arm_load)(char *filename, u_int64_t dest,
+    struct preloaded_file **result)
+{
+	int r;
+
+	r = __elfN(loadfile)(filename, dest, result);
+	if (r != 0)
+		return (r);
+
+	return (0);
+}
+
+int
+__elfN(arm_exec)(struct preloaded_file *fp)
+{
+	struct file_metadata *fmp;
+	vm_offset_t modulep, kernend;
+	Elf_Ehdr *e;
+	int error;
+	void (*entry)(void *);
+	EFI_STATUS status;
+
+	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+		return (EFTYPE);
+
+	e = (Elf_Ehdr *)&fmp->md_data;
+
+	if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0)
+		return (error);
+
+	entry = efi_translate(e->e_entry);
+	printf("Kernel entry at 0x%x...\n", (unsigned)entry);
+	printf("Kernel args: %s\n", fp->f_args);
+	printf("modulep: %#x\n", modulep);
+	printf("relocation_offset %llx\n", __elfN(relocation_offset));
+
+	status = BS->ExitBootServices(IH, efi_mapkey);
+	if (EFI_ERROR(status)) {
+		printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
+		    (long)status);
+		return (EINVAL);
+	}
+
+	dev_cleanup();
+
+	(*entry)((void *)modulep);
+	panic("exec returned");
+}
+
+static struct file_format arm_elf = {
+	__elfN(arm_load),
+	__elfN(arm_exec)
+};
+
+struct file_format *file_formats[] = {
+	&arm_elf,
+	NULL
+};
+

Added: head/sys/boot/efi/loader/arch/arm/ldscript.arm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/arm/ldscript.arm	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,86 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0;
+  ImageBase = .;
+  .peheader	: {
+    *(.peheader)
+  }
+  .text		: {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em. */
+    *(.gnu.warning)
+    *(.gnu.linkonce.t*)
+  } =0
+  _etext = .;
+  PROVIDE (etext = .);
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.data)
+    *(.gnu.linkonce.d*)
+    *(.rodata)
+    *(.rodata.*)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  .got1           : { *(.got1) }
+  .dynamic        : { *(.dynamic) }
+  /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+     get relocated with -mrelocatable. Also put in the .fixup pointers.
+     The current compiler no longer needs this, but keep it around for 2.7.2  */
+                PROVIDE (_GOT2_START_ = .);
+  .got2           :  { *(.got2) }
+                PROVIDE (__CTOR_LIST__ = .);
+  .ctors          : { *(.ctors) }
+                PROVIDE (__CTOR_END__ = .);
+                PROVIDE (__DTOR_LIST__ = .);
+  .dtors          : { *(.dtors) }
+                PROVIDE (__DTOR_END__ = .);
+                PROVIDE (_FIXUP_START_ = .);
+  .fixup          : { *(.fixup) }
+                PROVIDE (_FIXUP_END_ = .);
+                PROVIDE (_GOT2_END_ = .);
+                PROVIDE (_GOT_START_ = .);
+  .got            : { *(.got) }
+  .got.plt        : { *(.got.plt) }
+                PROVIDE (_GOT_END_ = .);
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  set_Xcommand_set	: {
+    __start_set_Xcommand_set = .;
+    *(set_Xcommand_set)
+    __stop_set_Xcommand_set = .;
+  }
+  __gp = .;
+   PROVIDE (__bss_start = .);
+  .sbss      :
+  {
+    *(.sbss)
+    *(.scommon)
+    *(.dynsbss)
+  }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+   PROVIDE (__bss_end = .);
+  .plt   : { *(.plt) }
+  .dynamic	: { *(.dynamic) }
+  .reloc	: { *(.reloc) }
+  .hash		: { *(.hash) }
+  .dynsym	: { *(.dynsym) }
+  .dynstr	: { *(.dynstr) }
+  _edata = .;
+}

Added: head/sys/boot/efi/loader/arch/arm/reloc.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/arm/reloc.c	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <elf.h>
+#include <bootstrap.h>
+
+/*
+ * A simple relocator for ARM binaries.
+ */
+void
+_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic)
+{
+	unsigned long relsz, relent;
+	unsigned long *newaddr;
+	Elf32_Rel *rel;
+	Elf32_Dyn *dynp;
+
+	/*
+	 * Find the relocation address, its size and the relocation entry.
+	 */
+	relsz = 0;
+	relent = 0;
+	for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+		switch (dynp->d_tag) {
+		case DT_REL:
+			rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr +
+			    ImageBase);
+			break;
+		case DT_RELSZ:
+			relsz = dynp->d_un.d_val;
+			break;
+		case DT_RELENT:
+			relent = dynp->d_un.d_val;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * Perform the actual relocation.
+	 */
+	for (; relsz > 0; relsz -= relent) {
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_ARM_RELATIVE:
+			/* Address relative to the base address. */
+			newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+			*newaddr += ImageBase;
+			break;
+		default:
+			/* XXX: do we need other relocations ? */
+			break;
+		}
+		rel = (Elf32_Rel *) ((caddr_t) rel + relent);
+	}
+}

Added: head/sys/boot/efi/loader/arch/arm/start.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/arm/start.S	Mon Apr  6 15:50:20 2015	(r281156)
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2014, 2015 Andrew Turner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+/*
+ * We need to be a PE32 file for EFI. On some architectures we can use
+ * objcopy to create the correct file, however on arm we need to do
+ * it ourselves.
+ */
+
+#define	IMAGE_FILE_MACHINE_ARM		0x01c2
+
+#define	IMAGE_SCN_CNT_CODE		0x00000020
+#define	IMAGE_SCN_CNT_INITIALIZED_DATA	0x00000040
+#define	IMAGE_SCN_MEM_DISCARDABLE	0x02000000
+#define	IMAGE_SCN_MEM_EXECUTE		0x20000000
+#define	IMAGE_SCN_MEM_READ		0x40000000
+
+	.section .peheader
+efi_start:
+	/* The MS-DOS Stub, only used to get the offset of the COFF header */
+	.ascii	"MZ"
+	.short	0
+	.space	0x38
+	.long	pe_sig - efi_start
+
+	/* The PE32 Signature. Needs to be 8-byte aligned */
+	.align	3
+pe_sig:
+	.ascii	"PE"
+	.short	0
+coff_head:
+	.short	IMAGE_FILE_MACHINE_ARM		/* ARM file */
+	.short	2				/* 2 Sections */
+	.long	0				/* Timestamp */
+	.long	0				/* No symbol table */
+	.long	0				/* No symbols */
+	.short	section_table - optional_header	/* Optional header size */
+	.short	0	/* Characteristics TODO: Fill in */
+
+optional_header:
+	.short	0x010b				/* PE32 (32-bit addressing) */
+	.byte	0				/* Major linker version */
+	.byte	0				/* Minor linker version */
+	.long	_edata - _end_header		/* Code size */
+	.long	0				/* No initialized data */
+	.long	0				/* No uninitialized data */
+	.long	_start - efi_start		/* Entry point */
+	.long	_end_header - efi_start		/* Start of code */
+	.long	0				/* Start of data */
+
+optional_windows_header:
+	.long	0				/* Image base */
+	.long	32				/* Section Alignment */
+	.long	8				/* File alignment */
+	.short	0				/* Major OS version */
+	.short	0				/* Minor OS version */
+	.short	0				/* Major image version */
+	.short	0				/* Minor image version */
+	.short	0				/* Major subsystem version */
+	.short	0				/* Minor subsystem version */
+	.long	0				/* Win32 version */
+	.long	_edata - efi_start		/* Image size */
+	.long	_end_header - efi_start		/* Header size */
+	.long	0				/* Checksum */
+	.short	0xa				/* Subsystem (EFI app) */
+	.short	0				/* DLL Characteristics */
+	.long	0				/* Stack reserve */
+	.long	0				/* Stack commit */
+	.long	0				/* Heap reserve */
+	.long	0				/* Heap commit */
+	.long	0				/* Loader flags */
+	.long	6				/* Number of RVAs */
+
+	/* RVAs: */
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+section_table:
+	/* We need a .reloc section for EFI */
+	.ascii	".reloc"
+	.byte	0
+	.byte	0				/* Pad to 8 bytes */
+	.long	0				/* Virtual size */
+	.long	0				/* Virtual address */
+	.long	0				/* Size of raw data */
+	.long	0				/* Pointer to raw data */
+	.long	0				/* Pointer to relocations */
+	.long	0				/* Pointer to line numbers */
+	.short	0				/* Number of relocations */
+	.short	0				/* Number of line numbers */
+	.long	(IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_MEM_DISCARDABLE)	/* Characteristics */
+
+	/* The contents of the loader */
+	.ascii	".text"
+	.byte	0
+	.byte	0
+	.byte	0				/* Pad to 8 bytes */
+	.long	_edata - _end_header		/* Virtual size */
+	.long	_end_header - efi_start		/* Virtual address */
+	.long	_edata - _end_header		/* Size of raw data */
+	.long	_end_header - efi_start		/* Pointer to raw data */
+	.long	0				/* Pointer to relocations */
+	.long	0				/* Pointer to line numbers */
+	.short	0				/* Number of relocations */
+	.short	0				/* Number of line numbers */
+	.long	(IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \
+		 IMAGE_SCN_MEM_READ)		/* Characteristics */
+_end_header:
+
+	.text
+_start:
+	/* Save the boot params to the stack */
+	push	{r0, r1}
+
+	adr	r0, .Lbase
+	ldr	r1, [r0]
+	sub	r5, r0, r1
+
+	ldr	r0, .Limagebase
+	add	r0, r0, r5
+	ldr	r1, .Ldynamic
+	add	r1, r1, r5
+
+	bl	_C_LABEL(_reloc)
+
+	/* Zero the BSS, _reloc fixed the values for us */
+	ldr	r0, .Lbss
+	ldr	r1, .Lbssend
+	mov	r2, #0
+
+1:	cmp	r0, r1
+	bgt	2f
+	str	r2, [r0], #4
+	b	1b
+2:
+
+	pop	{r0, r1}
+	bl	_C_LABEL(efi_main)
+
+1:	WFI
+	b	1b
+
+.Lbase:
+	.word	.
+.Limagebase:
+	.word	ImageBase
+.Ldynamic:
+	.word	_DYNAMIC
+.Lbss:
+	.word	__bss_start
+.Lbssend:
+	.word	__bss_end
+
+.align	3
+stack:
+	.space 512
+stack_end:
+

Modified: head/sys/boot/efi/loader/bootinfo.c
==============================================================================
--- head/sys/boot/efi/loader/bootinfo.c	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/loader/bootinfo.c	Mon Apr  6 15:50:20 2015	(r281156)
@@ -219,6 +219,9 @@ bi_copymodules(vm_offset_t addr)
 		if (fp->f_args)
 			MOD_ARGS(addr, fp->f_args, c);
 		v = fp->f_addr;
+#if defined(__arm__)
+		v -= __elfN(relocation_offset);
+#endif
 		MOD_ADDR(addr, v, c);
 		v = fp->f_size;
 		MOD_SIZE(addr, v, c);
@@ -332,6 +335,21 @@ bi_load(char *args, vm_offset_t *modulep
 	vm_offset_t dtbp;
 	int dtb_size;
 #endif
+#if defined(__arm__)
+	vm_offset_t vaddr;
+	int i;
+	/*
+	 * These metadata addreses must be converted for kernel after
+	 * relocation.
+	 */
+	uint32_t		mdt[] = {
+	    MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND,
+	    MODINFOMD_ENVP,
+#if defined(LOADER_FDT_SUPPORT)
+	    MODINFOMD_DTBP
+#endif
+	};
+#endif
 
 	howto = bi_getboothowto(args);
 
@@ -405,6 +423,22 @@ bi_load(char *args, vm_offset_t *modulep
 	md = file_findmetadata(kfp, MODINFOMD_KERNEND);
 	bcopy(&kernend, md->md_data, sizeof kernend);
 
+#if defined(__arm__)
+	*modulep -= __elfN(relocation_offset);
+
+	/* Do relocation fixup on metadata of each module. */
+	for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+		for (i = 0; i < sizeof mdt / sizeof mdt[0]; i++) {
+			md = file_findmetadata(xp, mdt[i]);
+			if (md) {
+				bcopy(md->md_data, &vaddr, sizeof vaddr);
+				vaddr -= __elfN(relocation_offset);
+				bcopy(&vaddr, md->md_data, sizeof vaddr);
+			}
+		}
+	}
+#endif
+
 	/* Copy module list and metadata. */
 	(void)bi_copymodules(addr);
 

Modified: head/sys/boot/efi/loader/copy.c
==============================================================================
--- head/sys/boot/efi/loader/copy.c	Mon Apr  6 15:45:45 2015	(r281155)
+++ head/sys/boot/efi/loader/copy.c	Mon Apr  6 15:50:20 2015	(r281156)
@@ -61,9 +61,21 @@ efi_copy_init(void)
 	}
 	staging_end = staging + STAGE_PAGES * 4096;
 
+#ifdef __arm__
+	/* Round the kernel load address to a 2MiB value */
+	staging = roundup2(staging, 2 * 1024 * 1024);
+#endif
+
 	return (0);
 }
 
+void *
+efi_translate(vm_offset_t ptr)
+{
+
+	return ((void *)(ptr + stage_offset));
+}
+
 ssize_t
 efi_copyin(const void *src, vm_offset_t dest, const size_t len)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504061550.t36FoLN1005813>