45. EFI_HII_DATABASE_PROTOCOL의 NewPackageList를 사용하여 문자열 패키지가 포함된 문자열 목록 게시

파트 1: 패키지 목록 데이터 생성의 일반적인 측면

지난 수업에서는 내부적으로 HII 데이터베이스가 패키지 목록과 해당 패키지를 연속적인 데이터 배열이 아닌 많은 이중 연결 리스트로 구현된 복잡한 데이터 구조로 저장되어 있다는 것을 발견했다.

하지만 EFI_HII_DATABASE_PROTOCOL 에서 ExportPackageLists 를 사용했을 때 패키지 목록과 해당 패키지의 연속 데이터 배열을 받을 수 있었다. 이는 HII 데이터베이스의 내부를 추상화하고 사용자 입장에서 분석하기 쉬운 형식으로 데이터를 제공하는 편리한 인터페이스라고 볼 수 있다.

EFI_HII_DATABASE_PROTOCOL 에서 NewPackageList 를 통해 패키지 목록을 데이터베이스에 추가하는 경우도 마찬가지이다. 이 함수는 동일한 형식의 연속적 데이터 배열에서 오는 패키지 목록을 예상한다.

EFI_HII_DATABASE_PROTOCOL.NewPackageList()

Summary:
Adds the packages in the package list to the HII database.

Prototype:
typedef
EFI_STATUS
(EFIAPI *EFI_HII_DATABASE_NEW_PACK) (
 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
 IN CONST EFI_HANDLE DriverHandle, OPTIONAL
 OUT EFI_HII_HANDLE *Handle
 );

Parameters:
This		A pointer to the EFI_HII_DATABASE_PROTOCOL instance
PackageList	A pointer to an EFI_HII_PACKAGE_LIST_HEADER structure
DriverHandle	Associate the package list with this EFI handle
Handle		A pointer to the EFI_HII_HANDLE instance
Description	This function adds the packages in the package list to the database and returns a handle. If there is a
		EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will create a
		package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.

ShowHII 애플리케이션의 출력을 다시 한번 살펴보자.

위 출력에서 각 패키지의 목록들이 하나 이상의 데이터 패키지를 포함하고 END 타입의 패키지로 끝나는 것을 볼 수 있다.

일반적인 패키지는 EFI_HII_PACKAGE_HEADER 와 데이터 컨텐츠가 포함된다. 하지만 END 타입의 패키지에는 EFI_HII_PACKAGE_HEADER 필드가 EFI_HII_PACKAGE_END 로 설정되어 있을 뿐이다.

따라서 기본적으로 패키지 목록 데이터의 모습은 다음과 같다.

일반적인 패키지에 다른 유형이 존재할 수 있다. 이 EFI_HII_PACKAGE_HEADER.type 필드에 존재하는 정의를 살펴보자.

다음 수업에서는 문자열 패키지가 포함된 패키지 목록을 추가할 것이다.

템플릿을 통해 application 만들기

이전 스크립트를 이용해 편리하게 애플리케이션을 제작하자.

그리고 UefiLessonsPkg/UefiLessonsPkg.dsc 에 application 정보를 추가한다.

패키지 목록 GUID

모든 패키지 목록에는 자체 GUID가 있어야기 때문에 UefiLessonsPkg/UefiLessonsPkg.dec 파일에 추가해주어야 한다.

애플리케이션 소스 코드에서 참조하기 위해 UefiLessonsPkg/HIIStringsC/HIIStringsC.inf 파일에도 선언한다.

마지막으로 Packages 섹션에 다음 UefiLessonsPkg/UefiLessonsPkg.dec 정보도 포함시킨다.

UefiHiiServicesLib

각 HII 프로토콜은 시스템에서 하나의 인스턴스만을 가지기 때문에 생성자의 모든 LocateProtocol 논리를 추상화하고 프로토콜의 전역 변수를 채우는 라이브러리가 있다. https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Library/UefiHiiServicesLib

따라서 마지막 애플리케이션에서 아래 코드를 사용하는 대신에

application의 *.inf 파일에 UefiHiiServicesLib 을 포함하고 gHiiDatabaseEFI_HII_DATABASE_PROTOCOL* 로 사용할 수 있다.

따라서 현재 application의 *.inf 파일에 UefiHiiServicesLib 를 Library classes section에 추가한다.

또한 application의 *.inf 에 이 라이브러리 패키지 *.dec 파일을 포함해야 한다.

최종적으로 소스 코드에서 해당 헤더를 선언하여 사용한다.

Application 코드 설명

아래 코드에서 패키지 목록의 크기를 계산하지 않기 때문에 약간의 트릭을 사용한다. 그리고 예시에서는 실제로 필요한 것보다 더 큰 숫자를 사용하고 있다.

이 장은 여러 파트로 분할되어 있으며 충분히 어렵기 때문에 이 이상의 어려움을 만들지 않고자 함을 미리 설명한다.

Last updated