mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
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
This commit is contained in:
parent
93d4534cdc
commit
63d071445e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=281156
@ -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_ */
|
||||
|
@ -10,7 +10,7 @@ SUBDIR+= fdt
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "arm"
|
||||
SUBDIR+= loader boot1
|
||||
.endif
|
||||
|
||||
|
@ -36,6 +36,14 @@ LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared
|
||||
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.c
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
26
sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
Normal file
26
sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
Normal file
@ -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
|
@ -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`
|
||||
|
165
sys/boot/efi/include/arm/efibind.h
Normal file
165
sys/boot/efi/include/arm/efibind.h
Normal file
@ -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
|
@ -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}
|
||||
|
5
sys/boot/efi/loader/arch/arm/Makefile.inc
Normal file
5
sys/boot/efi/loader/arch/arm/Makefile.inc
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= exec.c \
|
||||
start.S \
|
||||
reloc.c
|
107
sys/boot/efi/loader/arch/arm/exec.c
Normal file
107
sys/boot/efi/loader/arch/arm/exec.c
Normal file
@ -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
|
||||
};
|
||||
|
86
sys/boot/efi/loader/arch/arm/ldscript.arm
Normal file
86
sys/boot/efi/loader/arch/arm/ldscript.arm
Normal file
@ -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 = .;
|
||||
}
|
83
sys/boot/efi/loader/arch/arm/reloc.c
Normal file
83
sys/boot/efi/loader/arch/arm/reloc.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
190
sys/boot/efi/loader/arch/arm/start.S
Normal file
190
sys/boot/efi/loader/arch/arm/start.S
Normal file
@ -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:
|
||||
|
@ -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 *kernendp)
|
||||
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, vm_offset_t *kernendp)
|
||||
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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user