mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-24 07:06:42 +00:00
Add support for building the Linux kernel as a BDS target
This commit is contained in:
parent
517d242da5
commit
5a188f5b46
@ -450,6 +450,7 @@ CONFIG_ARCH_RANDOM=y
|
|||||||
# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set
|
# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set
|
||||||
CONFIG_EFI=y
|
CONFIG_EFI=y
|
||||||
CONFIG_EFI_STUB=y
|
CONFIG_EFI_STUB=y
|
||||||
|
CONFIG_EFI_STUB_BDS=y
|
||||||
# CONFIG_EFI_MIXED is not set
|
# CONFIG_EFI_MIXED is not set
|
||||||
# CONFIG_SECCOMP is not set
|
# CONFIG_SECCOMP is not set
|
||||||
# CONFIG_HZ_100 is not set
|
# CONFIG_HZ_100 is not set
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux-4.9.38/arch/x86/boot/compressed/eboot.c
|
diff --recursive -u clean/linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c
|
||||||
--- ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-07-15 06:17:55.000000000 -0400
|
--- clean/linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c 2017-07-15 06:17:55.000000000 -0400
|
||||||
+++ linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-09-22 14:55:37.055153767 -0400
|
+++ linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c 2017-12-01 16:03:10.524787842 -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.38/arch/x86/boot/compressed/eboot.c linux-4.9.38/arch/x86/boot/compressed/eboot.c
|
||||||
|
--- clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-07-15 06:17:55.000000000 -0400
|
||||||
|
+++ linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-12-04 13:44:42.902439205 -0500
|
||||||
@@ -16,6 +16,71 @@
|
@@ -16,6 +16,71 @@
|
||||||
#include "../string.h"
|
#include "../string.h"
|
||||||
#include "eboot.h"
|
#include "eboot.h"
|
||||||
@ -73,28 +83,7 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
static efi_system_table_t *sys_table;
|
static efi_system_table_t *sys_table;
|
||||||
|
|
||||||
static struct efi_config *efi_early;
|
static struct efi_config *efi_early;
|
||||||
@@ -249,6 +314,12 @@
|
@@ -710,6 +782,132 @@
|
||||||
|
|
||||||
void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
|
|
||||||
{
|
|
||||||
+#if 0
|
|
||||||
+ while(*str)
|
|
||||||
+ {
|
|
||||||
+ write_serial((char) *str++);
|
|
||||||
+ }
|
|
||||||
+#else
|
|
||||||
unsigned long output_string;
|
|
||||||
size_t offset;
|
|
||||||
|
|
||||||
@@ -273,6 +344,7 @@
|
|
||||||
|
|
||||||
efi_early->call(*func, out, str);
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static efi_status_t
|
|
||||||
@@ -710,6 +782,100 @@
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,13 +181,15 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
+ return -1;
|
+ return -1;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
/*
|
+
|
||||||
* Because the x86 boot code expects to be passed a boot_params we
|
+static int efi_early_init(struct efi_config * c)
|
||||||
* need to create one ourselves (usually the bootloader would create
|
+{
|
||||||
@@ -739,8 +905,18 @@
|
+ if (efi_early)
|
||||||
sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
|
+ return 0;
|
||||||
handle = (void *)(unsigned long)efi_early->image_handle;
|
+
|
||||||
|
+ efi_early = c;
|
||||||
|
+ sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
|
||||||
|
+
|
||||||
+ if(!sys_table)
|
+ if(!sys_table)
|
||||||
+ {
|
+ {
|
||||||
+ // We're NERFed and are the "DxeCore", so there is no system
|
+ // We're NERFed and are the "DxeCore", so there is no system
|
||||||
@ -209,13 +200,43 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
+ outb('!', 0x3f8);
|
+ outb('!', 0x3f8);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
/* Check if we were booted by the EFI firmware */
|
+ /* Check if we were booted by the EFI firmware */
|
||||||
- if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
|
||||||
+ if (!sys_table || sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
+ 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 +933,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;
|
return NULL;
|
||||||
|
|
||||||
if (efi_early->is64)
|
- if (efi_early->is64)
|
||||||
@@ -751,7 +927,6 @@
|
- 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,
|
status = efi_call_early(handle_protocol, handle,
|
||||||
&proto, (void *)&image);
|
&proto, (void *)&image);
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
@ -223,7 +244,7 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,6 +989,21 @@
|
@@ -814,6 +1006,21 @@
|
||||||
|
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
@ -245,7 +266,7 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
|
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
|
||||||
hdr->ramdisk_size = ramdisk_size & 0xffffffff;
|
hdr->ramdisk_size = ramdisk_size & 0xffffffff;
|
||||||
boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
|
boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
|
||||||
@@ -1068,6 +1262,7 @@
|
@@ -1068,6 +1275,7 @@
|
||||||
struct boot_params *efi_main(struct efi_config *c,
|
struct boot_params *efi_main(struct efi_config *c,
|
||||||
struct boot_params *boot_params)
|
struct boot_params *boot_params)
|
||||||
{
|
{
|
||||||
@ -253,10 +274,332 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux
|
|||||||
struct desc_ptr *gdt = NULL;
|
struct desc_ptr *gdt = NULL;
|
||||||
efi_loaded_image_t *image;
|
efi_loaded_image_t *image;
|
||||||
struct setup_header *hdr = &boot_params->hdr;
|
struct setup_header *hdr = &boot_params->hdr;
|
||||||
diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S linux-4.9.38/arch/x86/boot/compressed/head_64.S
|
@@ -1079,12 +1287,14 @@
|
||||||
--- ../clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-07-15 06:17:55.000000000 -0400
|
|
||||||
+++ linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-09-20 10:58:06.101915625 -0400
|
efi_early = c;
|
||||||
@@ -294,8 +294,12 @@
|
|
||||||
|
+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 +1308,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 +1336,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 +1345,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 +1409,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\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\n");
|
||||||
|
+ efi_event_signal(ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID);
|
||||||
|
+
|
||||||
|
+ // signal that dxe is about to end
|
||||||
|
+serial_string("signal dxe end\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\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.38/arch/x86/boot/compressed/head_64.S linux-4.9.38/arch/x86/boot/compressed/head_64.S
|
||||||
|
--- clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-07-15 06:17:55.000000000 -0400
|
||||||
|
+++ linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-12-01 15:46:51.952803007 -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
|
jne 2f
|
||||||
fail:
|
fail:
|
||||||
/* EFI init failed, so hang. */
|
/* EFI init failed, so hang. */
|
||||||
@ -270,9 +613,49 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S lin
|
|||||||
2:
|
2:
|
||||||
movl BP_code32_start(%esi), %eax
|
movl BP_code32_start(%esi), %eax
|
||||||
leaq preferred_addr(%rax), %rax
|
leaq preferred_addr(%rax), %rax
|
||||||
diff -u --recursive ../clean/linux-4.9.38/arch/x86/realmode/init.c linux-4.9.38/arch/x86/realmode/init.c
|
jmp *%rax
|
||||||
--- ../clean/linux-4.9.38/arch/x86/realmode/init.c 2017-07-15 06:17:55.000000000 -0400
|
|
||||||
+++ linux-4.9.38/arch/x86/realmode/init.c 2017-09-20 10:58:06.101915625 -0400
|
+.global preferred_addr
|
||||||
|
preferred_addr:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --recursive -u clean/linux-4.9.38/arch/x86/boot/header.S linux-4.9.38/arch/x86/boot/header.S
|
||||||
|
--- clean/linux-4.9.38/arch/x86/boot/header.S 2017-07-15 06:17:55.000000000 -0400
|
||||||
|
+++ linux-4.9.38/arch/x86/boot/header.S 2017-12-01 09:59:11.737255340 -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.38/arch/x86/Kconfig linux-4.9.38/arch/x86/Kconfig
|
||||||
|
--- clean/linux-4.9.38/arch/x86/Kconfig 2017-07-15 06:17:55.000000000 -0400
|
||||||
|
+++ linux-4.9.38/arch/x86/Kconfig 2017-12-01 09:58:28.892507523 -0500
|
||||||
|
@@ -1772,6 +1772,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.38/arch/x86/realmode/init.c linux-4.9.38/arch/x86/realmode/init.c
|
||||||
|
--- clean/linux-4.9.38/arch/x86/realmode/init.c 2017-07-15 06:17:55.000000000 -0400
|
||||||
|
+++ linux-4.9.38/arch/x86/realmode/init.c 2017-10-11 18:38:36.027243511 -0400
|
||||||
@@ -35,8 +35,8 @@
|
@@ -35,8 +35,8 @@
|
||||||
/* Has to be under 1M so we can execute real-mode AP code. */
|
/* Has to be under 1M so we can execute real-mode AP code. */
|
||||||
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
|
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
|
||||||
@ -298,9 +681,9 @@ diff -u --recursive ../clean/linux-4.9.38/arch/x86/realmode/init.c linux-4.9.38/
|
|||||||
|
|
||||||
setup_real_mode();
|
setup_real_mode();
|
||||||
set_real_mode_permissions();
|
set_real_mode_permissions();
|
||||||
diff -u --recursive ../clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c linux-4.9.38/drivers/acpi/acpica/evxfevnt.c
|
diff --recursive -u clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c linux-4.9.38/drivers/acpi/acpica/evxfevnt.c
|
||||||
--- ../clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-07-15 06:17:55.000000000 -0400
|
--- clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-07-15 06:17:55.000000000 -0400
|
||||||
+++ linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-09-20 10:58:06.101915625 -0400
|
+++ linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-10-11 18:38:36.027243511 -0400
|
||||||
@@ -111,6 +111,8 @@
|
@@ -111,6 +111,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,9 +693,9 @@ diff -u --recursive ../clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c linux-4
|
|||||||
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
|
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
diff -u --recursive ../clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c linux-4.9.38/drivers/acpi/acpica/hwacpi.c
|
diff --recursive -u clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c linux-4.9.38/drivers/acpi/acpica/hwacpi.c
|
||||||
--- ../clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-07-15 06:17:55.000000000 -0400
|
--- clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-07-15 06:17:55.000000000 -0400
|
||||||
+++ linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-09-20 10:58:06.101915625 -0400
|
+++ linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-10-11 18:38:36.027243511 -0400
|
||||||
@@ -168,12 +168,16 @@
|
@@ -168,12 +168,16 @@
|
||||||
|
|
||||||
status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
|
status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
|
||||||
@ -330,15 +713,56 @@ diff -u --recursive ../clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c linux-4.9
|
|||||||
return_UINT32(ACPI_SYS_MODE_LEGACY);
|
return_UINT32(ACPI_SYS_MODE_LEGACY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff -u --recursive ../clean/linux-4.9.38/init/initramfs.c linux-4.9.38/init/initramfs.c
|
diff --recursive -u clean/linux-4.9.38/include/linux/efi.h linux-4.9.38/include/linux/efi.h
|
||||||
--- ../clean/linux-4.9.38/init/initramfs.c 2017-07-15 06:17:55.000000000 -0400
|
--- clean/linux-4.9.38/include/linux/efi.h 2017-07-15 06:17:55.000000000 -0400
|
||||||
+++ linux-4.9.38/init/initramfs.c 2017-09-20 10:58:06.101915625 -0400
|
+++ linux-4.9.38/include/linux/efi.h 2017-11-30 13:46:12.391653428 -0500
|
||||||
@@ -609,7 +609,7 @@
|
@@ -287,10 +287,10 @@
|
||||||
{
|
void *create_event;
|
||||||
char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
|
void *set_timer;
|
||||||
if (err)
|
void *wait_for_event;
|
||||||
- panic("%s", err); /* Failed to decompress INTERNAL initramfs */
|
- void *signal_event;
|
||||||
+ panic("%s: %s", __func__, err); /* Failed to decompress INTERNAL initramfs */
|
- void *close_event;
|
||||||
if (initrd_start) {
|
+ efi_status_t (*signal_event)(void *);
|
||||||
#ifdef CONFIG_BLK_DEV_RAM
|
+ efi_status_t (*close_event)(void *);
|
||||||
int fd;
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user