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-09-19 14:55:16.395027896 -0400 @@ -16,6 +16,73 @@ #include "../string.h" #include "eboot.h" +#if 0 +#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; +} + +static void write_serial(char a) { + outb(a, PORT); + while (is_transmit_empty() == 0); +} + +static void write_serial_string(const char * s) +{ + while(*s) + write_serial(*s++); +} + +static void write_hex(unsigned long x, unsigned digits) +{ + while(digits-- > 0) + { + unsigned d = (x >> (digits * 4)) & 0xF; + if (d >= 0xA) + write_serial(d + 'A' - 0xA); + else + write_serial(d + '0'); + } + write_serial('\r'); + write_serial('\n'); +} +#endif + + + static efi_system_table_t *sys_table; static struct efi_config *efi_early; @@ -249,6 +316,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 +346,7 @@ efi_early->call(*func, out, str); } +#endif } static efi_status_t @@ -739,8 +813,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 +835,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; } @@ -1047,7 +1130,9 @@ status = efi_exit_boot_services(sys_table, handle, &map, &priv, exit_boot_func); if (status != EFI_SUCCESS) + { return status; + } e820ext = priv.e820ext; e820ext_size = priv.e820ext_size; @@ -1056,7 +1141,9 @@ status = setup_e820(boot_params, e820ext, e820ext_size); if (status != EFI_SUCCESS) + { return status; + } return EFI_SUCCESS; } 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-09-19 13:41:47.715096617 -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 --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-09-19 08:27:23.183585570 -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 --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 +++ ./linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-09-19 15:05:20.429486756 -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 --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 +++ ./linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-09-19 15:04:43.229254898 -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 --recursive -u ../clean/linux-4.9.38/drivers/acpi/acpica/tbfadt.c ./linux-4.9.38/drivers/acpi/acpica/tbfadt.c --- ../clean/linux-4.9.38/drivers/acpi/acpica/tbfadt.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/drivers/acpi/acpica/tbfadt.c 2017-09-19 13:46:37.599809800 -0400 @@ -344,6 +344,7 @@ /* Obtain the DSDT and FACS tables via their addresses within the FADT */ +#if 0 // NERF: the dsdt and facs tables will be updated later acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT. Xdsdt, ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, @@ -367,6 +368,7 @@ &acpi_gbl_xfacs_index); } } +#endif } /******************************************************************************* diff --recursive -u ../clean/linux-4.9.38/drivers/acpi/acpica/tbxface.c ./linux-4.9.38/drivers/acpi/acpica/tbxface.c --- ../clean/linux-4.9.38/drivers/acpi/acpica/tbxface.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/drivers/acpi/acpica/tbxface.c 2017-09-19 13:47:44.572900070 -0400 @@ -136,7 +136,11 @@ rsdp_address = acpi_os_get_root_pointer(); if (!rsdp_address) { - return_ACPI_STATUS(AE_NOT_FOUND); +// NERF: there is no root table since we came straight from DxeCore +printk("%s:%d No root table found, hoping for the best\n", __func__, __LINE__); + return_ACPI_STATUS(0); + //return_ACPI_STATUS(AE_NOT_FOUND); + //rsdp_address = fake_rsdp; } /* diff --recursive -u ../clean/linux-4.9.38/drivers/acpi/acpica/tbxfload.c ./linux-4.9.38/drivers/acpi/acpica/tbxfload.c --- ../clean/linux-4.9.38/drivers/acpi/acpica/tbxfload.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/drivers/acpi/acpica/tbxfload.c 2017-09-19 13:49:14.358362302 -0400 @@ -277,6 +277,7 @@ acpi_status status; u8 flags; u32 table_index; + union acpi_name_union * sig; ACPI_FUNCTION_TRACE(acpi_install_table); @@ -289,6 +290,30 @@ status = acpi_tb_install_standard_table(address, flags, FALSE, FALSE, &table_index); + if (!ACPI_SUCCESS(status)) + return_ACPI_STATUS(status); + + // NERF: the tables have been added *after* the root table + // was looked for, so we have to update the global pointers + // now that we have the actual tables. + sig = &acpi_gbl_root_table_list.tables[table_index].signature; + + if (ACPI_COMPARE_NAME(sig, ACPI_SIG_FADT)) { + printk("%s: FADT index=%d\n", __func__, table_index); + acpi_gbl_fadt_index = table_index; + acpi_tb_parse_fadt(); + } else + if (ACPI_COMPARE_NAME(sig, ACPI_SIG_FACS)) { + printk("%s: FACS index=%d\n", __func__, table_index); + acpi_gbl_facs_index = table_index; + } else + if (ACPI_COMPARE_NAME(sig, ACPI_SIG_DSDT)) { + printk("%s: DSDT index=%d\n", __func__, table_index); + acpi_gbl_dsdt_index = table_index; + } else { + // nothing special about this table + } + return_ACPI_STATUS(status); } diff --recursive -u ../clean/linux-4.9.38/drivers/acpi/tables.c ./linux-4.9.38/drivers/acpi/tables.c --- ../clean/linux-4.9.38/drivers/acpi/tables.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/drivers/acpi/tables.c 2017-09-19 13:50:47.511879998 -0400 @@ -475,7 +475,8 @@ ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA, ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, - ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL }; + ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_FACS, + NULL }; #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) @@ -487,8 +488,18 @@ void __init acpi_table_upgrade(void) { +#if 0 void *data = (void *)initrd_start; size_t size = initrd_end - initrd_start; +#else + // NERF: The initramfs that is bundled with the kernel has + // our tables in its cpio file. There is no boot loader to + // set the initrd_start variable, so we have to use this one. +extern char __initramfs_start[]; +extern unsigned long __initramfs_size; + void *data = (void *)__initramfs_start; + size_t size = __initramfs_size; +#endif int sig, no, table_nr = 0, total_offset = 0; long offset = 0; struct acpi_table_header *table; @@ -528,7 +539,11 @@ cpio_path, file.name); continue; } - if (acpi_table_checksum(file.data, table->length)) { + + // NERF: ignore checksum errors on FACS since it doesn't have one + // but allow it to be added anyway. + if (memcmp(table->signature, ACPI_SIG_FACS, 4) != 0 + && acpi_table_checksum(file.data, table->length)) { pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", cpio_path, file.name); continue; diff --recursive -u ../clean/linux-4.9.38/drivers/firmware/efi/vars.c ./linux-4.9.38/drivers/firmware/efi/vars.c --- ../clean/linux-4.9.38/drivers/firmware/efi/vars.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/drivers/firmware/efi/vars.c 2017-09-19 13:52:01.141079970 -0400 @@ -429,6 +429,12 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), void *data, bool duplicates, struct list_head *head) { + // NERF: We do not have the EfiVars protocol, so none of these + // routines will work. This avoids a possible kernel panic by + // not calling the random pointers in the runtime services. + printk("%s: not running\n", __func__); + return 0; + const struct efivar_operations *ops = __efivars->ops; unsigned long variable_name_size = 1024; efi_char16_t *variable_name; diff --recursive -u ../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-19 13:53:34.002593777 -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; diff --recursive -u ../clean/linux-4.9.38/init/main.c ./linux-4.9.38/init/main.c --- ../clean/linux-4.9.38/init/main.c 2017-07-15 06:17:55.000000000 -0400 +++ ./linux-4.9.38/init/main.c 2017-09-19 13:54:31.699534533 -0400 @@ -954,7 +954,9 @@ if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret) + { return 0; + } pr_err("Failed to execute %s (error %d)\n", ramdisk_execute_command, ret); } @@ -976,7 +978,9 @@ !try_to_run_init_process("/etc/init") || !try_to_run_init_process("/bin/init") || !try_to_run_init_process("/bin/sh")) + { return 0; + } panic("No working init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance.");