EFI的Protocol類似於物件導向中的Interface,它訂定好一個標準,而實作是經由別的程式來完成,而使用也是透過這個標準來使用。
一個Protocol基本上是由數個變數與函式指標所組成的結構,也會跟隨著一個唯一識別的GUID(Globally Unique Identifier),這部分與PEI階段的PEIM中的PPI滿像的,各個不同程式間可利用方法將所需的功能找出來使用。
安裝一個Protocol時會與自己對應的GUID配在一起,放置於Handle Database中,Handle Database是一個Linked List,每個Handle被串在一起,而Handle底下又與屬於它的所有GUID | Protocol相連。
EFI DRIVER BINDING PROTOCOL原型:
typedef struct _EFI_DRIVER_BINDING_PROTOCOL {
EFI_DRIVER_BINDING_PROTOCOL_SUPPORTED Supported;
EFI_DRIVER_BINDING_PROTOCOL_START Start;
EFI_DRIVER_BINDING_PROTOCOL_STOP Stop;
UINT32 Version;
EFI_HANDLE ImageHandle;
EFI_HANDLE DriverBindingHandle;
} EFI_DRIVER_BINDING_PROTOCOL;
其GUID:
#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
{0x18A031AB,0xB443,0x4D1A,0xA5,0xC0,0x0C,0x09,0x26,0x1E,0x9F,0x71}
extern EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
基本上是使用gEfiDriverBindingProtocolGuid這個變數來與EFI DRIVER BINDING PROTOCOL做關聯。
與Protocol常用的相關服務如下:
InstallMultipleProtocolInterfaces (
IN OUT EFI_HANDLE *Handle,
...
);
安裝數個Protocol與搭配的GUID至指定的Handle底下。
UninstallMultipleProtocolInterfaces (
IN EFI_HANDLE Handle,
...
);
移除數個Handle底下的Protocol與所搭配的GUID。
LocateHandleBuffer (
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID *Protocol OPTIONAL,
IN VOID *SearchKey OPTIONAL,
IN OUT UINTN *NoHandles,
OUT EFI_HANDLE **Buffer
);
可將全部或以特定的條件將Handle取出。
ProtocolsPerHandle (
IN EFI_HANDLE Handle,
OUT EFI_GUID ***ProtocolBuffer,
OUT UINTN *ProtocolBufferCount
);
取得指定的Handle底下所有的Protocol GUID陣列,並傳出數量。
OpenProtocolInformation (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
OUT UINTN *EntryCount
);
取得Handle底下指定的GUID的Information Entry陣列,並回傳數量。
LocateProtocol (
IN EFI_GUID *Protocol,
IN VOID *Registration OPTIONAL,
OUT VOID **Interface
);
以指定的GUID取出第一個Protocol。
HandleProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface
);
取出Handle中指定的Protocol,以GUID為識別。
OpenProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface OPTIONAL,
IN EFI_HANDLE AgentHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT32 Attributes
);
類似HandleProtocol(),但提供了更安全的做法,綁訂指定的Handle,避免使用中的Protocol被Uninstall。
此為最後一個參數的定義:
#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
依需要使用,有些定義可不用CloseProtocol()。
CloseProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
IN EFI_HANDLE AgentHandle,
IN EFI_HANDLE ControllerHandle
);
為以OpenProtocol()開啟的Protocol解除占用。
沒有留言:
張貼留言