setos

拙OS
Log | Files | Refs | LICENSE

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 }