1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
After you've written you application code in C you need to compile it for the target CPU architecture.
EDKII supports compilation for several CPU architectures. You can see the complete list if you look at the output of the `build --help` command:
```
$ build --help
...
Options:
...
-a TARGETARCH, --arch=TARGETARCH
ARCHS is one of list: IA32, X64, ARM, AARCH64, RISCV64
or EBC, which overrides target.txt's TARGET_ARCH
definition. To specify more archs, please repeat this
option.
...
```
The abbreviations above mean:
```
IA32 - x86 32bit
X64 - x86 64bit
ARM - ARM 32bit
AARCH64 - ARM 64bit
RISCV64 - RISCV 64bit
EBC - EFI Byte Code
```
As we use `qemu-system-x86_64` virualization tool, we've compiled our applications for the `X64` architecture.
In our first application examples we did it via an argument to the `build` command:
```
build ... --arch=X64 ...
```
Later we've constructed the `Conf/target.txt` file, so we could call the `build` command without any arguments. In this file we've indicated the target arch by setting the `TARGET_ARCH` define:
```
`TARGET_ARCH = X64`
```
Let's try to build our code for the x86 32bit (`IA32`) architecture.
To do this we can override default argument (which comes from the `Conf/target.txt`) via a command argument:
```
build --arch=IA32
```
If you try to do it right now, you'll get the error:
```
build.py...
: error 2000: Invalid parameter
Invalid ARCH specified. [Valid ARCH: X64]
- Failed -
```
This is happening because `IA32` architecture is not present in the architecture whitelist in our DSC file `UefiLessonsPkg/UefiLessonsPkg.dsc`:
```
[Defines]
...
SUPPORTED_ARCHITECTURES = X64
```
To correct this modify `SUPPORTED_ARCHITECTURES` to the following value:
```
[Defines]
...
SUPPORTED_ARCHITECTURES = IA32|X64
```
Now the build via `build --arch=IA32` should succeed. The results will be in the same `Build/UefiLessonsPkg/RELEASE_GCC5/` folder. But now along with the `X64` subfolder there would be the `IA32` subfolder.
You can verify that the generated application indeed are different via the Linux `file` command:
```
$ file Build/UefiLessonsPkg/RELEASE_GCC5/X64/PCDLesson.efi
Build/UefiLessonsPkg/RELEASE_GCC5/X64/PCDLesson.efi: MS-DOS executable PE32+ executable (EFI application) x86-64, for MS Windows
$ file Build/UefiLessonsPkg/RELEASE_GCC5/IA32/PCDLesson.efi
Build/UefiLessonsPkg/RELEASE_GCC5/IA32/PCDLesson.efi: MS-DOS executable PE32 executable (EFI application) Intel 80386, for MS Windows
```
# Architecture specifier for sections names
In our `UefiLessonsPkg/UefiLessonsPkg.dsc` file we have an override for the `PcdInt32Override` PCD:
```
[PcdsFixedAtBuild]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```
This override works for both `X64` and `IA32` builds:
```
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 44U
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/IA32/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 44U
```
It is possible to set override for the particular architecture. For example change the section name to the:
```
[PcdsFixedAtBuild.IA32]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```
Regenerate both builds and verify the PCD values:
```
$ build && build --arch=IA32
...
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 43U
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/IA32/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 44U
```
It is possible to have both the generic arch section and the qualified one:
```
[PcdsFixedAtBuild.IA32]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
[PcdsFixedAtBuild]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```
In this case `X64` arch PCD would get its value from the generic override, and `IA32` arch PCD would get its value from the qualified section. The order of sections is not important in this case:
```
$ build && build --arch=IA32
...
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 44U
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/IA32/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 45U
```
It is worth to notice that it is possible to provide different section names as a list, for example:
```
[PcdsFixedAtBuild.IA32, PcdsFixedAtBuild.X64]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
```
In this case the override would be applied for the `X64` and `IA32` builds, but not for the `ARM` build for example (if we would ever want to permit one).
# `common`
Keep and mind that currently you can write any name in the arch section name qualifier. EDKII doesn't perform any checks on this matter:
```
[PcdsFixedAtBuild.IA32]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
[PcdsFixedAtBuild.blablabla]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```
Off course in this case the `X64` PCD wouldn't get its override to the 44 value:
```
$ build && build --arch=IA32
...
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 43U
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/IA32/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 45U
```
So don't confuse `IA32` with `X32` or something like that. You woudn't see any error, but you'll get incorrect values.
As we will know next, there are many layers to the section name override (e.g. `[PcdsFixedAtBuild.XXX.YYY.ZZZ]`). If you want to override second layer but want to keep the first one as generic, you use `common` for indication that the override goes to any architecture. For example this override:
```
[PcdsFixedAtBuild.IA32]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
[PcdsFixedAtBuild.common]
gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```
Will give you the same results as with the `[PcdsFixedAtBuild.IA32]/[PcdsFixedAtBuild]` sections:
```
$ build && build --arch=IA32
...
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 44U
$ grep _PCD_VALUE_PcdInt32Override Build/UefiLessonsPkg/RELEASE_GCC5/IA32/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
#define _PCD_VALUE_PcdInt32Override 45U
```
But with a help of a `common` syntax you can construct overrides for other build aspects like `[PcdsFixedAtBuild.common.XXX]`.
# Other sections
In the example above we've used arch section name override for the `[PcdsFixedAtBuild]` section in the DSC file. But it is also to possible to override other sections in other EDKII metafiles (DEC/INF/FDF), for example:
```
[PcdsPatchableInModule.X64]
[PcdsDynamic.X64]
[Protocols.X64]
[LibraryClasses.X64]
[Components.X64]
[BuildOptions.X64]
[Guids.X64]
[Sources.X64]
[Includes.X64]
[Defines.X64]
[Depex.X64]
[Pcd.X64]
```
You should consult EDKII documentation for the particular metafile (DEC/INF/DSC/FDF), but generally almost every section name can be overriden with the ARCH qualifier. And the ARCH override would always be the first qualifier one in section naming.
|