Skip to content

Instantly share code, notes, and snippets.

@naoki9911
Last active September 14, 2018 15:32
Show Gist options
  • Save naoki9911/f4303a55f7d9a3c2f8d7c90d8c513415 to your computer and use it in GitHub Desktop.
Save naoki9911/f4303a55f7d9a3c2f8d7c90d8c513415 to your computer and use it in GitHub Desktop.
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/BlockIo.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SimpleFileSystem.h>
#include <Library/DevicePathLib.h>
#include <Guid/FileInfo.h>
#include <Guid/Acpi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include "elf.h"
#include "relocate.h"
#include "memory_map.h"
#include "graphic.h"
#include "structs.h"
void set_gdt(struct gdt *gdt,UINT32 type,UINT32 base,UINT32 lim);
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
CHAR16 *KernelPath = L"\\kernel";
CHAR16 *bmp_file = L"\\logo.bmp";
EFI_PHYSICAL_ADDRESS BootParamAddr = 0x50000;
EFI_PHYSICAL_ADDRESS KernelBaseAddr;
RelocateELF(KernelPath, &KernelBaseAddr);
Status = gBS->AllocatePages(AllocateAddress,EfiLoaderData,1,&BootParamAddr);
if(EFI_ERROR(Status)){
Print(L"Can not allocate boot param address\n");
}
struct boot_param *boot_param = (struct boot_param *)BootParamAddr;
boot_param->kernel_entry = (UINT64)KernelBaseAddr;
//途中省略
boot_param->kernel_addr = KernelBaseAddr;
Print(L"KernelAddress : %x\n",boot_param->kernel_addr);
boot_param->bootstrap_gdt_desc.size = sizeof(struct gdt)*3;
boot_param->bootstrap_gdt_desc.gdt_addr = (UINT64)boot_param->bootstrap_gdt;
boot_param->bootstrap_gdt[0].limit = 0;
boot_param->bootstrap_gdt[0].base1 = 0;
boot_param->bootstrap_gdt[0].base2 = 0;
boot_param->bootstrap_gdt[0].access_byte = 0;
boot_param->bootstrap_gdt[0].flags = 0;
boot_param->bootstrap_gdt[0].base3 = 0;
set_gdt(&(boot_param->bootstrap_gdt[1]),STA_X|STA_R,0x0,0xffffffff);
set_gdt(&(boot_param->bootstrap_gdt[2]),STA_W,0x0,0xffffffff);
Print(L"BootStrap GDT Descriptor Address: %x\n",&(boot_param->bootstrap_gdt_desc));
struct MemoryMap MemoryMap = {4096,NULL,4096,0,0,0};
Status = gBS->AllocatePool(EfiLoaderData, MemoryMap.BufferSize, &MemoryMap.Buffer);
if(EFI_ERROR(Status)){
Print(L"Failed to allocate memory to get memory map\n");
return Status;
}
Print(L"AllocatePool=%d\n",Status);
Status = DrawBMP(bmp_file,&(boot_param->graphic_config));
if(EFI_ERROR(Status)){
Print(L"Failed to draw bitmap file %s\n",bmp_file);
}
gBS->GetMemoryMap(
&MemoryMap.MapSize,
(EFI_MEMORY_DESCRIPTOR*)MemoryMap.Buffer,
&MemoryMap.MapKey,
&MemoryMap.DescriptorSize,
&MemoryMap.DescriptorVersion);
Status = gBS->ExitBootServices(ImageHandle, MemoryMap.MapKey);
if(EFI_ERROR(Status)){
Print(L"Could not exit boot services : %r",Status);
}
asm("lgdt %0": : "m"(boot_param->bootstrap_gdt_desc));
asm("push $0x08");
asm("push %0": : "m"(boot_param->kernel_addr));
asm("lretq");
while(1);
}
void set_gdt(struct gdt *gdt,UINT32 type,UINT32 base,UINT32 lim){
gdt->limit = (lim >> 12) & 0xFFFF;
gdt->base1 = base & 0xFFFF;
gdt->base2 = (base >> 16) & 0xFF;
gdt->access_byte = 0x90 | type;
gdt->flags = 0xC0 | ((lim >> 28) & 0xF);
gdt->base3 = (base >> 24) & 0xFF;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment