From 7a490f9f5aaaf59b9d5ac930bafe8b4159f09bac Mon Sep 17 00:00:00 2001 From: Konstantin Aladyshev Date: Fri, 26 Aug 2022 16:10:54 +0300 Subject: Lxx: Arch specifier in the section names Signed-off-by: Konstantin Aladyshev --- Lessons_uncategorized/Lesson_ARCH/README.md | 202 ++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 203 insertions(+) create mode 100644 Lessons_uncategorized/Lesson_ARCH/README.md diff --git a/Lessons_uncategorized/Lesson_ARCH/README.md b/Lessons_uncategorized/Lesson_ARCH/README.md new file mode 100644 index 0000000..4123b30 --- /dev/null +++ b/Lessons_uncategorized/Lesson_ARCH/README.md @@ -0,0 +1,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. + diff --git a/README.md b/README.md index 8bc2cab..9c6b11f 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ These series of lessons are intendend to get you started with UEFI programming i - [Lesson 73](Lessons/Lesson_73): Setting defaults for the VFR questions: `default`/`defaultstore`/`resetbutton` keywords _____ +- [Lesson XX](Lessons_uncategorized/Lesson_ARCH): Architecture specifier in section names - [Lesson XX](Lessons_uncategorized/Lesson_Build_tools): Build tools configuration via `Conf/tools_def.txt` file and `[BuildOptions]` section usage in INF and DSC files - [Lesson XX](Lessons_uncategorized/Lesson_FDF): Intro to FDF file format. Flash Device Image `[FD]` sections: flash chip defines and regions definition. OVMF image FDF file analysis. - [Lesson XX](Lessons_uncategorized/Lesson_FDF_FV/README.md): Firmware Volume (`FV`), FFS, files. Create simple FV with `RAW` files -- cgit v1.2.3-18-g5258