# 21. PCD 변수에 대한 Overriding

이번 장에서는, PCD Overriding 기능을 한 번 살펴보도록 하자. (이제부터 Override는 '재정의'라는 표현으로 대신 사용하겠다.

## INF 재정의

`PcdInt32Override`라는 이름으로 `UINT32` PCD 파일을 만들고 기본 값으로 42를 할당해 두자.

`UefiLessonsPkg/UefiLessonsPkg.dec` 경로에 이를 추가한다.

```
[PcdsFixedAtBuild]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|42|UINT32|0x3CB8ABB8
```

이제 INF 파일(`UefiLessonsPkg/PCDLesson/PCDLesson.inf`)을 통하여 PCD를 애플리케이션에 채울 때, PCD 재정의구문을 사용하여 PCD의 기본값을 다음과 같이 변경한다.

```
[FixedPcd]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|43
```

만약 이 애플리케이션을 빌드하고 `AutoGen.h`를 열어보면, `PcdInt32Override` 값이 재정의된 것을 볼 수 있다.

```
...
#define _PCD_VALUE_PcdInt32Override  43U
...
```

해당 결과 값을 확인하기 위해서 `PCDLesson.c` 파일에 Print문을 추가해 줄 수도 있다.

```
  Print(L"PcdInt32Override=%d\n", FixedPcdGet32(PcdInt32Override));
```

이 애플리케이션을 빌드하여 OVMF로 실행하면, 다음과 같은 결과가 나타난다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=43
```

따라서 모든 앱/드라이버가 `UefiLessonsPkg.dec` 파일에서 각각 다르게 선언된 PCD를 재정의할 수 있다.

## DSC 재정의

모든 모듈에 대해 로컬으로서 PCD를 덮어쓰는 것 외에도 DSC 파일을 통해 패키지에서 전체적으로 PCD를 재정의할 수 있다.

위의 INF에 대한 재정의를 삭제하지 않고, DSC 파일에 대한 재정의를 삭제해준다.(`UefiLessonsPkg.dsc`)

이 이후, 기본값을 44로 재정의해준다.

```
[PcdsFixedAtBuild]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```

그리고 애플리케이션을 빌드하고 OVMF에서 이를 실행하면 다음과 같은 결과가 출력된다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=44
```

여기까지 보면 알 수 있다시피, 재정의(Override)문에는 우선 순위가 존재한다.

```
DEC < INF < DSC
```

* 선언 파일(Declaration file, DEC)은 기본 값으로 PCD를 선언한다.
* 모든 앱/드라이버 정보 파일(INF)은 PCD의 값을 다르게 재정의할 수 있다.
* 그러나, 이러한 모든 앱/드라이버(DSC)를 포함하는 패키지 설명 파일은 모든 앱/드라이버에 대해 PCD를 무시할 수 있다.

이 경우, DSC 파일은 우리가 빌드하는 패키지의 DSC 파일을 의미한다는 점에 유의하는 것이 중요하다. 그리고 모듈의 origin 패키지의 DSC 파일과 같은 필요는 없다.

이를 증명하기 위해서 `OvmfPkg/OvmfPkgX64.dsc` 패키지를 모듈의 일부로 빌드해보겠다. `OvmfPkg/OvmfPkgX64.dsc`에 `[Components]` 부분에 `.inf` 파일을 추가해준다.

```
[Components]
  ...
  UefiLessonsPkg/PCDLesson/PCDLesson.inf
```

그 다음, OVMF 이미지를 빌드한다.

```
build --platform=OvmfPkg/OvmfPkgX64.dsc --arch=X64 --buildtarget=RELEASE --tagname=GCC5
```

이 경우, 애플리케이션의 이미지는 `Build/UefiLessonsPkg/RELEASE_GCC5/X64/PCDLesson.efi`의 경로가 아니라, 다음과 같은 경로에 존재한다.

```
Build/OvmfX64/RELEASE_GCC5/X64/PCDLesson.efi
```

따라서 해당 `.efi` 파일을 공유 디스크에 복사하고, OVMF 이미지에서 실행하면, 다음과 같은 결과가 나오게 된다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=43
```

`UefiLessosPkg.dsc` 파일에서 해주었던 재정의가 무시되는 것을 확인할 수 있다.

그 다음은 DSC 재정의를 위해 우리가 빌드하는 패키지의 DSC를 수정해야 한다.

```
$ vi OvmfPkg/OvmfPkgX64.dsc
---
[PcdsFixedAtBuild]
  ...
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
```

마지막으로 다시 OVMF 이미지를 재구축하여 업데이트 파일을 공유 디스크에 복사하고 실행하여 다음과 같은 결과값이 나오는 지 확인한다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=45
```

## FDF 재정의

`[Components]` 부분에 애플리케이션을 추가해주었을 때, 애플리케이션을 `OvmfPkgX64.dsc` 패키지의 일부로 컴파일하고자 한다고 위에서 언급한 적이 있다.

애플리케이션을 최종 OVMF 플래시 이미지에 포함하려면 FDF파일에 추가해주어야 한다.

여기서는 자세한 설명을 하지 않고, `[FV.DXEFV]` 섹션 끝에 다음 명령어를 추가해준다.

```
$ vi OvmfPkg/OvmfPkgX64.fdf
---
[FV.DXEFV]
...
INF  UefiLessonsPkg/PCDLesson/PCDLesson.inf
#################################################
```

여기서 주목해야할 점은, FDF 파일에서 SET문을 통해 PCD를 재정의할 수 있다는 것이다.

이를 위해서는 `[Defines]` 섹션의 수정이 필요하다.

```
$ vi OvmfPkg/OvmfPkgX64.fdf
---
[Defines]
...
SET gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override = 46
...
```

재정의 이후 빌드하고, 이를 확인한다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=46
```

또 다른 SET 명령어를 모듈의 `[FV.DXEFV]` 섹션에 추가해준다.

```
$ vi OvmfPkg/OvmfPkgX64.fdf
---
[FV.DXEFV]
...
INF  UefiLessonsPkg/PCDLesson/PCDLesson.inf
SET  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override = 47
#################################################
```

※ `[Defines]` 섹션에서의 재정의는 일반 재정의보다 선행되어야 한다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=47
```

## DSC 모듈 내에서의 재정의

다음 PCD 재정의는 DSC 모듈 내에서 진행하는 재정의 과정이다. 이 경우의 재정의 구문은 다음과 같다. 기존 추가해주었던 명령어에 내부 재정의를 덧씌워준다.

```
$ vi UefiLessonsPkg/UefiLessonsPkg.dsc
---
[Components]
  ...
  UefiLessonsPkg/PCDLesson/PCDLesson.inf {
    <PcdsFixedAtBuild>
      gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|48
  }
```

DSC 모듈 내에서의 재정의는 FDF 파일의 재정의보다 우선한다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=48
```

## CL(Command-Line)을 통한 재정의

마지막으로, 명령줄을 통해 PCD를 재정의할 수도 있다. 예를 들어보자면,

```
build --platform=OvmfPkg/OvmfPkgX64.dsc \
      --arch=X64 \
      --buildtarget=RELEASE \
      --tagname=GCC5 \
      --pcd="gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override=49"
```

위와 같은 명령어로 빌드한 이후, Print문을 통해 이를 확인하면, 다음과 같은 화면을 출력한다.

```
FS0:\> PCDLesson.efi
...
PcdInt32Override=49
```

## 마무리

이 장에서는 PCD 재정의의 우선 순위 규칙들 중, 일부를 언급했다. 보다 더 자세한 내용은 <https://edk2-docs.gitbook.io/edk-ii-dsc-specification/2_dsc_overview/27_pcd_section_processing#2.7.3.8-precedence> 확인하기 바란다.


---

# 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/21.pcd-variable-overriding.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.
