socsvn commit: r237877 - in soc2012/emc2: experimental
head/sys/boot/efi/include head/sys/boot/efi/include/i386
emc2 at FreeBSD.org
emc2 at FreeBSD.org
Mon Jun 18 04:42:41 UTC 2012
Author: emc2
Date: Mon Jun 18 04:42:39 2012
New Revision: 237877
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237877
Log:
Very hard-won progress. Due to a bug in stdint.h, uint64_t (and by
extension, UINT64) was being typedef'ed to unsigned long, but when compiling
with -m32, this meant sizeof(uint64_t) == 4. This ultimately caused the
EFI_SYSTEM_TABLE and others to have the wrong offsets, which caused the
errors I'd been seeing.
I added a temporary fix to detect when compiling for i386 vs amd64, and to
select the proper UINT64.
Added:
soc2012/emc2/experimental/reloc.c
Modified:
soc2012/emc2/experimental/Makefile
soc2012/emc2/experimental/helloworld.c
soc2012/emc2/experimental/start.S
soc2012/emc2/head/sys/boot/efi/include/efiapi.h
soc2012/emc2/head/sys/boot/efi/include/i386/efibind.h
Modified: soc2012/emc2/experimental/Makefile
==============================================================================
--- soc2012/emc2/experimental/Makefile Mon Jun 18 04:31:15 2012 (r237876)
+++ soc2012/emc2/experimental/Makefile Mon Jun 18 04:42:39 2012 (r237877)
@@ -1,13 +1,23 @@
-CC=gcc
-CFLAGS=-O2 -m32 -I../head/sys/boot/efi/include/ -I../head/sys/boot/efi/include/i386 -fPIC
-OBJCOPY=objcopy
+GCCPREFIX=
+#GCCPREFIX=/usr/local/mingw32/bin
+CC=${GCCPREFIX}gcc
+INCLUDEFLAGS=-I../head/sys/boot/efi/include/ -I../head/sys/boot/efi/include/i386 -I../head/sys/boot/common
+CFLAGS=-O2 -m32 ${INCLUDEFLAGS}
+#CFLAGS = -g -Os -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -Wno-array-bounds -c -m32 -malign-double -freorder-blocks -freorder-blocks-and-partition -O2 -mno-stack-arg-probe ${INCLUDEFLAGS}
+OBJCOPY=${GCCPREFIX}objcopy
+
EFIFORMAT=efi-app-ia32
LDSCRIPT=ldscript.i386
+CLEANFILES=helloworld.dll helloworld.obj helloworld.o helloworld helloworld.efi start.o reloc.o
+
all: helloworld.efi
clean:
- rm -f helloworld.o helloworld helloworld.efi start.o
+ rm -rf ${CLEANFILES}
+
+reloc.o: reloc.c
+ ${CC} -c ${CFLAGS} reloc.c
start.o: start.S
${CC} -c ${CFLAGS} start.S
@@ -15,8 +25,9 @@
helloworld.o: helloworld.c
${CC} -c ${CFLAGS} helloworld.c
-helloworld: helloworld.o start.o
- ${CC} -nostdlib -o helloworld -Wl,-T ${LDSCRIPT} -shared -symbolic helloworld.o start.o
+helloworld: helloworld.o start.o reloc.o
+ ${CC} -nostdlib -o helloworld -Wl,-T ${LDSCRIPT} -shared -symbolic helloworld.o start.o reloc.o
+# libefi.a
helloworld.efi: helloworld
${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
Modified: soc2012/emc2/experimental/helloworld.c
==============================================================================
--- soc2012/emc2/experimental/helloworld.c Mon Jun 18 04:31:15 2012 (r237876)
+++ soc2012/emc2/experimental/helloworld.c Mon Jun 18 04:42:39 2012 (r237877)
@@ -1,12 +1,55 @@
+#include <stdlib.h>
#include <efi.h>
-
+#include <efiapi.h>
+/*
+int main(int argc, char** argv) {
+ return -1;
+}
+*/
static unsigned short str[] =
{ 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\n', '\r', 0 };
+
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE* systab)
{
+ /*
+ sig = systab->Hdr.Signature;
+ rev = systab->Hdr.Revision;
+ hdrsize = systab->Hdr.HeaderSize;
+ CRC32 = systab->Hdr.CRC32;
+ reserved = systab->Hdr.Reserved;
+ vendor = systab->FirmwareVendor;
+ revision = systab->FirmwareRevision;
+ coninhandle = systab->ConsoleInHandle;
+ ConIn = systab->ConIn;
+ conouthandle = systab->ConsoleOutHandle;
+ ConOut = systab->ConOut;
+ */
+ systab->ConOut->OutputString(systab->ConOut, str);
+ /*
+ EFI_STATUS status;
+
+ IH = image;
+ ST = systab;
+ BS = ST->BootServices;
+ RS = ST->RuntimeServices;
+
+ heapsize = 2 * 1024 * 1024;
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
+ EFI_SIZE_TO_PAGES(heapsize), &heap);
+
+ if(NULL == ST->ConOut->Reset)
+ return -1;
+ else
+ return EFI_SUCCESS;
+ */
+ return sizeof(UINT64);
+ //return (EFI_STATUS)systab->ConOut;
+}
- systab->ConOut->ClearScreen(systab->ConOut);
+#include <stdio.h>
- return EFI_SUCCESS;
+main() {
+ printf("%d\n", sizeof(uint64_t));
+ return 0;
}
Added: soc2012/emc2/experimental/reloc.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2012/emc2/experimental/reloc.c Mon Jun 18 04:42:39 2012 (r237877)
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo at 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: soc2012/emc2/head/sys/boot/i386/efi/reloc.c 235458 2012-05-09 07:55:42Z avg $");
+
+#include <sys/types.h>
+#include <sys/elf32.h>
+#include <efi.h>
+#include <bootstrap.h>
+
+/*
+ * A simple relocator for IA32 EFI binaries.
+ */
+EFI_STATUS
+_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *system_table)
+{
+ 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.
+ * XXX: We are reusing code for the amd64 version of this, but
+ * we must make sure the relocation types are the same.
+ */
+ CTASSERT(R_386_NONE == R_X86_64_NONE);
+ CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE);
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_386_NONE:
+ /* No relocation needs be performed. */
+ break;
+ case R_386_RELATIVE:
+ /* Address relative to the base address. */
+ newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+ *newaddr += ImageBase;
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ return (EFI_LOAD_ERROR);
+ }
+ rel = (Elf32_Rel *) ((caddr_t) rel + relent);
+ }
+
+ return (EFI_SUCCESS);
+}
Modified: soc2012/emc2/experimental/start.S
==============================================================================
--- soc2012/emc2/experimental/start.S Mon Jun 18 04:31:15 2012 (r237876)
+++ soc2012/emc2/experimental/start.S Mon Jun 18 04:42:39 2012 (r237877)
@@ -46,8 +46,20 @@
pushl 12(%ebp) /* image_handle */
pushl 8(%ebp) /* system_table */
+ call 0f
+0: popl %eax
+ movl %eax, %ebx
+ addl $ImageBase-0b, %eax
+ addl $_DYNAMIC-0b, %ebx
+ pushl %ebx /* dynamic */
+ pushl %eax /* ImageBase */
+ call _reloc
+ cmpl $EFI_SUCCESS, %eax
+ jne 1f
+ popl %ebx /* remove ImageBase from the stack */
+ popl %ebx /* remove dynamic from the stack */
call efi_main
- leave
+1: leave
ret
END(_start)
Modified: soc2012/emc2/head/sys/boot/efi/include/efiapi.h
==============================================================================
--- soc2012/emc2/head/sys/boot/efi/include/efiapi.h Mon Jun 18 04:31:15 2012 (r237876)
+++ soc2012/emc2/head/sys/boot/efi/include/efiapi.h Mon Jun 18 04:42:39 2012 (r237877)
@@ -666,7 +666,7 @@
// Standard EFI table header
//
-typedef struct _EFI_TABLE_HEARDER {
+typedef struct _EFI_TABLE_HEADER {
UINT64 Signature;
UINT32 Revision;
UINT32 HeaderSize;
Modified: soc2012/emc2/head/sys/boot/efi/include/i386/efibind.h
==============================================================================
--- soc2012/emc2/head/sys/boot/efi/include/i386/efibind.h Mon Jun 18 04:31:15 2012 (r237876)
+++ soc2012/emc2/head/sys/boot/efi/include/i386/efibind.h Mon Jun 18 04:42:39 2012 (r237877)
@@ -84,9 +84,13 @@
//
// Basic EFI types of various widths
//
-
-typedef uint64_t UINT64;
-typedef int64_t INT64;
+#if defined(__amd64)
+typedef unsigned long UINT64;
+typedef long INT64;
+#elif defined(__i386)
+typedef unsigned long long UINT64;
+typedef long long INT64;
+#endif
#ifndef _BASETSD_H_
typedef uint32_t UINT32;
More information about the svn-soc-all
mailing list