43. HII 데이터베이스 개념 및 출력

이번 장에서는 HII(Human Interface Infrastructure)에 대해 학습한다.

모든 BIOS는 사용자와 어떤 형태로든 상호 작용이 있다. 예로 부팅 시 표시되는 이미지, 부팅 시 특수 키를 통해 BIOS 설정을 제어하는 메뉴 선택으로의 진입 등이다. 이러한 형식의 텍스트는 사용자 지정 글꼴을 적용할 수 있다. 그리고 BIOS에서 언어 설정을 변경할 경우 인터페이스의 모든 문자열이 변경된 언어로 번역되어야 한다.

HII의 주요 목표는 이러한 휴먼 인터페이스의 부분을 쉽게 검색하고 확장하기 위해 표준화 된 인터페이스를 제공하는 것이다. HII의 외부 드라이버/애플리케이션을 사용해 새로운 요소(예: 글꼴, 문자열, 이미지 또는 양식)를 플랫폼에 쉽게 설치하거나 존재하는 요소를 내부에 반영할 수 있다.

이는 모든 HII 데이터가 전체 플랫폼의 중앙 저장소 역할을 하는 특수 데이터베이스인 HII 데이터베이스에 저장되기 때문에 가능하다.

결국 Form Browser 는 HII 데이터베이스를 사용하여 사용자 인터페이스를 표시하고 사용자와 상호 작용하는 것이다.

HII 데이터베이스 콘텐츠를 탐색하는 애플리케이션을 만들어보자.

이전에 여러 번 새로운 애플리케이션을 만들며 반복적인 작업을 수행해왔다. 그리고 이 작업을 자동화하기 위해 간단한 스크립트를 작성하여 진행할 예정이다. https://github.com/Kostr/UEFI-Lessons/blob/master/scripts/createNewApp.sharrow-up-right

#!/bin/bash
##
# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
#
# SPDX-License-Identifier: MIT
##

# This is a simple script that creates a basic structure for your new UEFI application
# Put this script in your edk2 folder and run it with 1 argument - your new application name

APP_NAME=${1}

UUID=$(uuidgen)

mkdir -p UefiLessonsPkg/${APP_NAME}

cat << EOF > UefiLessonsPkg/${APP_NAME}/${APP_NAME}.inf
[Defines]
  INF_VERSION                    = 1.25
  BASE_NAME                      = ${APP_NAME}
  FILE_GUID                      = ${UUID}
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain
[Sources]
  ${APP_NAME}.c
[Packages]
  MdePkg/MdePkg.dec
[LibraryClasses]
  UefiApplicationEntryPoint
  UefiLib
EOF

cat << EOF > UefiLessonsPkg/${APP_NAME}/${APP_NAME}.c
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EFI_SUCCESS;
}
EOF

edk2 폴더에 해당 스크립트를 작성하고 새 애플리케이션 ShowHII 를 생성한다.

이렇게 하면 *.inf 파일 및 *.c 을 포함한 UefiLessonPkg/ShowHII 폴더가 생성된다. 새로 만들 애플리케이션을 UefiLessonsPkg/UefiLessonsPkg.dsc 의components section에 추가한다.

HII 데이터베이스에 접근하기 위해 EFI_HII_DATABASE_PROTOCOL 를 이용해야 한다.

해당 프로토콜에서 ExportPackageLists 함수를 주목하자.

HII 데이터베이스의 데이터가 GUID로 식별되는 패키지 목록으로 구성되기 때문에 이 함수를 통해 패키지 목록을 얻을 수 있다. 각 패키지 목록은 서로 다른 유형의 여러 패키지(form/font/strings/...)를 가질 수도 있다.

먼저 작성하는 애플리케이션에 EFI_HII_DATABASE_PROTOCOL 를 가져오고 필요한 헤더를 포함시킨다.

또한 ShowHII.inf 파일에 gEfiHiiDatabaseProtocolGuid 정보도 작성한다.

다음은 프로토콜의 ExportPackageLists 함수를 사용하기 위한 정보이다.

  • 데이터베이스에서 일부 패키지 목록이 아닌 모든 패키지 목록을 가져오려면 Handle 매개변수에 NULL 값을 사용한다.

  • 출력 배열의 크기를 미리 알 수 없기 때문에 표준 UEFI 메커니즘을 이용한다.

  1. 먼저 BufferSize=0 으로 ExportPackageLists 를 호출한다. 반환 값으로 EFI_BUFFER_TOO_SMALL 을 받지만 BufferSize 을 필요한 크기 값으로 재설정 받을 수 있다.

  2. 이후 gBS->AllocatePool 의 호출로 필요한 크기의 버퍼를 할당한다.

  3. 올바른 버퍼와 크기로 ExportPackageLists 를 호출한다.

  • 할당된 버퍼를 해제할 경우 Library/MemoryAllocationLib.h 에 존재하는 FreePool 함수를 사용하면 된다.

수집한 데이터는 각각 EFI_HII_PACKAGE_LIST_HEADER 라는 특별한 헤더가 존재하는 패키지 목록들이다. 해당 데이터를 처리해보자.

데이터를 파싱하고 패키지 목록에 존재하는 모든 정보를 출력하기 위해서는 반복문이 존재하는 함수를 작성해야 한다.

해당 함수를 다음과 같이 호출하면 된다.

작성한 애플리케이션을 빌드하고 실행해보자.

다음으로 PackageLists 를 살펴보자. 각 PackageListEFI_HII_PACKAGE_LIST_HEADER 바로 다음에 시작하는 여러 패키지들로 구성되어 있다. 그리고 각 패키지에는 자체 EFI_HII_PACKAGE_HEADER 가 존재한다.

다음은 사용 가능한 일부 패키지 유형에 대한 설명이다.

패키지 목록에는 필요한 만큼의 많은 패키지가 있을 수 있으며 모두 연결되어 있다. 패키지 목록의 모든 데이터 패키지 다음에는 패키지 목록의 끝을 표시하는 EFI_HII_PACKAGE_END 유형의 패키지가 존재해야 한다.

따라서 이 정보를 이용하여 패키지 목록 내의 모든 패키지 정보를 파싱하는 코드를 추가해보자.

그리고 PackageType 라는 패키지 유형 값을 출력가능한 문자열로 변환하는 함수를 작성하자.

위 두 가지를 추가하여 다시 애플리케이션을 빌드하고 실행하면 다음과 같은 결과를 얻을 수 있다.

출력된 GUID에 대한 정보는 다음과 같다.

https://github.com/tianocore/edk2/blob/master/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.infarrow-up-right

https://github.com/tianocore/edk2/blob/master/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.infarrow-up-right

https://github.com/tianocore/edk2/blob/master/OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.infarrow-up-right

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Logo/LogoDxe.infarrow-up-right

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.infarrow-up-right

EFI_FILE_EXPLORE_FORMSET_GUID https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/FileExplorerLib/FormGuid.harrow-up-right

RAM_DISK_FORM_SET_GUID gRamDiskFormSetGuid https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Include/Guid/RamDiskHii.harrow-up-right https://github.com/tianocore/edk2/blob/master/MdeModulePkg/MdeModulePkg.decarrow-up-right

gCustomizedDisplayLibGuid https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.carrow-up-right

gDisplayEngineGuid https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.carrow-up-right

https://github.com/tianocore/edk2/blob/master/OvmfPkg/PlatformDxe/Platform.infarrow-up-right

mFontPackageListGuid https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.carrow-up-right

gIScsiConfigGuid ISCSI_CONFIG_GUID https://github.com/tianocore/edk2/blob/master/NetworkPkg/Include/Guid/IScsiConfigHii.harrow-up-right https://github.com/tianocore/edk2/blob/master/NetworkPkg/NetworkPkg.decarrow-up-right

gShellLevel2HiiGuid SHELL_LEVEL2_HII_GUID https://github.com/tianocore/edk2/blob/master/ShellPkg/Include/Guid/ShellLibHiiGuid.harrow-up-right https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_LEVEL1_HII_GUID gShellLevel1HiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_LEVEL3_HII_GUID gShellLevel3HiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_DRIVER1_HII_GUID gShellDriver1HiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_DEBUG1_HII_GUID gShellDebug1HiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_BCFG_HII_GUID gShellBcfgHiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

SHELL_NETWORK1_HII_GUID gShellNetwork1HiiGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

gUefiShellFileGuid https://github.com/tianocore/edk2/blob/master/ShellPkg/Application/Shell/Shell.infarrow-up-right https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.decarrow-up-right

Last updated