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

다음 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
```

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

<pre class="language-c"><code class="lang-c">$ vi UefiLessonsPkg/PCDLesson/PCDLesson.c
---
  Print(L"PcdFeatureFlag=%d\n", FeaturePcdGet(PcdFeatureFlag));
<strong>  Print(L"PcdFeatureFlag=%d\n", PcdGetBool(PcdFeatureFlag));
</strong></code></pre>

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

```c
#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`을 사용해야 하기를 권고하지만, 함수 둘 모두 사용할 수 있다.

```c
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));
```

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

```shell
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의 구문에 대한 일종의 '조미료'이다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bob-mcd-team.gitbook.io/uefi/uefi-development/pcd/22.feature-flag-pcd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
