一、 编写源代码
-
编写C:\edkii\OvmfPkg\MyHelloWorldInstallPPI\MyHelloWorldInstallPPI.c,
#include <uefi.h> #include <Library/UefiLib.h> #include <Library/BaseLib.h> #include <Library/DebugLib.h> #include <Library/BaseMemoryLib.h> #include <Library/UefiDriverEntryPoint.h> #include <Library/PeimEntryPoint.h> #include <Library/PeiServicesLib.h> #include <Library/PeiServicesTablePointerLib.h> #include <Pi/PiHob.h> #include <Pi/PiPeiCis.h> EFI_GUID gMyHelloWorldPEIGUID = { 0xbdb38129, 0x4d65, 0x39f4, { 0x72, 0x12, 0x68, 0xcf, 0x5a, 0x19, 0xa, 0xf8 }}; EFI_STATUS EFIAPI PrintHelloMsg ( IN CHAR16 * Msg ) { DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] PrintHelloMsg : %s \n",Msg)); return EFI_SUCCESS; } typedef EFI_STATUS (EFIAPI * PRINTMSG)(CHAR16 *Msg); typedef struct _EFI_HELLOWORLD_PROTOCOL { PRINTMSG PrintMsg; }EFI_HELLOWORLD_PROTOCOL; EFI_HELLOWORLD_PROTOCOL mHelloWorldPpi = { PrintHelloMsg }; EFI_PEI_PPI_DESCRIPTOR mPpiListCodePpi = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gMyHelloWorldPEIGUID, &mHelloWorldPpi }; EFI_STATUS EFIAPI MyHelloWorldInstallPPIEntry( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status = EFI_SUCCESS; DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] MyHelloWorldInstallPPIEntry Start..\n")); PeiServicesInstallPpi (&mPpiListCodePpi); DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] MyHelloWorldInstallPPIEntry End..\n")); return Status; }
-
编写C:\edkii\OvmfPkg\MyHelloWorldInstallPPI\MyHelloWorldInstallPPI.inf,
[Defines] INF_VERSION = 0x00010006 BASE_NAME = MyHelloWorldInstallPPI FILE_GUID = 69E6DE5D-F09E-485E-9936-EB70FDCFC82A MODULE_TYPE = PEIM VERSION_STRING = 1.0 ENTRY_POINT = MyHelloWorldInstallPPIEntry [Sources] MyHelloWorldInstallPPI.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec MdeModulePkg/MdeModulePkg.dec [LibraryClasses] BaseLib PeimEntryPoint BaseMemoryLib DebugLib PeiServicesLib PrintLib #PeiLib #EfiCommonLib [depex] TRUE
-
编写 C:\edkii\OvmfPkg\MyHelloWorldLocatePPI\MyHelloWorldLocatePPI.c
#include <uefi.h> #include <Library/UefiLib.h> #include <Library/BaseLib.h> #include <Library/DebugLib.h> #include <Library/BaseMemoryLib.h> #include <Library/UefiDriverEntryPoint.h> #include <Library/PeimEntryPoint.h> #include <Library/PeiServicesLib.h> #include <Library/PeiServicesTablePointerLib.h> #include <Pi/PiHob.h> EFI_GUID gMyHelloWorldPEIGUID = { 0xbdb38129, 0x4d65, 0x39f4, { 0x72, 0x12, 0x68, 0xcf, 0x5a, 0x19, 0xa, 0xf8 }}; typedef EFI_STATUS (EFIAPI * PRINTMSG)(CHAR16 *Msg); typedef struct _EFI_HELLOWORLD_PROTOCOL { PRINTMSG PrintMsg; }EFI_HELLOWORLD_PROTOCOL; //ShellCEntryLib call user interface ShellAppMain EFI_STATUS EFIAPI MyHelloWorldLocatePPIEntry( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status = EFI_SUCCESS; EFI_HELLOWORLD_PROTOCOL *mHelloWorldPpi = NULL; DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] MyHelloWorldLocatePPIEntry Locate PPI Start..\n")); Status = PeiServicesLocatePpi ( &gMyHelloWorldPEIGUID, 0, NULL, (VOID **)&mHelloWorldPpi ); if (EFI_ERROR(Status)){ DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] MyHelloWorldLocatePPIEntry Locate PPI Fail..%r\n",Status)); return Status; } mHelloWorldPpi->PrintMsg(L"2019 CSDN Locate PPI Hello World ...\n"); DEBUG ((EFI_D_ERROR, "[MyHelloWorldPPI] MyHelloWorldLocatePPIEntry Locate PPI End..\n")); return Status; }
-
编写 C:\edkii\OvmfPkg\MyHelloWorldLocatePPI\MyHelloWorldLocatePPI.inf
[Defines] INF_VERSION = 0x00010006 BASE_NAME = MyHelloWorldLocatePPI FILE_GUID = 69E6DE6D-F39F-485f-9037-EB70FDCFC82B MODULE_TYPE = PEIM VERSION_STRING = 1.0 ENTRY_POINT = MyHelloWorldLocatePPIEntry [Sources] MyHelloWorldLocatePPI.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec MdeModulePkg/MdeModulePkg.dec [LibraryClasses] BaseLib PeimEntryPoint BaseMemoryLib DebugLib PeiServicesLib PrintLib #PeiLib #EfiCommonLib [depex] TRUE
-
修改C:\edkii\OvmfPkg\OvmfPkgX64.dsc
[Components] ... # # PEI Phase modules # INF OvmfPkg/MyHelloWorldInstallPPI/MyHelloWorldInstallPPI.inf INF OvmfPkg/MyHelloWorldLocatePPI/MyHelloWorldLocatePPI.inf ...
- 修改C:\edkii\OvmfPkg\OvmfPkgX64.fdf
[FV.PEIFV] ... # # PEI Phase modules # INF OvmfPkg/MyHelloWorldInstallPPI/MyHelloWorldInstallPPI.inf INF OvmfPkg/MyHelloWorldLocatePPI/MyHelloWorldLocatePPI.inf ...
二、 编译生成EFI文件
运行edksetup.bat
编译整个OvmfPkg Package
三、 运行HelloWorld PPI Driver
- 拷贝 C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fd 到C:\qemu
- 执行
setup-qemu-x64.bat | findstr MyHelloWorldPPI
的输出如下,
四、 小结
PPI(PEIM-to-PEIM Interface) 是一种PEIM驱动之间的通信方式,本文中MyHelloWorldInstallPPI
模块通过PeiServicesInstallPpi
提供了mPpiListCodePpi 服务,而MyHelloWorldLocatePPI
模块通过PeiServicesLocatePpi
获取了mPpiListCodePpi对象,通过访问对象的成员函数即可完成对驱动MyHelloWorldInstallPPI
资源的访问。