update to 4.14.62 and use the linuxboot.efi BDS

This commit is contained in:
Trammell Hudson 2018-08-09 10:20:22 -04:00
parent d876776ed7
commit c98bfe158f
Failed to extract signature
9 changed files with 49 additions and 690 deletions

View File

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 4.14.56 Kernel Configuration
# Linux/x86 4.14.62 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
@ -529,7 +529,6 @@ CONFIG_X86_SMAP=y
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_EFI_STUB_BDS=y
# CONFIG_EFI_MIXED is not set
# CONFIG_SECCOMP is not set
# CONFIG_HZ_100 is not set

View File

@ -1,6 +1,6 @@
modules-y += linux
linux_version := 4.14.56
linux_version := 4.14.62
linux_base_dir := linux-$(linux_version)
# TODO: fixup the patch process
@ -17,7 +17,7 @@ linux_url := https://cdn.kernel.org/pub/linux/kernel/v4.x/$(linux_tar)
linux-4.9.38_hash := 76d789d87dd51d2fd58c095727171984fa4a992f5e25b9e3eb1e5fd5cd129074
linux-4.9.80_hash := 9e2e83ccc0afc3f23340ed5e58a35d8c6300a7c58aa98ca913848de41226477b
linux-4.14.56_hash := d4f56cfac6d43a349e6172bf84613f788a8481a54a213261cf591ffd133bc42c
linux-4.14.62_hash := 51ca4d7e8ee156dc0f19bc7768915cfae41dbb0b4f251e4fa8b178c5674c22ab
linux_hash := $(linux-$(linux_version)_hash)

View File

@ -1,7 +1,7 @@
modules-$(CONFIG_LINUXBOOT) += linuxboot
linuxboot_version := git
linuxboot_repo := https://github.com/osresearch/linuxboot
linuxboot_repo := https://github.com/osresearch/linuxboot -b bds-pr
linuxboot_base_dir := linuxboot-$(linuxboot_version)
# linuxboot builds are specialized on a per-target basis.

View File

@ -1,685 +0,0 @@
diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c
--- ./clean/linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c 2018-02-07 15:51:28.534500400 -0500
@@ -1,5 +1,5 @@
#include "misc.h"
-int early_serial_base;
+int early_serial_base = 0x3f8;
#include "../early_serial_console.c"
diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/eboot.c linux-4.9.80/arch/x86/boot/compressed/eboot.c
--- ./clean/linux-4.9.80/arch/x86/boot/compressed/eboot.c 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/arch/x86/boot/compressed/eboot.c 2018-02-07 15:51:28.534500400 -0500
@@ -16,6 +16,71 @@
#include "../string.h"
#include "eboot.h"
+#define PORT 0x3f8 /* COM1 */
+
+#define DLAB 0x80
+
+#define TXR 0 /* Transmit register (WRITE) */
+#define RXR 0 /* Receive register (READ) */
+#define IER 1 /* Interrupt Enable */
+#define IIR 2 /* Interrupt ID */
+#define FCR 2 /* FIFO control */
+#define LCR 3 /* Line control */
+#define MCR 4 /* Modem control */
+#define LSR 5 /* Line Status */
+#define MSR 6 /* Modem Status */
+#define DLL 0 /* Divisor Latch Low */
+#define DLH 1 /* Divisor latch High */
+
+static void early_serial_init(int port, int baud)
+{
+ unsigned char c;
+ unsigned divisor;
+
+ outb(0x3, port + LCR); /* 8n1 */
+ outb(0, port + IER); /* no interrupt */
+ outb(0, port + FCR); /* no fifo */
+ outb(0x3, port + MCR); /* DTR + RTS */
+
+ divisor = 115200 / baud;
+ c = inb(port + LCR);
+ outb(c | DLAB, port + LCR);
+ outb(divisor & 0xff, port + DLL);
+ outb((divisor >> 8) & 0xff, port + DLH);
+ outb(c & ~DLAB, port + LCR);
+}
+
+static int is_transmit_empty() {
+ return inb(PORT + 5) & 0x20;
+}
+
+void serial_char(char a) {
+ outb(a, PORT);
+ while (is_transmit_empty() == 0);
+}
+
+void serial_string(const char * s)
+{
+ while(*s)
+ serial_char(*s++);
+}
+
+void serial_hex(unsigned long x, unsigned digits)
+{
+ while(digits-- > 0)
+ {
+ unsigned d = (x >> (digits * 4)) & 0xF;
+ if (d >= 0xA)
+ serial_char(d + 'A' - 0xA);
+ else
+ serial_char(d + '0');
+ }
+ serial_char('\r');
+ serial_char('\n');
+}
+
+
+
static efi_system_table_t *sys_table;
static struct efi_config *efi_early;
@@ -710,6 +775,132 @@
}
}
+#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID EFI_GUID(0x220e73b6, 0x6bdb, 0x4413, 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a)
+typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL {
+ uint64_t GetVolumeAttributes;
+ uint64_t SetVolumeAttributes;
+ uint64_t ReadFile;
+ uint64_t ReadSection;
+ uint64_t WriteFile;
+ uint64_t GetNextFile;
+ uint32_t KeySize;
+ uint64_t ParentHandle;
+ uint64_t GetInfo;
+ uint64_t SetInfo;
+} efi_firmware_volume2_protocol_t;
+
+
+/*
+ * attempt to locate the ramdisk in our firmware volume.
+ * This assumes that it has a well-known GUID.
+ */
+static int nerf_find_initrd(const efi_guid_t * initrd_guid, void ** buffer, uint32_t * size)
+{
+ efi_status_t status;
+ efi_guid_t fv_proto = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+ void ** handles = NULL;
+ unsigned long handle_count;
+
+ status = efi_call_early(locate_handle_buffer,
+ EFI_LOCATE_BY_PROTOCOL,
+ &fv_proto,
+ NULL,
+ &handle_count,
+ &handles
+ );
+
+ if (status != 0)
+ {
+ serial_string("locate_handle rc=");
+ serial_hex(status, 8);
+ return -1;
+ }
+
+ for(unsigned i = 0 ; i < handle_count ; i++)
+ {
+ efi_firmware_volume2_protocol_t * fv = NULL;
+ uint32_t auth_status = 0;
+
+ serial_string("handle=");
+ serial_hex((unsigned long) handles[i], 16);
+
+ status = efi_call_early(handle_protocol,
+ handles[i],
+ &fv_proto,
+ (void**) &fv
+ );
+
+ if (status != 0)
+ {
+ serial_string("handle proto rc=");
+ serial_hex(status, 8);
+ continue;
+ }
+
+ serial_string("fv=");
+ serial_hex((unsigned long) fv, 16);
+ serial_hex((unsigned long) &fv->ReadSection, 16);
+ serial_hex((unsigned long) fv->ReadSection, 16);
+
+ status = efi_early->call(fv->ReadSection,
+ fv,
+ initrd_guid,
+ 0x19, // EFI_SECTION_RAW
+ 0,
+ buffer,
+ size,
+ &auth_status
+ );
+ if (status != 0)
+ {
+ serial_string("read section rc=");
+ serial_hex(status, 8);
+ continue;
+ }
+
+ serial_string("initrd ");
+ serial_hex((unsigned long) *buffer, 16);
+ serial_hex(*size, 8);
+ return 0;
+ }
+
+ // this leaks the handle buffer.
+ serial_string("initrd not found\r\n");
+ return -1;
+}
+
+
+static int efi_early_init(struct efi_config * c)
+{
+ if (efi_early)
+ return 0;
+
+ efi_early = c;
+ sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
+
+ if(!sys_table)
+ {
+ // We're NERFed and are the "DxeCore", so there is no system
+ // table. The efi_config argument is actually the HobStart
+ // pointer, but who cares about that stuff.
+ // TODO: actually handle this case
+ while(1)
+ outb('!', 0x3f8);
+ }
+
+ /* Check if we were booted by the EFI firmware */
+ if (!sys_table || sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ return -1;
+
+ if (efi_early->is64)
+ setup_boot_services64(efi_early);
+ else
+ setup_boot_services32(efi_early);
+
+ return 0;
+}
+
+
/*
* Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create
@@ -735,23 +926,17 @@
unsigned long ramdisk_addr;
unsigned long ramdisk_size;
- efi_early = c;
- sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
- handle = (void *)(unsigned long)efi_early->image_handle;
+serial_string("make_boot_params\r\n");
- /* Check if we were booted by the EFI firmware */
- if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ if (efi_early_init(c) < 0)
return NULL;
- if (efi_early->is64)
- setup_boot_services64(efi_early);
- else
- setup_boot_services32(efi_early);
+serial_string("early_init done\r\n");
+ handle = (void *)(unsigned long)efi_early->image_handle;
status = efi_call_early(handle_protocol, handle,
&proto, (void *)&image);
if (status != EFI_SUCCESS) {
- efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
}
@@ -814,6 +999,21 @@
if (status != EFI_SUCCESS)
goto fail2;
+
+#if 1
+ void * initrd_ptr = NULL;
+ uint32_t initrd_size = 0;
+ if (nerf_find_initrd(
+ (const efi_guid_t*) "initrd.cpio/bios",
+ &initrd_ptr,
+ &initrd_size
+ ) == 0 )
+ {
+ ramdisk_addr = (uintptr_t) initrd_ptr;
+ ramdisk_size = initrd_size;
+ }
+#endif
+
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
hdr->ramdisk_size = ramdisk_size & 0xffffffff;
boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
@@ -1068,6 +1268,7 @@
struct boot_params *efi_main(struct efi_config *c,
struct boot_params *boot_params)
{
+serial_string("efi_main\r\n");
struct desc_ptr *gdt = NULL;
efi_loaded_image_t *image;
struct setup_header *hdr = &boot_params->hdr;
@@ -1079,12 +1280,14 @@
efi_early = c;
+serial_string("efi_main "); serial_hex(__LINE__, 4);
_table = (efi_system_table_t *)(unsigned long)efi_early->table;
handle = (void *)(unsigned long)efi_early->image_handle;
is64 = efi_early->is64;
sys_table = _table;
+serial_string("efi_main "); serial_hex(__LINE__, 4);
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
goto fail;
@@ -1098,9 +1301,11 @@
setup_efi_pci(boot_params);
+serial_string("efi_main "); serial_hex(__LINE__, 4);
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
sizeof(*gdt), (void **)&gdt);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
}
@@ -1124,6 +1329,7 @@
hdr->pref_address,
hdr->kernel_alignment);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "efi_relocate_kernel() failed!\n");
goto fail;
}
@@ -1132,8 +1338,10 @@
hdr->code32_start = bzimage_addr;
}
+serial_string("efi_main "); serial_hex(__LINE__, 4);
status = exit_boot(boot_params, handle, is64);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "exit_boot() failed!\n");
goto fail;
}
@@ -1194,8 +1402,263 @@
asm volatile("cli");
asm volatile ("lgdt %0" : : "m" (*gdt));
+serial_string("efi_main done "); serial_hex(__LINE__, 4);
return boot_params;
fail:
+serial_string("efi_main failed "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "efi_main() failed!\n");
return NULL;
}
+
+#ifdef CONFIG_EFI_STUB_BDS
+
+/*
+ * The LinuxBoot kernel is invoked as a DXE driver that registers
+ * the BDS (Boot Device Selector) protocol. Once all of the DXE
+ * executables have run, the DxeCore dispatcher will jump into the
+ * BDS to choose what kernel to run.
+ *
+ * In our case, it is this kernel. So we need to stash the config
+ * for when we are re-invoked.
+ */
+static void empty_function(void* unused) { (void) unused; }
+
+#define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x5ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9)
+#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID EFI_GUID(0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID EFI_GUID(0x24a2d66f, 0xeedd, 0x4086, 0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69)
+#define EFI_END_OF_DXE_EVENT_GROUP_GUID EFI_GUID(0x2ce967a, 0xdd7e, 0x4ffc, 0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80)
+#define EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID EFI_GUID(0x60ff8964, 0xe906, 0x41d0, 0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e)
+
+
+
+
+static void * efi_find_table(uint32_t search_guid)
+{
+ const efi_system_table_64_t * st = (const void*) efi_early->table;
+ const efi_config_table_64_t * ct = (const void*) st->tables;
+
+serial_string("num tables=");
+serial_hex(st->nr_tables, 4);
+
+ for(int i = 0 ; i < st->nr_tables; i++)
+ {
+ const efi_guid_t * guid = &ct[i].guid;
+serial_hex(*(uint64_t*)guid, 16);
+ if (*(uint32_t*) guid == search_guid)
+ return (void*) ct[i].table;
+
+ }
+
+ return NULL;
+}
+
+
+static void efi_event_signal(efi_guid_t guid)
+{
+ efi_status_t status;
+ void * event = NULL;
+
+ status = efi_call_early(create_event_ex,
+ 0x200, // EVT_NOTIFY_SIGNAL
+ 8, // EFI_TPL_CALLBACK
+ empty_function,
+ NULL,
+ &guid,
+ &event
+ );
+ if (status)
+ serial_hex(status, 8);
+
+ status = efi_call_early(signal_event, event);
+ if (status)
+ serial_hex(status, 8);
+
+ status = efi_call_early(close_event, event);
+ if (status)
+ serial_hex(status, 8);
+}
+
+
+static efi_handle_t * handle_buffer;
+static const unsigned handle_buffer_size = 0x2000 * sizeof(*handle_buffer);
+
+
+static void efi_visit_handles(efi_guid_t * protocol, void (*callback)(efi_handle_t, void*), void* priv)
+{
+ unsigned handle_count = handle_buffer_size;
+ memset(handle_buffer, 0, handle_buffer_size);
+
+serial_string("efi_visit_handles ");
+serial_hex(protocol ? *(uint32_t*) protocol : 0, 8);
+
+ efi_status_t status = efi_call_early(locate_handle,
+ protocol ? 2 : 0, // ByProtocol vs AllHandles
+ protocol,
+ NULL,
+ &handle_count,
+ handle_buffer
+ );
+ if (status != 0)
+ {
+ serial_string("status=");
+ serial_hex(status, 8);
+ return;
+ }
+
+serial_string("handle_count=");
+serial_hex(handle_count, 8);
+
+ for(int i = 0 ; i < handle_count/sizeof(*handle_buffer) ; i++)
+ {
+ //serial_hex((uint64_t) handle_buffer[i], 16);
+ callback(handle_buffer[i], priv);
+ }
+}
+
+
+static void efi_connect_controllers(efi_handle_t handle, void * recursive_arg)
+{
+ efi_call_early(connect_controller, handle, NULL, NULL, recursive_arg ? 1 : 0);
+}
+
+
+void efi_platform_init(void)
+{
+ // setup something to be called whenever device path events are
+ // generated. Ovmf just twiddles an atapi bit; ignoring for now
+
+ // connect all the pci root bridges
+serial_string("connect pci root brdiges\r\n");
+ efi_guid_t pci_protocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+ efi_visit_handles(&pci_protocol, efi_connect_controllers, (void*) 0);
+
+ // signal the acpi platform driver that it can download the ACPI tables
+serial_string("signal root bridges connected\r\n");
+ efi_event_signal(ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID);
+
+ // signal that dxe is about to end
+serial_string("signal dxe end\r\n");
+ efi_event_signal(EFI_END_OF_DXE_EVENT_GROUP_GUID);
+
+ // Prevent further changes to LockBoxes or SMRAM.
+ // not necessary, but we probably want to do it for security
+ efi_handle_t handle = NULL;
+ efi_guid_t smm_ready_to_lock = EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID;
+serial_string("signal smm ready to lock\r\n");
+ efi_call_early(install_protocol_interface,
+ &handle,
+ &smm_ready_to_lock,
+ 0, // EFI_NATIVE_INTERFACE,
+ NULL
+ );
+}
+
+
+static void efi_bds_main(void)
+{
+ efi_status_t status;
+
+serial_string("bds_main 1\r\n");
+ efi_low_alloc(sys_table, handle_buffer_size, 1,
+ (unsigned long *)&handle_buffer);
+serial_string("handle_buffer=");
+serial_hex((uint64_t) handle_buffer, 16);
+
+ // equivilant to PlatformBootManagerBeforeConsole
+ efi_platform_init();
+
+ // connect all drivers their contorllers
+ // this is copied from BmConnectAllDriversToAllControllers()
+ // the DXE services table is buried in the configuration
+ // table in the system table
+ const struct {
+ uint8_t pad[24 + 8 * 13]; // header and 13 functions
+ efi_status_t (*dispatch)(void);
+ } * dxe_services = efi_find_table(0x5ad34ba);
+
+ if (!dxe_services)
+ serial_string("No DXE system table found... will crash\n");
+ else {
+ serial_string("dispatch = ");
+ serial_hex((uint64_t) dxe_services->dispatch, 16);
+ }
+
+/**
+ Connect all the drivers to all the controllers.
+
+ This function makes sure all the current system drivers manage the correspoinding
+ controllers if have. And at the same time, makes sure all the system controllers
+ have driver to manage it if have.
+**/
+ do {
+ efi_visit_handles(NULL, efi_connect_controllers, (void*) 1);
+serial_string("bds_main dispatch\r\n");
+ } while(dxe_services->dispatch() == 0);
+
+ // free crashes, so just leak it
+ //serial_string("free\n");
+ //efi_call_early(free_pool, handle_buffer);
+
+ // signal that we're ready to boot, which will
+ // cause additional drivers to be loaded
+serial_string("bds_main 2\r\n");
+ efi_event_signal(EFI_EVENT_GROUP_READY_TO_BOOT);
+
+ // jump back into the real kernel startup routine
+ extern __attribute__((noreturn)) void (*efi_restart)(void * bp);
+serial_string("bds_main 5\r\n");
+ asm( "jmp efi_restart" : : "d"(efi_early) );
+}
+
+static struct
+{
+ void (*bds_main)(void);
+} efi_bds_arch_protocol;
+
+
+int efi_bds_entry(struct efi_config *c)
+{
+ efi_status_t status;
+ efi_guid_t bds_guid = EFI_BDS_ARCH_PROTOCOL_GUID;
+
+ efi_loaded_image_t *image;
+ efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+ void * handle;
+
+serial_string("bds_entry\r\n");
+
+ if (efi_early_init(c) < 0)
+ return -1;
+
+/*
+ handle = (void *)(unsigned long)efi_early->image_handle;
+ status = efi_call_early(handle_protocol, handle,
+ &proto, (void *)&image);
+serial_string(status ? "ERROR\r\n" : "OK\r\n");
+
+ // tell DxeCore where to call us when it is ready
+ // for the kernel to startup for real
+ struct efi_bds_arch_protocol * bds;
+ status = efi_low_alloc(sys_table, sizeof(*bds), 1,
+ (unsigned long *)&bds);
+ bds->bds_main = efi_bds_main;
+ bds->config = c;
+*/
+
+ efi_bds_arch_protocol.bds_main = efi_bds_main;
+
+ handle = (void*)(uintptr_t) efi_early->image_handle;
+ status = efi_call_early(install_protocol_interface,
+ &handle,
+ &bds_guid,
+ 0, // EFI_NATIVE_INTERFACE
+ &efi_bds_arch_protocol
+ );
+
+serial_string(status ? "ERROR\r\n" : "OK\r\n");
+
+ return 0;
+}
+
+#endif
diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/head_64.S linux-4.9.80/arch/x86/boot/compressed/head_64.S
--- ./clean/linux-4.9.80/arch/x86/boot/compressed/head_64.S 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/arch/x86/boot/compressed/head_64.S 2018-02-07 15:51:28.534500400 -0500
@@ -268,6 +268,11 @@
addq %rbp, efi64_config+32(%rip)
movq %rax, %rdi
+#ifdef CONFIG_EFI_STUB_BDS // LinuxBoot (NERF) registers BDS and returns immediately
+ jmp efi_bds_entry
+#endif
+.global efi_restart
+efi_restart:
call make_boot_params
cmpq $0,%rax
je fail
diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/header.S linux-4.9.80/arch/x86/boot/header.S
--- ./clean/linux-4.9.80/arch/x86/boot/header.S 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/arch/x86/boot/header.S 2018-02-07 15:51:28.534500400 -0500
@@ -171,7 +171,11 @@
.long 0x200 # SizeOfHeaders
.long 0 # CheckSum
+#ifdef CONFIG_EFI_STUB_BDS
+ .word 0xb # Subsystem (EFI boot service)
+#else
.word 0xa # Subsystem (EFI application)
+#endif
.word 0 # DllCharacteristics
#ifdef CONFIG_X86_32
.long 0 # SizeOfStackReserve
diff --recursive -u ./clean/linux-4.9.80/arch/x86/Kconfig linux-4.9.80/arch/x86/Kconfig
--- ./clean/linux-4.9.80/arch/x86/Kconfig 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/arch/x86/Kconfig 2018-02-07 15:51:28.538500435 -0500
@@ -1786,6 +1786,15 @@
See Documentation/efi-stub.txt for more information.
+config EFI_STUB_BDS
+ bool "EFI BDS support"
+ depends on EFI_STUB
+ ---help---
+ This kernel feature allows a bzImage to act as the BDS
+ (Boot Device Selector) component of the EFI firmware.
+ Unless you're building a LinuxBoot system, you want to
+ say no.
+
config EFI_MIXED
bool "EFI mixed-mode support"
depends on EFI_STUB && X86_64
--- linux-4.14.56/include/linux/efi.h.orig 2018-07-17 05:39:34.000000000 -0400
+++ linux-4.14.56/include/linux/efi.h 2018-07-17 06:32:16.671000000 -0400
@@ -302,10 +302,10 @@
void *create_event;
void *set_timer;
void *wait_for_event;
- void *signal_event;
- void *close_event;
+ efi_status_t (*signal_event)(void *);
+ efi_status_t (*close_event)(void *);
void *check_event;
- void *install_protocol_interface;
+ efi_status_t (*install_protocol_interface)(efi_handle_t *, efi_guid_t *, int, void *);
void *reinstall_protocol_interface;
void *uninstall_protocol_interface;
efi_status_t (*handle_protocol)(efi_handle_t, efi_guid_t *, void **);
@@ -323,20 +323,20 @@
void *get_next_monotonic_count;
void *stall;
void *set_watchdog_timer;
- void *connect_controller;
+ efi_status_t (*connect_controller)(efi_handle_t, efi_handle_t *, void **, unsigned);
void *disconnect_controller;
void *open_protocol;
void *close_protocol;
void *open_protocol_information;
void *protocols_per_handle;
- void *locate_handle_buffer;
+ efi_status_t (*locate_handle_buffer)(unsigned, efi_guid_t *, void *, unsigned *, efi_handle_t **);
efi_status_t (*locate_protocol)(efi_guid_t *, void *, void **);
void *install_multiple_protocol_interfaces;
void *uninstall_multiple_protocol_interfaces;
void *calculate_crc32;
void *copy_mem;
void *set_mem;
- void *create_event_ex;
+ efi_status_t (*create_event_ex)(uint32_t type, unsigned tpl, void (*func)(void*), void *context, efi_guid_t *, void **event_out);
} efi_boot_services_t;
typedef enum {
@@ -629,6 +629,9 @@
#define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
#define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+#define EFI_BDS_ARCH_PROTOCOL_GUID EFI_GUID(0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D)
+#define EFI_EVENT_GROUP_READY_TO_BOOT EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
+
/*
* This GUID is used to pass to the kernel proper the struct screen_info
* structure that was populated by the stub based on the GOP protocol instance

View File

@ -0,0 +1,45 @@
diff -u --recursive ../../clean/linux-4.14.62/arch/x86/boot/compressed/eboot.c linux-4.14.62/arch/x86/boot/compressed/eboot.c
--- ../../clean/linux-4.14.62/arch/x86/boot/compressed/eboot.c 2018-08-09 06:16:40.000000000 -0400
+++ linux-4.14.62/arch/x86/boot/compressed/eboot.c 2018-08-09 10:13:11.801000000 -0400
@@ -630,8 +630,8 @@
u16 *s2;
u8 *s1;
int i;
- unsigned long ramdisk_addr;
- unsigned long ramdisk_size;
+ unsigned long ramdisk_addr = 0;
+ unsigned long ramdisk_size = 0;
efi_early = c;
sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
@@ -686,9 +686,6 @@
/* Fill in upper bits of command line address, NOP on 32 bit */
boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32;
- hdr->ramdisk_image = 0;
- hdr->ramdisk_size = 0;
-
/* Clear APM BIOS info */
memset(bi, 0, sizeof(*bi));
@@ -712,10 +709,16 @@
if (status != EFI_SUCCESS)
goto fail2;
- hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
- hdr->ramdisk_size = ramdisk_size & 0xffffffff;
- boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
- boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32;
+
+ // don't overwrite the bzImage or loader provided ramdisk pointer
+ // unless the kernel command line specified a different one.
+ if (ramdisk_addr != 0)
+ {
+ hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
+ hdr->ramdisk_size = ramdisk_size & 0xffffffff;
+ boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
+ boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32;
+ }
return boot_params;
fail2: