原本想看看Logo是怎么显示的,但是发现可以通过EDK显示Logo的方式显示图片,因为我发现它并没有解码函数,就是写个Driver,代码会有点乱,我后面会整理后修改的。
在MdeModulePkg下,我们可以找到Logo此文件夹。
Logo.ibf中很简单,如下
Edk2 会把这个文件中的图片封装成UEFI HII Image数据包
HII(Human Interface Infrastructure )定义了一套管理用户输入的基础框架。HII数据库主要提供用户安装、卸载以及使用各种字符串、字体和图片等资源的接口。
大家可进入Spec看看
34. HII Protocols — UEFI Specification 2.10 documentation
说白一点就是可以直接通过GetImage函数去获得图片的数据,这中间很多操作不需要我们自己做
不看代码量,其实这个相对于来说会简单点,但由于我理解稍微浅,不能去说很多东西,甚至我目前说的可能就是错的。
其实Logo.c核心代码我觉得是这一行,就是弄到GetImageEx函数所需参数,这样才能把Image的数据打印出来。所以其他也可以不加。
可以看一下Image的数据结构,我们要想把图片打印出来,需要把图片数据放进缓冲区
看一眼我们需要的东西,PackageList,ImageId
ImageId就是我们在idf文件中定义图片的,但要用个c函数,D(t)=t将其换成本身,在这里就是图片。
主要是PackageList的获取,包含图像数据的HII包列表的句柄。主要做法就是将一个HII(Human Interface Infrastructure)包列表注册到HII数据库中。
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid,NULL,(VOID **)&HiiDatabase);ASSERT_EFI_ERROR (Status);Status = gBS->LocateProtocol (&gEfiHiiImageExProtocolGuid,NULL,(VOID **)&mHiiImageEx);ASSERT_EFI_ERROR (Status); Status = gBS->OpenProtocol (ImageHandle,&gEfiHiiPackageListProtocolGuid,(VOID **)&PackageList,ImageHandle,NULL,EFI_OPEN_PROTOCOL_GET_PROTOCOL);if (EFI_ERROR (Status)) {Print(L"HII Image Package with logo not found in PE/COFF resource section\n");return Status;}//// Publish HII package list to HII Database.//Status = HiiDatabase->NewPackageList (HiiDatabase,PackageList,NULL,&mHiiHandle);
所以,现在看来,edk2中显示Logo倒挺简单的,有时换个角度会有很好的效果。
代码:
同样创建ibf文件
将其加在Sources中
我们定义自己的图片
这里的话可以自己定义一个Protocol用来删除这个Driver
我就直接放出代码:
为了让大家自己尝试,我就不放.inf文件了。对于下面的头文件,有些是我之前测试加的,我暂时没删除,故有些头文件是多余的。
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.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>#include <Protocol/HiiDatabase.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/HiiImageEx.h>
#include <Protocol/PlatformLogo.h>
#include <Protocol/HiiPackageList.h>#include <Library/UefiDriverEntryPoint.h>
#include <Protocol/MyFirstProtocol.h>#define IMAGE_TOKEN(t) tEFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
EFI_HII_HANDLE mHiiHandle;
EFI_MY_FIRST_PROTOCOL *MyProtocol=NULL;//
//modify Edk2 define
//
EFI_STATUS
EFIAPI
GetImage (OUT EFI_IMAGE_INPUT *Image)
{return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,IMAGE_TOKEN(IMG_DAVID), Image);//Define IMG_DAVID
}EFI_STATUS
EFIAPI
DriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
){EFI_STATUS Status;EFI_HII_PACKAGE_LIST_HEADER *PackageList;EFI_HII_DATABASE_PROTOCOL *HiiDatabase;//EFI_HANDLE Handle;EFI_IMAGE_INPUT *Image=NULL;EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;EFI_MY_FIRST_PROTOCOL *Protocol;Status = gBS->LocateProtocol(&gEfiMyFirstProtocolGuid, NULL, &Protocol); if (Status == EFI_SUCCESS) { Print(L"Locate MyProtocol: Success\n");Print(L"This driver is already laoded!!!!\n");return EFI_ABORTED;} Status = gBS->InstallProtocolInterface (&ImageHandle,&gEfiMyFirstProtocolGuid,EFI_NATIVE_INTERFACE,MyProtocol);if(EFI_ERROR(Status)){Print(L"Failed to install protocol: %r\n", Status);return Status;}else{Print(L"Install Protocol: Success\n");}Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid,NULL,(VOID **)&HiiDatabase);ASSERT_EFI_ERROR (Status);Status = gBS->LocateProtocol (&gEfiHiiImageExProtocolGuid,NULL,(VOID **)&mHiiImageEx);ASSERT_EFI_ERROR (Status);//// Retrieve HII package list from ImageHandle//Status = gBS->OpenProtocol (ImageHandle,&gEfiHiiPackageListProtocolGuid,(VOID **)&PackageList,ImageHandle,NULL,EFI_OPEN_PROTOCOL_GET_PROTOCOL);if (EFI_ERROR (Status)) {Print(L"HII Image Package with logo not found in PE/COFF resource section\n");return Status;}//// Publish HII package list to HII Database.//Status = HiiDatabase->NewPackageList (HiiDatabase,PackageList,NULL,&mHiiHandle);Image = AllocatePool(sizeof(EFI_IMAGE_INPUT));Status=GetImage(Image);Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid,NULL,(VOID **)&GraphicsOutput);if (EFI_ERROR (Status)) {GraphicsOutput = NULL;Print (L"locate protocol gEfiGraphicsOutputProtocolGuid is error!\n");return Status;}EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;BltBuffer=Image->Bitmap;Status = GraphicsOutput->Blt (GraphicsOutput,BltBuffer,EfiBltBufferToVideo,0,0,0x0,0x0,Image->Width,Image->Height,Image->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));if (EFI_ERROR (Status)) {Print (L"GraphicsOutput Blt is error!\n");return Status;}return EFI_SUCCESS;
}EFI_STATUS
EFIAPI
DriverUnLoad(
IN EFI_HANDLE ImageHandle
){EFI_STATUS Status;Status = gBS->UninstallProtocolInterface (ImageHandle,&gEfiMyFirstProtocolGuid,MyProtocol);if (EFI_ERROR (Status)) {return Status;}return Status;
}