#include "lnxboot.h" #include "util.h" #include "efi/types.h" #include "efi/memmap.h" #include "efi/guid.h" unsigned short serial_port; void outb(unsigned short port, unsigned char value) { asm volatile ( "outb %b0, %1" ::"a" (value) ,"d" (port) ); } void serial_putc(char c) { outb(serial_port, c); } void serial_puts(const char* s) { while (*s) serial_putc(*(s++)); } void serial_put_formatted_u64(u64 v) { if (v == 0) { serial_putc('0'); } else { u64 max = 1; while (v > max) max *= 10; while (v) { serial_putc('0' + (u8)(v / max)); v %= max; max /= 10; } } } /** * We can't do anything, just hang. */ [[noreturn, gnu::naked]] void Hang() { // This should make us hang asm volatile ( " cli\n" "1: hlt\n" " jmp 1b" ); } /** * Congratulations, you panicked twice! */ [[noreturn]] void Panic(const char* message) { // We don't even do anything with the message, but it's nice to have just in case. Hang(); } void entry64(struct boot_params* boot_params) { while (1) {}; Panic("HELLO WORLD."); /* // get command line from kernel. we likely won't use it, but its nice to have. u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); // do we have efi? struct EfiSystemTable* systab_ptr = 0; if (boot_params) { systab_ptr = (struct EfiSystemTable*)( (u64)boot_params->efi_info.EfiSystemTable | ((u64)boot_params->efi_info.EfiSystemTableHigh << 32) ); EfiLoadStoredMemoryMap( (struct EfiMemoryDescription*)( (u64)boot_params->efi_info.EfiMemoryMap | ((u64)boot_params->efi_info.EfiMemoryMapHigh << 32) ), // this might be 0, we should probably check ---------------V boot_params->efi_info.EfiMemoryMapSize / boot_params->efi_info.EfiMemoryDescriptionSize, boot_params->efi_info.EfiMemoryDescriptionSize ); } // -- find acpi -- struct AcpiRSDP* AcpiRSDP = 0; // check bootparams if (boot_params->acpi_rsdp_addr) AcpiRSDP = boot_params->acpi_rsdp_addr; while (true) { volatile void* a = &EFI_ACPI_20_TABLE_GUID; } // check efi if (!AcpiRSDP && systab_ptr && systab_ptr->NumberOfTableEntries) { struct EfiConfigurationTable* ConfigurationTable = EfiTranslatePointer(systab_ptr->ConfigurationTable); for (int i = 0; i < systab_ptr->NumberOfTableEntries; i++) { if (CompareMemory(&ConfigurationTable[i].VendorGuid, &EFI_ACPI_20_TABLE_GUID, sizeof(EfiGuid))) { AcpiRSDP = ConfigurationTable[i].VendorTable; while (true) { volatile void* a = AcpiRSDP; } break; } } } // we're playing where's waldo with this stupid fucking tableS if (!AcpiRSDP) { for (struct AcpiRSDP* addr = 0x00000000; addr < 0x000FFFFF; addr = (void*)addr + 16) { if (addr->Signature[0] == 'R' && addr->Signature[1] == 'S' && addr->Signature[2] == 'D' && addr->Signature[3] == ' ' && addr->Signature[4] == 'P' && addr->Signature[5] == 'T' && addr->Signature[6] == 'R' && addr->Signature[7] == ' ') { AcpiRSDP = addr; break; } } } if (!AcpiRSDP) Panic("Failed to find ACPI RSDP"); // do we have acpi? while (1) { volatile void* p = AcpiRSDP; } // we dont have the privilege of getting a rodata segment. any reads off our stack cause a triple fault // for some fucking reason. allocate our strings and shit on the stack. //char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n"; //char s_vga_you_fucked_up[] = "YOU FUCKED UP.\n"; //char s_description[] = "A SERIOUS ERROR HAS OCCURED AND LINDOWS HAS STOPPED TO PREVENT FURTHER DAMAGE."; //char s_registers[] = "REGISTERS:"; //char s_call_trace[] = "CALL TRACE:"; //char s_dumpcore[] = "[(D)UMP CORE]"; //char s_poweroff[] = "[(P)OWER OFF]"; //char s_reboot[] = "[(R)EBOOT ]"; // You fucked up. //serial_puts(s_you_fucked_up); //serial_puts(s_description); //serial_putc('\n'); // register dump //serial_puts(s_registers); //serial_putc('\n'); //serial_putc('\n'); // call trace //serial_puts(s_call_trace); //serial_putc('\n'); //serial_putc('\n'); // thing // serial_puts("test\n"); // serial_puts(bzhead.cmd_line_ptr); // Die.*/ Panic("Nothing left to do."); }