Merge branch 'linux-4.14-update'

This commit is contained in:
Trammell Hudson 2018-08-13 06:31:37 -04:00
commit 2be492d7fd
Failed to extract signature
14 changed files with 74 additions and 12365 deletions

View File

@ -137,7 +137,7 @@ CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00
CONFIG_DRIVERS_UART_8250IO=y
CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="QEMU x86 q35/ich9"
CONFIG_CPU_ADDR_BITS=36
CONFIG_DEFAULT_CONSOLE_LOGLEVEL=4
CONFIG_DEFAULT_CONSOLE_LOGLEVEL=6
# CONFIG_USBDEBUG is not set
CONFIG_MAINBOARD_VERSION="1.0"
CONFIG_DRIVERS_PS2_KEYBOARD=y
@ -480,9 +480,9 @@ CONFIG_CONSOLE_QEMU_DEBUGCON=y
CONFIG_CONSOLE_QEMU_DEBUGCON_PORT=0x402
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6=y
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4=y
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
modules-y += linux
linux_version := 4.9.80
linux_version := 4.14.62
linux_base_dir := linux-$(linux_version)
# TODO: fixup the patch process
@ -17,6 +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.62_hash := 51ca4d7e8ee156dc0f19bc7768915cfae41dbb0b4f251e4fa8b178c5674c22ab
linux_hash := $(linux-$(linux_version)_hash)
@ -24,11 +25,12 @@ linux_hash := $(linux-$(linux_version)_hash)
$(build)/$(linux_dir)/.configured: $(linux_kconfig)
linux_configure := \
$(MAKE) -C .. \
mkdir -p "$(build)/$(linux_dir)" \
&& cp "$(pwd)/$(linux_kconfig)" "$(build)/$(linux_dir)/.config" \
&& $(MAKE) -C .. \
CROSS_COMPILE="$(CROSS)" \
O="$(build)/$(linux_dir)" \
KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
oldconfig \
olddefconfig \
linux_output += arch/x86/boot/bzImage
@ -87,7 +89,6 @@ EXTRA_FLAGS := -fdebug-prefix-map=$(pwd)=heads -gno-record-gcc-switches
linux_target := \
O="$(build)/$(linux_dir)" \
KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
CROSS_COMPILE="$(CROSS)" \
AFLAGS_KERNEL="$(EXTRA_FLAGS)" \
CFLAGS_KERNEL="$(EXTRA_FLAGS)" \
@ -147,9 +148,18 @@ $(build)/$(BOARD)/bzImage: $(build)/$(linux_dir)/.build
# menuconfig target allows us to easily reconfigure this Linux kernel
# Afterwars make linux.saveconfig to generate a minimal config from it
linux.menuconfig:
$(MAKE) \
-C "$(build)/$(linux_base_dir)" \
O="$(build)/$(linux_dir)" \
KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
menuconfig \
# The config file in the repo is stored as a "defconfig" format
# which only includes the options that have changed from the defaults.
linux.saveconfig:
$(MAKE) \
-C "$(build)/$(linux_base_dir)" \
O="$(build)/$(linux_dir)" \
savedefconfig
mv "$(build)/$(linux_dir)/defconfig" "$(pwd)/$(linux_kconfig)"

View File

@ -36,6 +36,7 @@ linuxboot_target := \
KERNEL=$(build)/$(BOARD)/bzImage \
INITRD=$(build)/$(BOARD)/initrd.cpio.xz \
CUSTOM=$(CUSTOMPWD) \
CROSS=$(CROSS) \
$(if $(CONFIG_LINUXBOOT_ROM), ROM=$(pwd)/$(CONFIG_LINUXBOOT_ROM)) \
all

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:

View File

@ -1,708 +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
@@ -294,13 +299,18 @@
jne 2f
fail:
/* EFI init failed, so hang. */
+ mov $0x3f8, %dx /* ttyS0 */
+ mov '@', %ax
+fail_loop:
+ outb %al, (%dx)
hlt
- jmp fail
+ jmp fail_loop
2:
movl BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax
jmp *%rax
+.global preferred_addr
preferred_addr:
#endif
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
diff --recursive -u ./clean/linux-4.9.80/include/linux/efi.h linux-4.9.80/include/linux/efi.h
--- ./clean/linux-4.9.80/include/linux/efi.h 2018-02-03 11:05:43.000000000 -0500
+++ linux-4.9.80/include/linux/efi.h 2018-02-07 15:51:35.130557903 -0500
@@ -287,10 +287,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 **);
@@ -308,20 +308,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 {
@@ -592,6 +592,11 @@
#define EFI_RNG_PROTOCOL_GUID EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#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