Reference Manual (0.6.2.3)
Copyright ©2018-2020 vit9696
12.5 Tips and Tricks
This document provides information on OpenCore user configuration file format used to set up the correct functioning of
the macOS operating system. It is to be read as the official clarification of expected OpenCore behaviour. All
deviations, if found in published OpenCore releases, shall be considered to be documentation or implementation
bugs which should be reported via the Acidanthera Bugtracker. An errata sheet is available in OpenCorePkg
This document is structured as a specification and is not meant to provide a step-by-step guide to configuring an end-user
Board Support Package (BSP). The intended audience of the document is anticipated to be programmers and engineers with a
basic understanding of macOS internals and UEFI functionality. For these reasons, this document is available
exclusively in English, and all other sources or translations of this document are unofficial and may contain
Third-party articles, utilities, books, and alikesimilar, may be more useful for a wider audience as they could provide
guide-like material. However, they are subject to their authors’ preferences, tastes, misinterpretations of this
document, and unavoidable obsolescence. In cases of using such sources, such as Dortania’s OpenCore Install
Guide and related material, please refer back to this document on every decision made and re-evaluate potential
Please note that regardless of the sources used, users are required to fully understand every OpenCore configuration option,
and the principles behind them, before posting issues to the Acidanthera Bugtracker.
Note: Creating this document would not have been possible without the invaluable contributions from other people:
Andrey1970, Goldfish64, dakanji, PMheart, and several others, with the full list available in OpenCorePkg history.
1.1 Generic Terms
- plist — Subset of ASCII Property List format written in XML, also know as XML plist format version
1. Uniform Type Identifier (UTI): com.apple.property-list. Plists consist of plist objects, which are
combined to form a hierarchical structure. Due to plist format not being well-defined, all the definitions of this
document may only be applied after plist is considered valid by running plutil -lint. External references:
https://www.apple.com/DTDs/PropertyList-1.0.dtd, man plutil.
- plist type — plist collections (plist array, plist dictionary, plist key) and primitives (plist string,
plist data, plist date, plist boolean, plist integer, plist real).
- plist object — definite realisation of plist type, which may be interpreted as value.
- plist array — array-like collection, conforms to array. Consists of zero or more plist objects.
- plist dictionary — map-like (associative array) collection, conforms to dict. Consists of zero or more
- plist key — contains one plist object going by the name of plist key, conforms to key. Consists of printable
7-bit ASCII characters.
Windows), see BootProtect for more details.
Duet bootstrap loader, which initialises UEFI environment on legacy BIOS firmwares firmware and loads
OpenCore.efi similarly to other bootstrap loaders. Modern Duet bootstrap loader will default to OpenCore.efi
on the same partition when present.
Directory used for storing supplemental ACPI information for ?? section.
Directory used for storing supplemental UEFI drivers for UEFI section.
Directory used for storing supplemental kernel information for ?? section.
Directory used for storing media resources, such as audio files for screen reader support. See ?? section for more
details. This directory also contains image files for graphical user interface. See OpenCanopy section for more
Directory used for storing supplemental tools.
Main booter driver responsible for operating system loading.
Hashes for all files potentially loadable by OC Config.
Signature for vault.plist.
Directory containing system reports generated by SysReport option.
OpenCore variable import file.
OpenCore log file.
Kernel panic log file.
Note: It is not guaranteed that paths longer than OC_STORAGE_SAFE_PATH_MAX (128 characters including
0-terminator) will be accessible within OpenCore.
3.2 Installation and Upgrade
To install OpenCore reflect the ?? described in the previous section on a EFI volume of a GPT partition. While corresponding
sections of this document do provide some information in regards to external resources like regarding external resources such as
ACPI tables, UEFI drivers, or kernel extensions (kexts), completeness of the matter is out of the scope of this document.
Information about kernel extensions may be found in a separate Kext List document available in OpenCore repository.
Vaulting information is provided in ?? section of this document.
OC config, just like any property lists can be edited with any stock textual editor (e.g. nano, vim), but specialised software
may provide better experience. On macOS the preferred GUI application is Xcode. For a lightweight cross-platform and
open-source alternative ProperTree editor can be utilised.
For BIOS booting a third-party UEFI environment provider will have to be used. OpenDuetPkg is one of the known UEFI
environment providers for legacy systems. To run OpenCore on such a legacy system, OpenDuetPkg can be installed with a
dedicated tool — BootInstall (bundled with OpenCore). Third-party utilities can be used to perform this on systems other
For upgrade purposes refer to Differences.pdf document, providing the information about the changes affecting the
configuration compared to the previous release, and Changelog.md document, containing the list of modifications across all
OpenCore can be compiled as an ordinary EDK II package. Since UDK development was abandoned by TianoCore, OpenCore
requires the use of EDK II Stable. Currently supported EDK II release is hosted in acidanthera/audk. The required patches for
the package are present in Patches directory.
The only officially supported toolchain is XCODE5. Other toolchains might work, but are neither supported, nor recommended.
Contribution of clean patches is welcome. Please do follow EDK II C Codestyle.
To compile with XCODE5, besides Xcode, one should also install NASM and MTOC. The latest Xcode version is recommended
for use despite the toolchain name. Example command sequence may look as follows:
git clone --depth=1 https://github.com/acidanthera/audk UDK
git submodule update --init --recommend-shallow
git clone --depth=1 https://github.com/acidanthera/OpenCorePkg
make -C BaseTools
build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc
Listing 1:Compilation Commands
For IDE usage Xcode projects are available in the root of the repositories. Another approach could be Sublime Text with
EasyClangComplete plugin. Add .clang_complete file with similar content to the UDK root:
Listing 2:ECC Configuration
Warning: Tool developers modifying config.plist or any other OpenCore files must ensure that their tool checks for
opencore-version NVRAM variable (see Debug Properties section below) and warn the user if the version listed is
unsupported or prerelease. OpenCore configuration may change across the releases and the tool shall ensure that it carefully
follows this document. Failure to do so may result in this tool to be considered as malware and blocked with all possible
3.4 Coding conventions
Just like As with any other project, we have conventions that we follow during the development. All third-party contributors
are highly recommended to read and follow advised to adhere to the conventions listed below before submitting their patches.
In general it is also recommended to firstly discuss the issue in patches. To minimise abortive work and the potential
rejection of submissions, third-party contributors should initially raise issues to the Acidanthera Bugtracker before
sending the patch to ensure no double work and to avoid the patch being rejectedfor feedback before submitting
Organisation. The codebase is contained in the OpenCorePkg repository, which is the primary EDK II package.
- Whenever changes are required in multiple repositories, separate pull requests should be sent to each.
- Committing the changes should happen firstly to dependent repositories, secondly to primary repositories to
avoid automatic build errors.
- Each unique commit should compile with XCODE5 and preferably with other toolchains. In the majority of the
cases it can be checked by accessing the CI interface. Ensuring that static analysis finds no warnings is preferred.
- External pull requests and tagged commits must be validated. That said, commits in master may build but may
not necessarily work.
- Internal branches should be named as follows: author-name-date, e.g. vit9696-ballooning-20191026.
- Commit messages should be prefixed with the primary module (e.g. library or code module) the changes were
made in. For example, OcGuardLib: Add OC_ALIGNED macro. For non-library changes Docs or Build prefixes
Design. The codebase is written in a subset of freestanding C11 (C17) supported by most modern toolchains used by EDK II.
Applying common software development practices or requesting clarification is recommended if any particular case is not
- Never rely on undefined behaviour and try to avoid implementation defined behaviour unless explicitly covered
below (feel free to create an issue when a relevant case is not present).
- Use OcGuardLib to ensure safe integral arithmetics avoiding overflows. Unsigned wraparound should be relied
on with care and reduced to the necessary amount.
- Check pointers for correct alignment with OcGuardLib and do not rely on the architecture being able to
dereference unaligned pointers.
- Use flexible array members instead of zero-length or one-length arrays where necessary.
- Use static assertions (STATIC_ASSERT) for type and value assumptions, and runtime assertions (ASSERT) for
precondition and invariant sanity checking. Do not use runtime assertions to check for errors as they should never
alter control flow and potentially be excluded.
- Assume UINT32/INT32 to be int-sized and use %u, %d, and %x to print them.
- Assume UINTN/INTN to be of unspecified size, and cast them to UINT64/INT64 for printing with %Lu, %Ld and so
on as normal.
- Do not rely on integer promotions for numeric literals. Use explicit casts when the type is
implementation-dependent or suffixes when type size is known. Assume U for UINT32 and ULL for UINT64.
- Do ensure unsigned arithmetics especially in bitwise maths, shifts in particular.
- sizeof operator should take variables instead of types where possible to be error prone. Use ARRAY_SIZE to
obtain array size in elements. Use L_STR_LEN and L_STR_SIZE macros from OcStringLib to obtain string literal
sizes to ensure compiler optimisation.
- Do not use goto keyword. Prefer early return, break, or continue after failing to pass error checking instead
of nesting conditionals.
- Use EFIAPI, force UEFI calling convention, only in protocols, external callbacks between modules, and functions
with variadic arguments.
- Provide inline documentation to every added function, at least describing its inputs, outputs, precondition,
postcondition, and giving a brief description.
- Do not use RETURN_STATUS. Assume EFI_STATUS to be a matching superset that is to be always used when
BOOLEAN is not enough.
- Security violations should halt the system or cause a forced reboot.
Codestyle. The codebase follows EDK II codestyle with few changes and clarifications.
- Write inline documentation for the functions and variables only once: in headers, where a header prototype is
available, and inline for static variables and functions.
- Use line length of 120 characters or less, preferably 100 characters.
- Use spaces after casts, e.g. (VOID *)(UINTN) Variable.
- Use SPDX license headers as shown in acidanthera/bugtracker#483.
The codebase incorporates EDK II debugging and few custom features to improve the experience.
- Use module prefixes, 2-5 letters followed by a colon (:), for debug messages. For OpenCorePkg use OC:, for
libraries and drivers use their own unique prefixes.
- Do not use dots (.) in the end of debug messages and separate EFI_STATUS, printed by %r, with a hyphen (e.g.
OCRAM: Allocation of %u bytes failed - %r\n).
- Use DEBUG_CODE_BEGIN () and DEBUG_CODE_END () constructions to guard debug checks that may potentially
reduce the performance of release builds and are otherwise unnecessary.
- Use DEBUG macro to print debug messages during normal functioning, and RUNTIME_DEBUG for debugging after
- Use DEBUG_VERBOSE debug level to leave debug messages for future debugging of the code, which are currently
not necessary. By default DEBUG_VERBOSE messages are ignored even in DEBUG builds.
- Use DEBUG_INFO debug level for all non critical messages (including errors) and DEBUG_BULK_INFO for extensive
messages that should not appear in NVRAM log that is heavily limited in size. These messages are ignored in
- Use DEBUG_ERROR to print critical human visible messages that may potentially halt the boot process, and
DEBUG_WARN for all other human visible errors, RELEASE builds included.
When trying to find the problematic change it is useful to rely on git-bisect functionality. There also are some unofficial
resources that provide per-commit binary builds of OpenCore, like such as Dortania.