44. HII 데이터베이스 내부

먼저 HII 데이터베이스의 기본 구조를 살펴보자. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h

typedef struct _HII_DATABASE_PRIVATE_DATA {
  UINTN                                 Signature;
  LIST_ENTRY                            DatabaseList;
  LIST_ENTRY                            DatabaseNotifyList;
  EFI_HII_FONT_PROTOCOL                 HiiFont;
  EFI_HII_IMAGE_PROTOCOL                HiiImage;
  EFI_HII_IMAGE_EX_PROTOCOL             HiiImageEx;
  EFI_HII_STRING_PROTOCOL               HiiString;
  EFI_HII_DATABASE_PROTOCOL             HiiDatabase;
  EFI_HII_CONFIG_ROUTING_PROTOCOL       ConfigRouting;
  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL   ConfigKeywordHandler;
  LIST_ENTRY                            HiiHandleList;
  INTN                                  HiiHandleCount;
  LIST_ENTRY                            FontInfoList;
  UINTN                                 Attribute;
  EFI_GUID                              CurrentLayoutGuid;
  EFI_HII_KEYBOARD_LAYOUT               *CurrentLayout;
} HII_DATABASE_PRIVATE_DATA;

해당 구조에는 기본 HII 프로토콜에 대한 포인터가 포함되어 있다. 이러한 각 프로토콜은 HII의 다른 부분과의 상호작용을 담당한다. 예를 들어 하나는 HII 데이터베이스(EFI_HII_FONT_PROTOCOL)의 글꼴과의 상호 작용을 담당하고, 다른 하나는 이미지와의 상호 작용(EFI_HII_IMAGE_PROTOCOL/EFI_HII_IMAGE_EX_PROTOCOL)과 문자열(EFI_HII_STRING_PROTOCOL)과의 상호작용을 담당한다.

앞서 데이터베이스에서 HII 패키지를 추가/제거하는 EFI_HII_DATABASE_PROTOCOL 를 살펴보았기 때문에 다른 HII 요소들을 통해 이 프로토콜의 가능성을 더 살펴보자.

프로토콜 외에도 이 구조는 다른 요소에 대한 이중 연결 리스트를 유지한다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h

이러한 목록 중에는 데이터 베이스 레코드 LIST_ENTRY DatabaseList 에 대한 이중 연결 리스트가 있다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h

LIST_ENTRY DatabaseList 는 첫번째 HII_DATABASE_RECORDDatabaseEntry 필드를 가르킨다. 이 구조에서 DatabaseEntry 는 차례로 다음 HII_DATABASE_RECORDDatabaseEntry 필드를 가르킨다.

각 데이터베이스 레코드에는 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 가 존재한다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h

각 이중 연결 리스트에는 이 패키지 목록에 있는 해당 유형의 패키지에 대한 포인터가 포함되어 있다. 이전 학습에서는 모든 패키지 목록과 해당 패키지를 연속 데이터 배열로 받았지만 이는 EFI_HII_DATABASE_PROTOCOLExportPackageLists 함수 기능일 뿐, HII 데이터는 플랫폼 메모리 전체에 분산 될 수 있는 이중 연결 리스트로 표현되어 있다.

HII_DATABASE_RECORD에 있는 또 다른 중요한 필드는 EFI_HII_HANDLE 핸들이다. 각 HII_DATABASE_RECORD 는 패키지 목록을 정의하고 EFI_HII_HANDLE 로 식별된다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h

하지만 GenerateHiiDatabaseRecord 함수 구현을 살펴보면 HII 핸들의 실제 구현을 볼 수 있다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c

HII_HANDLE 타입의 정의는 다음과 같다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h

Key 필드는 HII_DATABASE_PRIVATE_DATA 에 있는 HiiHandleCount 의 현재 값에 해당한다.

그리고 LIST_ENTRY Handle 은 시스템의 모든 HII_HANDLE 을 함께 연결하는데 도움이 된다. 중요한 점은 HII_DATABASE_PRIVATE_DATA 에 있는 LIST_ENTRY HiiHandleList 필드와 동일한 핸들 목록이다.

다음은 방금 다룬 HII 데이터 베이스 구조의 그림이다.

HII 데이터베이스 초기화

이 HII 데이터베이스 구조는 HiiDatabaseDxe 에서 정적 초기화 되었다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseEntry.c

HiiDatabaseDxe driver의 진입점은 linked lists(LIST_ENTRY)를 초기화하고 HII 데이버베이스의 모든 프로토콜을 시트템에 설치한다.

Linked lists 포인터

여기에 해당 필드에 대한 포인터로부터 구조체 포인터를 가져오는 전처리기 방법이 있다.

바로CR 매크로의 도움으로 DatabaseEntry 필드에 대한 포인터로 HII_DATABASE_RECORD 에 대한 포인터를 쉽게 얻는 것이다.

아래는CR 매크로에 대한 정의이다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/DebugLib.h

그리고 BASE_CR 에 대한 정의는 다음과 같다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h

마지막으로로OFFSET_OF 에 대한 정의이다.

Last updated