#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum { BOOT_FROM_HDD, BOOT_FROM_PXE, BOOT_FROM_CD }; void entry(uint8_t _boot_drive, int boot_from) { boot_drive = _boot_drive; booted_from_pxe = (boot_from == BOOT_FROM_PXE); booted_from_cd = (boot_from == BOOT_FROM_CD); stage3_loaded = booted_from_cd; // CD loads both stages mtrr_save(); term_textmode(); print("Limine " LIMINE_VERSION "\n\n"); if (!a20_enable()) panic("Could not enable A20 line"); init_e820(); init_memmap(); struct volume part; volume_create_index(); switch (boot_from) { case BOOT_FROM_HDD: print("Boot drive: %x\n", boot_drive); // Look for config file. print("Searching for config file...\n"); for (int i = 0; ; i++) { int ret = volume_get_by_coord(&part, boot_drive, i); switch (ret) { case INVALID_TABLE: panic("Partition table of boot drive is invalid."); case END_OF_TABLE: panic("Config file not found."); case NO_PARTITION: continue; } if (!init_config_disk(&part)) { print("Config file found and loaded.\n"); boot_partition = i; break; } } break; case BOOT_FROM_PXE: pxe_init(); if (init_config_pxe()) { panic("Failed to load config file"); } print("Config loaded via PXE\n"); break; case BOOT_FROM_CD: boot_partition = -1; // raw device volume_get_by_coord(&part, boot_drive, boot_partition); if (init_config_disk(&part)) panic("Failed to load config file"); break; } char *cmdline; char *config = menu(&cmdline); char *proto = config_get_value(config, 0, "PROTOCOL"); if (proto == NULL) { panic("PROTOCOL not specified"); } if (!strcmp(proto, "stivale")) { stivale_load(config, cmdline); } else if (!strcmp(proto, "stivale2")) { stivale2_load(config, cmdline, boot_from); } else if (!strcmp(proto, "linux")) { linux_load(config, cmdline); } else if (!strcmp(proto, "chainload")) { chainload(config); } else { panic("Invalid protocol specified"); } }