mirror of
https://github.com/linuxboot/heads.git
synced 2025-02-22 09:51:07 +00:00
Remove the patch to Linux efivar_init() since we now have efi vars for it to use. Also link in SmbiosDxe, although it is not currently used.
345 lines
9.6 KiB
Diff
345 lines
9.6 KiB
Diff
diff -u --recursive ../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-09-22 14:55:37.055153767 -0400
|
|
@@ -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;
|
|
@@ -249,6 +314,12 @@
|
|
|
|
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 @@
|
|
}
|
|
}
|
|
|
|
+#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;
|
|
+}
|
|
+
|
|
/*
|
|
* Because the x86 boot code expects to be passed a boot_params we
|
|
* need to create one ourselves (usually the bootloader would create
|
|
@@ -739,8 +905,18 @@
|
|
sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
|
|
handle = (void *)(unsigned long)efi_early->image_handle;
|
|
|
|
+ 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->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
|
+ if (!sys_table || sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
|
return NULL;
|
|
|
|
if (efi_early->is64)
|
|
@@ -751,7 +927,6 @@
|
|
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 +989,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 +1262,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;
|
|
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
|
|
--- ../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
|
|
@@ -294,8 +294,12 @@
|
|
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
|
|
diff -u --recursive ../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-09-20 10:58:06.101915625 -0400
|
|
@@ -35,8 +35,8 @@
|
|
/* Has to be under 1M so we can execute real-mode AP code. */
|
|
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
|
|
if (!mem) {
|
|
- pr_info("No sub-1M memory is available for the trampoline\n");
|
|
- return;
|
|
+ mem = 0x4000;
|
|
+ pr_info("No sub-1M memory is available for the trampoline, guessing %p\n", mem);
|
|
}
|
|
|
|
memblock_reserve(mem, size);
|
|
@@ -138,7 +138,12 @@
|
|
static int __init init_real_mode(void)
|
|
{
|
|
if (!real_mode_header)
|
|
- panic("Real mode trampoline was not allocated");
|
|
+ {
|
|
+ // ignore for now
|
|
+ //panic("Real mode trampoline was not allocated");
|
|
+ pr_warn("Real mode trampoline was not allocated");
|
|
+ return 0;
|
|
+ }
|
|
|
|
setup_real_mode();
|
|
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
|
|
--- ../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
|
|
@@ -111,6 +111,8 @@
|
|
}
|
|
|
|
ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
|
|
+printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
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
|
|
--- ../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
|
|
@@ -168,12 +168,16 @@
|
|
|
|
status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
|
|
if (ACPI_FAILURE(status)) {
|
|
+printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
|
|
+ return_UINT32(ACPI_SYS_MODE_ACPI);
|
|
return_UINT32(ACPI_SYS_MODE_LEGACY);
|
|
}
|
|
|
|
if (value) {
|
|
return_UINT32(ACPI_SYS_MODE_ACPI);
|
|
} else {
|
|
+//printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
|
|
+// return_UINT32(ACPI_SYS_MODE_ACPI);
|
|
return_UINT32(ACPI_SYS_MODE_LEGACY);
|
|
}
|
|
}
|
|
diff -u --recursive ../clean/linux-4.9.38/init/initramfs.c linux-4.9.38/init/initramfs.c
|
|
--- ../clean/linux-4.9.38/init/initramfs.c 2017-07-15 06:17:55.000000000 -0400
|
|
+++ linux-4.9.38/init/initramfs.c 2017-09-20 10:58:06.101915625 -0400
|
|
@@ -609,7 +609,7 @@
|
|
{
|
|
char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
|
|
if (err)
|
|
- panic("%s", err); /* Failed to decompress INTERNAL initramfs */
|
|
+ panic("%s: %s", __func__, err); /* Failed to decompress INTERNAL initramfs */
|
|
if (initrd_start) {
|
|
#ifdef CONFIG_BLK_DEV_RAM
|
|
int fd;
|