123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912 |
- static mboot_mod_t modules_mboot[sizeof(modules)/sizeof(*modules)] = {
- {0,0,0,1}
- };
- static struct multiboot multiboot_header = {
- /* flags; */ MULTIBOOT_FLAG_CMDLINE | MULTIBOOT_FLAG_MODS | MULTIBOOT_FLAG_MEM | MULTIBOOT_FLAG_MMAP | MULTIBOOT_FLAG_LOADER,
- /* mem_lower; */ 0x100000,
- /* mem_upper; */ 0x640000,
- /* boot_device; */ 0,
- /* cmdline; */ 0,
- /* mods_count; */ sizeof(modules)/sizeof(*modules),
- /* mods_addr; */ 0,
- /* num; */ 0,
- /* size; */ 0,
- /* addr; */ 0,
- /* shndx; */ 0,
- /* mmap_length; */ 0,
- /* mmap_addr; */ 0,
- /* drives_length; */ 0,
- /* drives_addr; */ 0,
- /* config_table; */ 0,
- /* boot_loader_name; */ 0,
- /* apm_table; */ 0,
- /* vbe_control_info; */ 0,
- /* vbe_mode_info; */ 0,
- /* vbe_mode; */ 0,
- /* vbe_interface_seg; */ 0,
- /* vbe_interface_off; */ 0,
- /* vbe_interface_len; */ 0,
- };
- static long ramdisk_off = 1;
- static long ramdisk_len = 1;
- int _eax = 1;
- int _ebx = 1;
- int _xmain = 1;
- struct mmap_entry {
- uint64_t base;
- uint64_t len;
- uint32_t type;
- uint32_t reserved;
- };
- extern unsigned short mmap_ent;
- extern unsigned short lower_mem;
- char * final_offset = NULL;
- extern char do_the_nasty[];
- static int strlen(char * s) {
- int out = 0;
- while (*s) {
- s++;
- out++;
- }
- return out;
- }
- #ifdef EFI_PLATFORM
- static EFI_GUID efi_graphics_output_protocol_guid =
- {0x9042a9de,0x23dc,0x4a38, {0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a}};
- #endif
- static void move_kernel(void) {
- clear();
- print("Relocating kernel...\n");
- Elf32_Header * header = (Elf32_Header *)KERNEL_LOAD_START;
- if (header->e_ident[0] != ELFMAG0 ||
- header->e_ident[1] != ELFMAG1 ||
- header->e_ident[2] != ELFMAG2 ||
- header->e_ident[3] != ELFMAG3) {
- print("Kernel is invalid?\n");
- }
- uintptr_t entry = (uintptr_t)header->e_entry;
- for (uintptr_t x = 0; x < (uint32_t)header->e_phentsize * header->e_phnum; x += header->e_phentsize) {
- Elf32_Phdr * phdr = (Elf32_Phdr *)((uint8_t*)KERNEL_LOAD_START + header->e_phoff + x);
- if (phdr->p_type == PT_LOAD) {
- //read_fs(file, phdr->p_offset, phdr->p_filesz, (uint8_t *)phdr->p_vaddr);
- print("Loading a Phdr... ");
- print_hex(phdr->p_vaddr);
- print(" ");
- print_hex(phdr->p_offset);
- print(" ");
- print_hex(phdr->p_filesz);
- print("\n");
- #ifdef EFI_PLATFORM
- EFI_PHYSICAL_ADDRESS addr = phdr->p_vaddr;
- uefi_call_wrapper(ST->BootServices->AllocatePages, 3, AllocateAddress, 0x80000000, phdr->p_memsz / 4096 + 1, &addr);
- #endif
- memcpy((uint8_t*)(uintptr_t)phdr->p_vaddr, (uint8_t*)KERNEL_LOAD_START + phdr->p_offset, phdr->p_filesz);
- long r = phdr->p_filesz;
- while (r < phdr->p_memsz) {
- *(char *)(phdr->p_vaddr + r) = 0;
- r++;
- }
- }
- }
- print("Setting up memory map...\n");
- #ifdef EFI_PLATFORM
- mboot_memmap_t * mmap = (void*)KERNEL_LOAD_START;
- memset((void*)KERNEL_LOAD_START, 0x00, 1024);
- multiboot_header.mmap_addr = (uintptr_t)mmap;
- EFI_STATUS e;
- UINTN mapSize = 0, mapKey, descriptorSize;
- UINT32 descriptorVersion;
- e = uefi_call_wrapper(ST->BootServices->GetMemoryMap, 5, &mapSize, NULL, &mapKey, &descriptorSize, NULL);
- print_("Memory map size is "); print_hex_(mapSize); print_("\n");
- EFI_MEMORY_DESCRIPTOR * efi_memory = (void*)(final_offset);
- final_offset += mapSize;
- while ((uintptr_t)final_offset & 0x3ff) final_offset++;
- e = uefi_call_wrapper(ST->BootServices->GetMemoryMap, 5, &mapSize, efi_memory, &mapKey, &descriptorSize, NULL);
- if (EFI_ERROR(e)) {
- print_("EFI error.\n");
- }
- uint64_t upper_mem = 0;
- int descriptors = mapSize / descriptorSize;
- for (int i = 0; i < descriptors; ++i) {
- EFI_MEMORY_DESCRIPTOR * d = efi_memory;
- mmap->size = sizeof(uint64_t) * 2 + sizeof(uintptr_t);
- mmap->base_addr = d->PhysicalStart;
- mmap->length = d->NumberOfPages * 4096;
- switch (d->Type) {
- case EfiConventionalMemory:
- case EfiLoaderCode:
- case EfiLoaderData:
- case EfiBootServicesCode:
- case EfiBootServicesData:
- case EfiRuntimeServicesCode:
- case EfiRuntimeServicesData:
- case EfiACPIReclaimMemory:
- mmap->type = 1;
- break;
- case EfiReservedMemoryType:
- case EfiUnusableMemory:
- case EfiMemoryMappedIO:
- case EfiMemoryMappedIOPortSpace:
- case EfiPalCode:
- case EfiACPIMemoryNVS:
- default:
- mmap->type = 2;
- break;
- }
- if (mmap->type == 1 && mmap->base_addr >= 0x100000) {
- upper_mem += mmap->length;
- }
- mmap = (mboot_memmap_t *) ((uintptr_t)mmap + mmap->size + sizeof(uintptr_t));
- efi_memory = (EFI_MEMORY_DESCRIPTOR *)((char *)efi_memory + descriptorSize);
- }
- multiboot_header.mem_lower = 1024;
- multiboot_header.mem_upper = upper_mem / 1024;
- /* Set up framebuffer */
- if (_efi_do_mode_set) {
- UINTN count;
- EFI_HANDLE * handles;
- EFI_GRAPHICS_OUTPUT_PROTOCOL * gfx;
- EFI_STATUS status;
- status = uefi_call_wrapper(ST->BootServices->LocateHandleBuffer,
- 5, ByProtocol, &efi_graphics_output_protocol_guid, NULL, &count, &handles);
- if (EFI_ERROR(status)) {
- print_("Error getting graphics device handle.\n");
- while (1) {};
- }
- status = uefi_call_wrapper(ST->BootServices->HandleProtocol,
- 3, handles[0], &efi_graphics_output_protocol_guid, (void **)&gfx);
- if (EFI_ERROR(status)) {
- print_("Error getting graphics device.\n");
- while (1) {};
- }
- #if 0
- print_("Attempting to set a sane mode (32bit color, etc.)\n");
- print_("There are 0x"); print_hex_(gfx->Mode->MaxMode); print_(" modes available.\n");
- print_("This is mode 0x"); print_hex_(gfx->Mode->Mode); print_(".\n");
- #endif
- int biggest = gfx->Mode->Mode;
- int big_width = 0;
- int big_height = 0;
- clear_();
- for (int i = 0; i < gfx->Mode->MaxMode; ++i) {
- EFI_STATUS status;
- UINTN size;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info;
- status = uefi_call_wrapper(gfx->QueryMode,
- 4, gfx, i, &size, &info);
- if (EFI_ERROR(status)) {
- print_("Error getting gfx mode 0x"); print_hex_(i); print_("\n");
- } else {
- print_("Mode "); print_int_(i); print_(" "); print_int_(info->HorizontalResolution);
- print_("x"); print_int_(info->VerticalResolution); print_(" ");
- print_int_(info->PixelFormat); print_("\n");
- if (_efi_do_mode_set == 1) {
- if (info->PixelFormat == 1 && info->HorizontalResolution >= big_width) {
- biggest = i;
- big_width = info->HorizontalResolution;
- }
- } else if (_efi_do_mode_set == 2) {
- if (info->PixelFormat == 1 && info->HorizontalResolution == 1024 &&
- info->VerticalResolution == 768) {
- biggest = i;
- break;
- }
- } else if (_efi_do_mode_set == 3) {
- if (info->PixelFormat == 1 && info->HorizontalResolution == 1920 &&
- info->VerticalResolution == 1080) {
- biggest = i;
- break;
- }
- } else if (_efi_do_mode_set == 4) {
- while (1) {
- print_("y/n? ");
- int resp = read_scancode();
- if (resp == 'y') {
- print_("y\n");
- biggest = i;
- goto done_video;
- } else if (resp == 'n') {
- print_("n\n");
- break;
- }
- print_("?\n");
- }
- }
- }
- }
- done_video:
- print_("Selected video mode was "); print_int_(biggest); print_("\n");
- uefi_call_wrapper(gfx->SetMode, 2, gfx, biggest);
- uint32_t high = gfx->Mode->FrameBufferBase >> 32;
- uint32_t low = gfx->Mode->FrameBufferBase & 0xFFFFFFFF;
- print_("Framebuffer address is 0x"); print_hex_(high); print_hex_(low); print_("\n");
- if (high) {
- clear_();
- print_("Framebuffer is outside of 32-bit memory range.\n");
- print_("EFI mode setting is not available - and graphics may not work in general.\n");
- while (1) {};
- }
- multiboot_header.flags |= (1 << 12); /* Enable framebuffer flag */
- multiboot_header.framebuffer_addr = low;
- multiboot_header.framebuffer_width = gfx->Mode->Info->HorizontalResolution;
- multiboot_header.framebuffer_height = gfx->Mode->Info->VerticalResolution;
- multiboot_header.framebuffer_pitch = gfx->Mode->Info->PixelsPerScanLine * 4;
- print_("Mode information passed to multiboot:\n");
- print_(" Address: 0x"); print_hex_(multiboot_header.framebuffer_addr); print_("\n");
- print_(" Width: "); print_int_(multiboot_header.framebuffer_width); print_("\n");
- print_(" Height: "); print_int_(multiboot_header.framebuffer_height); print_("\n");
- print_("\n");
- }
- memcpy(final_offset, cmdline, strlen(cmdline)+1);
- multiboot_header.cmdline = (uintptr_t)final_offset;
- final_offset += strlen(cmdline)+1;
- memcpy(final_offset, VERSION_TEXT, strlen(VERSION_TEXT)+1);
- multiboot_header.boot_loader_name = (uintptr_t)final_offset;
- final_offset += strlen(VERSION_TEXT)+1;
- while ((uintptr_t)final_offset & 0x3ff) final_offset++;
- multiboot_header.mods_addr = (uintptr_t)final_offset;
- memcpy(final_offset, &modules_mboot, sizeof(modules_mboot));
- final_offset += sizeof(modules_mboot);
- while ((uintptr_t)final_offset & 0x3ff) final_offset++;
- memcpy(final_offset, &multiboot_header, sizeof(multiboot_header));
- _ebx = (uintptr_t)final_offset;
- print("Jumping to main, good luck.\n");
- #else
- print_hex(mmap_ent);
- print("\n");
- memset((void*)KERNEL_LOAD_START, 0x00, 1024);
- mboot_memmap_t * mmap = (void*)KERNEL_LOAD_START;
- multiboot_header.mmap_addr = (uintptr_t)mmap;
- multiboot_header.mods_addr = (uintptr_t)&modules_mboot;
- multiboot_header.boot_loader_name = (uintptr_t)VERSION_TEXT;
- struct mmap_entry * e820 = (void*)0x5000;
- uint64_t upper_mem = 0;
- for (int i = 0; i < mmap_ent; ++i) {
- print("entry "); print_hex(i); print("\n");
- print("base: "); print_hex((uint32_t)e820[i].base); print("\n");
- print("type: "); print_hex(e820[i].type); print("\n");
- mmap->size = sizeof(uint64_t) * 2 + sizeof(uintptr_t);
- mmap->base_addr = e820[i].base;
- mmap->length = e820[i].len;
- mmap->type = e820[i].type;
- if (mmap->type == 1 && mmap->base_addr >= 0x100000) {
- upper_mem += mmap->length;
- }
- mmap = (mboot_memmap_t *) ((uintptr_t)mmap + mmap->size + sizeof(uintptr_t));
- }
- print("lower "); print_hex(lower_mem); print("KB\n");
- multiboot_header.mem_lower = 1024;
- print("upper ");
- print_hex(upper_mem >> 32);
- print_hex(upper_mem);
- print("\n");
-
- multiboot_header.mem_upper = upper_mem / 1024;
- _ebx = (unsigned int)&multiboot_header;
- #endif
- _eax = MULTIBOOT_EAX_MAGIC;
- _xmain = entry;
- #ifdef EFI_PLATFORM
- print_("\nExiting boot services and jumping to ");
- print_hex_(_xmain);
- print_(" with mboot_mag=");
- print_hex_(_eax);
- print_(" and mboot_ptr=");
- print_hex_(_ebx);
- print_("...\n");
- #if defined(__x86_64__)
- print_("&_xmain = "); print_hex_(((uintptr_t)&_xmain) >> 32); print_hex_((uint32_t)(uintptr_t)&_xmain); print_("\n");
- #endif
- if (1) {
- EFI_STATUS e;
- UINTN mapSize = 0, mapKey, descriptorSize;
- UINT32 descriptorVersion;
- uefi_call_wrapper(ST->BootServices->GetMemoryMap, 5, &mapSize, NULL, &mapKey, &descriptorSize, NULL);
- e = uefi_call_wrapper(ST->BootServices->ExitBootServices, 2, ImageHandleIn, mapKey);
- if (e != EFI_SUCCESS) {
- print_("Exit services failed. \n");
- print_hex_(e);
- }
- }
- #endif
- #if defined(__x86_64__)
- uint64_t foobar = ((uint32_t)(uintptr_t)&do_the_nasty) | (0x10L << 32L);
- uint32_t * foo = (uint32_t *)0x7c00;
- foo[0] = _eax;
- foo[1] = _ebx;
- foo[2] = _xmain;
- __asm__ __volatile__ (
- "push %0\n"
- "retf\n"
- : : "g"(foobar));
- #else
- __asm__ __volatile__ (
- "mov %1,%%eax \n"
- "mov %2,%%ebx \n"
- "jmp *%0" : : "g"(_xmain), "g"(_eax), "g"(_ebx) : "eax", "ebx"
- );
- #endif
- }
- #if defined(__x86_64__)
- __asm__ (
- "do_the_nasty:\n"
- "cli\n"
- //"mov 0x08, %ax\n"
- //"mov %ax, %ds\n"
- //"mov %ax, %es\n"
- //"mov %ax, %fs\n"
- //"mov %ax, %gs\n"
- //"mov %ax, %ss\n"
- ".code32\n"
- "mov %cr0, %eax\n"
- "and $0x7FFeFFFF, %eax\n"
- "mov %eax, %cr0\n"
- // Paging is disabled
- "mov $0xc0000080, %ecx\n"
- "rdmsr\n"
- "and $0xfffffeff, %eax\n"
- "wrmsr\n"
- "mov $0x640, %eax\n"
- "mov %eax, %cr4\n"
- "mov 0x7c00, %eax\n"
- "mov 0x7c04, %ebx\n"
- "mov 0x7c08, %ecx\n"
- "jmp *%ecx\n"
- "target: jmp target\n"
- ".code64\n"
- );
- #endif
- #ifndef EFI_PLATFORM
- static void do_it(struct ata_device * _device) {
- device = _device;
- if (device->atapi_sector_size != 2048) {
- print_hex(device->atapi_sector_size);
- print("\n - bad sector size\n");
- return;
- }
- for (int i = 0x10; i < 0x15; ++i) {
- ata_device_read_sector_atapi(device, i, (uint8_t *)root);
- switch (root->type) {
- case 1:
- root_sector = i;
- goto done;
- case 0xFF:
- return;
- }
- }
- return;
- done:
- restore_root();
- if (navigate(kernel_path)) {
- print("Found kernel.\n");
- print_hex(dir_entry->extent_start_LSB); print(" ");
- print_hex(dir_entry->extent_length_LSB); print("\n");
- long offset = 0;
- for (int i = dir_entry->extent_start_LSB; i < dir_entry->extent_start_LSB + dir_entry->extent_length_LSB / 2048 + 1; ++i, offset += 2048) {
- ata_device_read_sector_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset);
- }
- while (offset % 4096) offset++;
- restore_root();
- if (navigate(module_dir)) {
- memcpy(mod_dir, dir_entry, sizeof(iso_9660_directory_entry_t));
- print("Scanning modules...\n");
- char ** c = modules;
- int j = 0;
- while (*c) {
- print("load "); print(*c); print("\n");
- if (!navigate(*c)) {
- print("Failed to locate module! [");
- print(*c);
- multiboot_header.mods_count--;
- print("]\n");
- } else {
- modules_mboot[j].mod_start = KERNEL_LOAD_START + offset;
- modules_mboot[j].mod_end = KERNEL_LOAD_START + offset + dir_entry->extent_length_LSB;
- for (int i = dir_entry->extent_start_LSB; i < dir_entry->extent_start_LSB + dir_entry->extent_length_LSB / 2048 + 1; ++i, offset += 2048) {
- ata_device_read_sector_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset);
- }
- while (offset % 4096) offset++;
- j++;
- }
- c++;
- restore_mod();
- }
- print("Done.\n");
- restore_root();
- if (navigate(ramdisk_path)) {
- //clear_();
- ramdisk_off = KERNEL_LOAD_START + offset;
- ramdisk_len = dir_entry->extent_length_LSB;
- modules_mboot[multiboot_header.mods_count-1].mod_start = ramdisk_off;
- modules_mboot[multiboot_header.mods_count-1].mod_end = ramdisk_off + ramdisk_len;
- print_("Loading ramdisk");
- int i = dir_entry->extent_start_LSB;
- int sectors = dir_entry->extent_length_LSB / 2048 + 1;
- #define SECTORS 512
- while (sectors >= SECTORS) {
- print_(".");
- ata_device_read_sectors_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset, SECTORS);
- sectors -= SECTORS;
- offset += 2048 * SECTORS;
- i += SECTORS;
- }
- if (sectors > 0) {
- print_("!");
- ata_device_read_sectors_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset, sectors);
- offset += 2048 * sectors;
- }
- final_offset = (uint8_t *)KERNEL_LOAD_START + offset;
- set_attr(0x07);
- print("Done.\n");
- move_kernel();
- }
- } else {
- print("No mod directory?\n");
- }
- } else {
- print("boo\n");
- }
- return;
- }
- #endif
- struct fw_cfg_file {
- uint32_t size;
- uint16_t select;
- uint16_t reserved;
- char name[56];
- };
- static int boot_mode = 0;
- void swap_bytes(void * in, int count) {
- char * bytes = in;
- if (count == 4) {
- uint32_t * t = in;
- *t = (bytes[0] << 24) | (bytes[1] << 12) | (bytes[2] << 8) | bytes[3];
- } else if (count == 2) {
- uint16_t * t = in;
- *t = (bytes[0] << 8) | bytes[1];
- }
- }
- void show_menu(void) {
- #if 1
- /* Try to detect qemu headless boot */
- outports(0x510, 0x0000);
- if (inportb(0x511) == 'Q' &&
- inportb(0x511) == 'E' &&
- inportb(0x511) == 'M' &&
- inportb(0x511) == 'U') {
- uint32_t count = 0;
- uint8_t * bytes = (uint8_t *)&count;
- outports(0x510,0x0019);
- for (int i = 0; i < 4; ++i) {
- bytes[i] = inportb(0x511);
- }
- swap_bytes(&count, 4);
- #if 0
- print_("there are ");
- print_hex_(count);
- print_(" entries\n");
- #endif
- unsigned int bootmode_size = 0;
- int bootmode_index = -1;
- for (unsigned int i = 0; i < count; ++i) {
- struct fw_cfg_file file;
- uint8_t * tmp = (uint8_t *)&file;
- for (int j = 0; j < sizeof(struct fw_cfg_file); ++j) {
- tmp[j] = inportb(0x511);
- }
- if (!strcmp(file.name,"opt/org.toaruos.bootmode")) {
- swap_bytes(&file.size, 4);
- swap_bytes(&file.select, 2);
- bootmode_size = file.size;
- bootmode_index = file.select;
- }
- #if 0
- print_("selector "); print_hex_(file.select); print_(" is "); print_hex_(file.size); print_(" bytes\n");
- print_("and its name is: "); print_(file.name); print_("\n");
- #endif
- }
- if (bootmode_index != -1) {
- outports(0x510, bootmode_index);
- char tmp[33] = {0};
- for (int i = 0; i < 32 && i < bootmode_size; ++i) {
- tmp[i] = inportb(0x511);
- }
- for (int i = 0; i < BASE_SEL+1; ++i) {
- if (!strcmp(tmp,boot_mode_names[i].key)) {
- boot_mode = boot_mode_names[i].index;
- return;
- }
- }
- print_("fw_cfg boot mode not recognized: ");
- print_(tmp);
- print_("\n");
- }
- }
- #endif
- /* Determine number of options */
- sel_max = 0;
- while (boot_options[sel_max].value) {
- sel_max++;
- }
- sel_max += BASE_SEL + 1;
- #ifndef EFI_PLATFORM
- outportb(0x3D4, 14);
- outportb(0x3D5, 0xFF);
- outportb(0x3D4, 15);
- outportb(0x3D5, 0xFF);
- inportb(0x3DA);
- outportb(0x3C0, 0x30);
- char b = inportb(0x3C1);
- b &= ~8;
- outportb(0x3c0, b);
- #endif
- clear_();
- do {
- move_cursor(0,0);
- set_attr(0x1f);
- print_banner(VERSION_TEXT);
- set_attr(0x07);
- print_("\n");
- for (int i = 0; i < BASE_SEL+1; ++i) {
- set_attr(sel == i ? 0x70 : 0x07);
- print_(" ");
- char tmp[] = {'0' + (i + 1), '.', ' ', '\0'};
- print_(tmp);
- print_(boot_mode_names[i].title);
- print_("\n");
- }
- // put a gap
- set_attr(0x07);
- print_("\n");
- for (int i = 0; i < sel_max - BASE_SEL - 1; ++i) {
- toggle(BASE_SEL + 1 + i, *boot_options[i].value, boot_options[i].title);
- }
- set_attr(0x07);
- move_cursor(x,17);
- print_("\n");
- print_banner(HELP_TEXT);
- print_("\n");
- if (sel > BASE_SEL) {
- print_banner(boot_options[sel-BASE_SEL-1].description_1);
- print_banner(boot_options[sel-BASE_SEL-1].description_2);
- print_("\n");
- } else {
- print_banner(COPYRIGHT_TEXT);
- print_("\n");
- print_banner(LINK_TEXT);
- }
- int s = read_scancode();
- if (s == 0x50) { /* DOWN */
- if (sel > BASE_SEL && sel < sel_max - 1) {
- sel = (sel + 2) % sel_max;
- } else {
- sel = (sel + 1) % sel_max;
- }
- } else if (s == 0x48) { /* UP */
- if (sel > BASE_SEL + 1) {
- sel = (sel_max + sel - 2) % sel_max;
- } else {
- sel = (sel_max + sel - 1) % sel_max;
- }
- } else if (s == 0x4B) { /* LEFT */
- if (sel > BASE_SEL + 1) {
- sel -= 1;
- }
- } else if (s == 0x4D) { /* RIGHT */
- if (sel > BASE_SEL) {
- sel = (sel + 1) % sel_max;
- }
- } else if (s == 0x1c) {
- if (sel <= BASE_SEL) {
- boot_mode = boot_mode_names[sel].index;
- break;
- } else {
- int index = sel - BASE_SEL - 1;
- *boot_options[index].value = !*boot_options[index].value;
- }
- } else if (s >= 2 && s <= 10) {
- int i = s - 2;
- if (i <= BASE_SEL) {
- boot_mode = boot_mode_names[i].index;
- break;
- }
- #if 0
- } else {
- print_hex_(s);
- #endif
- }
- } while (1);
- }
- #ifdef EFI_PLATFORM
- /* EFI boot uses simple filesystem driver */
- static EFI_GUID efi_simple_file_system_protocol_guid =
- {0x0964e5b22,0x6459,0x11d2,0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b};
- static EFI_GUID efi_loaded_image_protocol_guid =
- {0x5B1B31A1,0x9562,0x11d2, {0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B}};
- static void boot(void) {
- UINTN count;
- EFI_HANDLE * handles;
- EFI_LOADED_IMAGE * loaded_image;
- EFI_FILE_IO_INTERFACE *efi_simple_filesystem;
- EFI_FILE *root;
- EFI_STATUS status;
- clear_();
- status = uefi_call_wrapper(ST->BootServices->HandleProtocol,
- 3, ImageHandleIn, &efi_loaded_image_protocol_guid,
- (void **)&loaded_image);
- if (EFI_ERROR(status)) {
- print_("There was an error (init)\n");
- while (1) {};
- }
- print_("Found loaded image...\n");
- status = uefi_call_wrapper(ST->BootServices->HandleProtocol,
- 3, loaded_image->DeviceHandle, &efi_simple_file_system_protocol_guid,
- (void **)&efi_simple_filesystem);
- if (EFI_ERROR(status)) {
- print_("There was an error.\n");
- while (1) {};
- }
- status = uefi_call_wrapper(efi_simple_filesystem->OpenVolume,
- 2, efi_simple_filesystem, &root);
- if (EFI_ERROR(status)) {
- print_("There was an error.\n");
- while (1) {};
- }
- EFI_FILE * file;
- CHAR16 kernel_name[16] = {0};
- {
- char * c = kernel_path;
- char * ascii = c;
- int i = 0;
- while (*ascii) {
- kernel_name[i] = *ascii;
- i++;
- ascii++;
- }
- if (kernel_name[i-1] == L'.') {
- kernel_name[i-1] = 0;
- }
- }
- /* Load kernel */
- status = uefi_call_wrapper(root->Open,
- 5, root, &file, kernel_name, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR(status)) {
- print_("There was an error.\n");
- while (1) {};
- }
- unsigned int offset = 0;
- UINTN bytes = 134217728;
- status = uefi_call_wrapper(file->Read,
- 3, file, &bytes, (void *)KERNEL_LOAD_START);
- if (EFI_ERROR(status)) {
- print_("There was an error.\n");
- while (1) {};
- }
- print_("Read "); print_hex_(bytes); print_(" bytes\n");
- offset += bytes;
- while (offset % 4096) offset++;
- print_("Reading modules...\n");
- char ** c = modules;
- int j = 0;
- while (*c) {
- if (strcmp(*c, "NONE")) {
- /* Try to load module */
- CHAR16 name[16] = {0};
- name[0] = L'm';
- name[1] = L'o';
- name[2] = L'd';
- name[3] = L'\\';
- char * ascii = *c;
- int i = 0;
- while (*ascii) {
- name[i+4] = (*ascii >= 'A' && *ascii <= 'Z') ? (*ascii - 'A' + 'a') : *ascii;
- name[i+5] = 0;
- i++;
- ascii++;
- }
- for (int i = 0; name[i]; ++i) {
- char c[] = {name[i], 0};
- print_(c);
- }
- print_("\n");
- bytes = 2097152;
- _try_module_again:
- status = uefi_call_wrapper(root->Open,
- 5, root, &file, name, EFI_FILE_MODE_READ, 0);
- if (!EFI_ERROR(status)) {
- status = uefi_call_wrapper(file->Read,
- 3, file, &bytes, (void *)(KERNEL_LOAD_START + (uintptr_t)offset));
- if (!EFI_ERROR(status)) {
- print_("Loaded "); print_(*c); print_("\n");
- modules_mboot[j].mod_start = KERNEL_LOAD_START + offset;
- modules_mboot[j].mod_end = KERNEL_LOAD_START + offset + bytes;
- j++;
- offset += bytes;
- while (offset % 4096) offset++;
- }
- } else {
- print_("Error opening "); print_(*c); print_(" "); print_hex_(status); print_("\n");
- while (1) { };
- }
- } else {
- multiboot_header.mods_count--;
- }
- c++;
- }
- {
- char * c = ramdisk_path;
- CHAR16 name[16] = {0};
- char * ascii = c;
- int i = 0;
- while (*ascii) {
- name[i] = *ascii;
- i++;
- ascii++;
- }
- if (name[i-1] == L'.') {
- name[i-1] == 0;
- }
- bytes = 134217728;
- status = uefi_call_wrapper(root->Open,
- 5, root, &file, name, EFI_FILE_MODE_READ, 0);
- if (!EFI_ERROR(status)) {
- status = uefi_call_wrapper(file->Read,
- 3, file, &bytes, (void *)(KERNEL_LOAD_START + (uintptr_t)offset));
- if (!EFI_ERROR(status)) {
- print_("Loaded "); print_(c); print_("\n");
- modules_mboot[multiboot_header.mods_count-1].mod_start = KERNEL_LOAD_START + offset;
- modules_mboot[multiboot_header.mods_count-1].mod_end = KERNEL_LOAD_START + offset + bytes;
- offset += bytes;
- while (offset % 4096) offset++;
- final_offset = (uint8_t *)KERNEL_LOAD_START + offset;
- } else {
- print_("Failed to read ramdisk\n");
- }
- } else {
- print_("Error opening "); print_(c); print_("\n");
- }
- }
- move_kernel();
- }
- #else
- /* BIOS boot uses native ATAPI drivers, need to find boot drive. */
- static void boot(void) {
- clear_();
- multiboot_header.cmdline = (uintptr_t)cmdline;
- ata_device_detect(&ata_primary_master);
- ata_device_detect(&ata_primary_slave);
- ata_device_detect(&ata_secondary_master);
- ata_device_detect(&ata_secondary_slave);
- if (ata_primary_master.is_atapi) {
- do_it(&ata_primary_master);
- }
- if (ata_primary_slave.is_atapi) {
- do_it(&ata_primary_slave);
- }
- if (ata_secondary_master.is_atapi) {
- do_it(&ata_secondary_master);
- }
- if (ata_secondary_slave.is_atapi) {
- do_it(&ata_secondary_slave);
- }
- while (1);
- }
- #endif
|