pax_global_header00006660000000000000000000000064117261041450014513gustar00rootroot0000000000000052 comment=75b62111f83dab433e901c1a7b0f05e058aa29de mfleming-efilinux-ee4479c/000077500000000000000000000000001172610414500155605ustar00rootroot00000000000000mfleming-efilinux-ee4479c/.gitignore000066400000000000000000000000451172610414500175470ustar00rootroot00000000000000*.o *.so *.efi *GTAGS *GPATH *GRTAGS mfleming-efilinux-ee4479c/Makefile000066400000000000000000000056051172610414500172260ustar00rootroot00000000000000# # Copyright (c) 2011, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * 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. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 # COPYRIGHT OWNER 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. # %.efi: %.so $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \ -j .rela -j .reloc --target=$(FORMAT) $*.so $@ OBJCOPY=objcopy HOST = $(shell $(CC) -dumpmachine | sed "s/\(-\).*$$//") ARCH := $(shell $(CC) -dumpmachine | sed "s/\(-\).*$$//") ifeq ($(ARCH),x86_64) LIBDIR=/usr/lib64 FORMAT=efi-app-x86-64 else ARCH=ia32 LIBDIR=/usr/lib FORMAT=efi-app-$(ARCH) endif INCDIR := /usr/include # gnuefi sometimes installs these under a gnuefi/ directory, and sometimes not CRT0 := $(shell find $(LIBDIR) -name crt0-efi-$(ARCH).o 2>/dev/null | tail -n1) LDSCRIPT := $(shell find $(LIBDIR) -name elf_$(ARCH)_efi.lds 2>/dev/null | tail -n1) CFLAGS=-I. -I$(INCDIR)/efi -I$(INCDIR)/efi/$(ARCH) \ -DEFI_FUNCTION_WRAPPER -fPIC -fshort-wchar -ffreestanding \ -Wall -Ifs/ -Iloaders/ -D$(ARCH) -Werror ifeq ($(ARCH),ia32) ifeq ($(HOST),x86_64) CFLAGS += -m32 endif endif LDFLAGS=-T $(LDSCRIPT) -Bsymbolic -shared -nostdlib -znocombreloc \ -L$(LIBDIR) $(CRT0) IMAGE=efilinux.efi OBJS = entry.o malloc.o FS = fs/fs.o LOADERS = loaders/loader.o \ loaders/bzimage/bzimage.o \ loaders/bzimage/graphics.o all: $(IMAGE) efilinux.efi: efilinux.so efilinux.so: $(OBJS) $(FS) $(LOADERS) $(LD) $(LDFLAGS) -o $@ $^ -lgnuefi -lefi $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) clean: rm -f $(IMAGE) efilinux.so $(OBJS) $(FS) $(LOADERS) mfleming-efilinux-ee4479c/README000066400000000000000000000007321172610414500164420ustar00rootroot00000000000000 efilinux - A UEFI bootloader efilinux is a UEFI OS loader. It was created as a reference implementation with the aim of being well documented and containing well written source code. gnu-efi is required to build efilinux. The latest development version of efilinux can be found at, git://git.kernel.org/pub/scm/boot/efilinux/efilinux.git Stable versions can be found at, http://www.kernel.org/pub/linux/boot/efilinux/ Matt Fleming mfleming-efilinux-ee4479c/efilinux.h000066400000000000000000000174021172610414500175600ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. * * This file contains some wrappers around the gnu-efi functions. As * we're not going through uefi_call_wrapper() directly, this allows * us to get some type-safety for function call arguments and for the * compiler to check that the number of function call arguments is * correct. * * It's also a good place to document the EFI interface. */ #ifndef __EFILINUX_H__ #define __EFILINUX_H__ #define EFILINUX_VERSION_MAJOR 1 #define EFILINUX_VERSION_MINOR 0 #define EFILINUX_CONFIG L"efilinux.cfg" extern EFI_SYSTEM_TABLE *sys_table; extern EFI_BOOT_SERVICES *boot; extern EFI_RUNTIME_SERVICES *runtime; /** * allocate_pages - Allocate memory pages from the system * @atype: type of allocation to perform * @mtype: type of memory to allocate * @num_pages: number of contiguous 4KB pages to allocate * @memory: used to return the address of allocated pages * * Allocate @num_pages physically contiguous pages from the system * memory and return a pointer to the base of the allocation in * @memory if the allocation succeeds. On success, the firmware memory * map is updated accordingly. * * If @atype is AllocateAddress then, on input, @memory specifies the * address at which to attempt to allocate the memory pages. */ static inline EFI_STATUS allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype, UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory) { return uefi_call_wrapper(boot->AllocatePages, 4, atype, mtype, num_pages, memory); } /** * free_pages - Return memory allocated by allocate_pages() to the firmware * @memory: physical base address of the page range to be freed * @num_pages: number of contiguous 4KB pages to free * * On success, the firmware memory map is updated accordingly. */ static inline EFI_STATUS free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages) { return uefi_call_wrapper(boot->FreePages, 2, memory, num_pages); } /** * allocate_pool - Allocate pool memory * @type: the type of pool to allocate * @size: number of bytes to allocate from pool of @type * @buffer: used to return the address of allocated memory * * Allocate memory from pool of @type. If the pool needs more memory * pages are allocated from EfiConventionalMemory in order to grow the * pool. * * All allocations are eight-byte aligned. */ static inline EFI_STATUS allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer) { return uefi_call_wrapper(boot->AllocatePool, 3, type, size, buffer); } /** * free_pool - Return pool memory to the system * @buffer: the buffer to free * * Return @buffer to the system. The returned memory is marked as * EfiConventionalMemory. */ static inline EFI_STATUS free_pool(void *buffer) { return uefi_call_wrapper(boot->FreePool, 1, buffer); } /** * get_memory_map - Return the current memory map * @size: the size in bytes of @map * @map: buffer to hold the current memory map * @key: used to return the key for the current memory map * @descr_size: used to return the size in bytes of EFI_MEMORY_DESCRIPTOR * @descr_version: used to return the version of EFI_MEMORY_DESCRIPTOR * * Get a copy of the current memory map. The memory map is an array of * EFI_MEMORY_DESCRIPTORs. An EFI_MEMORY_DESCRIPTOR describes a * contiguous block of memory. * * On success, @key is updated to contain an identifer for the current * memory map. The firmware's key is changed every time something in * the memory map changes. @size is updated to indicate the size of * the memory map pointed to by @map. * * @descr_size and @descr_version are used to ensure backwards * compatibility with future changes made to the EFI_MEMORY_DESCRIPTOR * structure. @descr_size MUST be used when the size of an * EFI_MEMORY_DESCRIPTOR is used in a calculation, e.g when iterating * over an array of EFI_MEMORY_DESCRIPTORs. * * On failure, and if the buffer pointed to by @map is too small to * hold the memory map, EFI_BUFFER_TOO_SMALL is returned and @size is * updated to reflect the size of a buffer required to hold the memory * map. */ static inline EFI_STATUS get_memory_map(UINTN *size, EFI_MEMORY_DESCRIPTOR *map, UINTN *key, UINTN *descr_size, UINT32 *descr_version) { return uefi_call_wrapper(boot->GetMemoryMap, 5, size, map, key, descr_size, descr_version); } /** * exit_boot_serivces - Terminate all boot services * @image: firmware-allocated handle that identifies the image * @key: key to the latest memory map * * This function is called when efilinux wants to take complete * control of the system. efilinux should not make calls to boot time * services after this function is called. */ static inline EFI_STATUS exit_boot_services(EFI_HANDLE image, UINTN key) { return uefi_call_wrapper(boot->ExitBootServices, 2, image, key); } /** * exit - Terminate a loaded EFI image * @image: firmware-allocated handle that identifies the image * @status: the image's exit code * @size: size in bytes of @reason. Ignored if @status is EFI_SUCCESS * @reason: a NUL-terminated status string, optionally followed by binary data * * This function terminates @image and returns control to the boot * services. This function MUST NOT be called until all loaded child * images have exited. All memory allocated by the image must be freed * before calling this function, apart from the buffer @reason, which * will be freed by the firmware. */ static inline EFI_STATUS exit(EFI_HANDLE image, EFI_STATUS status, UINTN size, CHAR16 *reason) { return uefi_call_wrapper(boot->Exit, 4, image, status, size, reason); } #define PAGE_SIZE 4096 static const CHAR16 *memory_types[] = { L"EfiReservedMemoryType", L"EfiLoaderCode", L"EfiLoaderData", L"EfiBootServicesCode", L"EfiBootServicesData", L"EfiRuntimeServicesCode", L"EfiRuntimeServicesData", L"EfiConventionalMemory", L"EfiUnusableMemory", L"EfiACPIReclaimMemory", L"EfiACPIMemoryNVS", L"EfiMemoryMappedIO", L"EfiMemoryMappedIOPortSpace", L"EfiPalCode", }; static inline const CHAR16 *memory_type_to_str(UINT32 type) { if (type > sizeof(memory_types)/sizeof(CHAR16 *)) return L"Unknown"; return memory_types[type]; } extern EFI_STATUS memory_map(EFI_MEMORY_DESCRIPTOR **map_buf, UINTN *map_size, UINTN *map_key, UINTN *desc_size, UINT32 *desc_version); #endif /* __EFILINUX_H__ */ mfleming-efilinux-ee4479c/entry.c000066400000000000000000000253321172610414500170720ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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 #include #include "efilinux.h" #include "fs.h" #include "protocol.h" #include "loader.h" #include "stdlib.h" #define ERROR_STRING_LENGTH 32 static CHAR16 *banner = L"efilinux loader %d.%d\n"; EFI_SYSTEM_TABLE *sys_table; EFI_BOOT_SERVICES *boot; EFI_RUNTIME_SERVICES *runtime; /** * memory_map - Allocate and fill out an array of memory descriptors * @map_buf: buffer containing the memory map * @map_size: size of the buffer containing the memory map * @map_key: key for the current memory map * @desc_size: size of the desc * @desc_version: memory descriptor version * * On success, @map_size contains the size of the memory map pointed * to by @map_buf and @map_key, @desc_size and @desc_version are * updated. */ EFI_STATUS memory_map(EFI_MEMORY_DESCRIPTOR **map_buf, UINTN *map_size, UINTN *map_key, UINTN *desc_size, UINT32 *desc_version) { EFI_STATUS err; *map_size = sizeof(**map_buf) * 31; get_map: /* * Because we're about to allocate memory, we may * potentially create a new memory descriptor, thereby * increasing the size of the memory map. So increase * the buffer size by the size of one memory * descriptor, just in case. */ *map_size += sizeof(**map_buf); err = allocate_pool(EfiLoaderData, *map_size, (void **)map_buf); if (err != EFI_SUCCESS) { Print(L"Failed to allocate pool for memory map"); goto failed; } err = get_memory_map(map_size, *map_buf, map_key, desc_size, desc_version); if (err != EFI_SUCCESS) { if (err == EFI_BUFFER_TOO_SMALL) { /* * 'map_size' has been updated to reflect the * required size of a map buffer. */ free_pool((void *)*map_buf); goto get_map; } Print(L"Failed to get memory map"); goto failed; } failed: return err; } static EFI_STATUS print_memory_map(void) { EFI_MEMORY_DESCRIPTOR *buf; UINTN desc_size; UINT32 desc_version; UINTN size, map_key; EFI_MEMORY_DESCRIPTOR *desc; EFI_STATUS err; int i; err = memory_map(&buf, &size, &map_key, &desc_size, &desc_version); if (err != EFI_SUCCESS) return err; Print(L"System Memory Map\n"); Print(L"System Memory Map Size: %d\n", size); Print(L"Descriptor Version: %d\n", desc_version); Print(L"Descriptor Size: %d\n", desc_size); desc = buf; i = 0; while ((void *)desc < (void *)buf + size) { UINTN mapping_size; mapping_size = desc->NumberOfPages * PAGE_SIZE; Print(L"[#%.2d] Type: %s\n", i, memory_type_to_str(desc->Type)); Print(L" Attr: 0x%016llx\n", desc->Attribute); Print(L" Phys: [0x%016llx - 0x%016llx]\n", desc->PhysicalStart, desc->PhysicalStart + mapping_size); Print(L" Virt: [0x%016llx - 0x%016llx]", desc->VirtualStart, desc->VirtualStart + mapping_size); Print(L"\n"); desc = (void *)desc + desc_size; i++; } free_pool(buf); return err; } static inline BOOLEAN isspace(CHAR16 ch) { return ((unsigned char)ch <= ' '); } static EFI_STATUS parse_args(CHAR16 *options, UINT32 size, CHAR16 **name, char **cmdline) { CHAR16 *n, *o, *filename = NULL; EFI_STATUS err; int i = 0; *cmdline = NULL; *name = NULL; /* Skip whitespace */ for (i = 0; i < size && isspace(options[i]); i++) ; /* No arguments */ if (i == size) goto usage; n = &options[i]; while (n <= &options[size]) { if (*n == '-') { switch (*++n) { case 'h': goto usage; case 'f': n++; /* Skip 'f' */ /* Skip whitespace */ while (isspace(*n)) n++; filename = n; i = 0; while (*n && !isspace(*n)) { i++; n++; } *n++ = '\0'; o = malloc(sizeof(*o) * (i + 1)); if (!o) { Print(L"Unable to alloc filename memory\n"); err = EFI_OUT_OF_RESOURCES; goto out; } o[i--] = '\0'; StrCpy(o, filename); *name = o; break; case 'l': list_boot_devices(); goto fail; case 'm': print_memory_map(); n++; goto fail; default: Print(L"Unknown command-line switch\n"); goto usage; } } else { char *s1; CHAR16 *s2; int j; j = StrLen(n); *cmdline = malloc(j + 1); if (!*cmdline) { Print(L"Unable to alloc cmdline memory\n"); err = EFI_OUT_OF_RESOURCES; goto free_name; } s1 = *cmdline; s2 = n; while (j--) *s1++ = *s2++; *s1 = '\0'; /* Consume the rest of the args */ n = &options[size] + 1; } } if (filename) return EFI_SUCCESS; usage: Print(L"usage: efilinux [-hlm] -f \n\n"); Print(L"\t-h: display this help menu\n"); Print(L"\t-l: list boot devices\n"); Print(L"\t-m: print memory map\n"); Print(L"\t-f : image to load\n"); fail: err = EFI_INVALID_PARAMETER; if (*cmdline) free(*cmdline); free_name: if (*name) free(*name); out: return err; } static inline BOOLEAN get_path(EFI_LOADED_IMAGE *image, CHAR16 *path, UINTN len) { CHAR16 *buf, *p, *q; int i, dev; dev = handle_to_dev(image->DeviceHandle); if (dev == -1) { Print(L"Couldn't find boot device handle\n"); return FALSE; } /* Find the path of the efilinux executable*/ p = DevicePathToStr(image->FilePath); q = p + StrLen(p); i = StrLen(p); while (*q != '\\' && *q != '/') { q--; i--; } buf = malloc(i * sizeof(CHAR16)); if (!buf) { Print(L"Failed to allocate buf\n"); FreePool(p); return FALSE; } memcpy((char *)buf, (char *)p, i * sizeof(CHAR16)); FreePool(p); buf[i] = '\0'; SPrint(path, len, L"%d:%s\\%s", dev, buf, EFILINUX_CONFIG); return TRUE; } static BOOLEAN read_config_file(EFI_LOADED_IMAGE *image, CHAR16 **options, UINT32 *options_size) { struct file *file; EFI_STATUS err; CHAR16 path[4096]; CHAR16 *u_buf, *q; char *a_buf, *p; UINT64 size; int i; err = get_path(image, path, sizeof(path)); if (err != TRUE) return FALSE; err = file_open(path, &file); if (err != EFI_SUCCESS) return FALSE; err = file_size(file, &size); if (err != EFI_SUCCESS) goto fail; /* * The config file contains ASCII characters, but the command * line parser expects arguments to be UTF-16. Convert them * once we've read them into 'a_buf'. */ /* Make sure we don't overflow the UINT32 */ if (size > 0xffffffff || (size * 2) > 0xffffffff ) { Print(L"Config file size too large. Ignoring.\n"); goto fail; } a_buf = malloc((UINTN)size); if (!a_buf) { Print(L"Failed to alloc buffer %d bytes\n", size); goto fail; } u_buf = malloc((UINTN)size * 2); if (!u_buf) { Print(L"Failed to alloc buffer %d bytes\n", size); free(a_buf); goto fail; } err = file_read(file, (UINTN *)&size, a_buf); if (err != EFI_SUCCESS) goto fail; Print(L"Using efilinux config file\n"); /* * Read one line. Stamp a NUL-byte into the buffer once we've * read the end of the first line. */ for (p = a_buf, i = 0; *p && *p != '\n' && i < size; p++, i++) ; if (*p == '\n') *p++ = '\0'; if (i == size && *p) { Print(L"Error: missing newline at end of config file?\n"); goto fail; } if ((p - a_buf) < size) Print(L"Warning: config file contains multiple lines?\n"); p = a_buf; q = u_buf; for (i = 0; i < size; i++) *q++ = *p++; free(a_buf); *options = u_buf; *options_size = (UINT32)size * 2; file_close(file); return TRUE; fail: file_close(file); return FALSE; } /** * efi_main - The entry point for the OS loader image. * @image: firmware-allocated handle that identifies the image * @sys_table: EFI system table */ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) { WCHAR *error_buf; EFI_STATUS err; EFI_LOADED_IMAGE *info; CHAR16 *name, *options; UINT32 options_size; char *cmdline; InitializeLib(image, _table); sys_table = _table; boot = sys_table->BootServices; runtime = sys_table->RuntimeServices; if (CheckCrc(sys_table->Hdr.HeaderSize, &sys_table->Hdr) != TRUE) return EFI_LOAD_ERROR; Print(banner, EFILINUX_VERSION_MAJOR, EFILINUX_VERSION_MINOR); err = fs_init(); if (err != EFI_SUCCESS) goto failed; err = handle_protocol(image, &LoadedImageProtocol, (void **)&info); if (err != EFI_SUCCESS) goto fs_deinit; if (!read_config_file(info, &options, &options_size)) { int i; options = info->LoadOptions; options_size = info->LoadOptionsSize; /* Skip the first word, that's our name. */ for (i = 0; i < options_size && options[i] != ' '; i++) ; options = &options[i]; options_size -= i; } if (options && options_size != 0) { err = parse_args(options, options_size, &name, &cmdline); /* We print the usage message in case of invalid args */ if (err == EFI_INVALID_PARAMETER) { fs_exit(); return EFI_SUCCESS; } if (err != EFI_SUCCESS) goto fs_deinit; } err = load_image(image, name, cmdline); if (err != EFI_SUCCESS) goto free_args; return EFI_SUCCESS; free_args: free(cmdline); free(name); fs_deinit: fs_exit(); failed: /* * We need to be careful not to trash 'err' here. If we fail * to allocate enough memory to hold the error string fallback * to returning 'err'. */ if (allocate_pool(EfiLoaderData, ERROR_STRING_LENGTH, (void **)&error_buf) != EFI_SUCCESS) { Print(L"Couldn't allocate pages for error string\n"); return err; } StatusToString(error_buf, err); Print(L": %s\n", error_buf); return exit(image, err, ERROR_STRING_LENGTH, error_buf); } mfleming-efilinux-ee4479c/fs/000077500000000000000000000000001172610414500161705ustar00rootroot00000000000000mfleming-efilinux-ee4479c/fs/fs.c000066400000000000000000000132061172610414500167460ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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 #include #include "efilinux.h" #include "fs.h" #include "stdlib.h" #include "protocol.h" struct fs_device { EFI_HANDLE handle; EFI_FILE_HANDLE fh; struct fs_ops *ops; }; static struct fs_device *fs_devices; static UINTN nr_fs_devices; /** * handle_to_dev - Return the device number for a handle * @handle: the device handle to search for */ int handle_to_dev(EFI_HANDLE *handle) { int i; for (i = 0; i < nr_fs_devices; i++) { if (fs_devices[i].handle == handle) break; } if (i == nr_fs_devices) return -1; return i; } /** * file_open - Open a file on a volume * @name: pathname of the file to open * @file: used to return a pointer to the allocated file on success */ EFI_STATUS file_open(CHAR16 *name, struct file **file) { EFI_FILE_HANDLE fh; struct file *f; CHAR16 *filename; EFI_STATUS err; int dev_len; int i; f = malloc(sizeof(*f)); if (!f) return EFI_OUT_OF_RESOURCES; for (dev_len = 0; name[dev_len]; ++dev_len) { if (name[dev_len] == ':') break; } if (!name[dev_len] || !dev_len) goto notfound; name[dev_len] = 0; if (name[0] >= '0' && name[0] <= '9') { i = Atoi(name); if (i >= nr_fs_devices) goto notfound; f->handle = fs_devices[i].fh; goto found; } for (i = 0; i < nr_fs_devices; i++) { EFI_DEVICE_PATH *path; CHAR16 *dev; path = DevicePathFromHandle(fs_devices[i].handle); dev = DevicePathToStr(path); if (!StriCmp(dev, name)) { f->handle = fs_devices[i].fh; free_pool(dev); break; } free_pool(dev); } if (i == nr_fs_devices) goto notfound; found: /* Strip the device name */ filename = name + dev_len + 1; /* skip any path separators */ while (*filename == ':' || *filename == '\\') filename++; err = uefi_call_wrapper(f->handle->Open, 5, f->handle, &fh, filename, EFI_FILE_MODE_READ, (UINT64)0); if (err != EFI_SUCCESS) goto fail; f->fh = fh; *file = f; return err; notfound: err = EFI_NOT_FOUND; fail: free(f); return err; } /** * file_close - Close a file handle * @f: the file to close */ EFI_STATUS file_close(struct file *f) { UINTN err; err = uefi_call_wrapper(f->handle->Close, 1, f->fh); if (err == EFI_SUCCESS) free(f); return err; } /** * list_boot_devices - Print a list of all disks with filesystems */ void list_boot_devices(void) { int i; Print(L"Devices:\n\n"); for (i = 0; i < nr_fs_devices; i++) { EFI_DEVICE_PATH *path; EFI_HANDLE dev_handle; CHAR16 *dev; dev_handle = fs_devices[i].handle; path = DevicePathFromHandle(dev_handle); dev = DevicePathToStr(path); Print(L"\t%d. \"%s\"\n", i, dev); free_pool(dev); } Print(L"\n"); } /* * Initialise filesystem protocol. */ EFI_STATUS fs_init(void) { EFI_HANDLE *buf; EFI_STATUS err; UINTN size = 0; int i, j; size = 0; err = locate_handle(ByProtocol, &FileSystemProtocol, NULL, &size, NULL); if (err != EFI_SUCCESS && size == 0) { Print(L"No devices support filesystems\n"); return err; } buf = malloc(size); if (!buf) return EFI_OUT_OF_RESOURCES; nr_fs_devices = size / sizeof(EFI_HANDLE); fs_devices = malloc(sizeof(*fs_devices) * nr_fs_devices); if (!fs_devices) { err = EFI_OUT_OF_RESOURCES; goto out; } err = locate_handle(ByProtocol, &FileSystemProtocol, NULL, &size, (void **)buf); for (i = 0; i < nr_fs_devices; i++) { EFI_FILE_IO_INTERFACE *io; EFI_FILE_HANDLE fh; EFI_HANDLE dev_handle; dev_handle = buf[i]; err = handle_protocol(dev_handle, &FileSystemProtocol, (void **)&io); if (err != EFI_SUCCESS) goto close_handles; err = volume_open(io, &fh); if (err != EFI_SUCCESS) goto close_handles; fs_devices[i].handle = dev_handle; fs_devices[i].fh = fh; } out: free(buf); return err; close_handles: for (j = 0; j < i; j++) { EFI_FILE_HANDLE fh; fh = fs_devices[j].fh; uefi_call_wrapper(fh->Close, 1, fh); } free(fs_devices); goto out; } void fs_close(void) { int i; for (i = 0; i < nr_fs_devices; i++) { EFI_FILE_HANDLE fh; fh = fs_devices[i].fh; uefi_call_wrapper(fh->Close, 1, fh); } } void fs_exit(void) { fs_close(); free(fs_devices); } mfleming-efilinux-ee4479c/fs/fs.h000066400000000000000000000063731172610414500167620ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. * */ #ifndef __FS_H__ #define __FS_H__ #define MAX_FILENAME 256 struct file { EFI_FILE_HANDLE handle; EFI_FILE_HANDLE fh; }; /** * volume_open - Open the root directory on a volume * @vol: the volume to open * @fh: place to return the open file handle for the root directory */ static inline EFI_STATUS volume_open(EFI_FILE_IO_INTERFACE *vol, EFI_FILE_HANDLE *fh) { return uefi_call_wrapper(vol->OpenVolume, 2, vol, fh); } /** * file_read - Read from an open file * @f: the file to read * @size: size in bytes to read from @f * @buf: place to store the data read */ static inline EFI_STATUS file_read(struct file *f, UINTN *size, void *buf) { return uefi_call_wrapper(f->handle->Read, 3, f->fh, size, buf); } /** * file_set_position - Set the current offset of a file * @f: the file on which we're changing current file position * @pos: the file offset to set the current position to */ static inline EFI_STATUS file_set_position(struct file *f, UINT64 pos) { return uefi_call_wrapper(f->fh->SetPosition, 2, f->fh, pos); } /** * file_size - Get the size (in bytes) of @file * @f: the file to query * @size: where to store the size of the file */ static inline EFI_STATUS file_size(struct file *f, UINT64 *size) { EFI_FILE_INFO *info; info = LibFileInfo(f->fh); if (!info) return EFI_UNSUPPORTED; *size = info->FileSize; free_pool(info); return EFI_SUCCESS; } extern EFI_STATUS file_open(CHAR16 *name, struct file **file); extern EFI_STATUS file_close(struct file *f); extern void list_boot_devices(void); extern int handle_to_dev(EFI_HANDLE *handle); extern void fs_close(void); extern EFI_STATUS fs_init(void); extern void fs_exit(void); #endif /* __FS_H__ */ mfleming-efilinux-ee4479c/loaders/000077500000000000000000000000001172610414500172115ustar00rootroot00000000000000mfleming-efilinux-ee4479c/loaders/bzimage/000077500000000000000000000000001172610414500206275ustar00rootroot00000000000000mfleming-efilinux-ee4479c/loaders/bzimage/bzimage.c000066400000000000000000000254231172610414500224170ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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 #include #include "efilinux.h" #include "bzimage.h" #include "fs.h" #include "loader.h" #include "protocol.h" #include "stdlib.h" #ifdef x86_64 #include "x86_64.h" #else #include "i386.h" #endif dt_addr_t gdt = { 0x800, (UINT64 *)0 }; dt_addr_t idt = { 0, 0 }; struct initrd { UINT64 size; struct file *file; }; static void parse_initrd(struct boot_params *buf, char *cmdline) { EFI_PHYSICAL_ADDRESS addr; struct initrd *initrds; int nr_initrds; EFI_STATUS err; UINT64 size; char *initrd; int i, j; /* * Has there been an initrd specified on the cmdline? */ buf->hdr.ramdisk_start = 0; buf->hdr.ramdisk_len = 0; initrd = cmdline; for (nr_initrds = 0; *initrd; nr_initrds++) { initrd = strstr(initrd, "initrd="); if (!initrd) break; initrd += strlen("initrd="); /* Consume filename */ while (*initrd && *initrd != ' ') initrd++; /* Consume space */ while (*initrd == ' ') initrd++; } if (!nr_initrds) return; initrds = malloc(sizeof(*initrds) * nr_initrds); if (!initrds) return; initrd = cmdline; for (i = 0; i < nr_initrds; i++) { CHAR16 filename[MAX_FILENAME], *n; struct initrd *rd = &initrds[i]; struct file *rdfile; char *o, *p; initrd = strstr(initrd, "initrd="); if (!initrd) break; initrd += strlen("initrd="); p = initrd; while (*p && *p != ' ') p++; for (o = initrd, n = filename; o != p; o++, n++) *n = *o; *n = '\0'; err = file_open(filename, &rdfile); if (err != EFI_SUCCESS) goto close_handles; file_size(rdfile, &size); rd->size = size; rd->file = rdfile; buf->hdr.ramdisk_len += size; } size = buf->hdr.ramdisk_len; err = emalloc(size, 0x1000, &addr); if (err != EFI_SUCCESS) goto close_handles; if ((UINTN)addr > buf->hdr.ramdisk_max) { Print(L"ramdisk address is too high!\n"); efree(addr, size); goto close_handles; } buf->hdr.ramdisk_start = (UINT32)(UINTN)addr; for (j = 0; j < nr_initrds; j++) { struct initrd *rd = &initrds[j]; size = rd->size; err = file_read(rd->file, (UINTN *)&size, (void *)(UINTN)addr); if (err != EFI_SUCCESS) { efree(addr, size); goto close_handles; } addr += size; } close_handles: for (j = 0; j < i; j++) { struct initrd *rd = &initrds[j]; file_close(rd->file); } free(initrds); } /** * load_kernel - Load a kernel image into memory from the boot device */ EFI_STATUS load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline) { UINTN map_size, _map_size, map_key; EFI_PHYSICAL_ADDRESS kernel_start, addr; struct boot_params *boot_params; EFI_MEMORY_DESCRIPTOR *map_buf; struct e820_entry *e820_map; struct boot_params *buf; struct efi_info *efi; UINT32 desc_version; UINT8 nr_setup_secs; struct file *file; UINTN desc_size; EFI_STATUS err; UINTN size = 0; int i, j = 0; err = file_open(name, &file); if (err != EFI_SUCCESS) goto out; err = file_set_position(file, (UINT64)0x1F1); if (err != EFI_SUCCESS) goto out; size = 1; err = file_read(file, &size, &nr_setup_secs); if (err != EFI_SUCCESS) goto out; nr_setup_secs++; /* Add the boot sector */ size = nr_setup_secs * 512; buf = malloc(size); if (!buf) goto out; err = file_set_position(file, (UINT64)0); if (err != EFI_SUCCESS) goto out; err = file_read(file, &size, buf); if (err != EFI_SUCCESS) goto out; /* Check boot sector signature */ if (buf->hdr.signature != 0xAA55) { Print(L"bzImage kernel corrupt"); err = EFI_INVALID_PARAMETER; goto out; } if (buf->hdr.header != SETUP_HDR) { Print(L"Setup code version is invalid"); err = EFI_INVALID_PARAMETER; goto out; } /* * Which setup code version? * * We only support relocatable kernels which require a setup * code version >= 2.05. */ if (buf->hdr.version < 0x205) { Print(L"Setup code version unsupported (too old)"); err = EFI_INVALID_PARAMETER; goto out; } /* Don't need an allocated ID, we're a prototype */ buf->hdr.loader_id = 0x1; parse_initrd(buf, cmdline); buf->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline; memset((char *)&buf->screen_info, 0x0, sizeof(buf->screen_info)); err = setup_graphics(buf); if (err != EFI_SUCCESS) goto out; /* * Time to allocate our memory. * * Because the kernel needs to decompress itself we first * allocate boot_params, gdt and space for the memory map * under the assumption that they'll be allocated at lower * addresses than the kernel. If we dont't allocate these data * structures first there is the potential for them to be * trashed when the kernel is decompressed! Allocating them * underneath the kernel should be safe. * * Max kernel size is 8MB */ err = emalloc(16384, 1, &addr); if (err != EFI_SUCCESS) goto out; boot_params = (struct boot_params *)(UINTN)addr; memset((void *)boot_params, 0x0, 16384); /* Copy first two sectors to boot_params */ memcpy((char *)boot_params, (char *)buf, 2 * 512); err = emalloc(gdt.limit, 8, (EFI_PHYSICAL_ADDRESS *)&gdt.base); if (err != EFI_SUCCESS) goto out; memset((char *)gdt.base, 0x0, gdt.limit); /* * 4Gb - (0x100000*0x1000 = 4Gb) * base address=0 * code read/exec * granularity=4096, 386 (+5th nibble of limit) */ gdt.base[2] = 0x00cf9a000000ffff; /* * 4Gb - (0x100000*0x1000 = 4Gb) * base address=0 * data read/write * granularity=4096, 386 (+5th nibble of limit) */ gdt.base[3] = 0x00cf92000000ffff; /* Task segment value */ gdt.base[4] = 0x0080890000000000; /* We're just interested in the map's size for now */ map_size = 0; err = get_memory_map(&map_size, NULL, NULL, NULL, NULL); if (err != EFI_SUCCESS && err != EFI_BUFFER_TOO_SMALL) goto out; again: _map_size = map_size; err = emalloc(map_size, 1, &addr); if (err != EFI_SUCCESS) goto out; map_buf = (EFI_MEMORY_DESCRIPTOR *)(UINTN)addr; size = 0x800000; err = emalloc(size, buf->hdr.kernel_alignment, &kernel_start); if (err != EFI_SUCCESS) goto out; /* * If the firmware doesn't sort the memory map by increasing * address it's possible that kernel_start may have been * allocated below boot_params or gdt.base. * * Print a warning and hope for the best. */ if (kernel_start < (UINTN)boot_params || kernel_start < (UINTN)map_buf || kernel_start < (UINTN)gdt.base) Print(L"Warning: kernel_start is too low.\n"); /* * Read the rest of the kernel image. */ err = file_read(file, &size, (void *)(UINTN)kernel_start); if (err != EFI_SUCCESS) goto out; boot_params->hdr.code32_start = (UINT32)((UINT64)kernel_start); /* * Remember! We've already allocated map_buf with emalloc (and * 'map_size' contains its size) which means that it should be * positioned below our allocation for the kernel. Use that * space for the memory map. */ err = get_memory_map(&map_size, map_buf, &map_key, &desc_size, &desc_version); if (err != EFI_SUCCESS) { if (err == EFI_BUFFER_TOO_SMALL) { /* * Argh! The buffer that we allocated further * up wasn't large enough which means we need * to allocate them again, but this time * larger. 'map_size' has been updated by the * call to memory_map(). */ efree(kernel_start, 0x800000); efree((UINTN)map_buf, _map_size); file_set_position(file, (UINT64)nr_setup_secs * 512); goto again; } goto out; } /* Close all open file handles */ fs_close(); err = exit_boot_services(image, map_key); if (err != EFI_SUCCESS) goto out; efi = &boot_params->efi_info; efi->efi_systab = (UINT32)(UINTN)sys_table; efi->efi_memdesc_size = desc_size; efi->efi_memdesc_version = desc_version; efi->efi_memmap = (UINT32)(UINTN)map_buf; efi->efi_memmap_size = map_size; #ifdef x86_64 efi->efi_systab_hi = (unsigned long)sys_table >> 32; efi->efi_memmap_hi = (unsigned long)map_buf >> 32; #endif memcpy((char *)&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(UINT32)); boot_params->alt_mem_k = 32 * 1024; e820_map = &boot_params->e820_map[0]; /* * Convert the EFI memory map to E820. */ for (i = 0; i < map_size / desc_size; i++) { EFI_MEMORY_DESCRIPTOR *d; unsigned int e820_type = 0; d = (EFI_MEMORY_DESCRIPTOR *)((unsigned long)map_buf + (i * desc_size)); switch(d->Type) { case EfiReservedMemoryType: case EfiRuntimeServicesCode: case EfiRuntimeServicesData: case EfiMemoryMappedIO: case EfiMemoryMappedIOPortSpace: case EfiPalCode: e820_type = E820_RESERVED; break; case EfiUnusableMemory: e820_type = E820_UNUSABLE; break; case EfiACPIReclaimMemory: e820_type = E820_ACPI; break; case EfiLoaderCode: case EfiLoaderData: case EfiBootServicesCode: case EfiBootServicesData: case EfiConventionalMemory: e820_type = E820_RAM; break; case EfiACPIMemoryNVS: e820_type = E820_NVS; break; default: continue; } if (j && e820_map[j-1].type == e820_type && (e820_map[j-1].addr + e820_map[j-1].size) == d->PhysicalStart) { e820_map[j-1].size += d->NumberOfPages << EFI_PAGE_SHIFT; } else { e820_map[j].addr = d->PhysicalStart; e820_map[j].size = d->NumberOfPages << EFI_PAGE_SHIFT; e820_map[j].type = e820_type; j++; } } boot_params->e820_entries = j; asm volatile ("lidt %0" :: "m" (idt)); asm volatile ("lgdt %0" :: "m" (gdt)); kernel_jump(kernel_start, boot_params); out: return err; } struct loader bzimage_loader = { load_kernel, }; mfleming-efilinux-ee4479c/loaders/bzimage/bzimage.h000066400000000000000000000133511172610414500224210ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. */ #ifndef __BZIMAGE_H__ #define __BZIMAGE_H__ #define BOOTSIG 0x1FE #define SETUP_VERSION 0x206 #define SETUP_HDR 0x53726448 /* 0x53726448 == "HdrS" */ #define E820_RAM 1 #define E820_RESERVED 2 #define E820_ACPI 3 #define E820_NVS 4 #define E820_UNUSABLE 5 struct setup_header { UINT8 setup_secs; /* Sectors for setup code */ UINT16 root_flags; UINT32 sys_size; UINT16 ram_size; UINT16 video_mode; UINT16 root_dev; UINT16 signature; /* Boot signature */ UINT16 jump; UINT32 header; UINT16 version; UINT16 su_switch; UINT16 setup_seg; UINT16 start_sys; UINT16 kernel_ver; UINT8 loader_id; UINT8 load_flags; UINT16 movesize; UINT32 code32_start; /* Start of code loaded high */ UINT32 ramdisk_start; /* Start of initial ramdisk */ UINT32 ramdisk_len; /* Lenght of initial ramdisk */ UINT32 bootsect_kludge; UINT16 heap_end; UINT8 ext_loader_ver; /* Extended boot loader version */ UINT8 ext_loader_type; /* Extended boot loader ID */ UINT32 cmd_line_ptr; /* 32-bit pointer to the kernel command line */ UINT32 ramdisk_max; /* Highest legal initrd address */ UINT32 kernel_alignment; /* Physical addr alignment required for kernel */ UINT8 relocatable_kernel; /* Whether kernel is relocatable or not */ UINT8 _pad2[3]; UINT32 cmdline_size; UINT32 hardware_subarch; UINT64 hardware_subarch_data; UINT32 payload_offset; UINT32 payload_length; UINT64 setup_data; } __attribute__((packed)); struct efi_info { UINT32 efi_loader_signature; UINT32 efi_systab; UINT32 efi_memdesc_size; UINT32 efi_memdesc_version; UINT32 efi_memmap; UINT32 efi_memmap_size; UINT32 efi_systab_hi; UINT32 efi_memmap_hi; }; struct e820_entry { UINT64 addr; /* start of memory segment */ UINT64 size; /* size of memory segment */ UINT32 type; /* type of memory segment */ } __attribute__((packed)); struct screen_info { UINT8 orig_x; /* 0x00 */ UINT8 orig_y; /* 0x01 */ UINT16 ext_mem_k; /* 0x02 */ UINT16 orig_video_page; /* 0x04 */ UINT8 orig_video_mode; /* 0x06 */ UINT8 orig_video_cols; /* 0x07 */ UINT8 flags; /* 0x08 */ UINT8 unused2; /* 0x09 */ UINT16 orig_video_ega_bx;/* 0x0a */ UINT16 unused3; /* 0x0c */ UINT8 orig_video_lines; /* 0x0e */ UINT8 orig_video_isVGA; /* 0x0f */ UINT16 orig_video_points;/* 0x10 */ /* VESA graphic mode -- linear frame buffer */ UINT16 lfb_width; /* 0x12 */ UINT16 lfb_height; /* 0x14 */ UINT16 lfb_depth; /* 0x16 */ UINT32 lfb_base; /* 0x18 */ UINT32 lfb_size; /* 0x1c */ UINT16 cl_magic, cl_offset; /* 0x20 */ UINT16 lfb_linelength; /* 0x24 */ UINT8 red_size; /* 0x26 */ UINT8 red_pos; /* 0x27 */ UINT8 green_size; /* 0x28 */ UINT8 green_pos; /* 0x29 */ UINT8 blue_size; /* 0x2a */ UINT8 blue_pos; /* 0x2b */ UINT8 rsvd_size; /* 0x2c */ UINT8 rsvd_pos; /* 0x2d */ UINT16 vesapm_seg; /* 0x2e */ UINT16 vesapm_off; /* 0x30 */ UINT16 pages; /* 0x32 */ UINT16 vesa_attributes; /* 0x34 */ UINT32 capabilities; /* 0x36 */ UINT8 _reserved[6]; /* 0x3a */ } __attribute__((packed)); struct boot_params { struct screen_info screen_info; UINT8 apm_bios_info[0x14]; UINT8 _pad2[4]; UINT64 tboot_addr; UINT8 ist_info[0x10]; UINT8 _pad3[16]; UINT8 hd0_info[16]; UINT8 hd1_info[16]; UINT8 sys_desc_table[0x10]; UINT8 olpc_ofw_header[0x10]; UINT8 _pad4[128]; UINT8 edid_info[0x80]; struct efi_info efi_info; UINT32 alt_mem_k; UINT32 scratch; UINT8 e820_entries; UINT8 eddbuf_entries; UINT8 edd_mbr_sig_buf_entries; UINT8 _pad6[6]; struct setup_header hdr; UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; UINT32 edd_mbr_sig_buffer[16]; struct e820_entry e820_map[128]; UINT8 _pad8[48]; UINT8 eddbuf[0x1ec]; UINT8 _pad9[276]; }; typedef struct { UINT16 limit; UINT64 *base; } __attribute__((packed)) dt_addr_t; extern EFI_STATUS setup_graphics(struct boot_params *buf); #endif /* __BZIMAGE_H__ */ mfleming-efilinux-ee4479c/loaders/bzimage/graphics.c000066400000000000000000000120061172610414500225720ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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 #include #include "efilinux.h" #include "bzimage.h" #include "protocol.h" #include "stdlib.h" static void find_bits(unsigned long mask, UINT8 *pos, UINT8 *size) { UINT8 first, len; first = 0; len = 0; if (mask) { while (!(mask & 0x1)) { mask = mask >> 1; first++; } while (mask & 0x1) { mask = mask >> 1; len++; } } *pos = first; *size = len; } EFI_STATUS setup_graphics(struct boot_params *buf) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; EFI_GUID graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; EFI_HANDLE *gop_handle = NULL; struct screen_info *si; EFI_STATUS err; UINTN nr_gops; UINTN size; int i; /* See if we have graphics output protocol */ size = 0; err = locate_handle(ByProtocol, &graphics_proto, NULL, &size, (void **)gop_handle); if (err != EFI_SUCCESS && err != EFI_BUFFER_TOO_SMALL) goto out; gop_handle = malloc(size); if (!gop_handle) goto out; err = locate_handle(ByProtocol, &graphics_proto, NULL, &size, (void **)gop_handle); if (err != EFI_SUCCESS) goto out; nr_gops = size / sizeof(EFI_HANDLE); for (i = 0; i < nr_gops; i++) { EFI_HANDLE *h = &gop_handle[i]; err = handle_protocol(*h, &graphics_proto, (void **)&gop); if (err != EFI_SUCCESS) continue; err = uefi_call_wrapper(gop->QueryMode, 4, gop, gop->Mode->Mode, &size, &info); if (err == EFI_SUCCESS) break; } /* We found a GOP */ if (i != nr_gops) { si = &buf->screen_info; /* EFI framebuffer */ si->orig_video_isVGA = 0x70; si->orig_x = 0; si->orig_y = 0; si->orig_video_page = 0; si->orig_video_mode = 0; si->orig_video_cols = 0; si->orig_video_lines = 0; si->orig_video_ega_bx = 0; si->orig_video_points = 0; si->lfb_base = gop->Mode->FrameBufferBase; si->lfb_size = gop->Mode->FrameBufferSize; si->lfb_width = info->HorizontalResolution; si->lfb_height = info->VerticalResolution; si->pages = 1; si->vesapm_seg = 0; si->vesapm_off = 0; if (info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) { si->lfb_depth = 32; si->red_size = 8; si->red_pos = 0; si->green_size = 8; si->green_pos = 8; si->blue_size = 8; si->blue_pos = 16; si->rsvd_size = 8; si->rsvd_pos = 24; si->lfb_linelength = info->PixelsPerScanLine * 4; } else if (info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { si->lfb_depth = 32; si->red_size = 8; si->red_pos = 16; si->green_size = 8; si->green_pos = 8; si->blue_size = 8; si->blue_pos = 0; si->rsvd_size = 8; si->rsvd_pos = 24; si->lfb_linelength = info->PixelsPerScanLine * 4; } else if (info->PixelFormat == PixelBitMask) { find_bits(info->PixelInformation.RedMask, &si->red_pos, &si->red_size); find_bits(info->PixelInformation.GreenMask, &si->green_pos, &si->green_size); find_bits(info->PixelInformation.BlueMask, &si->blue_pos, &si->blue_size); find_bits(info->PixelInformation.ReservedMask, &si->rsvd_pos, &si->rsvd_size); si->lfb_depth = si->red_size + si->green_size + si->blue_size + si->rsvd_size; si->lfb_linelength = (info->PixelsPerScanLine * si->lfb_depth) / 8; } else { si->lfb_depth = 4; si->red_size = 0; si->red_pos = 0; si->green_size = 0; si->green_pos = 0; si->blue_size = 0; si->blue_pos = 0; si->rsvd_size = 0; si->rsvd_pos = 0; si->lfb_linelength = si->lfb_width / 2; } } out: return err; } mfleming-efilinux-ee4479c/loaders/bzimage/i386.h000066400000000000000000000037041172610414500214750ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. */ #ifndef __I386_H__ #define __I386_H__ #define EFI_LOADER_SIGNATURE "EL32" static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start, struct boot_params *boot_params) { asm volatile ("cli \n" "movl %0, %%esi \n" "movl %1, %%ecx \n" "jmp *%%ecx \n" :: "m" (boot_params), "m" (kernel_start)); } #endif /* __I386_H__ */ mfleming-efilinux-ee4479c/loaders/bzimage/x86_64.h000066400000000000000000000041631172610414500217420ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. */ #ifndef __X86_64_H__ #define __X86_64_H__ #define EFI_LOADER_SIGNATURE "EL64" typedef void(*kernel_func)(void *, struct boot_params *); static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start, struct boot_params *boot_params) { kernel_func kf; asm volatile ("cli"); /* The 64-bit kernel entry is 512 bytes after the start. */ kf = (kernel_func)kernel_start + 512; /* * The first parameter is a dummy because the kernel expects * boot_params in %[re]si. */ kf(NULL, boot_params); } #endif /* __X86_64_H__ */ mfleming-efilinux-ee4479c/loaders/loader.c000066400000000000000000000015141172610414500206240ustar00rootroot00000000000000#include #include "loader.h" extern struct loader bzimage_loader; struct loader *loaders[] = { &bzimage_loader, NULL, }; /** * load_image - Attempt to load a new image * @handle: firmware-allocated handle that identifies the efilinux image * @name: filename of the new image to load * @cmdline: ascii command-line argument * * Try all of the registered loaders to see if any of them want to * load @name. If a loader successfully loads @name, it may not return * control to load_image(), for example see the bzImage loader. */ EFI_STATUS load_image(EFI_HANDLE handle, CHAR16 *name, char *cmdline) { struct loader **loader; EFI_STATUS err; err = EFI_UNSUPPORTED; for (loader = loaders; *loader != NULL; loader++) { err = (*loader)->load(handle, name, cmdline); if (err == EFI_SUCCESS) break; } return err; } mfleming-efilinux-ee4479c/loaders/loader.h000066400000000000000000000035211172610414500206310ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. * */ #ifndef __LOADER_H__ #define __LOADER_H__ struct loader { EFI_STATUS (*load)(EFI_HANDLE, CHAR16 *, char *); }; extern struct loader *loaders[]; extern EFI_STATUS load_image(EFI_HANDLE image, CHAR16 *name, char *cmdline); #endif /* __LOADER_H__ */ mfleming-efilinux-ee4479c/malloc.c000066400000000000000000000077011172610414500172000ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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 #include #include "efilinux.h" /** * emalloc - Allocate memory with a strict alignment requirement * @size: size in bytes of the requested allocation * @align: the required alignment of the allocation * @addr: a pointer to the allocated address on success * * If we cannot satisfy @align we return 0. */ EFI_STATUS emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr) { UINTN map_size, map_key, desc_size; EFI_MEMORY_DESCRIPTOR *map_buf; UINTN d, map_end; UINT32 desc_version; EFI_STATUS err; UINTN nr_pages = EFI_SIZE_TO_PAGES(size); err = memory_map(&map_buf, &map_size, &map_key, &desc_size, &desc_version); if (err != EFI_SUCCESS) goto fail; d = (UINTN)map_buf; map_end = (UINTN)map_buf + map_size; for (; d < map_end; d += desc_size) { EFI_MEMORY_DESCRIPTOR *desc; EFI_PHYSICAL_ADDRESS start, end, aligned; desc = (EFI_MEMORY_DESCRIPTOR *)d; if (desc->Type != EfiConventionalMemory) continue; if (desc->NumberOfPages < nr_pages) continue; start = desc->PhysicalStart; end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT); /* Low-memory is super-precious! */ if (end <= 1 << 20) continue; if (start < 1 << 20) { size -= (1 << 20) - start; start = (1 << 20); } aligned = (start + align -1) & ~(align -1); if ((aligned + size) <= end) { err = allocate_pages(AllocateAddress, EfiLoaderData, nr_pages, &aligned); if (err == EFI_SUCCESS) { *addr = aligned; break; } } } if (d == map_end) err = EFI_OUT_OF_RESOURCES; free_pool(map_buf); fail: return err; } /** * efree - Return memory allocated with emalloc * @memory: the address of the emalloc() allocation * @size: the size of the allocation */ void efree(EFI_PHYSICAL_ADDRESS memory, UINTN size) { UINTN nr_pages = EFI_SIZE_TO_PAGES(size); free_pages(memory, nr_pages); } /** * malloc - Allocate memory from the EfiLoaderData pool * @size: size in bytes of the requested allocation * * Return a pointer to an allocation of @size bytes of type * EfiLoaderData. */ void *malloc(UINTN size) { EFI_STATUS err; void *buffer; err = allocate_pool(EfiLoaderData, size, &buffer); if (err != EFI_SUCCESS) buffer = NULL; return buffer; } /** * free - Release memory to the EfiLoaderData pool * @buffer: pointer to the malloc() allocation to free */ void free(void *buffer) { free_pool(buffer); } mfleming-efilinux-ee4479c/protocol.h000066400000000000000000000055401172610414500175760ustar00rootroot00000000000000/* * Copyright (c) 2011, Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 * COPYRIGHT OWNER 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. */ #ifndef __PROTOCOL_H__ #define __PROTOCOL_H__ /** * handle_protocol - Query @handle to see if it supports @protocol * @handle: the handle being queried * @protocol: the GUID of the protocol * @interface: used to return the protocol interface * * Query @handle to see if @protocol is supported. If it is supported, * @interface contains the protocol interface. */ static inline EFI_STATUS handle_protocol(EFI_HANDLE handle, EFI_GUID *protocol, void **interface) { return uefi_call_wrapper(boot->HandleProtocol, 3, handle, protocol, interface); } /** * locate_handle - Search for handles that support @protocol * @type: the search type, which handles are returned * @protocol: the protocol to search by (only valid if @type is ByProtocol) * @key: the search key * @size: on input the size in bytes of @buffer, on output the size of * the returned array or the required size to store the array * in @buffer if it was not large enough * @buffer: buffere where the array of handles is returned */ static inline EFI_STATUS locate_handle(EFI_LOCATE_SEARCH_TYPE type, EFI_GUID *protocol, void *key, UINTN *size, EFI_HANDLE *buffer) { return uefi_call_wrapper(boot->LocateHandle, 5, type, protocol, key, size, buffer); } #endif /* __PROTOCOL_H__ */ mfleming-efilinux-ee4479c/stdlib.h000066400000000000000000000015501172610414500172130ustar00rootroot00000000000000#ifndef __STDLIB_H__ #define __STDLIB_H__ extern void *malloc(UINTN size); extern void free(void *buf); extern EFI_STATUS emalloc(UINTN, UINTN, EFI_PHYSICAL_ADDRESS *); extern void efree(EFI_PHYSICAL_ADDRESS, UINTN); static inline void memset(char *dst, char ch, UINTN size) { int i; for (i = 0; i < size; i++) dst[i] = ch; } static inline void memcpy(char *dst, char *src, UINTN size) { int i; for (i = 0; i < size; i++) *dst++ = *src++; } static inline int strlen(char *str) { int len; len = 0; while (*str++) len++; return len; } static inline char *strstr(char *haystack, char *needle) { char *p; char *word = NULL; int len = strlen(needle); if (!len) return NULL; p = haystack; while (*p) { word = p; if (!strncmpa((CHAR8 *)p, (CHAR8 *)needle, len)) break; p++; word = NULL; } return word; } #endif /* __STDLIB_H__ */