loader.c (3591B)
1 #include "uefi.h" 2 #include "utils.h" 3 EFI_SYSTEM_TABLE *SystemTable; 4 5 EFI_STATUS 6 EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *systab) 7 { 8 // init global variable. 9 SystemTable = systab; 10 11 EFI_STATUS stat; 12 char s8[32]; 13 14 // Output firmware bender. 15 SystemTable->ConOut->ClearScreen(SystemTable->ConOut); 16 efi_printf("vendor: %s\n", wstr2str(SystemTable->FirmwareVendor, s8)); 17 efi_printf("EfiMain: 0x%x\n", EfiMain); 18 19 // Output memory map information. 20 UINTN mmsize = 8196; 21 char mmbuf[8196]; 22 EFI_MEMORY_DESCRIPTOR *mmap; 23 UINTN mkey; 24 UINTN dsize; 25 UINT32 dver; 26 mmap = (EFI_MEMORY_DESCRIPTOR *) mmbuf; 27 stat = SystemTable->BootServices->GetMemoryMap(&mmsize, mmap, &mkey, &dsize, &dver); 28 if (stat != EFI_SUCCESS) { 29 efi_printf("get memory map: %d\n", stat); 30 return stat; 31 } 32 33 for (; mmap < (EFI_MEMORY_DESCRIPTOR *)(mmbuf + mmsize); 34 mmap = (EFI_MEMORY_DESCRIPTOR *) (((char *)mmap) + dsize)) { 35 if (mmap->Type != EfiConventionalMemory) { 36 continue; 37 } 38 efi_printf("%d\t%x\t%x\t%x\t%x\n", mmap->Type, mmap->VirtualStart, 39 mmap->PhysicalStart, mmap->NumberOfPages, mmap->Attribute); 40 } 41 42 EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; 43 stat = open_gop(ImageHandle, &gop); 44 if (stat != EFI_SUCCESS) { 45 efi_printf("open_gop: %d\n", stat); 46 return stat; 47 } 48 UINT32 *frame_buffer = (UINT32 *)gop->Mode->FrameBufferBase; 49 for (UINTN i = 0; i < gop->Mode->FrameBufferSize/4; i++) { 50 frame_buffer[i] = 0x427f94; 51 } 52 efi_printf("frame buffer: base: %x, size: %x\n", frame_buffer, 53 gop->Mode->FrameBufferSize); 54 55 EFI_FILE_PROTOCOL *root, *kernel; 56 stat = open_root(ImageHandle, &root); 57 if (stat != EFI_SUCCESS) { 58 efi_printf("open_root: %d\n", stat); 59 return stat; 60 } 61 stat = root->Open(root, &kernel, L"kernel.elf", 62 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); 63 if (stat != EFI_SUCCESS) { 64 efi_printf("open file \"kernel.elf\": %d\n", stat); 65 return stat; 66 } 67 ElfHdr kernel_ehdr; 68 stat = read_ehdr(kernel, &kernel_ehdr); 69 if (stat != EFI_SUCCESS) { 70 efi_printf("read ehdr of \"kernel.elf\": %d\n", stat); 71 return stat; 72 } 73 efi_printf("type:\t%x\nphoff:\t%x\nphentsize:\t%x\nphnum:\t%x\n", 74 kernel_ehdr.type, kernel_ehdr.phoff, 75 kernel_ehdr.phentsize, kernel_ehdr.phnum); 76 if (kernel_ehdr.phnum > 32) { 77 efi_printf("too many phdrs\n"); 78 return EFI_BUFFER_TOO_SMALL; 79 } 80 Phdr kernel_phdr[32]; 81 stat = read_phdr(kernel, &kernel_ehdr, kernel_phdr); 82 if (stat != EFI_SUCCESS) { 83 efi_printf("read phdr of \"kernel.elf\": %d\n", stat); 84 return stat; 85 } 86 for (UINT16 i = 0; i < kernel_ehdr.phnum; i++) { 87 efi_printf("type: %x, offset: %x, vaddr: %x\n", 88 kernel_phdr[i].type, kernel_phdr[i].offset, kernel_phdr[i].vaddr); 89 } 90 stat = load_elf(kernel, &kernel_ehdr, kernel_phdr); 91 if (stat != EFI_SUCCESS) { 92 efi_printf("load \"kernel.elf\": %d\n", stat); 93 return stat; 94 } 95 stat = kernel->Close(kernel); 96 if (stat != EFI_SUCCESS) { 97 efi_printf("close file: %d\n", stat); 98 return stat; 99 } 100 101 efi_printf("frame buffer: base: %x, %x, size: %x\n", frame_buffer, 102 gop->Mode->FrameBufferBase, 103 gop->Mode->FrameBufferSize); 104 105 mmsize = 8196; 106 stat = SystemTable->BootServices->GetMemoryMap(&mmsize, mmap, &mkey, &dsize, &dver); 107 if (stat != EFI_SUCCESS) { 108 efi_printf("get memory map: %d\n", stat); 109 return stat; 110 } 111 stat = SystemTable->BootServices->ExitBootServices(ImageHandle, mkey); 112 if (stat != EFI_SUCCESS) { 113 efi_printf("exit boot services: %d\n", stat); 114 return stat; 115 } 116 117 typedef void (* Kernel) (EFI_GRAPHICS_OUTPUT_PROTOCOL *); 118 ((Kernel) kernel_ehdr.entry)(gop); 119 120 return EFI_SUCCESS; 121 }