EDKII加载bin文件并运行

一.EDKII实现代码

.c文件:

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/SimpleFileSystem.h>
#include <Guid/FileInfo.h>
#include <Library/BmpSupportLib.h>
#include <IndustryStandard/Bmp.h>
#include <Library/MemoryAllocationLib.h>
 
typedef struct
{
    EFI_PHYSICAL_ADDRESS       FrameBufferBase;
    UINTN                      FrameBufferSize;
    UINT32                     HorizontalResolution;
    UINT32                     VerticalResolution;
    UINT32                     PixelsPerScanLine;
} VIDEO_CONFIG;
 
VIDEO_CONFIG VideoConfig = {0};
 
 
EFI_STATUS
EFIAPI
UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    EFI_STATUS Status = EFI_SUCCESS;
    UINTN NumHandles = 0;
    EFI_HANDLE *Buffer = NULL;
 
    /********************** 1.显示配置 *************************/
    Status = gBS->LocateHandleBuffer(
        ByProtocol,
        &gEfiGraphicsOutputProtocolGuid,
        NULL,
        &NumHandles,
        &Buffer
    );
 
    Print(L"Status = %d.\n", Status);
 
    if(EFI_ERROR(Status)) {
        Print(L"Failed to LocateHandleBuffer.\n");
        return Status;
    }
 
    Print(L"Hello Protocol.\n");
    Print(L"NumHandles = %d.\n", NumHandles);
 
    EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
 
    Status = gBS->OpenProtocol(
        Buffer[0],
        &gEfiGraphicsOutputProtocolGuid,
        (void **)&Gop,
        ImageHandle,
        NULL,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to OpenProtocol\n");
    }
 
    UINTN SizeofInfo = 0;
    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
    for(UINTN i = 0; i < Gop->Mode->MaxMode; i++)
    {
        Status = Gop->QueryMode(
            Gop,
            i,
            &SizeofInfo,
            &Info
        );
        if(EFI_ERROR(Status))
        {
            Print(L"Failed To QueryMode.\n");
            return Status;
        }
        Print(L"Mode = %d, H = %d, V = %d.\n",
            i,
            Info->HorizontalResolution,
            Info->VerticalResolution);
    }
 
    Status = Gop->SetMode(Gop, 18);       // 1440 * 900
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to SetMode.\n");
        return Status;
    }
 
    VideoConfig.FrameBufferBase = Gop->Mode->FrameBufferBase;
    VideoConfig.FrameBufferSize = Gop->Mode->FrameBufferSize;
    VideoConfig.HorizontalResolution = Gop->Mode->Info->HorizontalResolution;
    VideoConfig.VerticalResolution = Gop->Mode->Info->VerticalResolution;
    VideoConfig.PixelsPerScanLine = Gop->Mode->Info->PixelsPerScanLine;
    Print(L"FrameBufferBase=%llx\n", Gop->Mode->FrameBufferBase);
 
 
 
    /************************** 2.文件系统配置 ******************************/
    Status = gBS->LocateHandleBuffer(
        ByProtocol,
        &gEfiSimpleFileSystemProtocolGuid,
        NULL,
        &NumHandles,
        &Buffer
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to LocateHandleBuffer.\n");
        return Status;
    }
 
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
    Status = gBS->OpenProtocol(
        Buffer[0],
        &gEfiSimpleFileSystemProtocolGuid,
        (VOID **)&FileSystem,
        ImageHandle,
        NULL,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to OpenProtocol.\n");
        return Status;
    }
 
    EFI_FILE_PROTOCOL *Root;
    Status = FileSystem->OpenVolume(
        FileSystem,
        &Root
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to OpenVolume.\n");
        return Status;
    }

    CHAR16 *FileName = L"\\Logo.BMP";
    EFI_FILE_PROTOCOL *LogoHandle;
    Status = Root->Open(
        Root,
        &LogoHandle,
        FileName, // L"\\Logo.bmp"
        EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Open.\n");
        return Status;
    }
 
 
    /************************** 3.将logo文件数据读到内存 ******************************/
    /* a.获取文件大小等信息 */
    EFI_FILE_INFO *BmpFileInfo;
    UINTN InfoSize = sizeof(EFI_FILE_INFO) + StrLen(FileName) * 2;
 
    Status = gBS->AllocatePool(
        EfiLoaderData,
        InfoSize,
        (VOID **)&BmpFileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to AllocatePool.\n");
        return Status;
    }
 
    Status = LogoHandle->GetInfo(
        LogoHandle,
        &gEfiFileInfoGuid,
        &InfoSize,
        BmpFileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to GetInfo %d.\n", Status);
        return Status;
    }
    /* b.根据文件大小申请内存,存放文件数据 */
    UINT8 * FileBufferAddress;
    FileBufferAddress = (UINT8 *)AllocateZeroPool (BmpFileInfo->FileSize);
    /* c.读取文件数据到申请的内存 */
    UINTN BmpSize = BmpFileInfo->FileSize;
    Status = LogoHandle->Read(
        LogoHandle,
        &BmpSize,
        (VOID *)FileBufferAddress
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Read.\n");
        return Status;
    }

    /* d.将图形数据转换成blt */
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *EepromBitmap = NULL;
    UINTN                            GopBltSize;
    UINTN                            Height;
    UINTN                            Width;
    Status = TranslateBmpToGopBlt (
             (VOID *)FileBufferAddress,
             BmpSize,
             &EepromBitmap,
             &GopBltSize,
             &Height,
             &Width
             );
    if(EFI_ERROR(Status))
    {
        if (EepromBitmap != NULL)
            FreePool (EepromBitmap);
        Print(L"Failed to Blt Logo. %d\n", Status);
        return Status;
    }
 
    Status = Gop->Blt (
                Gop,
                EepromBitmap,
                EfiBltBufferToVideo,
                0,
                0,
                0x0,
                0x0,
                Width,
                Height,
                Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
                );
    if (EFI_ERROR (Status)) {
        Print (L"GraphicsOutput Blt is error!\n");
        return Status;
    }
 
    if (EepromBitmap != NULL)
        FreePool (EepromBitmap);
    
    FreePool(FileBufferAddress);       //释放存放logo file的buffer
    gBS->FreePool(BmpFileInfo);
    Status = LogoHandle->Close(LogoHandle);
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to close LogoHandle.\n");
        return Status;
    }

    /************************** 4.将Kernel.bin文件数据读到内存 ******************************/
    FileName = L"\\Kernel.bin";
    EFI_FILE_PROTOCOL *KernelHandle;
    Status = Root->Open(
        Root,
        &KernelHandle,
        FileName,
        EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Open.\n");
        return Status;
    }

    EFI_FILE_INFO *KernelFileInfo;
    InfoSize = sizeof(EFI_FILE_INFO) + StrLen(FileName) * 2;
    Status = gBS->AllocatePool(
        EfiLoaderData,
        InfoSize,
        (VOID **)&KernelFileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to AllocatePool.\n");
        return Status;
    }
 
    Status = KernelHandle->GetInfo(
        KernelHandle,
        &gEfiFileInfoGuid,
        &InfoSize,
        KernelFileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to GetInfo %d.\n", Status);
        return Status;
    }

    FileBufferAddress = (UINT8 *)AllocateZeroPool (KernelFileInfo->FileSize);
    UINTN KernelSize = KernelFileInfo->FileSize;
    Status = KernelHandle->Read(
        KernelHandle,
        &KernelSize,
        (VOID *)FileBufferAddress
    );
    if(EFI_ERROR(Status))
    {
        return Status;
    }

    
    /************************** 5.资源释放 ******************************/
    gBS->FreePool(KernelFileInfo);
    Status = KernelHandle->Close(KernelHandle);
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to close KernelHandle.\n");
        return Status;
    }
    Status = Root->Close(Root);
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Read.\n");
        return Status;
    }


    /************************** 6.关闭BOOT SERVICE ******************************/
    typedef struct
    {
        UINTN BufferSize;
        VOID *Buffer;
        UINTN MapSize;
        UINTN MapKey;
        UINTN DescriptorSize;
        UINT32 DescriptorVersion;
    } MEMORY_MAP;

    MEMORY_MAP MemMap = {4096 * 4, NULL,4096,0,0,0};
    Status = gBS->AllocatePool(
        EfiLoaderData,
        MemMap.BufferSize,
        &MemMap.Buffer
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Allocate pool for memory map failed.\n");
        return Status;
    }    
  
    Status = gBS->GetMemoryMap(
        &MemMap.BufferSize,
        (EFI_MEMORY_DESCRIPTOR *)MemMap.Buffer,
        &MemMap.MapKey,
        &MemMap.DescriptorSize,
        &MemMap.DescriptorVersion
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Get memory map error.\n");
        return Status;
    }

    Status = gBS->ExitBootServices(
        ImageHandle, MemMap.MapKey
    );
    if(EFI_ERROR(Status))
    {
        Print(L"ExitBootServices error.\n");
        return Status;
    }

/************************** 7.跳转到操作系统运行 ******************************/
    asm("jmp %0": : "m"(FileBufferAddress));

    return Status;
}

.inf文件:

[Defines]
    INF_VERSION = 0x00010006
    BASE_NAME = XV6Boot
    FILE_GUID = 4dc59a5b-97d9-4a08-808f-e979f47508c0
    MODULE_TYPE = UEFI_APPLICATION
    VERSION_STRING = 0.1
    ENTRY_POINT = UefiMain
 
[Sources]
    XV6Boot.c
 
[Packages]
    MdePkg/MdePkg.dec
    MdeModulePkg/MdeModulePkg.dec
 
[LibraryClasses]
    UefiApplicationEntryPoint
    BmpSupportLib
    UefiLib
 
[Guids]
    gEfiFileInfoGuid
 
[Protocols]
    gEfiSimpleFileSystemProtocolGuid

.dsc文件:

[Defines]
    PLATFORM_NAME = XV6BootPkg
    PLATFORM_GUID = 8365c20a-fc46-4fc8-9300-9499611f3862
    PLATFORM_VERSION = 0.1
    DSC_SPECIFICATION = 0x00010006
    SUPPORTED_ARCHITECTURES = X64
    BUILD_TARGETS = DEBUG|RELEASE
 
[LibraryClasses]
    UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
    UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
    PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
    DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
    BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
    BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
    UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
    DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
    UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
    BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
    SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
 
[Components]
    XV6BootPkg/XV6Boot.inf

二.bin文件实现代码

BITS 64
mov ecx, 0x0013C680
mov eax, 0xFF19679A
xor rdi, rdi
mov rdi, 0x80000000

Write:
    mov [rdi], eax
    add rdi, 4
    loop Write

jmp $

编译命令:

        nasm kernel.asm -f bin -o Kernel.bin

三.效果展示

kernel.asm文件的代码会将屏幕填充为蓝色。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

denglin12315

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值