EDKII实现bmp图片加载并显示的应用程序

一. 制作EDK II可以识别的BMP图片

1.EDKII 支持BGR32作为原始数据的BMP图片

2.所以,我们需要先找到或者自己制作一张满足这个要求的BMP图片

3.这里,我们采用自己制作BMP图片的方式,制作过程分为两骤(实现代码如下):

        a.用ffmpeg将.png图片转换成BGRA原始数据

        b.编写一个将BGRA数据组装成BMP图片的程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HEIGHT 225
#define WIDTH  225
 
typedef struct                       /**** BMP file header structure ****/  
{  
    unsigned int   bfSize;           /* Size of file */  
    unsigned short bfReserved1;      /* Reserved */  
    unsigned short bfReserved2;      /* ... */  
    unsigned int   bfOffBits;        /* Offset to bitmap data */  
} BITMAPFILEHEADER;
 
typedef struct                       /**** BMP file info structure ****/  
{  
    unsigned int   biSize;           /* Size of info header */  
    int            biWidth;          /* Width of image */  
    int            biHeight;         /* Height of image */  
    unsigned short biPlanes;         /* Number of color planes */  
    unsigned short biBitCount;       /* Number of bits per pixel */  
    unsigned int   biCompression;    /* Type of compression to use */  
    unsigned int   biSizeImage;      /* Size of image data */  
    int            biXPelsPerMeter;  /* X pixels per meter */  
    int            biYPelsPerMeter;  /* Y pixels per meter */  
    unsigned int   biClrUsed;        /* Number of colors used */  
    unsigned int   biClrImportant;   /* Number of important colors */  
} BITMAPINFOHEADER;  

char ffmpeg_line[128] = {0};

void MySaveBmp(const char *filename,unsigned char *rgbbuf,int width,int height)  
{  
    BITMAPFILEHEADER bfh;  
    BITMAPINFOHEADER bih;  
    /* 
     * Magic number for file. It does not fit in the header structure due to 
     * alignment requirements, so put it outside 
     * 文件的魔术字,由于对齐的需要,没办法将魔术字作为BITMAPFILEHEADER的成员,所以
     * 这里将魔术字放在BITMAPFILEHEADER开头外面的位置。
     */  
    unsigned short bfType=0x4d42;    //'BM'             
    bfh.bfReserved1 = 0;  
    bfh.bfReserved2 = 0;  
    bfh.bfSize = 2/* 2B魔术字 */+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+width*height*4;  
    bfh.bfOffBits = 2/* 2B魔术字 */ + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  
    bih.biSize = sizeof(BITMAPINFOHEADER); 
 
    printf("filesize = %u header size = %u \n", bfh.bfSize, bfh.bfOffBits);
 
    bih.biWidth = width;  
    bih.biHeight = height;  
    bih.biPlanes = 1;  
    bih.biBitCount = 32;  //一个像素对应的32bit
    bih.biCompression = 0;  
    bih.biSizeImage = 0;  
    bih.biXPelsPerMeter = 5000;  
    bih.biYPelsPerMeter = 5000;  
    bih.biClrUsed = 0;  
    bih.biClrImportant = 0;  
  
    FILE *file = fopen(filename, "w+");  
    if (!file)  
    {  
        printf("Could not write file\n");  
        return;  
    }  
  
    /*Write headers*/  
    fwrite(&bfType,sizeof(bfType),1,file);  
    fwrite(&bfh,sizeof(bfh),1, file);  
    fwrite(&bih,sizeof(bih),1, file);  
  
    fwrite(rgbbuf,width*height*4,1,file);  
    fclose(file);  
}
 
int main(void)
{
    unsigned int len = 0, i = 0;
    unsigned char *dest = NULL;
    unsigned char *dest2 = NULL;
    int ret = 0;
 
    printf("unsigned int = %ld\n", sizeof(unsigned int));
    printf("unsigned short = %ld\n", sizeof(unsigned short));
 
    dest = (char *)malloc(sizeof(unsigned char) * 4 * WIDTH * HEIGHT);
    if(!dest) {
        ret = -1;
        goto fail;
    }
 
    dest2 = (char *)malloc(sizeof(unsigned char) * 4 * WIDTH * HEIGHT);
    if(!dest2) {
        ret = -1;
        goto fail;
    }
 
    sprintf(ffmpeg_line, "ffmpeg -i origin.png -s %dx%d -pix_fmt bgra origin.rgb", WIDTH, HEIGHT);
    ret = system(ffmpeg_line);
    if(ret)
        goto fail;
 
    FILE *fp = fopen("origin.rgb", "r");
    if(!fp) {
        ret = 1;
        goto fail;
    }
    
    ret = fseek(fp, 0, SEEK_END);       //读写位置指针移动到文件尾
    if(ret) {
        ret = -1;
        goto fail;
    }
 
    len = ftell(fp);
    if(!len) {
        ret = -1;
        goto fail;
    }
 
    ret = fseek(fp, 0, SEEK_SET);         //读写位置指针移动到文件头
    if(ret) {
        ret = -1;
        goto fail;
    }
 
    len = fread(dest, sizeof(unsigned char), len, fp);
    if(!len) {
        ret = -1;
        goto fail;
    }
    printf("bgra file len= %u\n", len);
 
    fclose(fp);
 
    for(i = 0; i < WIDTH; i++)
        memcpy(&dest2[i * sizeof(unsigned char) * 4 * WIDTH], &dest[(HEIGHT - 1 - i) * sizeof(unsigned char) * 4 * WIDTH], sizeof(unsigned char) * 4 * WIDTH);
 
    MySaveBmp("origin.bmp", dest2, WIDTH, HEIGHT);
 
    ret = system("rm -rf origin.rgb");
 
fail:
    free(dest);
    free(dest2);
    return ret;
}
 

二. 编写EDKII 应用程序读取图片并现实在虚拟机中(两种方式)

标准应用程序工程模块Shell应用程序工程模块的联系和区别参考这两篇博客。

1.Shell应用程序工程模块

c源文件:

/** @file
  This is a test for show bmp
**/

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ShellLib.h>
#include <Library/BmpSupportLib.h>

#include <IndustryStandard/Bmp.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/HiiImageEx.h>

/**
  load bmp file to buffer

  @param   IN      CHAR16     *FileName
  @param   IN OUT  UINT8      **FileDataBuffer
  @param   IN OUT  UINTN      *DataLength

  @retval  EFI_SUCCESS
  @retval            

**/
EFI_STATUS
EFIAPI
LoadFiletoBuffer (
  IN      CHAR16           *FileName,
  IN OUT  UINT8            **FileDataBuffer,
  IN OUT  UINT64            *DataLength
)
{
  EFI_STATUS                      Status;
  EFI_FILE_HANDLE                 ReadFileHandle;
  EFI_FILE_PROTOCOL               *FileRoot;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;  
  EFI_FILE_INFO                   *ReadFileInfo = NULL;
  

  Status = gBS->LocateProtocol(
						      &gEfiSimpleFileSystemProtocolGuid, 
						      NULL,
					     	  (VOID **)&SimpleFileSystem
                  );
  if (EFI_ERROR(Status)) {
		  Print (L"not found gEfiSimpleFileSystemProtocolGuid!\n");
      return Status;	
	}
  
  Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &FileRoot);
  if (EFI_ERROR(Status)) {
		Print (L"OpenVolume is error !\n");
    return Status;	
	}

  Status = FileRoot->Open(
						           FileRoot, 
							         &ReadFileHandle, 
							         FileName,
							         EFI_FILE_MODE_READ , 
							         0 
                       );
  if (EFI_ERROR (Status)) {
    Print (L"open file root is error!\n");
    return Status;
  }
  
  ReadFileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)ReadFileHandle);

  *DataLength = ReadFileInfo->FileSize;
  *FileDataBuffer = (UINT8 *)AllocateZeroPool (*DataLength);

  Status = ReadFileHandle->Read (
                             ReadFileHandle,
                             DataLength,
                             *FileDataBuffer
                             );
  if (EFI_ERROR (Status)) {
    Print (L"Read file is error!\n");
    return Status;
  }	
  
  ReadFileHandle->Close (ReadFileHandle);
  FileRoot->Close (FileRoot);

  Print (L"Load File is Ok!\n");

  return Status;
}


/**
  UEFI application entry point which has an interface similar to a
  standard C main function.

  The ShellCEntryLib library instance wrappers the actual UEFI application
  entry point and calls this ShellAppMain function.

  @param  Argc             Argument count
  @param  Argv             The parsed arguments

  @retval  0               The application exited normally.
  @retval  Other           An error occurred.

**/
INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  EFI_STATUS                       Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput = NULL;
  UINT8                            *BmpDataBuffer;
  UINT64                           DataLength;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *EepromBitmap = NULL;
  UINTN                            GopBltSize;
  UINTN                            Height;
  UINTN                            Width;
  
  //Status = gST->ConOut->EnableCursor(gST->ConOut,FALSE);
  //Status = gST->ConOut->SetAttribute(gST->ConOut,EFI_WHITE|EFI_BACKGROUND_BLACK);
  //Status = gST->ConOut->ClearScreen(gST->ConOut);

  Status = gBS->LocateProtocol (
                  &gEfiGraphicsOutputProtocolGuid,
                  NULL,
                  (VOID **)&GraphicsOutput
                  );
  if (EFI_ERROR (Status)) {
    GraphicsOutput = NULL;
    Print (L"locate protocol gEfiGraphicsOutputProtocolGuid is error!\n");
    return Status;
  }
  
  Status = LoadFiletoBuffer (
             Argv[1],
             &BmpDataBuffer,
             &DataLength
             );
  if (EFI_ERROR (Status)) {
    Print (L"Load Bmp to Buffer is error!\n");
    return Status;
  }

  //
  // bmp to blt
  //
  Status = TranslateBmpToGopBlt (
             (VOID *)BmpDataBuffer,
             DataLength,
             &EepromBitmap,
             &GopBltSize,
             &Height,
             &Width
             );
  Print(L"height=%llu width=%llu DataLength=%llu\n", Height, Width, DataLength);

  if (EFI_ERROR (Status)) {
    if (EepromBitmap != NULL) {
      FreePool (EepromBitmap);
    }
    Print (L"TranslateBmpToGopBlt is error! Status=%d\n", Status);
    return Status;
  }
  
  Status = GraphicsOutput->Blt (
                             GraphicsOutput,
                             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);

  //Status = gST->ConOut->EnableCursor(gST->ConOut,TRUE);
  return 0;
}

inf文件:

## @file
#  head for bmp test
##

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = TestShow
  FILE_GUID                      = 079E8E98-AE93-1111-8A71-88C869F23E09
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = ShellCEntryLib

#
# The following information is for reference only and not required by the build tools.
#
#  VALID_ARCHITECTURES           = IA32 X64 EBC
#

[Sources]
  TestShow.c

[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec
  MdeModulePkg/MdeModulePkg.dec

[LibraryClasses]
  ShellCEntryLib
  UefiLib
  UefiBootServicesTableLib
  BaseMemoryLib
  MemoryAllocationLib
  ShellLib
  BmpSupportLib

[Protocols]
  gEfiGraphicsOutputProtocolGuid

dsc文件:

[Defines]
    PLATFORM_NAME = TestShowPkg
    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
    ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
    ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
    BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
    SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
    FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
    HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
    SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
    UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf

[Components]
    TestShowPkg/TestShow.inf

2.标准应用程序工程模块

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, 22);
    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;



    /************************** 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;
    }

    /* 打开Logo.BMP文件->esp目录下, 并记录到file handle */
    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 *FileInfo;
    UINTN InfoSize = sizeof(EFI_FILE_INFO) + StrLen(FileName) * 2;

    Status = gBS->AllocatePool(
        EfiLoaderData,
        InfoSize,
        (VOID **)&FileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to AllocatePool.\n");
        return Status;
    }

    Status = LogoHandle->GetInfo(
        LogoHandle,
        &gEfiFileInfoGuid,
        &InfoSize,
        FileInfo
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to GetInfo %d.\n", Status);
        return Status;
    }
    /* b.根据文件大小申请内存,存放文件数据 */
    Print(L"Logo.BMP size = %llu name = %s\n", FileInfo->FileSize, FileInfo->FileName);
    UINT8 * FileBufferAddress;
    FileBufferAddress = (UINT8 *)AllocateZeroPool (FileInfo->FileSize);
    /* c.读取文件数据到申请的内存 */
    UINTN BmpSize = FileInfo->FileSize;
    Status = LogoHandle->Read(
        LogoHandle,
        &BmpSize,
        (VOID *)FileBufferAddress
    );
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Read.\n");
        return Status;
    }
    /* d.释放file info信息内存 并 关闭打开的文件*/
    gBS->FreePool(FileInfo);
    Status = LogoHandle->Close(LogoHandle);
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to close.\n");
        return Status;
    }
    Status = Root->Close(Root);
    if(EFI_ERROR(Status))
    {
        Print(L"Failed to Read.\n");
        return Status;
    }

    EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *EepromBitmap = NULL;
    UINTN                            GopBltSize;
    UINTN                            Height;
    UINTN                            Width;
    Status = TranslateBmpToGopBlt (         // 将图形数据转换成blt
             (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);

    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 = ProtocolPkg
    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

三. 效果图

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

denglin12315

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

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

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

打赏作者

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

抵扣说明:

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

余额充值