c 파일의 메인 함수를 보면 2개의 인자로 EFI_HANDLE ImageHandle과 EFI_SYSTEM_TABLE *SystemTable을 받는 것을 볼 수 있다.
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
EFI_SYSTEM_TABLE은 이전 장에서 언급을 했으니 이번에는 ImageHandle에 대해서 알아보겠다.
/// A collection of related interfaces.
///
typedef VOID *EFI_HANDLE;
단순히 EFI_HANDLE type은 void에 대한 포인터인 것을 알 수 있으며 그로 인해서 모든것에 대한 포인터가 될 수 있다.
#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l')
///
/// IHANDLE - contains a list of protocol handles
///
typedef struct {
UINTN Signature;
/// All handles list of IHANDLE
LIST_ENTRY AllHandles;
/// List of PROTOCOL_INTERFACE's for this handle
LIST_ENTRY Protocols;
UINTN LocateRequest;
/// The Handle Database Key value when this handle was last created or modified
UINT64 Key;
} IHANDLE;
이 핸들에는 연결된 프로토콜 목록이 존재한다.
(프로토콜은 인터페이스와 같이 기능및 데이터 필드의 집합이다.)
핸들에 연결된 프로토콜 목록을 추적하기 위해서 해당 아래의 필드가 사용된다.
/// List of PROTOCOL_INTERFACE's for this handle
LIST_ENTRY Protocols;
이는 위에서 언급한 것과 같이 다음 구조를 가리키는 이중연결리스트(double-linked list)이다.
#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c')
///
/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
/// with a protocol interface structure
///
typedef struct {
UINTN Signature;
/// Link on IHANDLE.Protocols
LIST_ENTRY Link;
/// Back pointer
IHANDLE *Handle;
/// Link on PROTOCOL_ENTRY.Protocols
LIST_ENTRY ByProtocol;
/// The protocol ID
PROTOCOL_ENTRY *Protocol;
/// The interface value
VOID *Interface;
/// OPEN_PROTOCOL_DATA list
LIST_ENTRY OpenList;
UINTN OpenListCount;
} PROTOCOL_INTERFACE;
PROTOCOL_INTERFACE는 핸들의 이중연결리스트(double-linked list)되어 있다. 그리고 다음 구조인PROTOCOL_ENTRY를 가리키고 있다.
#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e')
///
/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
/// database. Each handler that supports this protocol is listed, along
/// with a list of registered notifies.
///
typedef struct {
UINTN Signature;
/// Link Entry inserted to mProtocolDatabase
LIST_ENTRY AllEntries;
/// ID of the protocol
EFI_GUID ProtocolID;
/// All protocol interfaces
LIST_ENTRY Protocols;
/// Registerd notification handlers
LIST_ENTRY Notify;
} PROTOCOL_ENTRY;
PROTOCOL_INTERFACE 구조는 별도의 프로토콜 데이터베이스에 존재하는 실제 PROTOCOL_ENTRY 구조를 가리키는 프록시일 뿐입니다.
위에서 시사한 점들은 아래의 그림으로 통해서 한눈에 볼 수 있다.
모든 핸들은 각 IHANDLE 구조의 AllHandles 필드의 도움으로 인하여 상호 연결된다.
모든 프로토콜은 PROTOCOL_ENTRY 구조의 AllEntries 필드의 도움으로 상호 연결된다.
각 Handle에는 Link 필드의 녹색 선을 통해 내부적으로 서로 연결된 모든 PROTOCOL_INTERFACES의 이중 연결구조로 되어있다.
각 프로토콜 항목은 사용되는 모든곳(PROTOCOL_INTERFACES)을 효과적으로 알고 있다.
UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
FS0: Alias(s):HD0a1:;BLK1:
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
BLK2: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Press ESC in 4 seconds to skip startup.nsh or any other key to continue.
Shell> fs0:
FS0:\> ImageHandle.efi
Signature: h n d l