50.UEFI_HII_RESOURCE_SECTION을 사용하여 문자열 패키지와 함께 HII 패키지 목록 게시하기
이번 장에서는 애플리케이션이 HII 문자열 패키지를 게시할 수 있는 또 다른 방법을 살펴본다. 이번에는 결과 EFI 파일 PE/COFF 리소스에 HII 데이터를 포함하는 것에 대해 알아본다.
애플리케이션 만들기
스크립트를 써서 평소와 같이 애플리케이션을 만든다.
./createNewApp.sh HIIStringsUNIRC우리의 DSC 패키지 파일 UefiLessonsPkg/UefiLessonsPkg.dsc에 추가한다.
[Components]
...
UefiLessonsPkg/HIIStringsUNI/HIIStringsUNI.inf마지막으로 패키지 목록에 대한 GUID가 필요하며 패키지 DEC 파일인 UefiLessonsPkg/UefiLessonsPkg.dec에서 선언해준다.
[Guids]
...
gHIIStringsUNIRCGuid = { 0x785693b4, 0x623e, 0x40fa, { 0x9a, 0x45, 0x68, 0xda, 0x38, 0x30, 0x89, 0xdd }}이제 HIIStringsUNI 앱과 유사하도록 애플리케이션 파일을 수정해준다. Strings.uni 파일을 만들고 애플리케이션의 INF 및 *.c 파일을 수정해야한다.
UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.infUefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.cUefiLessonsPkg/HIIStringsUNIRC/Strings.uni
모든 작업을 완료하면 HIIStringsUNI 애플리케이션과 동일한 결과를 얻을 수 있다.
이제 애플리케이션을 수정할 준비가 다 되었다.
UEFI_HII_RESOURCE_SECTION
UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.inf에 다음을 추가한다.
UEFI_HII_RESOURCE_SECTION 플래그는 HII 리소스 섹션이 PE 이미지로 생성되는지 여부를 지정한다. 애플리케이션을 빌드하면 다음 오류로 인해 애플리케이션을 빌드할 수 없다.
Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC/DEBUG/HIIStringsUNIRCStrDefs.h를 보면 이 파일에 여전히 문자열 토큰이 포함되어 있지만 HIIStringsUNIRCStrings는 더 이상 여기에 존재하지 않는 것을 알 수 있다.
그리고 AutoGen.c 파일에는 더 이상 HIIStringsUNIRCStrings 배열 초기화 코드가 포함되어 있지 않다(Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC/DEBUG/AutoGen.c).
이제 우리의 문자열이 결과로 나오는 *.efi 이미지의 특수 섹션으로 인코딩되어 들어가는 것이다.
이를 우리가 얻으려면 애플리케이션 EFI_HANDLE ImageHandle에서 프로토콜 EFI_HII_PACKAGE_LIST_PROTOCOL을 검색해야 한다.
다음은 Shell이 모든 프로그램을 로드하는 데 사용하는 EFI_BOOT_SERVICES.LoadImage() 함수에 대한 UEFI 스펙의 관련 내용이다.
https://github.com/tianocore/edk2/blob/master/MdePkg/MdePkg.dec에 따르면 EFI_HII_PACKAGE_LIST_PROTOCOL은 gEfiHiiPackageListProtocolGuid로 식별된다.
우리의 INF 파일의 [Packages] 섹션에 MdeModulePkg/MdeModulePkg.dec가 이미 있으므로 이 GUID를 [Protocols] 섹션에 추가하기만 하면 된다.
코드에서는 OpenProtocol UEFI 부트 서비스의 도움으로 애플리케이션의 ImageHandle 에서 PackageList 프로토콜을 얻을 수 있다.
결과의 PackageList는 HIIStringsUNI 애플리케이션의 경우와 같이 StrGather 스크립트의 결과인 일부 size 헤더가 있는 문자열 패키지가 아니다. HIIStringsC 애플리케이션에서 수동으로 구성한 것과 같은 일반 PackageList이다. 따라서 HiiAddPackages 라이브러리 함수를 사용하는 대신 EFI_HII_DATABASE_PROTOCOL.NewPackageList()를 직접 사용해야 한다.
여기서는 gHiiDatabase를 사용했으므로 필요한 헤더인 #include <Library/UefiHiiServicesLib.h>를 추가하고 애플리케이션 INF 파일의 [LibraryClasses]에 UefiHiiServicesLib를 추가하는 것을 잊지 말자.
이제 애플리케이션을 빌드하고 실행해보면 모든 것이 정상인것을 확인할 수 있다.
유형이 'HII'인 PE/COFF 리소스
objdump를 사용하여 애플리케이션 헤더를 살펴보자. -x 옵션을 사용하여 모든 헤더의 내용을 출력할 수 있다.
화살표 뒤의 사항에 주의하면서 보자.
이제 UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.inf에 UEFI_HII_RESOURCE_SECTION을 주석 처리해준다.
애플리케이션 빌드 후에 objdump를 다시 한 번 실행해보면 다음과 같은 결과를 얻을 수 있다.
이 버전의 애플리케이션을 실행하려고 하면 아래와 같이 실행된다.
Last updated