如何创建自己的Protocol并调用

编写自己的Protocol

        步骤1:在Package的Include/Protocol中编写CreateProtocol.h文件。

        步骤2:在EmulatorPkg/Application中创建CreateProtocol文件,里面编写CreateProtocol.c和CreateProtocol.inf文件,其中在c文件中分配内存并安装。

        步骤3:使用自己上一篇使用的程序,在此基础上调用创建的Protocol。

先放代码,然后分别在各个部分重要的地方解释一下。

 CreateProtocol.h:

#ifndef __CREATE_PROTOCOL_H__
#define __CREATE_PROTOCOL_H__
#include <Uefi.h>
//定义Protocol的GUID
#define EFI_HELLO_WORLD_GUID  {0x038f1af5, 0x1c8d, 0x408f, { 0xab, 0x25, 0x30, 0xae, 0xb5, 0x96, 0x5d, 0x6e }}
//定义Protocol的结构体
typedef struct _EFI_HELLO_WORLD_PROTOCOL  EFI_HELLO_WORLD_PROTOCOL;
//函数指针
typedef 
EFI_STATUS
(EFIAPI *HELLO)(
  IN EFI_HELLO_WORLD_PROTOCOL *This
  );
struct _EFI_HELLO_WORLD_PROTOCOL{
  UINTN Version;
  HELLO Hello;
};
extern EFI_GUID gEfiHelloWorldProtocolGuid;
#endif

        如上代码所示,主要定义了一个Protocol结构体,里面有一个Version和一个函数指针。同时定义了一个EFI_GUID。同时要在对应的.dec文件中Protocols下定义gEfiHelloWorldProtocolGuid,本文在EmulatorPkg.dec下添加。

CreateProtocol.c:

//Protocol的实现和安装
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Protocol/CreateProtocol.h>
//创建函数
EFI_STATUS
EFIAPI
Hello(
  IN EFI_HELLO_WORLD_PROTOCOL *This
  )
{
  //Debug((EFI_D_ERROR,"Hello world tangrenhui!!!"));
  Print(L"Hello world tangrenhui!!!\n");
  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
ProtocolServerEntry(
  IN EFI_HANDLE ImageHandle,
  IN EFI_SYSTEM_TABLE *Systemtable
  )
{
  EFI_STATUS Status;
  EFI_HELLO_WORLD_PROTOCOL *Protocol;
  //开始分配空间和安装
  Protocol =  AllocatePool(sizeof(EFI_HELLO_WORLD_PROTOCOL));
  //判断是否分配成功
if(NULL == Protocol)//没有分配成功
  {
    DEBUG ((EFI_D_ERROR, "[%a][%d]: Out of resource.", __FUNCTION__, __LINE__));
    return EFI_OUT_OF_RESOURCES;
  }
  //分配成功
  Protocol->Version = 0x01;
  Protocol->Hello   = Hello;

  //安装

  Status=gBS->InstallProtocolInterface(
        &ImageHandle,
        &gEfiHelloWorldProtocolGuid,
        EFI_NATIVE_INTERFACE,
        Protocol
        );
  //判断
  if(EFI_ERROR(Status))
  {

        //DEBUG ((EFI_D_ERROR, "Install EFI_HELLO_WORLD_PROTOCOL failed. - %r\n", Status));
        DEBUG((EFI_D_ERROR, "InstallProtocol failed\n"));
        FreePool(Protocol);
        return Status;
  }
  return EFI_SUCCESS;
}

        如上述代码所示,先分配空间AllocatePool(sizeof(EFI_HELLO_WORLD_PROTOCOL)),使用EFI_HELLO_WORLD_PROTOCOL *Protocol的Protocol来接收返回值,然后判断是否分配成功,如果分配成功那就对他的成员进行赋值即Protocol->Version = 0x01、 Protocol->Hello   = Hello;。然后开始安装,使用InstallProtocolInterface,参考对应UEFI手册,如下图所示

       第一个参数为ImageHandle,第二个参数为EFI_GUID,第三个参数参考手册对应的如图。

        第四个参数为本模块实现的Protocol实例。

CreateProtocol.inf:

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ProtocolServer
FILE_GUID = 3d8ee62a-8f25-4a0c-bcc7-a0c8edc31643
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = ProtocolServerEntry

[Sources]
CreateProtocol.c

[Packages]
MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec

[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiLib
MemoryAllocationLib
DebugLib

[Protocols]
gEfiHelloWorldProtocolGuid

        调用的时候:在上一个博客使用的文件里面新增内容。

Print(L"Using Protocol\n");
        EFI_HELLO_WORLD_PROTOCOL     *Protocol;
        Status = gBS->LocateProtocol(
                        &gEfiHelloWorldProtocolGuid,
                        NULL,
                        (VOID **)&Protocol
                        );
        if(EFI_ERROR(Status)){
                //DEBUG((EFI_ERROR, "Locate EFI_HELLO_WORLD_PROTOCOL failed. %r\n", Status));
                DEBUG((EFI_D_ERROR, "LocateProtocol Status: %r\n", Status));
                return Status;
        }
        Status = Protocol->Hello(Protocol);
        if(EFI_ERROR(Status)){
                //DEBUG((EFI_ERROR, "Protocol->Hello world failed. %r\n" , Status));a
                DEBUG((EFI_D_ERROR, "UseProtocol Status: %r\n", Status));
                return Status;
        }
        Print(L"My Protocol be used!!\n");

        此部分重要地方,在上一个文件中也基本都有讲述,此处不给予阐述,直接编译,编译之后先运行由于Protocol创建的.efi文件,再运行测试的efi文件,由于我写的是DXE_DRIVER,所以运行时候需要输入load,结果如下图所示。证明调用成功。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值