setos

拙OS
Log | Files | Refs | LICENSE

boot.c (3481B)


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