This is useful if you cannot or don't want to change the
          command-line options your boot loader passes to the kernel.
 
+config EFI_STUB
+       bool
+
 config EFI
        bool "UEFI runtime support"
        depends on OF && !CPU_BIG_ENDIAN
        select UCS2_STRING
        select EFI_PARAMS_FROM_FDT
        select EFI_RUNTIME_WRAPPERS
+       select EFI_STUB
+       select EFI_ARMSTUB
        default y
        help
          This option provides support for runtime services provided
 
 core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
 libs-y         := arch/arm64/lib/ $(libs-y)
 libs-y         += $(LIBGCC)
+libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/
 
 # Default target when executing plain make
 KBUILD_IMAGE   := Image.gz
 
 
 CPPFLAGS_vmlinux.lds   := -DTEXT_OFFSET=$(TEXT_OFFSET)
 AFLAGS_head.o          := -DTEXT_OFFSET=$(TEXT_OFFSET)
-CFLAGS_efi-stub.o      := -DTEXT_OFFSET=$(TEXT_OFFSET) \
-                          -I$(src)/../../../scripts/dtc/libfdt
+CFLAGS_efi-stub.o      := -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_insn.o = -pg
 
 #include <asm/efi.h>
 #include <asm/sections.h>
 
-/* Include shared EFI stub code */
-#include "../../../drivers/firmware/efi/efi-stub-helper.c"
-#include "../../../drivers/firmware/efi/fdt.c"
-#include "../../../drivers/firmware/efi/arm-stub.c"
-
-
 efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
                                 unsigned long *image_addr,
                                 unsigned long *image_size,
 
 $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
 
 ifeq ($(CONFIG_EFI_STUB), y)
-       VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o
+       VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \
+                               $(objtree)/drivers/firmware/efi/libstub/lib.a
 endif
 
 $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE
 
        }
 }
 
-#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
-
 static void find_bits(unsigned long mask, u8 *pos, u8 *size)
 {
        u8 first, len;
 
 config EFI_RUNTIME_WRAPPERS
        bool
 
+config EFI_ARMSTUB
+       bool
+
 endmenu
 
 config UEFI_CPER
 
 obj-$(CONFIG_UEFI_CPER)                        += cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)          += runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)     += runtime-wrappers.o
+obj-$(CONFIG_EFI_STUB)                 += libstub/
 
--- /dev/null
+#
+# The stub may be linked into the kernel proper or into a separate boot binary,
+# but in either case, it executes before the kernel does (with MMU disabled) so
+# things like ftrace and stack-protector are likely to cause trouble if left
+# enabled, even if doing so doesn't break the build.
+#
+cflags-$(CONFIG_X86_32)                := -march=i386
+cflags-$(CONFIG_X86_64)                := -mcmodel=small
+cflags-$(CONFIG_X86)           += -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+                                  -fPIC -fno-strict-aliasing -mno-red-zone \
+                                  -mno-mmx -mno-sse -DDISABLE_BRANCH_PROFILING
+
+cflags-$(CONFIG_ARM64)         := $(subst -pg,,$(KBUILD_CFLAGS))
+cflags-$(CONFIG_ARM)           := $(subst -pg,,$(KBUILD_CFLAGS)) \
+                                  -fno-builtin -fpic -mno-single-pic-base
+
+KBUILD_CFLAGS                  := $(cflags-y) \
+                                  $(call cc-option,-ffreestanding) \
+                                  $(call cc-option,-fno-stack-protector)
+
+GCOV_PROFILE                   := n
+
+lib-y                          := efi-stub-helper.o
+lib-$(CONFIG_EFI_ARMSTUB)      += arm-stub.o fdt.o
+
+CFLAGS_fdt.o                   += -I$(srctree)/scripts/dtc/libfdt/