InstallProcotolInterface() 是用来安装 Protocol 的函数,之前有提及【参考1】。这次研究和实验了一下它的具体代码。
在\MdeModulePkg\Core\Dxe\DxeMain\DxeMain.c有定义 BootService 的函数:
//
// DXE Core Module Variables
//
EFI_BOOT_SERVICES mBootServices = {
{
EFI_BOOT_SERVICES_SIGNATURE, // Signature
EFI_BOOT_SERVICES_REVISION, // Revision
sizeof (EFI_BOOT_SERVICES), // HeaderSize
0, // CRC32
0 // Reserved
},
………………………………………
(EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent
(EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface
(EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface
………………………………………
具体实现在 \MdeModulePkg\Core\Dxe\Hand\Handle.c 文件中:
/**
Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which
Calls the private one which contains a BOOLEAN parameter for notifications
@param UserHandle The handle to install the protocol handler on,
or NULL if a new handle is to be allocated
@param Protocol The protocol to add to the handle
@param InterfaceType Indicates whether Interface is supplied in
native form.
@param Interface The interface for the protocol being added
@return Status code
**/
EFI_STATUS
EFIAPI
CoreInstallProtocolInterface (
IN OUT EFI_HANDLE *UserHandle,
IN EFI_GUID *Protocol,
IN EFI_INTERFACE_TYPE InterfaceType,
IN VOID *Interface
)
{
return CoreInstallProtocolInterfaceNotify (
UserHandle,
Protocol,
InterfaceType,
Interface,
TRUE
);
}
上述会跳转到同一个文件中的下面这个函数:
EFI_STATUS
CoreInstallProtocolInterfaceNotify (
IN OUT EFI_HANDLE *UserHandle,
IN EFI_GUID *Protocol,
IN EFI_INTERFACE_TYPE InterfaceType,
IN VOID *Interface,
IN BOOLEAN Notify
)
{
PROTOCOL_INTERFACE *Prot;
PROTOCOL_ENTRY *ProtEntry;
IHANDLE *Handle;
EFI_STATUS Status;
VOID *ExistingInterface;
//
// returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
// Also added check for invalid UserHandle and Protocol pointers.
//
if (UserHandle == NULL || Protocol == NULL) {
return EFI_INVALID_PARAMETER;
}
if (InterfaceType != EFI_NATIVE_INTERFACE) {
return EFI_INVALID_PARAMETER;
}
//
// Print debug message
//
DEBUG((DEBUG_INFO, "LABZ InstallProtocolInterface: %g %p\n", Protocol, Interface));
Status = EFI_OUT_OF_RESOURCES;
Prot = NULL;
Handle = NULL;
比如,按照上述修改之后,运行下面的命令 build -a X64 -p OvmfPkg\OvmfPkgX64.dsc 即可生成 QEMU 的 BIOS:OVMF.fd,在 \Build\OvmfX64\DEBUG_VS2015x86\FV\ 。
将它copy 到 QEMU 的目录后,运行 qemu-system-x86_64.exe -m 256 -bios ovmf.fd -debugcon file:debug.log -global isa-debugcon.iobase=0x402 -net none 即可抓到串口 log。例如:
Memory Allocation 0x00000003 0xFEA4000 - 0xFEC8FFF
Memory Allocation 0x00000003 0xFEA4000 - 0xFEC8FFF
Memory Allocation 0x00000004 0xFE84000 - 0xFEA3FFF
Memory Allocation 0x00000004 0xFC00000 - 0xFDFFFFF
Memory Allocation 0x00000007 0xFE00000 - 0xFE83FFF
Memory Allocation 0x00000004 0xBF36000 - 0xBF55FFF
FV Hob 0x900000 - 0x12FFFFF
LABZ InstallProtocolInterface: D8117CFE-94A6-11D4-9A3A-0090273FC14D FEC3E30
LABZ InstallProtocolInterface: 8F644FA9-E850-4DB1-9CE2-0B44698E8DA4 FA11EB0
LABZ InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B FA11C18
LABZ InstallProtocolInterface: 220E73B6-6BDB-4413-8405-B974B108619A FA10BB0
LABZ InstallProtocolInterface: EE4E5898-3914-4259-9D6E-DC7BD79403CF FEC4B10
参考: