22. Feature Flag PCD와 BOOLEAN FixedAtBuild PCD의 비교

Lesson 22에서는 다른 Feature Flag PCD라고 하는 PCD 유형을 소개할 예정이다. 이는 기본적으로 Boolean 값을 가진다.

다음 PCD를 DEC 파일에 추가하도록 하자.

$ vi UefiLessonsPkg/UefiLessonsPkg.dec
---
[PcdsFeatureFlag]
  gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag|TRUE|BOOLEAN|0x16DD586E

그리고 이 FeaturePcd를 INF(PCDLesson.inf) 파일에 넣어준다. INF 파일에서 이 유형의 PCD는 [FeaturePcd] 섹션으로 이동한다.

$ vi UefiLessonsPkg/PCDLesson/PCDLesson.inf
---
[FeaturePcd]
  gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag

PCDLesson.c 파일에서 PCD 값을 얻으려면 FeaturePcdGet 또는 거의 동일한 PcdGetBool 함수를 사용할 수 있으며, 이는 https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/PcdLib.h 참고하면 된다.

#define FeaturePcdGet(TokenName)            _PCD_GET_MODE_BOOL_##TokenName
...
#define PcdGetBool(TokenName)               _PCD_GET_MODE_BOOL_##TokenName

플래그를 출력하기 위해서 두 함수 모두 사용해보도록 하겠다.

$ vi UefiLessonsPkg/PCDLesson/PCDLesson.c
---
  Print(L"PcdFeatureFlag=%d\n", FeaturePcdGet(PcdFeatureFlag));
  Print(L"PcdFeatureFlag=%d\n", PcdGetBool(PcdFeatureFlag));

빌드를 하기 이전에 AutoGen.h 모듈을 체크해보면 다음과 같은 코드를 확인할 수 있다.

#define _PCD_TOKEN_PcdFeatureFlag  0U
#define _PCD_SIZE_PcdFeatureFlag 1
#define _PCD_GET_MODE_SIZE_PcdFeatureFlag  _PCD_SIZE_PcdFeatureFlag
#define _PCD_VALUE_PcdFeatureFlag  ((BOOLEAN)1U)
extern const  BOOLEAN  _gPcd_FixedAtBuild_PcdFeatureFlag;
#define _PCD_GET_MODE_BOOL_PcdFeatureFlag  _gPcd_FixedAtBuild_PcdFeatureFlag
//#define _PCD_SET_MODE_BOOL_PcdFeatureFlag  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD

따라서, PCD에 대한 두 함수 실행은, 다음과 같이 변환된다.

FeaturePcdGet/PcdGetBool(PcdFeatureFlag) --> _PCD_GET_MODE_BOOL_PcdFeatureFlag --> _gPcd_FixedAtBuild_PcdFeatureFlag

그리고 이 gPcdFixedAtBuild_PcdFeatureFlag 변수는 AutoGen.c 파일에 존재하는 상수이다.

GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag;  // = ((BOOLEAN)1U);

이제 OVMF에서 애플리케이션을 실행하면 다음과 같은 출력을 확인할 수 있다.

FS0:\> PCDLesson.efi
...
PcdFeatureFlag=1
PcdFeatureFlag=1

[PcdsFixedAtBuild] bool 데이터 유형 PCD와 비교

보다시피 feature PCD는 PcdFixedAtBuild 섹션 아래에 정의된 Boolean PCD와 유사하다.

DEC(UefiLessonsPkg.dec) 파일에서 선언된 방식을 비교해보자.

$ cat UefiLessonsPkg/UefiLessonsPkg.dec
---
[PcdsFixedAtBuild]
  ...
  gUefiLessonsPkgTokenSpaceGuid.PcdBool|TRUE|BOOLEAN|0x69E88A63

[PcdsFeatureFlag]
  gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag|TRUE|BOOLEAN|0x16DD586E

그리고 INF(PCDLessons.inf) 파일에서는,

$ cat UefiLessonsPkg/PCDLesson/PCDLesson.inf
---
[FixedPcd]
  ...
  gUefiLessonsPkgTokenSpaceGuid.PcdBool

[FeaturePcd]
  gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag

FeatureFlag PCD의 경우, PCDLesson.c에 대해서는 FixedPcdGetBool 대신에 FeaturePcdGet을 사용해야 하기를 권고하지만, 함수 둘 모두 사용할 수 있다.

Print(L"PcdFeatureFlag=%d\n", FeaturePcdGet(PcdFeatureFlag)); // already used
Print(L"PcdFeatureFlag=%d\n", PcdGetBool(PcdFeatureFlag)); // already used
Print(L"PcdBool=%d\n", FixedPcdGetBool(PcdBool));
Print(L"PcdBool=%d\n", PcdGetBool(PcdBool));

해당 코드의 결과는 다음과 같다.

FS0:\> PCDLesson.efi
...
PcdFeatureFlag=1
PcdFeatureFlag=1
PcdBool=1
PcdBool=1

이제 AutoGen 파일의 PCD에 대한 코드를 비교해보도록 하겠다.

$ cat Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.c
---
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdBool = _PCD_VALUE_PcdBool;
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag = _PCD_VALUE_PcdFeatureFlag;
$ cat Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
---
#define _PCD_TOKEN_PcdBool  0U
#define _PCD_SIZE_PcdBool 1
#define _PCD_GET_MODE_SIZE_PcdBool  _PCD_SIZE_PcdBool
#define _PCD_VALUE_PcdBool  1U
extern const  BOOLEAN  _gPcd_FixedAtBuild_PcdBool;
#define _PCD_GET_MODE_BOOL_PcdBool  _gPcd_FixedAtBuild_PcdBool
//#define _PCD_SET_MODE_BOOL_PcdBool  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD

#define _PCD_TOKEN_PcdFeatureFlag  0U
#define _PCD_SIZE_PcdFeatureFlag 1
#define _PCD_GET_MODE_SIZE_PcdFeatureFlag  _PCD_SIZE_PcdFeatureFlag
#define _PCD_VALUE_PcdFeatureFlag  ((BOOLEAN)1U)
extern const  BOOLEAN  _gPcd_FixedAtBuild_PcdFeatureFlag;
#define _PCD_GET_MODE_BOOL_PcdFeatureFlag  _gPcd_FixedAtBuild_PcdFeatureFlag
//#define _PCD_SET_MODE_BOOL_PcdFeatureFlag  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD

보다시피 차이점은 미묘하다. 따라서 FeaturePcd는 단순히 부울 FixedAtBuild PCD의 구문에 대한 일종의 '조미료'이다.

Last updated