Author: andrew Date: Wed Apr 1 08:30:40 2015 New Revision: 280950 URL: https://svnweb.freebsd.org/changeset/base/280950
Log: Move the efi loaders to be under sys/boot/efi. This will help us add support for booting arm and arm64 from UEFI. Differential Revision: https://reviews.freebsd.org/D2164 Reviewed by: emaste, imp (previous version) Sponsored by: The FreeBSD Foundation Added: head/sys/boot/efi/boot1/ head/sys/boot/efi/boot1/Makefile - copied, changed from r280949, head/sys/boot/amd64/boot1.efi/Makefile head/sys/boot/efi/boot1/Makefile.fat - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat head/sys/boot/efi/boot1/boot1.c - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/boot1.c head/sys/boot/efi/boot1/fat.tmpl.bz2.uu - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu head/sys/boot/efi/boot1/generate-fat.sh - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh head/sys/boot/efi/loader/ head/sys/boot/efi/loader/Makefile - copied, changed from r280570, head/sys/boot/amd64/efi/Makefile head/sys/boot/efi/loader/arch/ head/sys/boot/efi/loader/arch/amd64/ head/sys/boot/efi/loader/arch/amd64/Makefile.inc (contents, props changed) head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S - copied unchanged from r280570, head/sys/boot/amd64/efi/amd64_tramp.S head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c - copied, changed from r280570, head/sys/boot/amd64/efi/elf64_freebsd.c head/sys/boot/efi/loader/arch/amd64/framebuffer.c - copied unchanged from r280570, head/sys/boot/amd64/efi/framebuffer.c head/sys/boot/efi/loader/arch/amd64/framebuffer.h - copied unchanged from r280570, head/sys/boot/amd64/efi/framebuffer.h head/sys/boot/efi/loader/arch/amd64/ldscript.amd64 - copied unchanged from r280570, head/sys/boot/amd64/efi/ldscript.amd64 head/sys/boot/efi/loader/arch/amd64/reloc.c - copied unchanged from r280570, head/sys/boot/amd64/efi/reloc.c head/sys/boot/efi/loader/arch/amd64/start.S - copied unchanged from r280570, head/sys/boot/amd64/efi/start.S head/sys/boot/efi/loader/autoload.c - copied, changed from r280570, head/sys/boot/amd64/efi/autoload.c head/sys/boot/efi/loader/bootinfo.c - copied, changed from r280570, head/sys/boot/amd64/efi/bootinfo.c head/sys/boot/efi/loader/conf.c - copied, changed from r280570, head/sys/boot/amd64/efi/conf.c head/sys/boot/efi/loader/copy.c - copied, changed from r280570, head/sys/boot/amd64/efi/copy.c head/sys/boot/efi/loader/devicename.c - copied, changed from r280570, head/sys/boot/amd64/efi/devicename.c head/sys/boot/efi/loader/loader_efi.h - copied, changed from r280570, head/sys/boot/amd64/efi/x86_efi.h head/sys/boot/efi/loader/main.c - copied, changed from r280570, head/sys/boot/amd64/efi/main.c head/sys/boot/efi/loader/version - copied unchanged from r280570, head/sys/boot/amd64/efi/version Deleted: head/sys/boot/amd64/ Modified: head/sys/boot/efi/Makefile head/sys/boot/efi/Makefile.inc Modified: head/sys/boot/efi/Makefile ============================================================================== --- head/sys/boot/efi/Makefile Wed Apr 1 08:25:40 2015 (r280949) +++ head/sys/boot/efi/Makefile Wed Apr 1 08:30:40 2015 (r280950) @@ -2,4 +2,8 @@ SUBDIR= libefi +.if ${MACHINE_CPUARCH} == "amd64" +SUBDIR+= loader boot1 +.endif + .include <bsd.subdir.mk> Modified: head/sys/boot/efi/Makefile.inc ============================================================================== --- head/sys/boot/efi/Makefile.inc Wed Apr 1 08:25:40 2015 (r280949) +++ head/sys/boot/efi/Makefile.inc Wed Apr 1 08:30:40 2015 (r280950) @@ -7,7 +7,10 @@ CFLAGS+= -march=i386 .endif # Options used when building app-specific efi components +# See conf/kern.mk for the correct set of these CFLAGS+= -ffreestanding -fshort-wchar -Wformat +CFLAGS+= -mno-red-zone +CFLAGS+= -mno-mmx -mno-sse -mno-aes -mno-avx -msoft-float LDFLAGS+= -nostdlib .include "../Makefile.inc" Copied and modified: head/sys/boot/efi/boot1/Makefile (from r280949, head/sys/boot/amd64/boot1.efi/Makefile) ============================================================================== --- head/sys/boot/amd64/boot1.efi/Makefile Wed Apr 1 08:25:40 2015 (r280949, copy source) +++ head/sys/boot/efi/boot1/Makefile Wed Apr 1 08:30:40 2015 (r280950) @@ -17,19 +17,19 @@ SRCS= boot1.c reloc.c start.S CFLAGS+= -fPIC CFLAGS+= -I. -CFLAGS+= -I${.CURDIR}/../../efi/include -CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. # Always add MI sources and REGULAR efi loader bits -.PATH: ${.CURDIR}/../efi ${.CURDIR}/../../common +.PATH: ${.CURDIR}/../loader/arch/amd64 ${.CURDIR}/../../common CFLAGS+= -I${.CURDIR}/../../common FILES= boot1.efi boot1.efifat FILESMODE_boot1.efi= ${BINMODE} -LDSCRIPT= ${.CURDIR}/../efi/ldscript.${MACHINE_CPUARCH} +LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH} LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc ${PROG}: ${LDSCRIPT} @@ -39,7 +39,7 @@ OBJDUMP?= objdump .if ${MACHINE_CPUARCH} == "amd64" EFI_TARGET= efi-app-x86_64 -.else +.elif ${MACHINE_CPUARCH} == "i386" EFI_TARGET= efi-app-ia32 .endif Copied: head/sys/boot/efi/boot1/Makefile.fat (from r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/boot1/Makefile.fat Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat) @@ -0,0 +1,3 @@ +# This file autogenerated by generate-fat.sh - DO NOT EDIT +# $FreeBSD$ +BOOT1_OFFSET=0x2d Copied: head/sys/boot/efi/boot1/boot1.c (from r280570, head/sys/boot/amd64/boot1.efi/boot1.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/boot1/boot1.c Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/boot1.c) @@ -0,0 +1,552 @@ +/*- + * Copyright (c) 1998 Robert Nordier + * All rights reserved. + * Copyright (c) 2001 Robert Drehmel + * All rights reserved. + * Copyright (c) 2014 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms are freely + * permitted provided that the above copyright notice and this + * paragraph and the following disclaimer are duplicated in all + * such forms. + * + * This software is provided "AS IS" and without any express or + * implied warranties, including, without limitation, the implied + * warranties of merchantability and fitness for a particular + * purpose. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/dirent.h> +#include <machine/elf.h> +#include <machine/stdarg.h> + +#include <efi.h> +#include <eficonsctl.h> + +#define _PATH_LOADER "/boot/loader.efi" +#define _PATH_KERNEL "/boot/kernel/kernel" + +#define BSIZEMAX 16384 + +typedef int putc_func_t(char c, void *arg); + +struct sp_data { + char *sp_buf; + u_int sp_len; + u_int sp_size; +}; + +static const char digits[] = "0123456789abcdef"; + +static void panic(const char *fmt, ...) __dead2; +static int printf(const char *fmt, ...); +static int putchar(char c, void *arg); +static int vprintf(const char *fmt, va_list ap); +static int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); + +static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); +static int __putc(char c, void *arg); +static int __puts(const char *s, putc_func_t *putc, void *arg); +static int __sputc(char c, void *arg); +static char *__uitoa(char *buf, u_int val, int base); +static char *__ultoa(char *buf, u_long val, int base); + +static int domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet); +static void load(const char *fname); + +EFI_SYSTEM_TABLE *systab; +EFI_HANDLE *image; + +static void +bcopy(const void *src, void *dst, size_t len) +{ + const char *s = src; + char *d = dst; + + while (len-- != 0) + *d++ = *s++; +} + +static void +memcpy(void *dst, const void *src, size_t len) +{ + bcopy(src, dst, len); +} + +static void +bzero(void *b, size_t len) +{ + char *p = b; + + while (len-- != 0) + *p++ = 0; +} + +static int +strcmp(const char *s1, const char *s2) +{ + for (; *s1 == *s2 && *s1; s1++, s2++) + ; + return ((u_char)*s1 - (u_char)*s2); +} + +static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL; +static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; +static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; +static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; + +static EFI_BLOCK_IO *bootdev; +static EFI_DEVICE_PATH *bootdevpath; +static EFI_HANDLE *bootdevhandle; + +EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab) +{ + EFI_HANDLE handles[128]; + EFI_BLOCK_IO *blkio; + UINTN i, nparts = sizeof(handles); + EFI_STATUS status; + EFI_DEVICE_PATH *devpath; + EFI_BOOT_SERVICES *BS; + EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; + char *path = _PATH_LOADER; + + systab = Xsystab; + image = Ximage; + + BS = systab->BootServices; + status = BS->LocateProtocol(&ConsoleControlGUID, NULL, + (VOID **)&ConsoleControl); + if (status == EFI_SUCCESS) + (void)ConsoleControl->SetMode(ConsoleControl, + EfiConsoleControlScreenText); + + printf(" \n>> FreeBSD EFI boot block\n"); + printf(" Loader path: %s\n", path); + + status = systab->BootServices->LocateHandle(ByProtocol, + &BlockIoProtocolGUID, NULL, &nparts, handles); + nparts /= sizeof(handles[0]); + + for (i = 0; i < nparts; i++) { + status = systab->BootServices->HandleProtocol(handles[i], + &DevicePathGUID, (void **)&devpath); + if (EFI_ERROR(status)) + continue; + + while (!IsDevicePathEnd(NextDevicePathNode(devpath))) + devpath = NextDevicePathNode(devpath); + + status = systab->BootServices->HandleProtocol(handles[i], + &BlockIoProtocolGUID, (void **)&blkio); + if (EFI_ERROR(status)) + continue; + + if (!blkio->Media->LogicalPartition) + continue; + + if (domount(devpath, blkio, 1) >= 0) + break; + } + + if (i == nparts) + panic("No bootable partition found"); + + bootdevhandle = handles[i]; + load(path); + + panic("Load failed"); + + return EFI_SUCCESS; +} + +static int +dskread(void *buf, u_int64_t lba, int nblk) +{ + EFI_STATUS status; + int size; + + lba = lba / (bootdev->Media->BlockSize / DEV_BSIZE); + size = nblk * DEV_BSIZE; + status = bootdev->ReadBlocks(bootdev, bootdev->Media->MediaId, lba, + size, buf); + + if (EFI_ERROR(status)) + return (-1); + + return (0); +} + +#include "ufsread.c" + +static ssize_t +fsstat(ufs_ino_t inode) +{ +#ifndef UFS2_ONLY + static struct ufs1_dinode dp1; + ufs1_daddr_t addr1; +#endif +#ifndef UFS1_ONLY + static struct ufs2_dinode dp2; +#endif + static struct fs fs; + static ufs_ino_t inomap; + char *blkbuf; + void *indbuf; + size_t n, nb, size, off, vboff; + ufs_lbn_t lbn; + ufs2_daddr_t addr2, vbaddr; + static ufs2_daddr_t blkmap, indmap; + u_int u; + + blkbuf = dmadat->blkbuf; + indbuf = dmadat->indbuf; + if (!dsk_meta) { + inomap = 0; + for (n = 0; sblock_try[n] != -1; n++) { + if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE, + SBLOCKSIZE / DEV_BSIZE)) + return -1; + memcpy(&fs, dmadat->sbbuf, sizeof(struct fs)); + if (( +#if defined(UFS1_ONLY) + fs.fs_magic == FS_UFS1_MAGIC +#elif defined(UFS2_ONLY) + (fs.fs_magic == FS_UFS2_MAGIC && + fs.fs_sblockloc == sblock_try[n]) +#else + fs.fs_magic == FS_UFS1_MAGIC || + (fs.fs_magic == FS_UFS2_MAGIC && + fs.fs_sblockloc == sblock_try[n]) +#endif + ) && + fs.fs_bsize <= MAXBSIZE && + fs.fs_bsize >= sizeof(struct fs)) + break; + } + if (sblock_try[n] == -1) { + printf("Not ufs\n"); + return -1; + } + dsk_meta++; + } else + memcpy(&fs, dmadat->sbbuf, sizeof(struct fs)); + if (!inode) + return 0; + if (inomap != inode) { + n = IPERVBLK(&fs); + if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK)) + return -1; + n = INO_TO_VBO(n, inode); +#if defined(UFS1_ONLY) + memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n, + sizeof(struct ufs1_dinode)); +#elif defined(UFS2_ONLY) + memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n, + sizeof(struct ufs2_dinode)); +#else + if (fs.fs_magic == FS_UFS1_MAGIC) + memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n, + sizeof(struct ufs1_dinode)); + else + memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n, + sizeof(struct ufs2_dinode)); +#endif + inomap = inode; + fs_off = 0; + blkmap = indmap = 0; + } + size = DIP(di_size); + n = size - fs_off; + return (n); +} + +static struct dmadat __dmadat; + +static int +domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet) +{ + + dmadat = &__dmadat; + bootdev = blkio; + bootdevpath = device; + if (fsread(0, NULL, 0)) { + if (!quiet) + printf("domount: can't read superblock\n"); + return (-1); + } + if (!quiet) + printf("Succesfully mounted UFS filesystem\n"); + return (0); +} + +static void +load(const char *fname) +{ + ufs_ino_t ino; + EFI_STATUS status; + EFI_HANDLE loaderhandle; + EFI_LOADED_IMAGE *loaded_image; + void *buffer; + size_t bufsize; + + if ((ino = lookup(fname)) == 0) { + printf("File %s not found\n", fname); + return; + } + + bufsize = fsstat(ino); + status = systab->BootServices->AllocatePool(EfiLoaderData, + bufsize, &buffer); + fsread(ino, buffer, bufsize); + + /* XXX: For secure boot, we need our own loader here */ + status = systab->BootServices->LoadImage(TRUE, image, bootdevpath, + buffer, bufsize, &loaderhandle); + if (EFI_ERROR(status)) + printf("LoadImage failed with error %d\n", status); + + status = systab->BootServices->HandleProtocol(loaderhandle, + &LoadedImageGUID, (VOID**)&loaded_image); + if (EFI_ERROR(status)) + printf("HandleProtocol failed with error %d\n", status); + + loaded_image->DeviceHandle = bootdevhandle; + + status = systab->BootServices->StartImage(loaderhandle, NULL, NULL); + if (EFI_ERROR(status)) + printf("StartImage failed with error %d\n", status); +} + +static void +panic(const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + printf("panic: %s\n", buf); + va_end(ap); + + while (1) {} +} + +static int +printf(const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Don't annoy the user as we probe for partitions */ + if (strcmp(fmt,"Not ufs\n") == 0) + return 0; + + va_start(ap, fmt); + ret = vprintf(fmt, ap); + va_end(ap); + return (ret); +} + +static int +putchar(char c, void *arg) +{ + CHAR16 buf[2]; + + if (c == '\n') { + buf[0] = '\r'; + buf[1] = 0; + systab->ConOut->OutputString(systab->ConOut, buf); + } + buf[0] = c; + buf[1] = 0; + systab->ConOut->OutputString(systab->ConOut, buf); + return (1); +} + +static int +vprintf(const char *fmt, va_list ap) +{ + int ret; + + ret = __printf(fmt, putchar, 0, ap); + return (ret); +} + +static int +vsnprintf(char *str, size_t sz, const char *fmt, va_list ap) +{ + struct sp_data sp; + int ret; + + sp.sp_buf = str; + sp.sp_len = 0; + sp.sp_size = sz; + ret = __printf(fmt, __sputc, &sp, ap); + return (ret); +} + +static int +__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) +{ + char buf[(sizeof(long) * 8) + 1]; + char *nbuf; + u_long ul; + u_int ui; + int lflag; + int sflag; + char *s; + int pad; + int ret; + int c; + + nbuf = &buf[sizeof buf - 1]; + ret = 0; + while ((c = *fmt++) != 0) { + if (c != '%') { + ret += putc(c, arg); + continue; + } + lflag = 0; + sflag = 0; + pad = 0; +reswitch: c = *fmt++; + switch (c) { + case '#': + sflag = 1; + goto reswitch; + case '%': + ret += putc('%', arg); + break; + case 'c': + c = va_arg(ap, int); + ret += putc(c, arg); + break; + case 'd': + if (lflag == 0) { + ui = (u_int)va_arg(ap, int); + if (ui < (int)ui) { + ui = -ui; + ret += putc('-', arg); + } + s = __uitoa(nbuf, ui, 10); + } else { + ul = (u_long)va_arg(ap, long); + if (ul < (long)ul) { + ul = -ul; + ret += putc('-', arg); + } + s = __ultoa(nbuf, ul, 10); + } + ret += __puts(s, putc, arg); + break; + case 'l': + lflag = 1; + goto reswitch; + case 'o': + if (lflag == 0) { + ui = (u_int)va_arg(ap, u_int); + s = __uitoa(nbuf, ui, 8); + } else { + ul = (u_long)va_arg(ap, u_long); + s = __ultoa(nbuf, ul, 8); + } + ret += __puts(s, putc, arg); + break; + case 'p': + ul = (u_long)va_arg(ap, void *); + s = __ultoa(nbuf, ul, 16); + ret += __puts("0x", putc, arg); + ret += __puts(s, putc, arg); + break; + case 's': + s = va_arg(ap, char *); + ret += __puts(s, putc, arg); + break; + case 'u': + if (lflag == 0) { + ui = va_arg(ap, u_int); + s = __uitoa(nbuf, ui, 10); + } else { + ul = va_arg(ap, u_long); + s = __ultoa(nbuf, ul, 10); + } + ret += __puts(s, putc, arg); + break; + case 'x': + if (lflag == 0) { + ui = va_arg(ap, u_int); + s = __uitoa(nbuf, ui, 16); + } else { + ul = va_arg(ap, u_long); + s = __ultoa(nbuf, ul, 16); + } + if (sflag) + ret += __puts("0x", putc, arg); + ret += __puts(s, putc, arg); + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + pad = pad * 10 + c - '0'; + goto reswitch; + default: + break; + } + } + return (ret); +} + +static int +__sputc(char c, void *arg) +{ + struct sp_data *sp; + + sp = arg; + if (sp->sp_len < sp->sp_size) + sp->sp_buf[sp->sp_len++] = c; + sp->sp_buf[sp->sp_len] = '\0'; + return (1); +} + +static int +__puts(const char *s, putc_func_t *putc, void *arg) +{ + const char *p; + int ret; + + ret = 0; + for (p = s; *p != '\0'; p++) + ret += putc(*p, arg); + return (ret); +} + +static char * +__uitoa(char *buf, u_int ui, int base) +{ + char *p; + + p = buf; + *p = '\0'; + do + *--p = digits[ui % base]; + while ((ui /= base) != 0); + return (p); +} + +static char * +__ultoa(char *buf, u_long ul, int base) +{ + char *p; + + p = buf; + *p = '\0'; + do + *--p = digits[ul % base]; + while ((ul /= base) != 0); + return (p); +} + Copied: head/sys/boot/efi/boot1/fat.tmpl.bz2.uu (from r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/boot1/fat.tmpl.bz2.uu Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu) @@ -0,0 +1,20 @@ +FAT template boot filesystem created by generate-fat.sh +DO NOT EDIT +$FreeBSD$ +begin 644 fat.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 +M'I#0-H&HQI&0&3&FH>H>*`JHHU3V]1%/4/2``T#0`!H``#0`````#1H,@``6 +M'1&G'&@?$6[T#A)?X8$A160"20BO#")0J4TB1*4GXF$B4I,&>43+=_?K=#3* +M6]<E0HE`UBF?(J%8BRF#?8OQ2'D)`)(EL2;F4.'R>R"ZNKJZI,9*68E8*E2Q +M4J5*E3'(1830A"$(12A-"<(0A#]VD)H0A"$,>I0FA"$(0I\>P^=F5:M6K5JU +M:DI3:64UN;[7%5B]Y-^\]@_K@B:N\/,5F%&H<\G#IXQXAEFC&D?![6%0'6MR +MX1@@%FC"FD`M7,/SXFNG:2`'-0<-C$8^+$N.7M1B,^6)9,DV9,0A\OL<:C"L +ML1V&,<\9YRB>XV#BG")'6NKRK^("UF2XO?_L!#29">MGDF$R3).!PX&%E,4C +M''=(FL1.`_3?CN@-IB2PI3!FF\<8X.X@D,>CA90I)#M$XRPNDFJELL<3=1?8 +M2B7\5Z64,!7Z;EEBW-MXN-4IJ@W$462]-*\YCR,-B,5[W?=3&L/U>SX,WV#\ +M\B`:I"'0Z)5"$1B.E)(K[5I4RS`%R$>Y\D0NR*,;<9CZ:^V3P(I?D<D#!UC) +D^M-HEE3SAN-8O0FQ$(`$(DF`?ZQ]'U2F_XNY(IPH2!0UE2$` +` +end Copied: head/sys/boot/efi/boot1/generate-fat.sh (from r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/boot1/generate-fat.sh Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh) @@ -0,0 +1,66 @@ +#!/bin/sh + +# This script generates the dummy FAT filesystem used for the EFI boot +# blocks. It uses newfs_msdos to generate a template filesystem with the +# relevant interesting files. These are then found by grep, and the offsets +# written to a Makefile snippet. +# +# Because it requires root, and because it is overkill, we do not +# do this as part of the normal build. If makefs(8) grows workable FAT +# support, this should be revisited. + +# $FreeBSD$ + +FAT_SIZE=1600 #Size in 512-byte blocks of the produced image + +BOOT1_SIZE=128k + +# +# Known filenames +# amd64: BOOTx64.efi +# arm64: BOOTaa64.efi +# +if [ -z "$1" ]; then + echo "Usage: $0 filename" + exit 1 +fi + +FILENAME=$1 + +# Generate 800K FAT image +OUTPUT_FILE=fat.tmpl + +dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=$FAT_SIZE +DEVICE=`mdconfig -a -f $OUTPUT_FILE` +newfs_msdos -F 12 -L EFI $DEVICE +mkdir stub +mount -t msdosfs /dev/$DEVICE stub + +# Create and bless a directory for the boot loader +mkdir -p stub/efi/boot + +# Make a dummy file for boot1 +echo 'Boot1 START' | dd of=stub/efi/boot/$FILENAME cbs=$BOOT1_SIZE count=1 conv=block + +umount stub +mdconfig -d -u $DEVICE +rmdir stub + +# Locate the offset of the fake file +BOOT1_OFFSET=$(hd $OUTPUT_FILE | grep 'Boot1 START' | cut -f 1 -d ' ') + +# Convert to number of blocks +BOOT1_OFFSET=$(echo 0x$BOOT1_OFFSET | awk '{printf("%x\n",$1/512);}') + +echo '# This file autogenerated by generate-fat.sh - DO NOT EDIT' > Makefile.fat +echo '# $FreeBSD$' >> Makefile.fat +echo "BOOT1_OFFSET=0x$BOOT1_OFFSET" >> Makefile.fat + +bzip2 $OUTPUT_FILE +echo 'FAT template boot filesystem created by generate-fat.sh' > $OUTPUT_FILE.bz2.uu +echo 'DO NOT EDIT' >> $OUTPUT_FILE.bz2.uu +echo '$FreeBSD$' >> $OUTPUT_FILE.bz2.uu + +uuencode $OUTPUT_FILE.bz2 $OUTPUT_FILE.bz2 >> $OUTPUT_FILE.bz2.uu +rm $OUTPUT_FILE.bz2 + Copied and modified: head/sys/boot/efi/loader/Makefile (from r280570, head/sys/boot/amd64/efi/Makefile) ============================================================================== --- head/sys/boot/amd64/efi/Makefile Wed Mar 25 11:14:17 2015 (r280570, copy source) +++ head/sys/boot/efi/loader/Makefile Wed Apr 1 08:30:40 2015 (r280950) @@ -12,27 +12,24 @@ MK_SSP= no PROG= loader.sym INTERNALPROG= +.PATH: ${.CURDIR}/../../efi/loader # architecture-specific loader code SRCS= autoload.c \ bootinfo.c \ conf.c \ copy.c \ devicename.c \ - elf64_freebsd.c \ - framebuffer.c \ main.c \ - reloc.c \ vers.c -SRCS+= amd64_tramp.S \ - start.S -.PATH: ${.CURDIR}/../../i386/libi386 -SRCS+= nullconsole.c \ - comconsole.c + +.PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH} +.include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc" CFLAGS+= -fPIC -CFLAGS+= -I. -CFLAGS+= -I${.CURDIR}/../../efi/include -CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR} +CFLAGS+= -I${.CURDIR}/arch/${MACHINE_CPUARCH} +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -DNO_PCI @@ -60,14 +57,14 @@ CFLAGS+= -I${.CURDIR}/../../common FILES= loader.efi FILESMODE_loader.efi= ${BINMODE} -LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_CPUARCH} +LDSCRIPT= ${.CURDIR}/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH} LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc CLEANFILES= vers.c loader.efi NEWVERSWHAT= "EFI loader" ${MACHINE_CPUARCH} -vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version +vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../../efi/loader/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} OBJCOPY?= objcopy @@ -75,7 +72,7 @@ OBJDUMP?= objdump .if ${MACHINE_CPUARCH} == "amd64" EFI_TARGET= efi-app-x86_64 -.else +.elif ${MACHINE_CPUARCH} == "i386" EFI_TARGET= efi-app-ia32 .endif @@ -89,7 +86,7 @@ loader.efi: loader.sym -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} -LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a +LIBEFI= ${.OBJDIR}/../libefi/libefi.a DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${LDSCRIPT} LDADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} Added: head/sys/boot/efi/loader/arch/amd64/Makefile.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/loader/arch/amd64/Makefile.inc Wed Apr 1 08:30:40 2015 (r280950) @@ -0,0 +1,11 @@ +# $FreeBSD$ + +SRCS+= amd64_tramp.S \ + start.S \ + framebuffer.c \ + elf64_freebsd.c \ + reloc.c + +.PATH: ${.CURDIR}/../../i386/libi386 +SRCS+= nullconsole.c \ + comconsole.c Copied: head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S (from r280570, head/sys/boot/amd64/efi/amd64_tramp.S) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/efi/amd64_tramp.S) @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Benno Rice under sponsorship from + * the FreeBSD Foundation. + * 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/asmacros.h> + + .text + .globl amd64_tramp + +/* + * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend, + * uint64_t modulep, uint64_t pagetable, uint64_t entry) + */ +amd64_tramp: + cli /* Make sure we don't get interrupted. */ + movq %rdi,%rsp /* Switch to our temporary stack. */ + + movq %rdx,%r12 /* Stash the kernel values for later. */ + movq %rcx,%r13 + movq %r8,%r14 + movq %r9,%r15 + + callq *%rsi /* Call copy_finish so we're all ready to go. */ + + pushq %r12 /* Push kernend. */ + salq $32,%r13 /* Shift modulep and push it. */ + pushq %r13 + pushq %r15 /* Push the entry address. */ + movq %r14,%cr3 /* Switch page tables. */ + ret /* "Return" to kernel entry. */ + + ALIGN_TEXT +amd64_tramp_end: + + .data + .globl amd64_tramp_size +amd64_tramp_size: + .long amd64_tramp_end-amd64_tramp Copied and modified: head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c (from r280570, head/sys/boot/amd64/efi/elf64_freebsd.c) ============================================================================== --- head/sys/boot/amd64/efi/elf64_freebsd.c Wed Mar 25 11:14:17 2015 (r280570, copy source) +++ head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c Wed Apr 1 08:30:40 2015 (r280950) @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$"); #include "actypes.h" #include "actbl.h" -#include "x86_efi.h" +#include "loader_efi.h" static EFI_GUID acpi_guid = ACPI_TABLE_GUID; static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; @@ -57,8 +57,14 @@ extern int bi_load(char *args, vm_offset static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); -struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; -struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; +static struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; +static struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; + +struct file_format *file_formats[] = { + &amd64_elf, + &amd64_elf_obj, + NULL +}; #define PG_V 0x001 #define PG_RW 0x002 @@ -168,7 +174,7 @@ elf64_exec(struct preloaded_file *fp) if (err != 0) return(err); - status = BS->ExitBootServices(IH, x86_efi_mapkey); + status = BS->ExitBootServices(IH, efi_mapkey); if (EFI_ERROR(status)) { printf("%s: ExitBootServices() returned 0x%lx\n", __func__, (long)status); @@ -177,7 +183,7 @@ elf64_exec(struct preloaded_file *fp) dev_cleanup(); - trampoline(trampstack, x86_efi_copy_finish, kernend, modulep, PT4, + trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4, ehdr->e_entry); panic("exec returned"); Copied: head/sys/boot/efi/loader/arch/amd64/framebuffer.c (from r280570, head/sys/boot/amd64/efi/framebuffer.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/boot/efi/loader/arch/amd64/framebuffer.c Wed Apr 1 08:30:40 2015 (r280950, copy of r280570, head/sys/boot/amd64/efi/framebuffer.c) @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Benno Rice under sponsorship from + * the FreeBSD Foundation. + * 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 <stand.h> + +#include <efi.h> +#include <efilib.h> +#include <machine/metadata.h> + +static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + +int +efi_find_framebuffer(struct efi_fb *efifb) +{ + EFI_GRAPHICS_OUTPUT *gop; + EFI_STATUS status; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; + + status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop); + if (EFI_ERROR(status)) + return (1); + + mode = gop->Mode; + info = gop->Mode->Info; + + efifb->fb_addr = mode->FrameBufferBase; + efifb->fb_size = mode->FrameBufferSize; + efifb->fb_height = info->VerticalResolution; + efifb->fb_width = info->HorizontalResolution; + efifb->fb_stride = info->PixelsPerScanLine; + + switch (info->PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + efifb->fb_mask_red = 0x000000ff; + efifb->fb_mask_green = 0x0000ff00; + efifb->fb_mask_blue = 0x00ff0000; + efifb->fb_mask_reserved = 0xff000000; + break; + case PixelBlueGreenRedReserved8BitPerColor: + efifb->fb_mask_red = 0x00ff0000; + efifb->fb_mask_green = 0x0000ff00; + efifb->fb_mask_blue = 0x000000ff; + efifb->fb_mask_reserved = 0xff000000; + break; + case PixelBitMask: + efifb->fb_mask_red = info->PixelInformation.RedMask; + efifb->fb_mask_green = info->PixelInformation.GreenMask; + efifb->fb_mask_blue = info->PixelInformation.BlueMask; + efifb->fb_mask_reserved = + info->PixelInformation.ReservedMask; + break; + default: + return (1); + } + return (0); +} *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"