aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGraeme Gregory <graeme.gregory@linaro.org>2013-09-25 17:11:20 +0100
committerGraeme Gregory <graeme.gregory@linaro.org>2013-09-25 17:11:20 +0100
commit882ad6f719d2fffca930b2dc8f820cd0a390f101 (patch)
tree6e39f714dff250d39d6c6438d85f050667583c31 /arch
parent62193f0a8fb44d1fad2858acfd7cb8d9f579ad15 (diff)
parenta8d253c2faf573319613a5154663e0d4fa09948b (diff)
Merge branch 'efi-stub-submitted-20130809-fixes' of git://git.linaro.org/people/roy.franz/linux into leg-kernel
Conflicts: arch/arm/Kconfig
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/boot/Makefile10
-rw-r--r--arch/arm/boot/compressed/Makefile17
-rw-r--r--arch/arm/boot/compressed/efi-header.S111
-rw-r--r--arch/arm/boot/compressed/efi-stub.c475
-rw-r--r--arch/arm/boot/compressed/efi-stub.h5
-rw-r--r--arch/arm/boot/compressed/head.S83
-rw-r--r--arch/arm/boot/compressed/string.c21
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/boot/compressed/eboot.c490
-rw-r--r--arch/x86/boot/compressed/eboot.h9
11 files changed, 750 insertions, 484 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e6cf288b6704..5913f21a3b63 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1894,6 +1894,17 @@ bool "UEFI runtime service support"
However, even with this option, the resultant kernel should
continue to boot on existing non-UEFI platforms.
+config EFI_STUB
+ bool "EFI stub support"
+ depends on !CPU_BIG_ENDIAN
+ ---help---
+ This kernel feature allows a zImage to be loaded directly
+ by EFI firmware without the use of a bootloader. A PE/COFF
+ header is added to the zImage in a way that makes the binary
+ both a Linux zImage and an PE/COFF executable that can be
+ executed directly by EFI firmware.
+ See Documentation/efi-stub.txt for more information.
+
config SECCOMP
bool
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 84aa2caf07ed..f1192f5ddbae 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -31,7 +31,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
$(call if_changed,objcopy)
- @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
+ @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' ' (#'`cat .version`')'
$(obj)/Image $(obj)/zImage: FORCE
@echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
@@ -46,14 +46,14 @@ $(obj)/xipImage: FORCE
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
- @$(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready' ' (#'`cat .version`')'
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
- @$(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready' ' (#'`cat .version`')'
endif
@@ -78,7 +78,7 @@ fi
$(obj)/uImage: $(obj)/zImage FORCE
@$(check_for_multiple_loadaddr)
$(call if_changed,uimage)
- @$(kecho) ' Image $@ is ready'
+ @$(kecho) ' Image $@ is ready' ' (#'`cat .version`')'
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(Q)$(MAKE) $(build)=$(obj)/bootp $@
@@ -86,7 +86,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
- @$(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready' ' (#'`cat .version`')'
PHONY += initrd FORCE
initrd:
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 7ac1610252ba..551dbf9c78ba 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -103,11 +103,22 @@ libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))
$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
$(call cmd,shipped)
-$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
+$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o efi-stub.o): \
$(addprefix $(obj)/,$(libfdt_hdrs))
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
-OBJS += $(libfdt_objs) atags_to_fdt.o
+OBJS += atags_to_fdt.o
+USE_LIBFDT = y
+endif
+
+ifeq ($(CONFIG_EFI_STUB),y)
+CFLAGS_efi-stub.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+OBJS += efi-stub.o
+USE_LIBFDT = y
+endif
+
+ifeq ($(USE_LIBFDT),y)
+OBJS += $(libfdt_objs)
endif
targets := vmlinux vmlinux.lds \
@@ -125,7 +136,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
-ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin -fno-stack-protector -I$(obj)
asflags-y := -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol.
diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S
new file mode 100644
index 000000000000..6965e0fd9d7d
--- /dev/null
+++ b/arch/arm/boot/compressed/efi-header.S
@@ -0,0 +1,111 @@
+@ Copyright (C) 2013 Linaro Ltd; <roy.franz@linaro.org>
+@
+@ This file contains the PE/COFF header that is part of the
+@ EFI stub.
+@
+
+ .org 0x3c
+ @
+ @ The PE header can be anywhere in the file, but for
+ @ simplicity we keep it together with the MSDOS header
+ @ The offset to the PE/COFF header needs to be at offset
+ @ 0x3C in the MSDOS header.
+ @ The only 2 fields of the MSDOS header that are used are this
+ @ PE/COFF offset, and the "MZ" bytes at offset 0x0.
+ @
+ .long pe_header @ Offset to the PE header.
+
+ .align 3
+pe_header:
+ .ascii "PE"
+ .short 0
+
+coff_header:
+ .short 0x01c2 @ ARM or Thumb
+ .short 2 @ nr_sections
+ .long 0 @ TimeDateStamp
+ .long 0 @ PointerToSymbolTable
+ .long 1 @ NumberOfSymbols
+ .short section_table - optional_header @ SizeOfOptionalHeader
+ .short 0x306 @ Characteristics.
+ @ IMAGE_FILE_32BIT_MACHINE |
+ @ IMAGE_FILE_DEBUG_STRIPPED |
+ @ IMAGE_FILE_EXECUTABLE_IMAGE |
+ @ IMAGE_FILE_LINE_NUMS_STRIPPED
+
+optional_header:
+ .short 0x10b @ PE32 format
+ .byte 0x02 @ MajorLinkerVersion
+ .byte 0x14 @ MinorLinkerVersion
+
+ .long _edata - efi_stub_entry @ SizeOfCode
+
+ .long 0 @ SizeOfInitializedData
+ .long 0 @ SizeOfUninitializedData
+
+ .long efi_stub_entry @ AddressOfEntryPoint
+ .long efi_stub_entry @ BaseOfCode
+ .long 0 @ data
+
+extra_header_fields:
+ .long 0 @ ImageBase
+ .long 0x20 @ SectionAlignment
+ .long 0x20 @ FileAlignment
+ .short 0 @ MajorOperatingSystemVersion
+ .short 0 @ MinorOperatingSystemVersion
+ .short 0 @ MajorImageVersion
+ .short 0 @ MinorImageVersion
+ .short 0 @ MajorSubsystemVersion
+ .short 0 @ MinorSubsystemVersion
+ .long 0 @ Win32VersionValue
+
+ .long _edata @ SizeOfImage
+
+ @ Everything before the entry point is considered part of the header
+ .long efi_stub_entry @ SizeOfHeaders
+ .long 0 @ CheckSum
+ .short 0xa @ Subsystem (EFI application)
+ .short 0 @ DllCharacteristics
+ .long 0 @ SizeOfStackReserve
+ .long 0 @ SizeOfStackCommit
+ .long 0 @ SizeOfHeapReserve
+ .long 0 @ SizeOfHeapCommit
+ .long 0 @ LoaderFlags
+ .long 0x0 @ NumberOfRvaAndSizes
+
+ # Section table
+section_table:
+
+ #
+ # The EFI application loader requires a relocation section
+ # because EFI applications must be relocatable. This is a
+ # dummy section as far as we are concerned.
+ #
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 @ end of 0 padding of section name
+ .long 0
+ .long 0
+ .long 0 @ SizeOfRawData
+ .long 0 @ PointerToRawData
+ .long 0 @ PointerToRelocations
+ .long 0 @ PointerToLineNumbers
+ .short 0 @ NumberOfRelocations
+ .short 0 @ NumberOfLineNumbers
+ .long 0x42100040 @ Characteristics (section flags)
+
+
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 @ end of 0 padding of section name
+ .long _edata - efi_stub_entry @ VirtualSize
+ .long efi_stub_entry @ VirtualAddress
+ .long _edata - efi_stub_entry @ SizeOfRawData
+ .long efi_stub_entry @ PointerToRawData
+
+ .long 0 @ PointerToRelocations (0 for executables)
+ .long 0 @ PointerToLineNumbers (0 for executables)
+ .short 0 @ NumberOfRelocations (0 for executables)
+ .short 0 @ NumberOfLineNumbers (0 for executables)
+ .long 0xe0500020 @ Characteristics (section flags)
diff --git a/arch/arm/boot/compressed/efi-stub.c b/arch/arm/boot/compressed/efi-stub.c
new file mode 100644
index 000000000000..87584e4262ad
--- /dev/null
+++ b/arch/arm/boot/compressed/efi-stub.c
@@ -0,0 +1,475 @@
+/*
+ * linux/arch/arm/boot/compressed/efi-stub.c
+ *
+ * Copyright (C) 2013 Linaro Ltd; <roy.franz@linaro.org>
+ *
+ * This file implements the EFI boot stub for the ARM kernel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/efi.h>
+#include <libfdt.h>
+#include "efi-stub.h"
+
+/* EFI function call wrappers. These are not required for
+ * ARM, but wrappers are required for X86 to convert between
+ * ABIs. These wrappers are provided to allow code sharing
+ * between X86 and ARM. Since these wrappers directly invoke the
+ * EFI function pointer, the function pointer type must be properly
+ * defined, which is not the case for X86 One advantage of this is
+ * it allows for type checking of arguments, which is not
+ * possible with the X86 wrappers.
+ */
+#define efi_call_phys0(f) f()
+#define efi_call_phys1(f, a1) f(a1)
+#define efi_call_phys2(f, a1, a2) f(a1, a2)
+#define efi_call_phys3(f, a1, a2, a3) f(a1, a2, a3)
+#define efi_call_phys4(f, a1, a2, a3, a4) f(a1, a2, a3, a4)
+#define efi_call_phys5(f, a1, a2, a3, a4, a5) f(a1, a2, a3, a4, a5)
+
+/* The maximum uncompressed kernel size is 32 MBytes, so we will reserve
+ * that for the decompressed kernel. We have no easy way to tell what
+ * the actuall size of code + data the uncompressed kernel will use.
+ */
+#define MAX_UNCOMP_KERNEL_SIZE 0x02000000
+
+/* The kernel zImage should be located between 32 Mbytes
+ * and 128 MBytes from the base of DRAM. The min
+ * address leaves space for a maximal size uncompressed image,
+ * and the max address is due to how the zImage decompressor
+ * picks a destination address.
+ */
+#define ZIMAGE_OFFSET_LIMIT 0x08000000
+#define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE
+
+#define PRINTK_PREFIX "EFIstub: "
+
+struct fdt_region {
+ u64 base;
+ u64 size;
+};
+
+
+/* Include shared EFI stub code */
+#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
+
+static int relocate_kernel(efi_system_table_t *sys_table,
+ unsigned long *zimage_addr,
+ unsigned long zimage_size,
+ unsigned long min_addr, unsigned long max_addr)
+{
+ unsigned long cur_zimage_addr;
+ unsigned long new_addr = 0;
+
+ efi_status_t status;
+
+ if (!zimage_addr || !zimage_size)
+ return EFI_INVALID_PARAMETER;
+
+ cur_zimage_addr = *zimage_addr;
+
+ if (cur_zimage_addr > min_addr
+ && (cur_zimage_addr + zimage_size) < max_addr) {
+ /* We don't need to do anything, as kernel is at an
+ * acceptable address already.
+ */
+ return EFI_SUCCESS;
+ }
+ /*
+ * The EFI firmware loader could have placed the kernel image
+ * anywhere in memory, but the kernel has restrictions on the
+ * min and max physical address it can run at.
+ */
+ status = efi_low_alloc(sys_table, zimage_size, 0,
+ &new_addr, min_addr);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Failed to allocate usable memory for kernel.\n");
+ return status;
+ }
+
+ if (new_addr > (max_addr - zimage_size)) {
+ efi_free(sys_table, zimage_size, new_addr);
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Failed to allocate usable memory for kernel.\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /* We know source/dest won't overlap since both memory ranges
+ * have been allocated by UEFI, so we can safely use memcpy.
+ */
+ memcpy((void *)new_addr, (void *)(unsigned long)cur_zimage_addr,
+ zimage_size);
+
+ /* Return the load address */
+ *zimage_addr = new_addr;
+
+ return status;
+}
+
+
+/* Convert the unicode UEFI command line to ASCII to pass to kernel.
+ * Size of memory allocated return in *cmd_line_len.
+ * Returns NULL on error.
+ */
+static char *convert_cmdline_to_ascii(efi_system_table_t *sys_table,
+ efi_loaded_image_t *image,
+ unsigned long *cmd_line_len,
+ u32 max_addr)
+{
+ u16 *s2;
+ u8 *s1 = NULL;
+ unsigned long cmdline_addr = 0;
+ int load_options_size = image->load_options_size / 2; /* ASCII */
+ void *options = image->load_options;
+ int options_size = 0;
+ int status;
+ int i;
+ u16 zero = 0;
+
+ if (options) {
+ s2 = options;
+ while (*s2 && *s2 != '\n' && options_size < load_options_size) {
+ s2++;
+ options_size++;
+ }
+ }
+
+ if (options_size == 0) {
+ /* No command line options, so return empty string*/
+ options_size = 1;
+ options = &zero;
+ }
+
+ options_size++; /* NUL termination */
+
+ status = efi_high_alloc(sys_table, options_size, 0,
+ &cmdline_addr, max_addr);
+ if (status != EFI_SUCCESS)
+ return NULL;
+
+ s1 = (u8 *)cmdline_addr;
+ s2 = (u16 *)options;
+
+ for (i = 0; i < options_size - 1; i++)
+ *s1++ = *s2++;
+
+ *s1 = '\0';
+
+ *cmd_line_len = options_size;
+ return (char *)cmdline_addr;
+}
+
+
+static int update_fdt(efi_system_table_t *sys_table, void *orig_fdt, void *fdt,
+ int new_fdt_size, char *cmdline_ptr, u64 initrd_addr,
+ u64 initrd_size, efi_memory_desc_t *memory_map,
+ int map_size, int desc_size)
+{
+ int node;
+ int status;
+ unsigned long fdt_val;
+
+ status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
+ if (status != 0)
+ goto fdt_set_fail;
+
+ node = fdt_subnode_offset(fdt, 0, "chosen");
+ if (node < 0) {
+ node = fdt_add_subnode(fdt, 0, "chosen");
+ if (node < 0) {
+ status = node; /* node is error code when negative */
+ goto fdt_set_fail;
+ }
+ }
+
+ if ((cmdline_ptr != NULL) && (strlen(cmdline_ptr) > 0)) {
+ status = fdt_setprop(fdt, node, "bootargs", cmdline_ptr,
+ strlen(cmdline_ptr) + 1);
+ if (status)
+ goto fdt_set_fail;
+ }
+
+ /* Set intird address/end in device tree, if present */
+ if (initrd_size != 0) {
+ u64 initrd_image_end;
+ u64 initrd_image_start = cpu_to_fdt64(initrd_addr);
+ status = fdt_setprop(fdt, node, "linux,initrd-start",
+ &initrd_image_start, sizeof(u64));
+ if (status)
+ goto fdt_set_fail;
+ initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
+ status = fdt_setprop(fdt, node, "linux,initrd-end",
+ &initrd_image_end, sizeof(u64));
+ if (status)
+ goto fdt_set_fail;
+ }
+
+ /* Add FDT entries for EFI runtime services in chosen node. */
+ node = fdt_subnode_offset(fdt, 0, "chosen");
+ fdt_val = cpu_to_fdt32((unsigned long)sys_table);
+ status = fdt_setprop(fdt, node, "efi-system-table",
+ &fdt_val, sizeof(fdt_val));
+ if (status)
+ goto fdt_set_fail;
+
+ fdt_val = cpu_to_fdt32(desc_size);
+ status = fdt_setprop(fdt, node, "efi-mmap-desc-size",
+ &fdt_val, sizeof(fdt_val));
+ if (status)
+ goto fdt_set_fail;
+
+ fdt_val = cpu_to_fdt32(map_size);
+ status = fdt_setprop(fdt, node, "efi-runtime-mmap-size",
+ &fdt_val, sizeof(fdt_val));
+ if (status)
+ goto fdt_set_fail;
+
+ fdt_val = cpu_to_fdt32((unsigned long)memory_map);
+ status = fdt_setprop(fdt, node, "efi-runtime-mmap",
+ &fdt_val, sizeof(fdt_val));
+
+ /* Stuff the whole memory map into FDT */
+ status = fdt_setprop(fdt, node, "efi-runtime-mmap-blob",
+ memory_map, sizeof(map_size));
+
+ if (status)
+ goto fdt_set_fail;
+
+ return EFI_SUCCESS;
+
+fdt_set_fail:
+ if (status == -FDT_ERR_NOSPACE)
+ return EFI_BUFFER_TOO_SMALL;
+
+ return EFI_LOAD_ERROR;
+}
+
+
+
+int efi_entry(void *handle, efi_system_table_t *sys_table,
+ unsigned long *zimage_addr)
+{
+ efi_loaded_image_t *image;
+ int status;
+ unsigned long nr_pages;
+ const struct fdt_region *region;
+
+ void *fdt;
+ int err;
+ int node;
+ unsigned long zimage_size = 0;
+ unsigned long dram_base;
+ /* addr/point and size pairs for memory management*/
+ u64 initrd_addr;
+ u64 initrd_size = 0;
+ u64 fdt_addr;
+ u64 fdt_size = 0;
+ u64 kernel_reserve_addr;
+ u64 kernel_reserve_size = 0;
+ char *cmdline_ptr;
+ unsigned long cmdline_size = 0;
+
+ unsigned long map_size, desc_size;
+ unsigned long mmap_key;
+ efi_memory_desc_t *memory_map;
+
+ unsigned long new_fdt_size;
+ unsigned long new_fdt_addr;
+
+ efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+
+ /* Check if we were booted by the EFI firmware */
+ if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ goto fail;
+
+ efi_printk(sys_table, PRINTK_PREFIX"Booting Linux using EFI stub.\n");
+
+
+ /* get the command line from EFI, using the LOADED_IMAGE protocol */
+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
+ handle, &proto, (void *)&image);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
+ goto fail;
+ }
+
+ /* We are going to copy this into device tree, so we don't care where in
+ * memory it is.
+ */
+ cmdline_ptr = convert_cmdline_to_ascii(sys_table, image,
+ &cmdline_size, 0xFFFFFFFF);
+ if (!cmdline_ptr) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to allocate memory for command line.\n");
+ goto fail;
+ }
+
+#if 1
+ /* HACK, so we can boot from boot manager. If we are passed a real
+ * command line, use it.
+ *
+ * TODO_RFRANZ - for debug only, not for real patch series
+ */
+ if (!cmdline_ptr[0]) {
+ cmdline_ptr = "initrd=initrd dtb=dtb console=ttyAMA0 earlyprintk=keep";
+ efi_printk(sys_table, PRINTK_PREFIX"Booted from boot manager, forcing command line to: ");
+ efi_printk(sys_table, cmdline_ptr);
+ efi_printk(sys_table, "\n");
+ }
+#endif
+
+ /* We first load the device tree, as we need to get the base address of
+ * DRAM from the device tree. The zImage, device tree, and initrd
+ * have address restrictions that are relative to the base of DRAM.
+ */
+ status = handle_cmdline_files(sys_table, image, cmdline_ptr, "dtb=",
+ 0xffffffff, &fdt_addr, &fdt_size);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to load device tree blob.\n");
+ goto fail_free_cmdline;
+ }
+
+ err = fdt_check_header((void *)(unsigned long)fdt_addr);
+ if (err != 0) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Device tree header not valid\n");
+ goto fail_free_fdt;
+ }
+ if (fdt_totalsize((void *)(unsigned long)fdt_addr) > fdt_size) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Incomplete device tree.\n");
+ goto fail_free_fdt;
+
+ }
+
+
+ /* Look up the base of DRAM from the device tree. fdt_addr is
+ * a 64 bit value (efi_phys_addr_t), but EFI guarantees that
+ * all addresses are 32 bit for ARM32. */
+ fdt = (void *)(u32)fdt_addr;
+ node = fdt_subnode_offset(fdt, 0, "memory");
+ region = fdt_getprop(fdt, node, "reg", NULL);
+ if (region) {
+ dram_base = fdt64_to_cpu(region->base);
+ } else {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: No 'memory' node in device tree.\n");
+ goto fail_free_fdt;
+ }
+
+ /* Reserve memory for the uncompressed kernel image. */
+ kernel_reserve_addr = dram_base;
+ kernel_reserve_size = MAX_UNCOMP_KERNEL_SIZE;
+ nr_pages = round_up(kernel_reserve_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+ status = efi_call_phys4(sys_table->boottime->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &kernel_reserve_addr);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to allocate memory for uncompressed kernel.\n");
+ goto fail_free_fdt;
+ }
+
+ /* Relocate the zImage, if required. */
+ zimage_size = image->image_size;
+ status = relocate_kernel(sys_table, zimage_addr, zimage_size,
+ dram_base + MIN_ZIMAGE_OFFSET,
+ dram_base + ZIMAGE_OFFSET_LIMIT);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Failed to relocate kernel\n");
+ goto fail_free_kernel_reserve;
+ }
+
+ status = handle_cmdline_files(sys_table, image, cmdline_ptr, "initrd=",
+ dram_base + ZIMAGE_OFFSET_LIMIT,
+ &initrd_addr, &initrd_size);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to load initrd\n");
+ goto fail_free_zimage;
+ }
+
+ /* Estimate size of new FDT, and allocate memory for it. We
+ * will allocate a bigger buffer if this ends up being too
+ * small, so a rough guess is OK here.*/
+ new_fdt_size = fdt_size + cmdline_size + 0x200;
+ while (1) {
+ status = efi_high_alloc(sys_table, new_fdt_size, 0,
+ &new_fdt_addr,
+ dram_base + ZIMAGE_OFFSET_LIMIT);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to allocate memory for new device tree.\n");
+ goto fail_free_initrd;
+ }
+
+ /* Now that we have done our final memory allocation (and free)
+ * we can get the memory map key needed
+ * forexit_boot_services.*/
+ status = efi_get_memory_map(sys_table, &memory_map, &map_size,
+ &desc_size, &mmap_key);
+ if (status != EFI_SUCCESS)
+ goto fail_free_new_fdt;
+
+ status = update_fdt(sys_table,
+ fdt, (void *)new_fdt_addr, new_fdt_size,
+ cmdline_ptr,
+ initrd_addr, initrd_size,
+ memory_map, map_size, desc_size);
+
+ /* Succeeding the first time is the expected case. */
+ if (status == EFI_SUCCESS)
+ break;
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ /* We need to allocate more space for the new
+ * device tree, so free existing buffer that is
+ * too small. Also free memory map, as we will need
+ * to get new one that reflects the free/alloc we do
+ * on the device tree buffer. */
+ efi_free(sys_table, new_fdt_size, new_fdt_addr);
+ efi_call_phys1(sys_table->boottime->free_pool,
+ memory_map);
+ new_fdt_size += new_fdt_size/4;
+ }
+ else
+ {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Unable to constuct new device tree.\n");
+ goto fail_free_mmap;
+ }
+ }
+
+ /* Now we are ready to exit_boot_services.*/
+ status = efi_call_phys2(sys_table->boottime->exit_boot_services,
+ handle, mmap_key);
+
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, PRINTK_PREFIX"ERROR: Exit boot services failed.\n");
+ goto fail_free_mmap;
+ }
+
+
+ /* Now we need to return the FDT address to the calling
+ * assembly to this can be used as part of normal boot.
+ */
+ return new_fdt_addr;
+
+fail_free_mmap:
+ efi_call_phys1(sys_table->boottime->free_pool, memory_map);
+
+fail_free_new_fdt:
+ efi_free(sys_table, new_fdt_size, new_fdt_addr);
+
+fail_free_initrd:
+ efi_free(sys_table, initrd_size, initrd_addr);
+
+fail_free_zimage:
+ efi_free(sys_table, zimage_size, *zimage_addr);
+
+fail_free_kernel_reserve:
+ efi_free(sys_table, kernel_reserve_size, kernel_reserve_addr);
+
+fail_free_fdt:
+ efi_free(sys_table, fdt_size, fdt_addr);
+
+fail_free_cmdline:
+ efi_free(sys_table, cmdline_size, (u32)cmdline_ptr);
+
+fail:
+ return EFI_STUB_ERROR;
+}
diff --git a/arch/arm/boot/compressed/efi-stub.h b/arch/arm/boot/compressed/efi-stub.h
new file mode 100644
index 000000000000..0fe937679f5a
--- /dev/null
+++ b/arch/arm/boot/compressed/efi-stub.h
@@ -0,0 +1,5 @@
+#ifndef _ARM_EFI_STUB_H
+#define _ARM_EFI_STUB_H
+/* Error code returned to ASM code instead of valid FDT address. */
+#define EFI_STUB_ERROR (~0)
+#endif
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 75189f13cf54..aae3c75c2ec0 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -10,6 +10,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "efi-stub.h"
.arch armv7-a
/*
@@ -120,21 +121,92 @@
*/
.align
.arm @ Always enter in ARM state
+ .text
start:
.type start,#function
- .rept 7
+#ifdef CONFIG_EFI_STUB
+ @ Magic MSDOS signature for PE/COFF + ADD opcode
+ @ the EFI stub only supports little endian, as the EFI functions
+ @ it invokes are little endian.
+ .word 0x62805a4d
+#else
+ mov r0, r0
+#endif
+ .rept 5
mov r0, r0
.endr
- ARM( mov r0, r0 )
- ARM( b 1f )
- THUMB( adr r12, BSYM(1f) )
- THUMB( bx r12 )
+
+ adrl r12, BSYM(zimage_continue)
+ ARM( mov pc, r12 )
+ THUMB( bx r12 )
+ @ zimage_continue will be in ARM or thumb mode as configured
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
+
+#ifdef CONFIG_EFI_STUB
+ @ Portions of the MSDOS file header must be at offset
+ @ 0x3c from the start of the file. All PE/COFF headers
+ @ are kept contiguous for simplicity.
+#include "efi-header.S"
+
+efi_stub_entry:
+ @ The EFI stub entry point is not at a fixed address, however
+ @ this address must be set in the PE/COFF header.
+ @ EFI entry point is in A32 mode, switch to T32 if configured.
+ THUMB( adr r12, BSYM(1f) )
+ THUMB( bx r12 )
THUMB( .thumb )
1:
+ @ Save lr on stack for possible return to EFI firmware.
+ @ Don't care about fp, but need 64 bit alignment....
+ stmfd sp!, {fp, lr}
+
+ @ allocate space on stack for passing current zImage address
+ @ and for the EFI stub to return of new entry point of
+ @ zImage, as EFI stub may copy the kernel. Pointer address
+ @ is passed in r2. r0 and r1 are passed through from the
+ @ EFI firmware to efi_entry
+ adr r3, start
+ str r3, [sp, #-8]!
+ mov r2, sp @ pass pointer in r2
+ bl efi_entry
+ ldr r3, [sp], #8 @ get new zImage address from stack
+
+ @ Check for error return from EFI stub. r0 has FDT address
+ @ or EFI_STUB_ERROR error code.
+ cmp r0, #EFI_STUB_ERROR
+ beq efi_load_fail
+
+ @ Save return values of efi_entry
+ stmfd sp!, {r0, r3}
+ bl cache_clean_flush
+ bl cache_off
+ ldmfd sp!, {r0, r3}
+
+ @ Set parameters for booting zImage according to boot protocol
+ @ put FDT address in r2, it was returned by efi_entry()
+ @ r1 is FDT machine type, and r0 needs to be 0
+ mov r2, r0
+ mov r1, #0xFFFFFFFF
+ mov r0, #0
+
+ @ Branch to (possibly) relocated zImage that is in r3
+ @ Make sure we are in A32 mode, as zImage requires
+ THUMB( bx r3 )
+ ARM( mov pc, r3 )
+
+efi_load_fail:
+ @ Return EFI_LOAD_ERROR to EFI firmware on error.
+ @ Switch back to ARM mode for EFI is done based on
+ @ return address on stack in case we are in THUMB mode
+ ldr r0, =0x80000001
+ ldmfd sp!, {fp, pc} @ put lr from stack into pc
+#endif
+
+ THUMB( .thumb )
+zimage_continue:
mrs r9, cpsr
#ifdef CONFIG_ARM_VIRT_EXT
bl __hyp_stub_install @ get into SVC mode, reversibly
@@ -167,7 +239,6 @@ not_angel:
* by the linker here, but it should preserve r7, r8, and r9.
*/
- .text
#ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
index 36e53ef9200f..5397792942db 100644
--- a/arch/arm/boot/compressed/string.c
+++ b/arch/arm/boot/compressed/string.c
@@ -111,6 +111,27 @@ char *strchr(const char *s, int c)
return (char *)s;
}
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char *strstr(const char *s1, const char *s2)
+{
+ size_t l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *)s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
#undef memset
void *memset(void *s, int c, size_t count)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e241a1930c98..ae619ef7f438 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1592,7 +1592,7 @@ config EFI_STUB
This kernel feature allows a bzImage to be loaded directly
by EFI firmware without the use of a bootloader.
- See Documentation/x86/efi-stub.txt for more information.
+ See Documentation/efi-stub.txt for more information.
config SECCOMP
def_bool y
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a425f09..7011e3314fc5 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -19,214 +19,10 @@
static efi_system_table_t *sys_table;
-static void efi_char16_printk(efi_char16_t *str)
-{
- struct efi_simple_text_output_protocol *out;
-
- out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
- efi_call_phys2(out->output_string, out, str);
-}
-
-static void efi_printk(char *str)
-{
- char *s8;
-
- for (s8 = str; *s8; s8++) {
- efi_char16_t ch[2] = { 0 };
-
- ch[0] = *s8;
- if (*s8 == '\n') {
- efi_char16_t nl[2] = { '\r', 0 };
- efi_char16_printk(nl);
- }
-
- efi_char16_printk(ch);
- }
-}
-
-static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
- unsigned long *desc_size)
-{
- efi_memory_desc_t *m = NULL;
- efi_status_t status;
- unsigned long key;
- u32 desc_version;
-
- *map_size = sizeof(*m) * 32;
-again:
- /*
- * Add an additional efi_memory_desc_t because we're doing an
- * allocation which may be in a new descriptor region.
- */
- *map_size += sizeof(*m);
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, *map_size, (void **)&m);
- if (status != EFI_SUCCESS)
- goto fail;
-
- status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size,
- m, &key, desc_size, &desc_version);
- if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table->boottime->free_pool, m);
- goto again;
- }
-
- if (status != EFI_SUCCESS)
- efi_call_phys1(sys_table->boottime->free_pool, m);
-
-fail:
- *map = m;
- return status;
-}
-
-/*
- * Allocate at the highest possible address that is not above 'max'.
- */
-static efi_status_t high_alloc(unsigned long size, unsigned long align,
- unsigned long *addr, unsigned long max)
-{
- unsigned long map_size, desc_size;
- efi_memory_desc_t *map;
- efi_status_t status;
- unsigned long nr_pages;
- u64 max_addr = 0;
- int i;
-
- status = __get_map(&map, &map_size, &desc_size);
- if (status != EFI_SUCCESS)
- goto fail;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
-again:
- for (i = 0; i < map_size / desc_size; i++) {
- efi_memory_desc_t *desc;
- unsigned long m = (unsigned long)map;
- u64 start, end;
-
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- if (desc->num_pages < nr_pages)
- continue;
- start = desc->phys_addr;
- end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
+#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
- if ((start + size) > end || (start + size) > max)
- continue;
-
- if (end - size > max)
- end = max;
-
- if (round_down(end - size, align) < start)
- continue;
-
- start = round_down(end - size, align);
-
- /*
- * Don't allocate at 0x0. It will confuse code that
- * checks pointers against NULL.
- */
- if (start == 0x0)
- continue;
-
- if (start > max_addr)
- max_addr = start;
- }
-
- if (!max_addr)
- status = EFI_NOT_FOUND;
- else {
- status = efi_call_phys4(sys_table->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
- if (status != EFI_SUCCESS) {
- max = max_addr;
- max_addr = 0;
- goto again;
- }
-
- *addr = max_addr;
- }
-
-free_pool:
- efi_call_phys1(sys_table->boottime->free_pool, map);
-
-fail:
- return status;
-}
-
-/*
- * Allocate at the lowest possible address.
- */
-static efi_status_t low_alloc(unsigned long size, unsigned long align,
- unsigned long *addr)
-{
- unsigned long map_size, desc_size;
- efi_memory_desc_t *map;
- efi_status_t status;
- unsigned long nr_pages;
- int i;
-
- status = __get_map(&map, &map_size, &desc_size);
- if (status != EFI_SUCCESS)
- goto fail;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- for (i = 0; i < map_size / desc_size; i++) {
- efi_memory_desc_t *desc;
- unsigned long m = (unsigned long)map;
- u64 start, end;
-
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
-
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- if (desc->num_pages < nr_pages)
- continue;
-
- start = desc->phys_addr;
- end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
-
- /*
- * Don't allocate at 0x0. It will confuse code that
- * checks pointers against NULL. Skip the first 8
- * bytes so we start at a nice even number.
- */
- if (start == 0x0)
- start += 8;
-
- start = round_up(start, align);
- if ((start + size) > end)
- continue;
-
- status = efi_call_phys4(sys_table->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &start);
- if (status == EFI_SUCCESS) {
- *addr = start;
- break;
- }
- }
- if (i == map_size / desc_size)
- status = EFI_NOT_FOUND;
-
-free_pool:
- efi_call_phys1(sys_table->boottime->free_pool, map);
-fail:
- return status;
-}
-
-static void low_free(unsigned long size, unsigned long addr)
-{
- unsigned long nr_pages;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
-}
static void find_bits(unsigned long mask, u8 *pos, u8 *size)
{
@@ -624,242 +420,6 @@ void setup_graphics(struct boot_params *boot_params)
}
}
-struct initrd {
- efi_file_handle_t *handle;
- u64 size;
-};
-
-/*
- * Check the cmdline for a LILO-style initrd= arguments.
- *
- * We only support loading an initrd from the same filesystem as the
- * kernel image.
- */
-static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
- struct setup_header *hdr)
-{
- struct initrd *initrds;
- unsigned long initrd_addr;
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
- u64 initrd_total;
- efi_file_io_interface_t *io;
- efi_file_handle_t *fh;
- efi_status_t status;
- int nr_initrds;
- char *str;
- int i, j, k;
-
- initrd_addr = 0;
- initrd_total = 0;
-
- str = (char *)(unsigned long)hdr->cmd_line_ptr;
-
- j = 0; /* See close_handles */
-
- if (!str || !*str)
- return EFI_SUCCESS;
-
- for (nr_initrds = 0; *str; nr_initrds++) {
- str = strstr(str, "initrd=");
- if (!str)
- break;
-
- str += 7;
-
- /* Skip any leading slashes */
- while (*str == '/' || *str == '\\')
- str++;
-
- while (*str && *str != ' ' && *str != '\n')
- str++;
- }
-
- if (!nr_initrds)
- return EFI_SUCCESS;
-
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA,
- nr_initrds * sizeof(*initrds),
- &initrds);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for initrds\n");
- goto fail;
- }
-
- str = (char *)(unsigned long)hdr->cmd_line_ptr;
- for (i = 0; i < nr_initrds; i++) {
- struct initrd *initrd;
- efi_file_handle_t *h;
- efi_file_info_t *info;
- efi_char16_t filename_16[256];
- unsigned long info_sz;
- efi_guid_t info_guid = EFI_FILE_INFO_ID;
- efi_char16_t *p;
- u64 file_sz;
-
- str = strstr(str, "initrd=");
- if (!str)
- break;
-
- str += 7;
-
- initrd = &initrds[i];
- p = filename_16;
-
- /* Skip any leading slashes */
- while (*str == '/' || *str == '\\')
- str++;
-
- while (*str && *str != ' ' && *str != '\n') {
- if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
- break;
-
- if (*str == '/') {
- *p++ = '\\';
- *str++;
- } else {
- *p++ = *str++;
- }
- }
-
- *p = '\0';
-
- /* Only open the volume once. */
- if (!i) {
- efi_boot_services_t *boottime;
-
- boottime = sys_table->boottime;
-
- status = efi_call_phys3(boottime->handle_protocol,
- image->device_handle, &fs_proto, &io);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to handle fs_proto\n");
- goto free_initrds;
- }
-
- status = efi_call_phys2(io->open_volume, io, &fh);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to open volume\n");
- goto free_initrds;
- }
- }
-
- status = efi_call_phys5(fh->open, fh, &h, filename_16,
- EFI_FILE_MODE_READ, (u64)0);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to open initrd file: ");
- efi_char16_printk(filename_16);
- efi_printk("\n");
- goto close_handles;
- }
-
- initrd->handle = h;
-
- info_sz = 0;
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, NULL);
- if (status != EFI_BUFFER_TOO_SMALL) {
- efi_printk("Failed to get initrd info size\n");
- goto close_handles;
- }
-
-grow:
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, info_sz, &info);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for initrd info\n");
- goto close_handles;
- }
-
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, info);
- if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table->boottime->free_pool, info);
- goto grow;
- }
-
- file_sz = info->file_size;
- efi_call_phys1(sys_table->boottime->free_pool, info);
-
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to get initrd info\n");
- goto close_handles;
- }
-
- initrd->size = file_sz;
- initrd_total += file_sz;
- }
-
- if (initrd_total) {
- unsigned long addr;
-
- /*
- * Multiple initrd's need to be at consecutive
- * addresses in memory, so allocate enough memory for
- * all the initrd's.
- */
- status = high_alloc(initrd_total, 0x1000,
- &initrd_addr, hdr->initrd_addr_max);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc highmem for initrds\n");
- goto close_handles;
- }
-
- /* We've run out of free low memory. */
- if (initrd_addr > hdr->initrd_addr_max) {
- efi_printk("We've run out of free low memory\n");
- status = EFI_INVALID_PARAMETER;
- goto free_initrd_total;
- }
-
- addr = initrd_addr;
- for (j = 0; j < nr_initrds; j++) {
- u64 size;
-
- size = initrds[j].size;
- while (size) {
- u64 chunksize;
- if (size > EFI_READ_CHUNK_SIZE)
- chunksize = EFI_READ_CHUNK_SIZE;
- else
- chunksize = size;
- status = efi_call_phys3(fh->read,
- initrds[j].handle,
- &chunksize, addr);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to read initrd\n");
- goto free_initrd_total;
- }
- addr += chunksize;
- size -= chunksize;
- }
-
- efi_call_phys1(fh->close, initrds[j].handle);
- }
-
- }
-
- efi_call_phys1(sys_table->boottime->free_pool, initrds);
-
- hdr->ramdisk_image = initrd_addr;
- hdr->ramdisk_size = initrd_total;
-
- return status;
-
-free_initrd_total:
- low_free(initrd_total, initrd_addr);
-
-close_handles:
- for (k = j; k < i; k++)
- efi_call_phys1(fh->close, initrds[k].handle);
-free_initrds:
- efi_call_phys1(sys_table->boottime->free_pool, initrds);
-fail:
- hdr->ramdisk_image = 0;
- hdr->ramdisk_size = 0;
-
- return status;
-}
/*
* Because the x86 boot code expects to be passed a boot_params we
@@ -883,6 +443,8 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
u16 *s2;
u8 *s1;
int i;
+ u64 ramdisk_addr;
+ u64 ramdisk_size;
sys_table = _table;
@@ -893,13 +455,14 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
status = efi_call_phys3(sys_table->boottime->handle_protocol,
handle, &proto, (void *)&image);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
+ efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
}
- status = low_alloc(0x4000, 1, (unsigned long *)&boot_params);
+ status = efi_low_alloc(sys_table, 0x4000, 1,
+ (unsigned long *)&boot_params, 0);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc lowmem for boot params\n");
+ efi_printk(sys_table, "Failed to alloc lowmem for boot params\n");
return NULL;
}
@@ -943,9 +506,10 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
options_size++; /* NUL termination */
- status = low_alloc(options_size, 1, &cmdline);
+ status = efi_low_alloc(sys_table, options_size, 1,
+ &cmdline, 0);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for cmdline\n");
+ efi_printk(sys_table, "Failed to alloc mem for cmdline\n");
goto fail;
}
@@ -969,16 +533,20 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
memset(sdt, 0, sizeof(*sdt));
- status = handle_ramdisks(image, hdr);
+ status = handle_cmdline_files(sys_table, image,
+ (char *)(unsigned long)hdr->cmd_line_ptr,
+ "initrd=", hdr->initrd_addr_max,
+ &ramdisk_addr, &ramdisk_size);
if (status != EFI_SUCCESS)
goto fail2;
+ hdr->ramdisk_image = ramdisk_addr;
+ hdr->ramdisk_size = ramdisk_size;
return boot_params;
fail2:
- if (options_size)
- low_free(options_size, hdr->cmd_line_ptr);
+ efi_free(sys_table, options_size, hdr->cmd_line_ptr);
fail:
- low_free(0x4000, (unsigned long)boot_params);
+ efi_free(sys_table, 0x4000, (unsigned long)boot_params);
return NULL;
}
@@ -1001,7 +569,8 @@ static efi_status_t exit_boot(struct boot_params *boot_params,
again:
size += sizeof(*mem_map) * 2;
_size = size;
- status = low_alloc(size, 1, (unsigned long *)&mem_map);
+ status = efi_low_alloc(sys_table, size, 1,
+ (unsigned long *)&mem_map, 0);
if (status != EFI_SUCCESS)
return status;
@@ -1009,7 +578,7 @@ get_map:
status = efi_call_phys5(sys_table->boottime->get_memory_map, &size,
mem_map, &key, &desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL) {
- low_free(_size, (unsigned long)mem_map);
+ efi_free(sys_table, _size, (unsigned long)mem_map);
goto again;
}
@@ -1111,7 +680,7 @@ get_map:
return EFI_SUCCESS;
free_mem_map:
- low_free(_size, (unsigned long)mem_map);
+ efi_free(sys_table, _size, (unsigned long)mem_map);
return status;
}
@@ -1134,10 +703,10 @@ static efi_status_t relocate_kernel(struct setup_header *hdr)
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
nr_pages, &start);
if (status != EFI_SUCCESS) {
- status = low_alloc(hdr->init_size, hdr->kernel_alignment,
- &start);
+ status = efi_low_alloc(sys_table, hdr->init_size,
+ hdr->kernel_alignment, &start, 0);
if (status != EFI_SUCCESS)
- efi_printk("Failed to alloc mem for kernel\n");
+ efi_printk(sys_table, "Failed to alloc mem for kernel\n");
}
if (status == EFI_SUCCESS)
@@ -1177,14 +746,15 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
EFI_LOADER_DATA, sizeof(*gdt),
(void **)&gdt);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for gdt structure\n");
+ efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
}
gdt->size = 0x800;
- status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address);
+ status = efi_low_alloc(sys_table, gdt->size, 8,
+ (unsigned long *)&gdt->address, 0);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for gdt\n");
+ efi_printk(sys_table, "Failed to alloc mem for gdt\n");
goto fail;
}
@@ -1192,7 +762,7 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
EFI_LOADER_DATA, sizeof(*idt),
(void **)&idt);
if (status != EFI_SUCCESS) {
- efi_printk("Failed to alloc mem for idt structure\n");
+ efi_printk(sys_table, "Failed to alloc mem for idt structure\n");
goto fail;
}
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index e5b0a8f91c5f..81b6b652b46a 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -11,9 +11,6 @@
#define DESC_TYPE_CODE_DATA (1 << 0)
-#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
-#define EFI_READ_CHUNK_SIZE (1024 * 1024)
-
#define EFI_CONSOLE_OUT_DEVICE_GUID \
EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \
0x3f, 0xc1, 0x4d)
@@ -62,10 +59,4 @@ struct efi_uga_draw_protocol {
void *blt;
};
-struct efi_simple_text_output_protocol {
- void *reset;
- void *output_string;
- void *test_string;
-};
-
#endif /* BOOT_COMPRESSED_EBOOT_H */