73. VFR question 기본값 설정

default/defaultstore/resetbutton

요소의 기본 값 설정

HIIFormDataElements 애플리케이션에 기본 값을 추가해보자.

defualt 키워드를 사용하여 요소에 기본 값을 설정할 수 있다.

새로 추가된 문자열 토큰 정보는 반드시 String.uni 파일에 추가하자.

형식을 로드한 직후 orderedlist 요소의 순서가 기본 설정 값으로 변경을 진행하기 전에 이미 기본 값으로 변경된 것을 볼 수 있다. 조금 이상할 수도 있지만 표준 값인 0x000000 이 요소에 영향을 주지 않기 때문이라는 정도로만 생각하자.

어쨌든 F9 키를 사용하여 값을 기본 값으로 재 설정해보자.

아래와 같은 확인 창이 나타난다.

그리고 Y 를 눌러 형식에 변경된 값을 확인해보자

IFR

IFR 코드를 확인해보면 Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst

EFI_IFR_DEFAULT opcode를 통해 모든 기본 값이 표시되는 것을 볼 수 있다.

위 모든 구문은 값 필드가 포함된 구조체의 첫 번째 형식(EFI_IFR_DEFAULT)을 사용한다. 가능한 값 유형은 다음과 같다.

또한 위 모든 구문의 DefaultId 값이 0 인 것을 알 수 있따. 이제 그럼 기본 저장소가 무엇인지에 대해 알아보자.

기본 저장소

먼저 UEFI formset에서 여러 기본 저장소를 정의할 수 있다는 것을 이해해야 한다.

만약 HIIFormDataElements application의 Form.list 파일을 보게 된다면 formset이 이미 2개의 기본 저장소를 가진 것을 볼 수 있다. Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst

Opcode 0x5cEFI_IFR_DEFAULTSTORE 에 해당한다.

코드에서 ID가 0x00000x0001 이면서이름이 없는 두 개의 기본 저장소를 정의한다.

일반적으로 UEFI 스은 기본 저장소 ID(UINT16)에 대해 가능한 모든 값을 4개의 클래스로 나눈다.

  • 0x0000-0x3fff: UEFI Spec에 의해 예약되어짐

  • 0x4000-0x7fff: 플랫폼 공급자 사용

  • 0x8000-0xbfff: 하드웨어 공급업체 사용

  • 0xc000-0xffff: 펌웨어 공급업체 사용

첫 번째 그룹에는 이미 정의된 3개의 클래스가 있다.

  • 0x0000 - "standard defaults"(정상 작동을 위한 시스템/장치를 준비하는데 사용하는 기본 값)

  • 0x0001 - "manufacturing defaults"(제조를 위해 시스템/장치를 준비하는데 사용하는 기본 값)

  • 0x0002 - "safe defaults"("안전 모드" 또는 낮은 위험모드에서 시스템을 부팅하는데 사용되는 기본 값)

이를 통해 formset에 "standard defaults"과 "manufacturing defaults"이라는 기본 저장소가 있다는 것을 알 수 있다. 이들은 항상 VFR 컴파일러에 의해 모든 formset에 생성되어 진다.

위의 값에 대한 모든 정의 아래에서 볼 수 있다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h

VFR의 기본 저장소 정의

만약 VFR에 여러 기본 저장소를 지원하려면 대부분 명시적 정의가 필요하다.

VFR에는 defaultstore 라는 특별한 요소가 존재한다. https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/26_vfr_default_stores_definition

기본적인 문법은 다음과 같다.

"standard defaults" 와 "manufacturing defaults" 를 명시적으로 정의하기 위해 다음과 같이 사용할 수 있다.

물론 *.uni 파일에 새 문자열 토큰도 추가해야 한다.

이제 저장소에 다른 정의를 제공할 수 있다.

IFR

IFR 코드를 통해 생성한 defaultsotre 코드가 EFI_IFR_DEFAULTSTORE opcode를 어떻게 변환했는지 확인해보자.

실질적으로 변경된 사항은 없으며 DefaultName 필드의 문자열 토큰만 업데이트 되었다.

하지만 이제 기본 값이 저장소를 참조하는 방법을 볼 수가있다.

resetbutton

이전에는 값을 기본 값으로 설정하기 위해서 F9 키를 form browser에서 사용했다. 기본 저장소가 있는 지금은 어떻게 해야 할까?

이러한 종류의 기능을 위해 VFRresetbutton 이라는 요소를 제공한다. 이 요소는 question 값을 기본 저장소의 값으로 설정할 수 있는 버튼을 생성할 수 있다.

두 개의 기본 저장소에 대해 2개의 버튼을 생성하자.

계속 강조하지만 *.uni 에 새 문자열 토큰 생성하는 것을 잊지 말자.

이 코드는 다음과 같은 형태를 만들어 낼 것이다.

첫 번째 버튼이 numeric 값을 7로 설정하는 걸 확인할 수 있다.

두 번째 버튼으로 8을 설정한다.

IFR

resetbutton 의 IFR 코드는 다음과 같다.

이 요소는 EFI_IFR_RESET_BUTTON opcode에 의해 정의되어 졌다.

기본 값을 정의하는 다른 방법

oneof 는 모든 HII 메뉴에서 가장 공통적인 요소이며 flags 필드와 함께 옵션 대신 "standard storage" 과 "manufacturing storage" 값을 정의할 수 있다. 이를 통해 요소 가독성을 높힐 수 있다.

이 경우 0x55 값은 "standard storage", 0x33 값은 "manufacturing storage"로 설정되었다. 앞서 만들었던 resetbuuton를 통해 이 기능을 확인할 수 있다.

flags 로 정의된 기본 값과 default 키워드로 정의된 것을 혼합하여 사용할 수 있지만, 이 경우 UEFI Spec은 엄격한 우선 순위를 갖는다. 하지만 사용하지 않는 것을 추천한다.

flags 는 오직 "standard storage" 와 "manufacturing storage" 에 대한 참조 생성에 이용된다는 점을 기억하자. 기본 저장소 ID는 다른 사용자 지정 저장소에 대한 참조를 정의할 수 없다.

일정하지 않은 기본 값

기본 값을 표현식으로 정의할 수 있다. 이 경우에는 defaults value = <...> 와 같은 문법이 사용된다. 대부분의 경우 기본 값이 다른 question 값에 속해 있을 때 사용된다.

이 코드를 통해 "standard storage"로 재설정하면 numeric 기본값이 0x55 로 변경되는 결과와 "manufacturing storage"로 재설정하면 numberic 기본값이 0x33 으로 변경되는 결과를 얻을 수 있다.

참조하는 name 은실제 questionref(< name>) 사용 전에 정의되어야 한다는 점을 유의하자.

지금 IFR 코드를 보면 완전히 다른 방식으로 인코딩 되었다는 것을 볼 수 있다.

이 경우에 EFI_IFR_DEFAULT_2 구조체의 Type 필드가 EFI_IFR_TYPE_OTHER 값임이 확인된다.

EFI_IFR_VALUEEFI_IFR_QUESTION_REF1 에 대한 정의이다.

기본 저장소 우선 순위

만약 resetbutton 요소를 이용해 기본 저장소의 값을 ID=0x5555 로 정의했으나 default 와 같은 요소로 기본 저장소의 값을 다른 값으로 (예로 ID=0x3333) 지정했을 경우에 어떤 일이 발생하는지 알아보자.

아래는이해를 위한 예시이다.

이 경우 numeric 은 가장 낮은 ID를 가진 defaultstore 에서 값을 가져온다. 따라서 numeric 값은 7로 설정된다.

이는 코드를 단순화하는데 도움이 되는 일반적인 규칙이다. 예로 몇 가지 요소에 대해서만 "standard defaults" 과 다른 "manufacturing storage" 기본 값을 지원하려는 경우 이러한 요소에 대해서만 추가 코드를 작성해야 한다.

Last updated