Mercurial > unleashed > prev-conversion
changeset 18798:f656a72baba3
8919 loader.efi: remove efi_main() from libefi
author | Toomas Soome <tsoome@me.com> |
---|---|
date | Tue, 12 Dec 2017 13:08:57 +0200 |
parents | 0889ab17b493 |
children | 44db128cd592 |
files | usr/src/boot/sys/boot/efi/boot1/boot1.c usr/src/boot/sys/boot/efi/include/efiapi.h usr/src/boot/sys/boot/efi/include/efidevp.h usr/src/boot/sys/boot/efi/include/efilib.h usr/src/boot/sys/boot/efi/libefi/libefi.c usr/src/boot/sys/boot/efi/loader/Makefile usr/src/boot/sys/boot/efi/loader/efi_main.c |
diffstat | 7 files changed, 228 insertions(+), 189 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/boot/sys/boot/efi/boot1/boot1.c Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/boot1/boot1.c Tue Dec 12 13:08:57 2017 +0200 @@ -52,8 +52,6 @@ /* The initial number of handles used to query EFI for partitions. */ #define NUM_HANDLES_INIT 24 -EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); - EFI_SYSTEM_TABLE *systab; EFI_BOOT_SERVICES *bs; static EFI_HANDLE *image; @@ -93,7 +91,7 @@ static BOOLEAN nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath) { - int len; + size_t len; if (imgpath == NULL || imgpath->Type != devpath->Type || imgpath->SubType != devpath->SubType)
--- a/usr/src/boot/sys/boot/efi/include/efiapi.h Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/include/efiapi.h Tue Dec 12 13:08:57 2017 +0200 @@ -356,7 +356,7 @@ IN EFI_STATUS ExitStatus, IN UINTN ExitDataSize, IN CHAR16 *ExitData OPTIONAL - ); + ) __dead2; typedef EFI_STATUS
--- a/usr/src/boot/sys/boot/efi/include/efidevp.h Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/include/efidevp.h Tue Dec 12 13:08:57 2017 +0200 @@ -51,7 +51,7 @@ #define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) #define DevicePathSubType(a) ( (a)->SubType ) -#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) +#define DevicePathNodeLength(a) ((size_t)(((a)->Length[0]) | ((a)->Length[1] << 8))) #define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) #define IsDevicePathType(a, t) ( DevicePathType(a) == t ) #define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE)
--- a/usr/src/boot/sys/boot/efi/include/efilib.h Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/include/efilib.h Tue Dec 12 13:08:57 2017 +0200 @@ -84,8 +84,10 @@ void efi_time_init(void); void efi_time_fini(void); +EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); + EFI_STATUS main(int argc, CHAR16 *argv[]); -void exit(EFI_STATUS status); +void efi_exit(EFI_STATUS status) __dead2; void delay(int usecs); /* EFI environment initialization. */
--- a/usr/src/boot/sys/boot/efi/libefi/libefi.c Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/libefi/libefi.c Tue Dec 12 13:08:57 2017 +0200 @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 2000 Doug Rabson * All rights reserved. * @@ -27,36 +27,13 @@ #include <sys/cdefs.h> #include <efi.h> -#include <eficonsctl.h> #include <efilib.h> -#include <stand.h> EFI_HANDLE IH; EFI_SYSTEM_TABLE *ST; EFI_BOOT_SERVICES *BS; EFI_RUNTIME_SERVICES *RS; -static EFI_PHYSICAL_ADDRESS heap; -static UINTN heapsize; - -static CHAR16 * -arg_skipsep(CHAR16 *argp) -{ - - while (*argp == ' ' || *argp == '\t' || *argp == '\n') - argp++; - return (argp); -} - -static CHAR16 * -arg_skipword(CHAR16 *argp) -{ - - while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n') - argp++; - return (argp); -} - void * efi_get_table(EFI_GUID *tbl) { @@ -70,158 +47,3 @@ } return (NULL); } - -void exit(EFI_STATUS exit_code) -{ - - BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); - BS->Exit(IH, exit_code, 0, NULL); -} - -void -efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) -{ - static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL; - static EFI_GUID console_control_protocol = - EFI_CONSOLE_CONTROL_PROTOCOL_GUID; - EFI_CONSOLE_CONTROL_PROTOCOL *console_control = NULL; - EFI_LOADED_IMAGE *img; - CHAR16 *argp, *args, **argv; - EFI_STATUS status; - SIMPLE_TEXT_OUTPUT_INTERFACE *conout; - UINTN i, max_dim, best_mode, cols, rows; - int argc, addprog; - - IH = image_handle; - ST = system_table; - BS = ST->BootServices; - RS = ST->RuntimeServices; - - status = BS->LocateProtocol(&console_control_protocol, NULL, - (VOID **)&console_control); - if (status == EFI_SUCCESS) - (void)console_control->SetMode(console_control, - EfiConsoleControlScreenText); - - conout = ST->ConOut; - max_dim = best_mode = 0; - for (i = 0; i <= conout->Mode->MaxMode ; i++) { - status = conout->QueryMode(conout, i, &cols, &rows); - if (EFI_ERROR(status)) - continue; - if (cols * rows > max_dim) { - max_dim = cols * rows; - best_mode = i; - } - } - if (max_dim > 0) - conout->SetMode(conout, best_mode); - - heapsize = 64 * 1024 * 1024; - /* 4GB upper limit, try to leave some space from 1MB */ - heap = 0x0000000100000000; - status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, - EFI_SIZE_TO_PAGES(heapsize), &heap); - if (status != EFI_SUCCESS) - BS->Exit(IH, status, 0, NULL); - - setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize)); - - status = conout->QueryMode(conout, best_mode, &cols, &rows); - if (EFI_ERROR(status)) { - setenv("LINES", "24", 1); - setenv("COLUMNS", "80", 1); - } else { - char buf[8]; - snprintf(buf, sizeof (buf), "%u", (unsigned)rows); - setenv("LINES", buf, 1); - snprintf(buf, sizeof (buf), "%u", (unsigned)cols); - setenv("COLUMNS", buf, 1); - } - - /* Use exit() from here on... */ - - status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img); - if (status != EFI_SUCCESS) - exit(status); - - /* - * Pre-process the (optional) load options. If the option string - * is given as an ASCII string, we use a poor man's ASCII to - * Unicode-16 translation. The size of the option string as given - * to us includes the terminating null character. We assume the - * string is an ASCII string if strlen() plus the terminating - * '\0' is less than LoadOptionsSize. Even if all Unicode-16 - * characters have the upper 8 bits non-zero, the terminating - * null character will cause a one-off. - * If the string is already in Unicode-16, we make a copy so that - * we know we can always modify the string. - */ - if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { - if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { - args = malloc(img->LoadOptionsSize << 1); - for (argc = 0; argc < img->LoadOptionsSize; argc++) - args[argc] = ((char*)img->LoadOptions)[argc]; - } else { - args = malloc(img->LoadOptionsSize); - memcpy(args, img->LoadOptions, img->LoadOptionsSize); - } - } else - args = NULL; - - /* - * Use a quick and dirty algorithm to build the argv vector. We - * first count the number of words. Then, after allocating the - * vector, we split the string up. We don't deal with quotes or - * other more advanced shell features. - * The EFI shell will pass the name of the image as the first - * word in the argument list. This does not happen if we're - * loaded by the boot manager. This is not so easy to figure - * out though. The ParentHandle is not always NULL, because - * there can be a function (=image) that will perform the task - * for the boot manager. - */ - /* Part 1: Figure out if we need to add our program name. */ - addprog = (args == NULL || img->ParentHandle == NULL || - img->FilePath == NULL) ? 1 : 0; - if (!addprog) { - addprog = - (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || - DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || - DevicePathNodeLength(img->FilePath) <= - sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0; - if (!addprog) { - /* XXX todo. */ - } - } - /* Part 2: count words. */ - argc = (addprog) ? 1 : 0; - argp = args; - while (argp != NULL && *argp != 0) { - argp = arg_skipsep(argp); - if (*argp == 0) - break; - argc++; - argp = arg_skipword(argp); - } - /* Part 3: build vector. */ - argv = malloc((argc + 1) * sizeof(CHAR16*)); - argc = 0; - if (addprog) - argv[argc++] = (CHAR16 *)L"loader.efi"; - argp = args; - while (argp != NULL && *argp != 0) { - argp = arg_skipsep(argp); - if (*argp == 0) - break; - argv[argc++] = argp; - argp = arg_skipword(argp); - /* Terminate the words. */ - if (*argp != 0) - *argp++ = 0; - } - argv[argc] = NULL; - - status = main(argc, argv); - exit(status); -}
--- a/usr/src/boot/sys/boot/efi/loader/Makefile Wed Jan 24 16:20:33 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/loader/Makefile Tue Dec 12 13:08:57 2017 +0200 @@ -26,10 +26,10 @@ MACHINE= $(MACH64) # architecture-specific loader code -SRCS= autoload.c bootinfo.c conf.c copy.c devicename.c main.c self_reloc.c \ - smbios.c acpi.c vers.c memmap.c multiboot2.c -OBJS= autoload.o bootinfo.o conf.o copy.o devicename.o main.o self_reloc.o \ - smbios.o acpi.o vers.o memmap.o multiboot2.o +SRCS= autoload.c bootinfo.c conf.c copy.c devicename.c efi_main.c main.c \ + self_reloc.c smbios.c acpi.c vers.c memmap.c multiboot2.c +OBJS= autoload.o bootinfo.o conf.o copy.o devicename.o efi_main.o main.o \ + self_reloc.o smbios.o acpi.o vers.o memmap.o multiboot2.o ASFLAGS=-m64 -fPIC CFLAGS= -O2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/boot/sys/boot/efi/loader/efi_main.c Tue Dec 12 13:08:57 2017 +0200 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2000 Doug Rabson + * 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> + +#include <efi.h> +#include <eficonsctl.h> +#include <efilib.h> +#include <stand.h> + +static EFI_PHYSICAL_ADDRESS heap; +static UINTN heapsize; + +void +efi_exit(EFI_STATUS exit_code) +{ + + BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); + BS->Exit(IH, exit_code, 0, NULL); +} + +void +exit(int status) +{ + + efi_exit(EFI_LOAD_ERROR); +} + +static CHAR16 * +arg_skipsep(CHAR16 *argp) +{ + + while (*argp == ' ' || *argp == '\t' || *argp == '\n') + argp++; + return (argp); +} + +static CHAR16 * +arg_skipword(CHAR16 *argp) +{ + + while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n') + argp++; + return (argp); +} + +EFI_STATUS +efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) +{ + static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL; + static EFI_GUID console_control_protocol = + EFI_CONSOLE_CONTROL_PROTOCOL_GUID; + EFI_CONSOLE_CONTROL_PROTOCOL *console_control = NULL; + EFI_LOADED_IMAGE *img; + CHAR16 *argp, *args, **argv; + EFI_STATUS status; + SIMPLE_TEXT_OUTPUT_INTERFACE *conout; + UINTN i, max_dim, best_mode, cols, rows; + int argc, addprog; + + IH = image_handle; + ST = system_table; + BS = ST->BootServices; + RS = ST->RuntimeServices; + + status = BS->LocateProtocol(&console_control_protocol, NULL, + (VOID **)&console_control); + if (status == EFI_SUCCESS) + (void)console_control->SetMode(console_control, + EfiConsoleControlScreenText); + + conout = ST->ConOut; + max_dim = best_mode = 0; + for (i = 0; i <= conout->Mode->MaxMode ; i++) { + status = conout->QueryMode(conout, i, &cols, &rows); + if (EFI_ERROR(status)) + continue; + if (cols * rows > max_dim) { + max_dim = cols * rows; + best_mode = i; + } + } + if (max_dim > 0) + conout->SetMode(conout, best_mode); + + heapsize = 64 * 1024 * 1024; + /* 4GB upper limit, try to leave some space from 1MB */ + heap = 0x0000000100000000; + status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, + EFI_SIZE_TO_PAGES(heapsize), &heap); + if (status != EFI_SUCCESS) + BS->Exit(IH, status, 0, NULL); + + setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize)); + + status = conout->QueryMode(conout, best_mode, &cols, &rows); + if (EFI_ERROR(status)) { + setenv("LINES", "24", 1); + setenv("COLUMNS", "80", 1); + } else { + char buf[8]; + snprintf(buf, sizeof (buf), "%u", (unsigned)rows); + setenv("LINES", buf, 1); + snprintf(buf, sizeof (buf), "%u", (unsigned)cols); + setenv("COLUMNS", buf, 1); + } + + /* Use efi_exit() from here on... */ + + status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img); + if (status != EFI_SUCCESS) + efi_exit(status); + + /* + * Pre-process the (optional) load options. If the option string + * is given as an ASCII string, we use a poor man's ASCII to + * Unicode-16 translation. The size of the option string as given + * to us includes the terminating null character. We assume the + * string is an ASCII string if strlen() plus the terminating + * '\0' is less than LoadOptionsSize. Even if all Unicode-16 + * characters have the upper 8 bits non-zero, the terminating + * null character will cause a one-off. + * If the string is already in Unicode-16, we make a copy so that + * we know we can always modify the string. + */ + if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { + if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { + args = malloc(img->LoadOptionsSize << 1); + for (argc = 0; argc < (int)img->LoadOptionsSize; argc++) + args[argc] = ((char*)img->LoadOptions)[argc]; + } else { + args = malloc(img->LoadOptionsSize); + memcpy(args, img->LoadOptions, img->LoadOptionsSize); + } + } else + args = NULL; + + /* + * Use a quick and dirty algorithm to build the argv vector. We + * first count the number of words. Then, after allocating the + * vector, we split the string up. We don't deal with quotes or + * other more advanced shell features. + * The EFI shell will pass the name of the image as the first + * word in the argument list. This does not happen if we're + * loaded by the boot manager. This is not so easy to figure + * out though. The ParentHandle is not always NULL, because + * there can be a function (=image) that will perform the task + * for the boot manager. + */ + /* Part 1: Figure out if we need to add our program name. */ + addprog = (args == NULL || img->ParentHandle == NULL || + img->FilePath == NULL) ? 1 : 0; + if (!addprog) { + addprog = + (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || + DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || + DevicePathNodeLength(img->FilePath) <= + sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0; + if (!addprog) { + /* XXX todo. */ + } + } + /* Part 2: count words. */ + argc = (addprog) ? 1 : 0; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argc++; + argp = arg_skipword(argp); + } + /* Part 3: build vector. */ + argv = malloc((argc + 1) * sizeof(CHAR16*)); + argc = 0; + if (addprog) + argv[argc++] = (CHAR16 *)L"loader.efi"; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argv[argc++] = argp; + argp = arg_skipword(argp); + /* Terminate the words. */ + if (*argp != 0) + *argp++ = 0; + } + argv[argc] = NULL; + + status = main(argc, argv); + efi_exit(status); + return (status); +}