Date: Mon, 18 Jun 2012 04:42:39 +0000 From: emc2@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r237877 - in soc2012/emc2: experimental head/sys/boot/efi/include head/sys/boot/efi/include/i386 Message-ID: <20120618044239.9432E1065675@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120618044239.9432E1065675>