68. VFR 추가 입력 요소 Part 3: oneof & orderedlist

oneof 요소

oneof 요소는 미리 정의된 세트에서 옵션을 선택할 수 있다. (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.6.2-vfr-oneof-statement-definition)

Form.vfr에 다음 코드를 추가해주자.

oneof
  varid = FormData.OneOfValue,
  prompt = STRING_TOKEN(ONEOF_PROMPT),
  help = STRING_TOKEN(ONEOF_HELP),
  option text = STRING_TOKEN(ONEOF_OPTION1), value = 0x00, flags = DEFAULT;
  option text = STRING_TOKEN(ONEOF_OPTION2), value = 0x33, flags = 0;
  option text = STRING_TOKEN(ONEOF_OPTION3), value = 0x55, flags = 0;
endoneof;

Strings.uni에 새 문자열 토근을 추가해주자.

#string ONEOF_PROMPT           #language en-US  "OneOf list prompt"
#string ONEOF_HELP             #language en-US  "OneOf list help"
#string ONEOF_OPTION1          #language en-US  "OneOf list option 1"
#string ONEOF_OPTION2          #language en-US  "OneOf list option 2"
#string ONEOF_OPTION3          #language en-US  "OneOf list option 3"

마지막으로 Data.h에 값을 넣어주자.

이를 Build 후 실행 시 아래와 같은 결과가 나타난다.

사용 가능한 옵션 중 하나를 선택 가능하다.

옵션 2를 선택하면 아래와 같이 뜬다. 옵션 2는 위에서 value 값을 0x33으로 설정했다. 그렇기 때문에 dmpstore 명령으로 해당 변수의 값을 확인하면 0x33이 있는 것 확인 가능하다.

IFR 코드는 아래와 같다 (Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst):

첫 번째 opcode는 아래와 같다.

옵션 opcode에 대한 정의는 다음과 같다.

설명에 따르면 Value 필드의 내용은 Type 필드의 값에 따라 달라진다. 다음은 해당 type 플래그의 주석이 있는 모든 가능한 value type이다.

우리는 구조에서 데이터를 UINT8 OneOf로 선언했다. 따라서 컴파일러는 type 플래그를 EFI_IFR_TYPE_NUM_SIZE_8로 자동으로 공제했다. 이를 UINT16 OneOf로 변경하면 컴파일러는 type 필드 값을 EFI_IFR_TYPE_NUM_SIZE_16으로 변경한다.

아래의 출력을 이전의 출력과 비교해보자.

예를 들어 type을 EFI_HII_DATE OneOfValue로 설정하려고 하면 EFI_IFR_TYPE_VALUE가 숫자외에 많은 값을 가질 수 있지만 오류가 발생한다.

따라서 EFI_IFR_TYPE_VALUE의 하위 유형만 지원되는 것을 볼 수 있다.

orderedlist 요소

옵션이 있는 또 다른 요소는 orderdlist 요소이다. (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.8-vfr-orderedlist-statement-definition)

이전과 동일하게 Form.vfr, Strings.uni, Data.h에 값을 넣어주겠다. (Data.h에는 3개의 옵션을 사용하기 위해서 배열을 3으로 선언했다.)

빌드 후 실행하면 아래와 같은 화면이 나온다.

선택을 하면 아래와 같이 나오며 +/-를 통하여 이동이 가능하다.

순서를 2 1 3으로 변경하고 F10을 눌러 저장해보자.

그러면 UEFI 변수의 OrderedListValue 필드에 다음 데이터가 표시된다.

IFR

IFR코드를 살펴보자. (Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst)

첫번째 코드 요소는 EFI_IFR_ORDERED_LIST이다.

데이터를 필드와 일치시키면 새 필드에 대해 다음 데이터를 얻게 된다.

모든 것이 order이고 요소에는 3개의 옵션이 있으므로 MaxContainter=0x3이다. 옵션 IFR 코드를 보면 옵션이 oneof 요소에서 사용된 것과 동일한 opcode EFI_IFR_ONE_OF_OPTION으로 인코딩된 것을 볼 수 있다.

원리는 동일하다. 데이터를 UINT8에서 UINT16으로 인코딩하는 경우 컴파일러는 옵션을EFI_IFR_TYPE_NUM_SIZE_16(=UINT16)으로 인코딩하고 스토리지에 다음과 같이 표시된다.

orderedlist를 사용하면 숫자가 아닌 데이터 유형을 사용할 수도 있다. 예를 들어 변수를 날짜 배열로 인코딩도 가능하다.

당연히 VFR에서 코드를 변경 해줘야 한다.

이런 코드에 대한 IFR 데이터를 파싱하면 모든 옵션이 #define EFI_IFR_TYPE_DATE 0x06 type으로 인코딩된 것을 볼 수 있다.

데이터 배열의 크기가 사용 가능한 옵션보다 작으면 모든 것이 컴파일되지만 HII에서는 첫번째 array size 옵션만 표시된다. 예를 들어 UINT8 OrderedListValue[2]의 결과는 아래와 같다.

Last updated