60. gRT->SetVariable() 함수를 사용한 UEFI 변수 생성, 변경 및 삭제

비휘발성 UEFI 변수(재부팅 후에도 지속되는 변수)와 함께 작동하는 HII 폼을 만들기 전에 UEFI 변수 서비스를 한 번 더 확인해야 한다.

지금까지는 gRT->GetVariablegRT->GetNextVariableName 서비스를 통해 이미 존재하는 변수만 확인했다.

이번 장에서는 사용자 지정 UEFI 변수를 생성, 변경 및 삭제할 수 있는 애플리케이션을 만들어 본다.

이번 장에서는 gRT->SetVariable 함수를 사용한다.

SetVariable()

Summary:
Sets the value of a variable.

Prototype:
typedef
EFI_STATUS
SetVariable (
 IN CHAR16 *VariableName,
 IN EFI_GUID *VendorGuid,
 IN UINT32 Attributes,
 IN UINTN DataSize,
 IN VOID *Data
 );

Parameters:
VariableName 	A Null-terminated string that is the name of the vendor’s variable.
		Each VariableName is unique for each VendorGuid.
		VariableName must contain 1 or more characters. If VariableName is an empty string, then
		EFI_INVALID_PARAMETER is returned
VendorGuid 	A unique identifier for the vendor
Attributes 	Attributes bitmask to set for the variable
DataSize 	The size in bytes of the Data buffer ... A size of zero causes the variable to be deleted.
Data 		The contents for the variable

이제 애플리케이션을 생성한다.

UefiLessonsPkg/UefiLessonsPkg.dsc

사용자에게 사용자 정의 UEFI 변수를 만들거나 삭제할 수 있는 기능을 제공한다. 단순화를 위해 변수 값은 사용자가 제공하는 문자열이다. 아래는애플리케이션에 대한 도움말이다. UefiLessonsPkg/SetVariableExample/SetVariableExample.c

변수를 생성할 때 변수 속성을 제공해야 한다는 것을 알 수 있다. 아래는 플래그의 조합일 수 있다.

  • EFI_VARIABLE_NOW_VOLATILE - 재부팅 후에도 변수가 남아있다.

  • EFI_VARIABLE_BOOTSERVICE_ACCESS - 변수를UEFI 단계에서 사용할 수 있다.

  • EFI_VARIABLE_RUNTIME_ACCESS - 변수를 OS단계에서 사용할 수 있다. (EFI_BOOT_SERVICES.ExitBootServices() 호출이 성공한 후)

이러한 플래그는 아래 링크에 정의되어 있으며, 지금은 다루지 않을 다른 플래그도 있다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiMultiPhase.h

위에서 살펴본 3개의 플래그가 있는 경우 아래 조합으로만 사용할 수 있다.

NON_VOLATILE
BOOTSERVICE_ACCESS
RUNTIME_ACCESS

+

+

+

+

+

+

+

+

때로는 코드에서 아래와 같은 변수 속성 조합을 볼 수 있다. https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Include/Guid/VariableFormat.h

이제 다시 애플리케이션을 이어간다. 애플리케이션에서 명령 인자를 처리할 수 있도록 코드를 작성한다.

UefiLessonsPkg/SetVariableExample/SetVariableExample.c

UefiLessonsPkg/SetVariableExample/SetVariableExample.inf

Argc==4일 때, 들어오는 인자를 변수 생성을 위한 입력으로 처리한다. 인자를 파싱하고 gRT->SetVariable 서비스를 호출한다.

Argc==2일 때는 사용자가 변수 이름만 제공했음을 의미하여 도움말 메시지에 따라 해당 변수를 삭제해야 한다. 이를 위해 DataSize가 0인 gRT->SetVariable을 호출한다.

모든 변수는 gEfiCallerIdGuid GUID에서 생성되며, 여기서는 bb2a829f-7943-4691-a03a-f1f48519d7e6를 의미한다.

애플리케이션을 빌드 후 UEFI 공유 폴더에 복사한다.

이번에는 UEFI 변수를 다루기 때문에 아래 명령을 통해 QEMU를 실행한다.

존재하는 UEFI 변수를 보려면 UEFI Shell에서 dmpstore 명령을 사용할 수 있다. dmpstore 명령어에는 특정 GUID와 관련된 변수만 출력하는 옵션이 있다. UEFI Shell에서 바로 실행하면 GUID와 관련된 내용이 없어 확인할 수 없다.

SetVariableExample.efi 애플리케이션을 통해 Hello 라는 내용을 가진 MyVar 변수를 생성한다.

dmpstore 명령을 통해 변수가 생성된 것을 확인할 수 있다.

MyVar 변수를 수정한다.

MyVar 변수를 삭제한다.

또한 변수를 생성할 때 위에서 확인했던 조합이 아닌 경우에는 변수를 생성할 수 없다.

NV+BSBS 속성을 가진 두 개의 변수를 생성한다.

QEMU를 재실행 하고 dmpsote 명령을 확인하면 MyPersistentVar 변수가 남아있는 것을 확인할 수 있다.

또한 이미 생성된 변수의 속성을 변경할 수 없는지 확인할 수 있다.

dmpstore 명령을 사용해 변수를 삭제할 수도 있다.

dmpsotre -d <GUID>명령을 사용해 GUID 뒤에 있는 모든 변수를 삭제할 수 있다.

여기서는 예시로 애플리케이션에서 변수 내용을 단순 문자열로 하여 진행했지만 변수에는 복잡한 구조가 저장될 수 있다.

Last updated