65. VFR 추가 입력 요소 Part 1: number

이전 장에서는 checkbox VFR요소를 사용했었다. 사용자 입력에 사용할 수 있는 다른 VFR 요소들을 살펴보자.

efivarstore에서 사용자 정의 구조체를 사용하는 HII 애플리케이션 생성하기

HIIFormCheckbox 드라이버의 코드를 기반으로 하나의 checkbox 요소가 포함된 HIIFormDataElements 드라이버를 만들어보자.

이 레슨의 UEFI 변수는 폼에 있는 다른 VFR 요소의 데이터를 포함하므로 사용자 정의 구조체 유형 내부의 checkbox에 대한 UINT8 스토리지를 배치해야 한다.

typedef를 통해 사용자 정의 구조체를 만들기 위해 헤더 파일 UefiLessonsPkg/HIIFormDataElements/Data.h 를 생성한다. 변수 이름과 GUID 정의(우리의 경우 FORMSET_GUID와 동일하다고 결정함)도 이 헤더파일로 이동시켜준다.

UefiLessonsPkg/HIIFormDataElements/Data.h

#ifndef _DATA_H_
#define _DATA_H_

#define FORMSET_GUID  {0x531bc507, 0x9191, 0x4fa2, {0x94, 0x46, 0xb8, 0x44, 0xe3, 0x5d, 0xd1, 0x2a}}

#define UEFI_VARIABLE_STRUCTURE_NAME L"FormData"

#pragma pack(1)
typedef struct {
  UINT8 CheckboxValue;
} UEFI_VARIABLE_STRUCTURE;
#pragma pack()

#endif

다음은 UefiLessonsPkg/HIIFormDataTemplate/HIIFormDataElements.c에 적용해야 하는 수정 사항이다.

그리고 UefiLessonsPkg/HIIFormDataElements/Form.vfr의 수정사항

드라이버를 빌드하고 모든 것이 제대로 작동하는지 확인해본다.

숫자형 VFR 요소

숫자 VFR 요소를 조사해보자. 이를 통해 사용자는 HII 폼에서 숫자 값을 입력할 수 있다. https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.6.1-vfr-numeric-statement-definition

새 요소에는 스토리지가 필요하므로 UEFI 변수 구조에 UINT8 NumericValue 필드를 추가한다.

또한 HII폼에 필요한 몇 가지 문자열을 UefiLessonsPkg/HIIFormDataElements/Strings.uni에 추가한다.

요소에 대한 최소한의 VFR 코드는 다음과 같다.

minimummaximum필드는 숫자 요소에 필수이다. 이 예제에서는 값을 5..20 범위로 제한한다.

UEFI 변수의 크기를 변경했으므로 드라이버를 로드하기 전에 제거하는 것이 좋다.(unload 명령어 사용)

우리의 폼을 로드하면 다음과 같다.

보다시피 기본적으로 값은 0이다.(ZeroMem(&EfiVarstore, sizeof(EfiVarstore))을 사용하기 때문) 이는 값이 제한 범위(5..20)를 벗어남을 의미한다. 요점은 HII 폼은 초기 값을 제어할 수 없다는 것이다. 최대값 및 최소값은 오직 사용자의입력에 대한 제한이다.

범위를 벗어난 값(예: 4)을 입력하려고 하면 폼에서 허용하지 않는다.

폼 엔진은 허용되지 않는 입력을 입력하는 것까지만 허용한다. 예를 들어 첫 번째 기호로 3을 입력하면 폼 엔진은 다른 숫자 기호를 추가로 입력하는 것을 허용하지 않는다. 값이 사용 가능한 범위를 벗어나기 때문이다.

그러나 허용 범위에 있으면 값을 성공적으로 입력하고 저장(F10)할 수 있다.

dmpstore 명령을 사용하여 값이 성공적으로 설정되었는지 확인할 수 있다. 우리의 경우 값은 저장소의 두 번째 바이트에 있다.(0x0f = 15)

단계 필드

숫자 VFR 요소는 단계 필드를 포함할 수 있다. 예를 들어

이 필드가 있는 경우 폼의 왼쪽 하단에 값 조정 도움말 메시지가 표시된다.

이는 +/-를 입력하여 요소 값을 늘리거나 줄일 수 있음을 의미한다. 그리고 +/-를 입력할 때마다 단계 필드에 설정한 값만큼 값이 증가/감소한다. 폼 엔진은 심지어 범위 필드를 어느 정도 존중한다. 예를 들어 값이 19이고 +를 입력하면 값이 20으로 설정된다. 다음 +는 값을 5로 변경하고 다음 +7로 변경한다.

IFR 코드 분석

평소처럼 바뀐 IFR 코드를 조사해보자.

Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst

이를 해석하려면 UEFI 스펙을 참조해야한다.

checkbox 요소에 대해 이야기할 때 이미 EFI_IFR_OP_HEADEREFI_IFR_QUESTION_HEADER를 조사했었다.

이 데이터를 빼면 10 05 14 02만 남는다.

이것은 우리의 새 필드가 다음과 같이 채워짐을 의미한다.

0x10 값을 갖는 Flags 필드를 제외하고 모든 것이 예상대로 채워진다. 0x10은 무슨 의미일까?

특수 숫자 플래그는 다음과 같다.

따라서 우리의 경우 EFI_IFR_DISPLAY_UINT_DECEFI_IFR_NUMERIC_SIZE_1 플래그가 있는 것이다. 즉, 부호 없는 10진수로 표시되며 크기는 1바이트라는 것을 표시해준다.

숫자 플래그

플래그 값을 변경하려면 VFR에서 이 키워드를 사용해야 한다.

예를 들어 flags = DISPLAY_UINT_HEX를 사용하면 값이 16진수로 렌더링된다.

음의 정수를 설정할 가능성을 추가하려면 DISPLAY_INT_DEC 플래그를 추가하면 된다.

크기 플래그는 기본적으로 저장소의 변수의 크기에 따라 자동으로 설정된다. 예를 들어 숫자 필드의 유형을 UINT32로 변경하는 경우,

VFR 코드:

빌드 하면 다음 IFR 결과를 생성한다.

데이터를 구문 분석해보면,

크기 플래그가 EFI_IFR_NUMERIC_SIZE_1에서 EFI_IFR_NUMERIC_SIZE_4로 변경되었다.

빌드 시스템은 빌드 프로세스에서 스토리지 크기를 확인한다는 것을 알 수 있다.

그래서 크기만 UINT8로 되돌리고 minimum/maximum/step에 대해 UINT32 값을 그대로 두면 빌드가 실패한다.

또한 저장소 크기와 충돌하는 크기 플래그를 입력할 수 없다.

efivarstore의 경우 크기 플래그는 중복성을 가진다. 이것은 다른 유형의 스토리지를 사용하는 경우에만 중요하다. 하지만 VFR에 있는 저장소의 크기를 명시적으로 표시하려는 경우에 넣을 수 있다.

또한 UEFI 변수 크기를 변경할 때마다 UEFI 변수를 삭제하는 것을 잊지 말자. 꼭 업데이트된 드라이버를 로드하기 전에 수행해야 한다.

| 연산자의 도움으로 여러 플래그를 결합할 수 있음을 기억하자.

Last updated