///
/// 128 bit buffer containing a unique identifier value.
/// Unless otherwise specified, aligned on a 64 bit boundary.
///
typedef struct {
UINT32 Data1;
UINT16 Data2;
UINT16 Data3;
UINT8 Data4[8];
} GUID;
GUID는 위와 같이 4바이트-2바이트-2바이트-8바이트로 구성되어 있다. 다행히도 위와 같은 구조체의 필드 하나씩 직접 뽑아줄 필요가 없다는 것이다.
Print 함수의 %g 옵션을 사용하면 GUIDs가 출력되기 때문에 간편하게 출력할 수 있다.
Print 옵션에 대해서는 아래 링크에 자세히 설명되어 있다.
()
/// Printing Guid Using %g Option
Print("GUID=%g\n", myGUID);
우리는 PROTOCOL_INTERFACE 구조에서 참조되는 PROTOCOL_ENTRY의 EFI_GUID 필드를 출력할 것이다.
따라서 이전 챕터에서 언급한 것과 동일한 이유로 구조를 재정의 해야한다.
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;
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;
이전 챕터에서 설명한 것과 동일하게 LINK는 다른 PROTOCOL_INTERFACE에 존재하는 LIST_ENTRY구조를 가리킨다(double-linked list). 아래는 이를 간략하게 표헌한 모습이다.
FS0:\> ImageHandle.efi
h n d l
Back Protocol Interface Link: 68D4320
Forward Protocol Interface Link: 6891520
Current Link: 6891520
p i f c
Back Link: 6891430
Forward Link: 6891B20
GUID=752F3136-4E16-4FDC-A22A-E5F46812F4CA
Current Link: 6891B20
p i f c
Back Link: 6891520
Forward Link: 68D4320
GUID=BC62157E-3E33-4FEC-9920-2D3B36D750DF
Current Link: 68D4320
p i f c
Back Link: 6891B20
Forward Link: 6891430
GUID=5B1B31A1-9562-11D2-8E3F-00A0C969723B
Current Link: 6891430
? ? ?
Back Link: 68D4320
Forward Link: 6891520
GUID=00000000-0000-0000-0000-000000000000
다음으로 남은 두개의 GUID는 UEFI 스펙(specification)에서 확인할 수 있다.
EFI_LOADE_IMAGE_DEVICE_PATH_PROTOCOL -
EFI_LOADE_IMAGE_DEVICE_PATH_PROTOCOL이 설치된 경우 Loaded Image Device Path Protocol은 PE/COFF 이미지가 EFI 부팅서비스인 LoadImage()를 통해 로드될 때 사용된 장치 경로를 지정해준다.
마지막으로 출력된 PROTOCOL_INTERFACE 구조는 유효한 " p i f c" 서명이 없으므로 해당 GUID를 유심히 볼 필요는 없다.
하지만 우리는 Link 필드의 ForwardLink나 BackLink가 필요한 것이 아닌 PROTOCOL_INTERFACE 구조 자체에 대한 포인터가 필요하다.
따라서 아래와 같이 몇가지 매크로에 대한 정의가 필요하다. 해당 매크로는 리눅스 커널 프로그래밍을 공부했다면 친숙하게 느껴질 수도 있다. 혹시라도 모를 사람을 위해서 자세히 설명된 링크를 아래에 첨부하겠다.
()
두곳에서 사용되는 것을 볼 수 있다. 사용되는 곳에서의 GUID에 대한 정의는 아래의 링크들에 들어가면 볼 수 있다.
()
()