x86/efi changes for v3.3
Linus,
Please pull the latest x86-efi-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-efi-for-linus
Thanks,
Ingo
------------------>
Maarten Lankhorst (1):
x86, efi: Break up large initrd reads
Matt Fleming (9):
x86: Add missing bzImage fields to struct setup_header
x86: Don't use magic strings for EFI loader signature efi.h: Add struct definition for boot time services efi.h: Add efi_image_loaded_t
efi.h: Add allocation types for boottime->allocate_pages() efi.h: Add graphics protocol guids
efi.h: Add boottime->locate_handle search types
efi: Add EFI file I/O data types
x86, efi: EFI boot stub support
arch/x86/Kconfig | 7 + arch/x86/boot/compressed/Makefile | 10 +- arch/x86/boot/compressed/eboot.c | 1022 ++++++++++++++++++++++++++++++++ arch/x86/boot/compressed/eboot.h | 61 ++ arch/x86/boot/compressed/efi_stub_32.S | 86 +++ arch/x86/boot/compressed/efi_stub_64.S | 1 + arch/x86/boot/compressed/head_32.S | 22 + arch/x86/boot/compressed/head_64.S | 20 + arch/x86/boot/compressed/string.c | 9 + arch/x86/boot/header.S | 158 +++++ arch/x86/boot/string.c | 35 ++ arch/x86/boot/tools/build.c | 39 ++ arch/x86/include/asm/bootparam.h | 2 + arch/x86/include/asm/efi.h | 4 + arch/x86/kernel/asm-offsets.c | 2 + arch/x86/kernel/setup.c | 7 +- include/linux/efi.h | 136 +++++- 17 files changed, 1613 insertions(+), 8 deletions(-) create mode 100644 arch/x86/boot/compressed/eboot.c create mode 100644 arch/x86/boot/compressed/eboot.h create mode 100644 arch/x86/boot/compressed/efi_stub_32.S create mode 100644 arch/x86/boot/compressed/efi_stub_64.S
arch/x86/Kconfig +7 -0
@@ -1478,6 +1478,13 @@ config EFI resultant kernel should continue to boot on existing non-EFI platforms. +config EFI_STUB + bool "EFI stub support" + depends on EFI + ---help--- + This kernel feature allows a bzImage to be loaded directly + by EFI firmware without the use of a bootloader. + config SECCOMP def_bool y prompt "Enable seccomp to safely compute untrusted bytecode"
arch/x86/boot/compressed/Makefile +9 -1
@@ -23,7 +23,15 @@ LDFLAGS_vmlinux := -T hostprogs-y := mkpiggy -$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o $(obj)/piggy.o FORCE +VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ + $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \ + $(obj)/piggy.o + +ifeq ($(CONFIG_EFI_STUB), y) + VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o +endif + +$(obj)/vmlinux: $(VMLINUX_OBJS) FORCE $(call if_changed,ld) @:
arch/x86/boot/compressed/eboot.c new file +1022 -0
1,022 lines not on this page · raw message
arch/x86/boot/compressed/eboot.h new file +61 -0
61 lines not on this page · raw message
arch/x86/boot/compressed/efi_stub_32.S new file +86 -0
86 lines not on this page · raw message
arch/x86/boot/compressed/efi_stub_64.S new file +1 -0
@@ -0,0 +1 @@ +#include "../../platform/efi/efi_stub_64.S"
arch/x86/boot/compressed/head_32.S +22 -0
@@ -32,6 +32,28 @@ __HEAD ENTRY(startup_32) +#ifdef CONFIG_EFI_STUB + /* + * We don't need the return address, so set up the stack so + * efi_main() can find its arugments. + */ + add $0x4, %esp + + call efi_main + cmpl $0, %eax + je preferred_addr + movl %eax, %esi + call 1f +1: + popl %eax + subl $1b, %eax + subl BP_pref_address(%esi), %eax + add BP_code32_start(%esi), %eax + leal preferred_addr(%eax), %eax + jmp *%eax + +preferred_addr: +#endif cld /* * Test KEEP_SEGMENTS flag to see if the bootloader is asking
arch/x86/boot/compressed/head_64.S +20 -0
@@ -199,6 +199,26 @@ ENTRY(startup_64) * an identity mapped page table being provied that maps our * entire text+data+bss and hopefully all of memory. */ +#ifdef CONFIG_EFI_STUB + pushq %rsi + mov %rcx, %rdi + mov %rdx, %rsi + call efi_main + popq %rsi + cmpq $0,%rax + je preferred_addr + movq %rax,%rsi + call 1f +1: + popq %rax + subq $1b, %rax + subq BP_pref_address(%rsi), %rax + add BP_code32_start(%esi), %eax + leaq preferred_addr(%rax), %rax + jmp *%rax + +preferred_addr: +#endif /* Setup data segments. */ xorl %eax, %eax
arch/x86/boot/compressed/string.c +9 -0
@@ -1,2 +1,11 @@#include "misc.h" + +int memcmp (const void *s1,const void *s2,size_t len) +{ +u8 diff; + asm("repe; cmpsb; setnz %0" + :"=qm" (diff),"+D" (s1),"+S" (s2),"+c" (len)); +return diff; +} +#include "../string.c"
arch/x86/boot/header.S +158 -0
179 lines not on this page · raw message
arch/x86/boot/string.c +35 -0
@@ -111,3 +111,38 @@ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int basreturn result; } + +/** +* strlen - Find the length of a string +* @s: The string to be sized +*/ +size_t strlen (const char *s) +{ +const char *sc; + +for (sc = s; *sc !='\0' ; ++sc) +/* nothing */ ; +return sc - 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 ; +}
arch/x86/boot/tools/build.c +39 -0
@@ -135,6 +135,9 @@ static void usage(void)int main (int argc,char ** argv) { +#ifdef CONFIG_EFI_STUB +unsigned int file_sz, pe_header; +#endif unsigned int i, sz, setup_sectors;int c;u32 sys_size;
@@ -194,6 +197,42 @@ int main(int argc, char ** argv) buf[0x1f6 ] = sys_size >>16 ; buf[0x1f7 ] = sys_size >>24 ; +#ifdef CONFIG_EFI_STUB + file_sz = sz + i + ((sys_size *16 ) - sz); + + pe_header = *(unsigned int *)&buf[0x3c ]; + +/* Size of code */ + *(unsigned int *)&buf[pe_header +0x1c ] = file_sz; + +/* Size of image */ + *(unsigned int *)&buf[pe_header +0x50 ] = file_sz; + +#ifdef CONFIG_X86_32 +/* Address of entry point */ + *(unsigned int *)&buf[pe_header +0x28 ] = i; + +/* .text size */ + *(unsigned int *)&buf[pe_header +0xb0 ] = file_sz; + +/* .text size of initialised data */ + *(unsigned int *)&buf[pe_header +0xb8 ] = file_sz; +#else +/* +* Address of entry point. startup_32 is at the beginning and +* the 64-bit entry point (startup_64) is always 512 bytes +* after. +*/ + *(unsigned int *)&buf[pe_header +0x28 ] = i +512 ; + +/* .text size */ + *(unsigned int *)&buf[pe_header +0xc0 ] = file_sz; + +/* .text size of initialised data */ + *(unsigned int *)&buf[pe_header +0xc8 ] = file_sz; +#endif /* CONFIG_X86_32 */ +#endif /* CONFIG_EFI_STUB */ + crc =partial_crc32 (buf, i, crc);if (fwrite (buf,1 , i, stdout) != i)die ("Writing setup failed" );
arch/x86/include/asm/bootparam.h +2 -0
@@ -64,6 +64,8 @@ struct setup_header {__u32 payload_offset;__u32 payload_length;__u64 setup_data; +__u64 pref_address; +__u32 init_size; } __attribute__((packed));struct sys_desc_table {
arch/x86/include/asm/efi.h +4 -0
@@ -3,6 +3,8 @@#ifdef CONFIG_X86_32 +#define EFI_LOADER_SIGNATURE "EL32" +extern unsigned long asmlinkage efi_call_phys (void *, ...);#define efi_call_phys0 (f) efi_call_phys(f)
@@ -35,6 +37,8 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);#else /* !CONFIG_X86_32 */ +#define EFI_LOADER_SIGNATURE "EL64" +extern u64 efi_call0 (void *fp);extern u64 efi_call1 (void *fp,u64 arg1);extern u64 efi_call2 (void *fp,u64 arg1,u64 arg2);
arch/x86/kernel/asm-offsets.c +2 -0
@@ -67,4 +67,6 @@ void common(void) {OFFSET (BP_hardware_subarch, boot_params, hdr.hardware_subarch);OFFSET (BP_version, boot_params, hdr.version);OFFSET (BP_kernel_alignment, boot_params, hdr.kernel_alignment); +OFFSET (BP_pref_address, boot_params, hdr.pref_address); +OFFSET (BP_code32_start, boot_params, hdr.code32_start); }
arch/x86/kernel/setup.c +1 -6
@@ -752,12 +752,7 @@ void __init setup_arch(char **cmdline_p)#endif #ifdef CONFIG_EFI if (!strncmp ((char *)&boot_params.efi_info.efi_loader_signature, -#ifdef CONFIG_X86_32 -"EL32" , -#else -"EL64" , -#endif -4 )) { +EFI_LOADER_SIGNATURE ,4 )) { efi_enabled =1 ;efi_memblock_x86_reserve_range (); }
include/linux/efi.h +135 -1
172 lines not on this page · raw message