锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

OpenCore安装教程

时间:2022-09-17 17:00:01 kk系列连接器55v2a3b变送器隔离变送器ws1521le36sn08dno传感器ba附带连接器连接器dc62pk87

目录

  • 介绍
    • 1.1 通用术语
  • 配置
    • 2.2 配置处理
    • 2.3 配置结构
  • 设置
    • 3.1 目录结构
    • 3.2 安装和升级
    • 3.3 贡献代码
    • 3.4 代码约定
  • ACPI
    • 4.1 简介
    • 4.2 属性列表
      • 1. `Add`
      • 2. `Delete`
      • 3. `Patch`
      • 4. `Quirks`
    • 4.3 Add 属性
      • 1. `Comment`
      • 2. `Enabled`
      • 3. `Path`
    • 4.4 Delete 属性
      • 1. `All`
      • 2. `Comment`
      • 3. `Enabled`
      • 4. `OemTableId`
      • 5. `TableLength`
      • 6. `TableSignature`
    • 4.5 Patch 属性
      • 1. `Base`
      • 2. `BaseSkip`
      • 3. `Comment`
      • 4. `Count`
      • 5. `Enabled`
      • 6. `Find`
      • 7. `Limit`
      • 8. `Mask`
      • 9. `OemTableId`
      • 10. `Replace`
      • 11. `ReplaceMark`
      • 12. `Skip`
      • 13. `TableLength`
      • 14. `TableSignature`
    • 4.6 Quirks 属性
      • 1. `FadtEnableReset`
      • 2. `NormalizeHeaders`
      • 3. `RebaseRegions`
      • 4. `ResetHwSig`
      • 5. `ResetLogoStatus`
  • Booter
    • 5.1 简介
    • 5.2 属性列表
      • 1. `MmioWhitelist`
      • 2. `Patch`
      • 3. `Quirks`
    • 5.3 MmioWhitelist 属性
      • 1. `Address`
      • 2. `Comment`
      • 3. `Enabled`
    • 5.4 Patch 属性
      • 1. `Arch`
      • 2. `Comment`
      • 3. `Count`
      • 4. `Enabled`
      • 5. `Find`
      • 6. `Identifier`
      • 7. `Limit`
      • 8. `Mask`
      • 9. `Replace`
      • 10. `ReplaceMask`
      • 11. `Skip`
    • 5.5 Quirks 属性
      • 2. `AllowRelocationBlock`
      • 2. `AvoidRuntimeDefrag`
      • 3. `DevirtualiseMmio`
      • 4. `DisableSingleUser`
      • 5. `DisableVariableWrite`
      • 6. `DiscardHibernateMap`
      • 7. `EnableSafeModeSlide`
      • 8. `EnableWriteUnprotector`
      • 9. `ForceExitBootServices`
      • 10. `ProtectMemoryRegions`
      • 11. `ProtectSecureBoot`
      • 12. `ProtectUefiServices`
      • 13. `ProvideCustomSlide`
      • 14. `ProvideMaxSlide`
      • 15. `RebuildAppleMemoryMap`
      • 16. `SetupVirtualMap`
      • 17. `SignalAppleOS`
      • 18. `SyncRuntimePermissions`
  • DeviceProperties
    • 6.1 简介
    • 6.2 属性列表
      • 1. `Add`
      • 2. `Delete`
    • 6.3 常见属性
  • Kernel
    • 7.1 简介
    • 7.2 属性列表
      • 1. Add
      • 2. Block
      • 3. Emulate
      • 4. Force
      • 5. Patch
      • 6. Quirks
      • 7. Scheme
    • 7.3 Add 属性
      • 1. `Arch`
      • 2. `BundlePath`
      • 3. `Comment`
      • 4. `Enabled`
      • 5. `ExecutablePath`
      • 6. `MaxKernel`
      • 7. `MinKernel`
      • 8. `PlistPath`
    • 7.4 Block 属性
      • 1. `Arch`
      • 2. `Comment`
      • 3. `Enabled`
      • 4. `Identifier`
      • 5. `MaxKernel`
      • 6. `MinKernel`
    • 7.5 Emulate 属性
      • 1. `Cpuid1Data`
      • 2 `Cpuid1Mask`
      • 3. `DummyPowerManagement`
      • 4. `MaxKernel`
      • 5. `MinKernel`
    • 7.6 Force 属性
      • 1. `Arch`
      • 2. `BundlePath`
      • 3. `Comment`
      • 4. `Enabled`
      • 5. `ExecutablePath`
      • 6. `Identifier`
      • 7. `MaxKernel`
      • 8. `MinKernel`
      • 9. `PlistPath`
    • 7.7 Patch 属性
      • 1. `Arch`
      • 2. `Base`
      • 3. `Comment`
      • 4. `Count`
      • 5. `Enabled`
      • 6. `Find`
      • 7. `Identifier`
      • 8. `Limit`
      • 9. `Mask`
      • 10. `MaxKernel`
      • 11. `MinKernel`
      • 12. `Replace`
      • 13. `ReplaceMask`
      • 14. `Skip`
    • 7.8 Quirks 属性
      • 1. `AppleCpuPmCfgLock`
      • 2. `AppleXcpmCfgLock`
      • 3. `AppleXcpmExtraMsrs`
      • 4. `AppleXcpmForceBoost`
      • 5. `CustomSMBIOSGuid`
      • 6. `DisableIoMapper`
      • 7. `DisableLinkeditJettison`
      • 8. `DisableRtcChecksum`
      • 9. `ExtendBTFeatureFlags`
      • 10. `ExternalDiskIcons`
      • 11. `ForceSecureBootScheme`
      • 12. `IncreasePciBarSize`
      • 13. `LapicKernelPanic`
      • 14. `LegacyCommpage`
      • 15. `PanicNoKextDump`
      • 16. `PowerTimeoutKernelPanic`
      • 17. `SetApfsTrimTimeout`
      • 18. `ThirdPartyDrives`
      • 19. `XhciPortLimit`
    • 7.9 Scheme 属性
      • 1. `FuzzyMatch`
      • 2. `KernelArch`
      • 3. `KernelCache`
  • Misc
    • 8.1 简介
    • 8.2 属性列表
      • 1. `Boot`
      • 2. `BlessOverride`
      • 3. `Debug`
      • 4. `Entries`
      • 5. `Security`
      • 6. `Tools`
    • 8.3 Boot 属性
      • 1. `ConsoleAttributes`
      • 2. `HibernateMode`
      • 3. `HideAuxiliary`
      • 4. `LauncherOption`
      • 5. `LauncherPath`
      • 6. `PickerAttributes`
      • 7. `PickerAudioAssist`
      • 8. `PollAppleHotKeys`
      • 9. `ShowPicker`
      • 10. `TakeoffDelay`
      • 11. `Timeout`
      • 12. `PickerMode`
      • 13. `PickerVariant`
    • 8.4 Debug 属性
      • 1. `AppleDebug`
      • 2. `ApplePanic`
      • 3. `DisableWatchDog`
      • 4. `DisplayDelay`
      • 5. `DisplayLevel`
      • 6. `SerialInit`
      • 7. `SysReport`
      • 8. `Target`
    • 8.5 Security 属性
      • 1. `AllowNvramReset`
      • 2. `AllowSetDefault`
      • 3. `AllowToggleSip`
      • 4. `ApECID`
      • 5. `AuthRestart`
      • 6. `BlacklistAppleUpdate`
      • 7. `DmgLoading`
      • 8. `EnablePassword`
      • 9. `ExposeSensitiveData`
      • 10. `HaltLevel`
      • 11. `PasswordHash`
      • 12. `PasswordSalt`
      • 13. `Vault`
      • 14. `ScanPolicy`
      • 15. `SecureBootModel`
    • 8.6 Entry 属性
      • 1. `Arguments`
      • 2. `Auxiliary`
      • 3. `Comment`
      • 4. `Enabled`
      • 5. `Flavour`
      • 6. `Name`
      • 7. `Path`
      • 8. `RealPath`
      • 9. TextMode
  • NVRAM
    • 9.1 简介
    • 9.2 属性列表
      • 1. `Add`
      • 2. `Delete`
      • 3. `LegacyEnable`
      • 4. `LegacyOverwrite`
      • 5. `LegacySchema`
      • 6. `WriteFlash`
    • 9.3 必需变量
    • 9.4 建议变量
    • 9.5 其他变量
  • PlatformInfo
    • 10.1 属性列表
      • 1. `Automatic`
      • 2. `CustomMemory`
      • 3. `UpdateDataHub`
      • 4. `UpdateNVRAM`
      • 5. `UpdateSMBIOS`
      • 6. `UpdateSMBIOSMode`
      • 7. `UseRawUuidEncoding`
      • 7. `Generic`
      • 8. `DataHub`
      • 9. `Memory`
      • 10. `PlatformNVRAM`
      • 11. `SMBIOS`
    • 10.2 Generic 属性
      • 1. `SpoofVendor`
      • 2. `AdviseWindows`
      • 3. `MaxBIOSVersion`
      • 4. `SystemMemoryStatus`
      • 5. `ProcessorType`
      • 6. `SystemProductName`
      • 7. `SystemSerialNumber`
      • 8. `SystemUUID`
      • 9. `MLB`
      • 10. `ROM`
    • 10.3 DataHub 属性
      • 1. `PlatformName`
      • 2. `SystemProductName`
      • 3. `SystemSerialNumber`
      • 4. `SystemUUID`
      • 5. `BoardProduct`
      • 6. `BoardRevision`
      • 7. `StartupPowerEvents`
      • 8. `InitialTSC`
      • 9. `FSBFrequency`
      • 10. `ARTFrequency`
      • 11. `DevicePathsSupported`
      • 12. `SmcRevision`
      • 13. `SmcBranch`
      • 14. `SmcPlatform`
    • 10.4 Memory 属性
      • 1. `DataWidth`
      • 2. `Devices`
      • 3. `ErrorCorrection`
      • 4. FormFactor
      • 5. `MaxCapacity`
      • 6. `TotalWidth`
      • 7. `Type`
      • 8. `TypeDetail`
    • 10.4.1 Memory Device 属性
      • 1. `AssetTag`
      • 2. `BankLocator`
      • 3. `DeviceLocator`
      • 4. `Manufacturer`
      • 5. `PartNumber`
      • 6. `SerialNumber`
      • 7. `Size`
      • 8. `Speed`
    • 10.5 PlatformNVRAM 属性
      • 1. `BID`
      • 2. `ROM`
      • 3. `MLB`
      • 4. `FirmwareFeatures`
      • 5. `FirmwareFeaturesMask`
      • 6. `SystemUUID`
    • 10.6 SMBIOS 属性
      • 1. `BIOSVendor`
      • 2. `BIOSVersion`
      • 3. `BIOSReleaseDate`
      • 4. `SystemManufacturer`
      • 5. `SystemProductName`
      • 6. `SystemVersion`
      • 7. `SystemSerialNumber`
      • 8. `SystemUUID`
      • 9. `SystemSKUNumber`
      • 10. `SystemFamily`
      • 11. `BoardManufacturer`
      • 12. `BoardProduct`
      • 13. `BoardVersion`
      • 14. `BoardSerialNumber`
      • 15. `BoardAssetTag`
      • 16. `BoardType`
      • 17. `BoardLocationInChassis`
      • 18. `ChassisManufacturer`
      • 19. `ChassisType`
      • 20. `ChassisVersion`
      • 21. `ChassisSerialNumber`
      • 22. `ChassisAssetTag`
      • 23. `PlatformFeature`
      • 24. `SmcVersion`
      • 25. `FirmwareFeatures`
      • 26.`FirmwareFeaturesMask`
      • 27. `ProcessorType`
  • UEFI
    • 11.1 简介
    • 11.2 驱动列表
    • 11.3 工具与应用程序
    • 11.4 OpenCanopy
    • 11.5 OpenRuntime
    • 11.6 属性列表
      • 1. `APFS`
      • 2. `Audio`
      • 3. `ConnectDrivers`
      • 4. `Drivers`
      • 5. `Input`
      • 6. `Output`
      • 7. `ProtocolOverrides`
      • 8. `Quirks`
      • 9. `ReservedMemory`
    • 11.7 APFS 属性
      • 1. `EnableJumpstart`
      • 2. `GlobalConnect`
      • 3. `HideVerbose`
      • 4. `JumpstartHotPlug`
      • 5. `MinDate`
      • 6. `MinVersion`
    • 11.8 Audio 属性
      • 1. `AudioCodec`
      • 2. `AudioDevice`
      • 3. `AudioOut`
      • 4. `AudioSupport`
      • 5. `MinimumVolume`
      • 6. `PlayChime`
      • 7. `SetupDelay`
      • 8. `VolumeAmplifier`
    • 11.9 Input 属性
      • 1. `KeyFiltering`
      • 2. `KeyForgetThreshold`
      • 3. `KeyMergeThreshold`
      • 4. `KeySupport`
      • 5. `KeySupportMode`
      • 6. `KeySwap`
      • 7. `PointerSupport`
      • 8. `PointerSupportMode`
      • 9. `TimerResolution`
    • 11.10 Output 属性
      • 1. `TextRenderer`
      • 2. `ConsoleMode`
      • 3. `Resolution`
      • 4. `ForceResolution`
      • 4. `ClearScreenOnModeSwitch`
      • 5. `DirectGopRendering`
      • 6. `IgnoreTextInGraphics`
      • 7. `ReplaceTabWithSpace`
      • 8. `ProvideConsoleGop`
      • 9. `ReconnectOnResChange`
      • 10. `SanitiseClearScreen`
      • 11. `UgaPassThrough`
    • 11.11 ProtocolOverrides 属性
      • 1. `AppleAudio`
      • 2. `AppleBootPolicy`
      • 3. `AppleDebugLog`
      • 4. `AppleEvent`
      • 5. `AppleFramebufferInfo`
      • 6. `AppleImageConversion`
      • 7. `AppleImg4Verification`
      • 8. `AppleKeyMap`
      • 9. `AppleRtcRam`
      • 10. `AppleSecureBoot`
      • 11. `AppleSmcIo`
      • 12. `AppleUserInterfaceTheme`
      • 13. `DataHub`
      • 14. `DeviceProperties`
      • 15. `FirmwareVolume`
      • 16. `HashServices`
      • 17. `OSInfo`
      • 18. `UnicodeCollation`
    • 11.12 Quirks 属性
      • 1. `DisableSecurityPolicy`
      • 1. `ExitBootServicesDelay`
      • 2. `IgnoreInvalidFlexRatio`
      • 3. `ReleaseUsbOwnership`
      • 4. `RequestBootVarRouting`
      • 5. `TscSyncTimeout`
      • 6. `UnblockFsConnect`
    • 11.13 ReservedMemory 属性
      • 1. `Address`
      • 2. `Comment`
      • 3. `Size`
      • 4. `Type`
      • 5. `Enabled`
  • 排错
    • 12.1 旧版 Apple 操作系统
      • 1. macOS 10.8 和 10.9
      • 2. macOS 10.7
      • 3. macOS 10.6
      • 4. macOS 10.5
      • 5. macOS 10.4
    • 12.2 UEFI 安全启动
    • 12.3 Windows 支持
      • 1. 我能安装 Windows 系统吗?
      • 2. 我需要安装其他什么软件吗?
      • 3. 为什么我会在 Boot Camp 启动硬盘 控制面板 中看到 `Basic data partition`?
      • 4. 如何选择 NTFS 驱动程序
    • 12.4 调试
    • 12.5 技巧和窍门
      • 1. 啊呀呀呀我系统没法启动了我该怎么看日志啊?
      • 2. macOS 启动失败我该怎么调试?
      • 3. 如何自定义启动项?
      • 4. 如何选择默认启动的系统?
      • 5. 安装 macOS 最简单的方法是什么?
      • 6. 为什么无法加载 Recovery 恢复镜像 进行在线安装?
      • 7. 我可以在 Apple 的硬件、或虚拟机中使用 OpenCore 吗?
      • 8. 为什么 Find 和 Replace 的补丁的长度必须相等?
      • 9. 我应该如何决定哪些 `Booter` Quirk 需要被启用?

介绍

1.1 通用术语

  • plist — 是一种用 XML 编写的、储存 ASCII 属性列表格式的集合文件,又称 XML 1.0 版。 统一类型标识符(UTI): com.apple.property-list。 plist 由多个 plist object 组成,这些对象组合在一起形成一种具有层次的结构。 由于 plist 格式的定义不明确,因此本文中的所有定义只有在运行 plutil -lint 有效后才能被应用。外部参考: https://www.apple.com/DTDs/PropertyList-1.0.dtd, man plutil
  • plist type — 指 plist 集合(plist array, plist dictionary, plist key)和基本类型(plist string, plist data, plist date, plist boolean, plist integer, plist real)。
  • plist object — 是用来定义 plist type 的实现形式,可以理解为值。
  • plist array — 类数组集合,参数为 array。包含零个或多个 plist object
  • plist dictionary — 类地图(关联数组)集合,参数为 dict 。包含零个或多个 plist key
  • plist key — 包含一个以 plist key 名称命名的 plist object,参数为 key。由 7 位 ASCII 集的可打印字符组成。
  • plist string — 7 位 ASCII 集的可打印字符串,参数为 string
  • plist data — base64 编码的对象,参数为 data
  • plist date — ISO-8601 日期表示法,参数为 date,不支持。
  • plist boolean — 逻辑声明对象,其值为 true (1) 或 false (0),参数为 truefalse
  • plist integer — 带符号的 10 进制,参数为 integer。适用于以二进制补码表示的 64 位无符号整数,除非在特定的 plist object 描述中明确提及一个更小的、有或无符号的整数类型。
  • plist real — 浮点数,参数为 real,不支持。
  • plist metadata — 实现将 value 强制转换为 data。 允许传递 plist string,此时的结果用空结果字节序列(即 C 字符串)表示;允许传递 plist integer,此时的结果用二进制补码形式的 32 位小尾数字节序列表示;允许传递 plist boolean, 此时的值为一个字节:01 表示 true00 表示 false;允许传递 plist data 本身。其他类型或更大的整数会导致未定义、非预期的行为。

配置

2.2 配置处理

如果 OpenCore 发现了 OC Config,则至少会读取并处理一次。根据 OpenCore 的引导机制的不同,如果存在多个 OC Config 文件,OpenCore 可能会读取其中任何一个或数个。如果硬盘中没有 OC Config,OpenCore 将会使用可选值和无效值的规则。

OC Config 有大小、嵌套和键值数量的限制。OC Config 的大小不得超过 16 MB,嵌套层数不得超过 8 层,每个 plist object 中最多有 16384 个节点(一个 plist dictionary 将被计为一对节点)。不符合上述规则的 OC Config 文件将可能导致未定义、非预期的行为。常见的 OC Config 错误格式包括:

  • 不符合 plist DTD
  • 存在本文档中没有记载的 plist object
  • 违反文件大小、嵌套层级和键值数量的限制

我们建议(但非强制)遇到格式错误的 OC Config 时中止、当作 OC Config 不存在的情况来处理。为了能够向前兼容,我们建议(但非强制)对采用无效值的行为进行警告。采用无效值的建议做法是在使用的情况下遵守以下规则:

Type Value
plist string Empty string ()
plist data Empty data ()
plist integer 0 (0)
plist boolean False ()
plist tristate False ()

2.3 配置结构

OC Config 包括以下几个独立部分,将在本文档中分别进行介绍。默认情况下配置文件将尽可能不启用任何功能以及禁用某些功能。总的来说,这些配置一般由如下的操作构成:

  • Add:为数据提供 添加 操作支持。已经存在的值不会被覆盖,必要时请使用 Delete。
  • Delete:为数据提供 删除 操作支持。
  • Patch:为数据提供 补丁 操作支持。
  • Quirks:提供特定的黑科技支持。

配置文件分为以下几个独立部分:

  • ACPI
  • Booter
  • DeviceProperties
  • Kernel
  • Misc
  • NVRAM
  • PlatformInfo
  • UEFI

设置

3.1 目录结构

ESP
├── EFI
│    ├── BOOT
│    │    └── BOOTx64.efi
│    └── OC
│        ├── ACPI
│        │    ├── DSDT.aml
│        │    ├── SSDT-1.aml
│        │    └── MYTABLE.aml
│        ├── Drivers
│        │    ├── MyDriver.efi
│        │    └── OtherDriver.efi
│        ├── Kexts
│        │    ├── MyKext.kext
│        │    └── OtherKext.kext
│        ├── Resources
│        │    ├── Audio
│        │    ├── Font
│        │    ├── Image
│        │    └── Label
│        ├── Tools
│        │    └── Tool.efi
│        ├── OpenCore.efi
│        ├── config.plist
│        ├── vault.plist
│        └── vault.sig
├── boot
├── nvram.plist
├── opencore-YYYY-MM-DD-HHMMSS.txt
├── panic-YYYY-MM-DD-HHMMSS.txt
└── SysReport
Figure 1: 目录结构

使用目录引导时,使用的目录结构应该遵循上述目录结构。可用的条目有:

  • BOOTx64.efiBOOTIa32.efi — 初始引导程序,用来加载 OpenCore.efi。对于大部分固件来说,BOOTx64.efi 是 UEFI 默认启动项,但也可以重命名后放到自定义位置,避免因 BOOTx64.efi 被其它操作系统(如 Windows)所覆盖而导致 OpenCore 无法启动。更多细节请参见 LauncherOption
  • boot — Duet bootstrap loader,用于在传统 BIOS 固件上模拟 UEFI 环境、并加载 OpenCore.efi
  • ACPI — 用于存储 ACPI 补充信息的目录。
  • Drivers — 用于存储 UEFI 补充驱动程序的目录。
  • Kexts — 用于存储内核驱动(kext)补充的目录。
  • Resources — 媒体资源使用的目录,如 屏幕朗读 的语音文件(见「UEFI Audio 属性」章节)。这一目录同时也用于存放 GUI 界面所使用的图片,见 OpenCanopy 相关章节。
  • Tools — 用于存储补充工具的目录。
  • OpenCore.efi — 主引导应用程序,负责操作系统加载。OpenCore.efi 所在的目录称为 根目录。默认 根目录 为 “EFI/OC”,但是当直接启动 OpenCore.efi 或通过自定义启动器启动 OpenCore.efi 时,其他包含 OpenCore.efi 的目录也同样支持。
  • config.plist — OC Config(即 OpenCore 的配置文件,见「配置术语」)。
  • vault.plist — OC Config 可能加载的所有文件的哈希。
  • vault.sigvault.plist 的签名文件。
  • SysReport — 存放 SysReport 功能产生的系统错误报告。
  • nvram.plist — OpenCore 变量导入文件。
  • opencore-YYYY-MM-DD-HHMMSS.txt — OpenCore 日志文件。
  • panic-YYYY-MM-DD-HHMMSS.txt — Kernal Panic 日志文件。

: 受限于固件的实现行为,OpenCore 可能无法访问绝对路径长度大于 OC_STORAGE_SAFE_PATH_MAX(默认值为 128)的目录。

3.2 安装和升级

如果要安装 OpenCore,请在使用 GPT 格式的硬盘上、按照上一节的文件夹结构建立文件和文件夹。尽管本文档的相应部分的确提供了有关你所需的外部资源(如 ACPI 表、UEFI 驱动程序或 kexts)的某些信息,但是本文档不保证会提供关于这些外部资源的全部信息。关于 kext 的完整信息可以查看由 OpenCore 提供的 可选 kext 列表;而本文档也在安全属性的相关章节提供了 Vauting 的相关信息。

OpenCore 的配置文件可以使用任何常规的文本编辑器(如 nano、vim、VSCode)进行编辑,但是专用软件可以带来更好的体验。在 macOS 上我们推荐使用 Xcode。你也可以使用 ProperTree ,这是一个轻量级的跨平台的开源 plist 编辑器。

如果要通过 BIOS 进行开机,你必须使用第三方 UEFI 环境提供程序。OpenDuetPkg 是一个常用的为旧操作系统提供 Legacy 引导的 UEFI 环境提供程序。要在这样的旧操作系统上运行 OpenCore,你可以使用一个独立的工具 BootInstall 安装 OpenDuetPkg(目前已和 OpenCore 打包在一起发布)。

如果要升级 OpenCore,Differences.pdf 提供了 OpenCore 配置文件变更的相关信息,Changelog.md 提供了 OpenCore 的更新日志。

3.3 贡献代码

OpenCore 可以作为普通的 EDK II 进行编译。由于 TianoCore 放弃了对 UDK 的开发,因此 OpenCore 需要使用 EDK II Stable。目前支持的 EDK II 版本托管在 acidanthera/audk。软件包所需的补丁在 Patches 目录下。

XCODE5 是官方唯一支持的工具链。使用其他工具链虽然也有可能正常工作,但我们的态度是既不推荐、也不支持。也欢迎贡献一些干净、简洁的补丁,代码规范务必遵循 EDK II C Codestyle。

要使用 XCODE5 编译,除了 Xcode 之外,还需要安装 NASM 和 MTOC。建议使用最新的 Xcode 版本,不必因为工具链叫 XCODE5 而纠结于 Xcode 的版本号。命令行举例如下:

git clone --depth=1 https://github.com/acidanthera/audk UDK
cd UDK
git submodule update --init --recommend-shallow
git clone --depth=1 https://github.com/acidanthera/OpenCorePkg
source edksetup.sh
make -C BaseTools
build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc
Listing 1: 编译指令

对于 IDE 的用法,Xcode 项目可在资源库的根目录下使用。还有一种方法是使用 Sublime Text 并带有 EasyClangComplete 插件。在你的 UDK 根目录下添加类似内容的 .clang_complete 文件:

-I/UefiPackages/MdePkg
-I/UefiPackages/MdePkg/Include
-I/UefiPackages/MdePkg/Include/X64
-I/UefiPackages/OpenCorePkg/Include/AMI
-I/UefiPackages/OpenCorePkg/Include/Acidanthera
-I/UefiPackages/OpenCorePkg/Include/Apple
-I/UefiPackages/OpenCorePkg/Include/Apple/X64
-I/UefiPackages/OpenCorePkg/Include/Duet
-I/UefiPackages/OpenCorePkg/Include/Generic
-I/UefiPackages/OpenCorePkg/Include/Intel
-I/UefiPackages/OpenCorePkg/Include/Microsoft
-I/UefiPackages/OpenCorePkg/Include/VMware
-I/UefiPackages/OvmfPkg/Include
-I/UefiPackages/UefiCpuPkg/Include
-IInclude
-include
/UefiPackages/MdePkg/Include/Uefi.h
-fshort-wchar
-Wall
-Wextra
-Wno-unused-parameter
-Wno-missing-braces
-Wno-missing-field-initializers
-Wno-tautological-compare
-Wno-sign-compare
-Wno-varargs
-Wno-unused-const-variable
-DOC_TARGET_NOOPT=1
-DNO_MSABI_VA_FUNCS=1
Listing 2: ECC 配置

{% note danger 警告 %}
工具开发人员修改 config.plist 或其他任何 OpenCore 文件时,都务必检查 opencore-version NVRAM 变量(详见后面的 Debug Properties 章节),如果版本号不支持或尚未发布,则需警告用户。OpenCore 配置可能因版本不同而改变,因此工具开发应仔细遵循本文档,否则可能会当作恶意软件并阻止发布。
{% endnote %}

3.4 代码约定

和其他项目一样,我们在开发过程中也有一些约定。强烈建议所有第三方贡献者在提交补丁之前仔细阅读并遵循以下约定。另外,我们也建议在发送补丁之前先在 Acidanthera Bugtracker 里讨论一下,以免与其他人的工作重复,导致你的补丁被拒绝。

组织结构。代码库包含在 OpenCorePkg 仓库中,它是主要的 EDK II 软件包。

  • 每当需要在多个仓库中进行修改时,都应当分别向每个仓库发送拉取请求(Pull Requests)。
  • 提交更改应该首先提交至依赖仓库,其次才是主仓库,以避免自动构建错误。
  • 每个独立的提交都应该用 XCODE5 编译,并最好也用其他工具链编译。在大多数情况下都可以通过 CI interface 进行检查。最好确保静态分析不提示任何警告。
  • 外部的拉取请求和标记的提交都必须经过验证。也就是说,在 master 中的提交可能会被构建,但并不一定成功。
  • 内部分支应命名如下:作者-名字-日期,比如 vit9696-ballooning-20191026
  • 提交说明(Commit Messages)应该以更改的主要模块(如库或代码模块)为前缀。例如,OcGuardLib: Add OC_ALIGNED macro。对于非库的改变,则应使用 Docs 或者 Build 作为前缀。

设计。代码库是使用独立的 C11 (C17) 子集编写的,能够被 EDK II 使用的大多数较新的工具链支持。如果下面没有讨论特殊情况,建议使用常见的软件开发操作,或者另附解释说明。

  • 永远不要依赖未定义的行为,也要尽量避免实施定义的行为,除非明确涉及到下面的情况(如果缺少相关案例,随时都可以创建一个 Issue,不必拘谨)。
  • 使用 OcGuardLib 来确保安全的积分运算,避免溢出。依赖无符号数回绕(Unsigned Wraparound)时应当谨慎,不要增加不必要的数量。
  • OcGuardLib 检查指针是否正确对齐,虽然架构能够反引用未对齐的指针,但是不要依赖它。
  • 必要时使用柔性数组成员(Flexible Array Member)替代长度为 0 或为 1 的数组。
  • 使用静态断言(STATIC_ASSERT)进行类型和值的假设,使用运行时断言(ASSERT)进行前提条件和不变指标的合理性检查。不要使用运行时断言来检查错误,因为他们绝不应该控制业务流程,并且有可能被排除。
  • UINT32/INT32 默认为 int 大小,并用 %u%d%x 来打印。
  • UINTN/INTN 默认为未定大小,转换为 UINT64/INT64,与 %Lu%Ld 等正常打印。
  • 不要为了数字字面量而依赖整型提升。当类型为实现依赖(implementation-dependent)的时候,使用显式转换(Explicit Cast);当类型大小已知的时候,使用后缀。默认 U 代表 UINT32ULL 代表 UINT64
  • 尤其要确保按位运算时、特别是按位移位时,作无符号的算术。
  • sizeof 运算符应该尽可能地采用变量,而不是类型,否则容易出错。使用 ARRAY_SIZE 获取数组的元素大小。使用 OcStringLib 中的 L_STR_LENL_STR_SIZE 宏,获取字符串文字大小,以保证编译器的优化。
  • 不要使用 goto 关键词。宁可在未能通过错误检查时,提前使用 returnbreakcontinue,也不要嵌套条件语句。
  • 使用 EFIAPI,强制执行 UEFI 调用约定,只在模块之间的协议、外部回调和带有变量参数的函数中使用。
  • 为每一个新增函数提供行内注释,至少要描述其输入、输出、前置条件、后置条件,并给出简要说明。
  • 不要使用 RETURN_STATUS。把 EFI_STATUS 默认为一个当 BOOLEAN 不够用时将始终使用的、相匹配的超集。
  • 违反安全规定的行为应停止系统运行或强制重启。

代码规范。代码库遵循 EDK II codestyle,并作了些许改动和解释。

  • 只为函数和变量写一次行内注释:在头文件中(如果有头文件原型)和 static 变量、函数的行内书写。
  • 行长在 120 个字符(100 个字符更好)以内。
  • 在转换后使用空格,如 (VOID *)(UINTN) Variable
  • 换行时使用两个空格来缩进。
  • 在公共函数前加上 Oc 或其他含义清晰的前缀。
  • 私有的 static 函数不要加上前缀,私有的 non-static 函数要使用 Internal 前缀。
  • 使用 SPDX 许可证标头,如 acidanthera/bugtracker#483 所示。

排错。代码库中加入了 EDK II 调试和一些自定义功能,以改善体验。

  • 调试信息应使用模块前缀,2-5 个字母,后面加一个冒号(:)。对于 OpenCorePkg 使用 OC:,对于库和驱动程序则使用自己独特的前缀。
  • 不要在调试信息结尾使用句点(.),要将 %r 打印的 EFI_STATUS 用连字符隔开(例如 OCRAM: Allocation of %u bytes failed - **%rtextbackslash n)。
  • 使用 DEBUG_CODE_BEGIN ()DEBUG_CODE_END () 结构来看守 可能会降低版本构建性能的 和 在其他方面不必要的 调试检查。
  • 在正常工作时,使用 DEBUG 宏打印调试信息,在 EXIT_BOOT_SERVICES 后使用 RUNTIME_DEBUG 进行调试。
  • 使用 DEBUG_VERBOSE 调试级别留下信息,这些信息虽然目前用不到,但可以方便用于以后的调试。默认情况下, DEBUG_VERBOSE 信息即使在 DEBUG 构建中也会被忽略。
  • 使用 DEBUG_INFO 调试级别来处理所有非关键信息(包括错误),使用 DEBUG_BULK_INFO 来处理不应该出现在 NVRAM 日志中的大量信息,因为 NVRAM 日志的大小十分受限。这些信息在 RELEASE 构建中会被忽略。
  • 使用 DEBUG_ERROR 来打印关键的、可以看见的、可能会停止启动过程的信息,使用 DEBUG_WARN 来打印所有其他可被看见的错误信息,这些都包含在 RELEASE 构建中。

当试图找到有问题的更改时,依靠 git-bisect 功能会很有帮助。另外还有一些非官方资源,提供了按照逐条 Commit 更新的 OpenCore 编译文件,如 Dortania。

ACPI

4.1 简介

ACPI(Advanced Configuration and Power Interface,高级配置和电源接口)是发现和配置计算机硬件的开放标准。
ACPI 规格 定义了实现用的标准表(如 DSDTSSDTFACSDMAR)和各种方法(如 _DSM_PRW)。现代硬件几乎不需要更改即可保持 ACPI 兼容性,但是 OpenCore 仍然提供了修改 ACPI 的方法。

要反汇编和编译 ACPI 表,可以使用由 ACPICA 开发的 iASL compiler。你可以从 Acidanthera/MaciASL 下载 iASL 的图形界面程序。

对 ACPI 的修补按照如下顺序执行:

  • Patch
  • Delete
  • Add
  • Quirks

为了解决操作系统检测的问题,所有对 ACPI 的更改会在所有操作系统上生效。但是在某些场景下(ACPI 编写不规范、操作系统链式引导启动、ACPI 调试)会出现问题。因此在修补 ACPI 时,需要使用 \_OSI 方法。

在系统引导前加载补丁使得编写「代理」补丁成为可能 —— 「代理」补丁即通过重命名的方法修补 DSDT 中的原始行为,然后通过 SSDT 注入同名的行为进行替代。

OpenCore、WhateverGreen、VirtualSmc、VoodooPS2 的 GitHub 仓库中都包含了部分 SSDT 和其他 ACPI 修补的方法。在 AppleLife 的 Laboratory 版块、DSDT 版块提供了不少教程和样例(如 笔记本电池修补教程)。Dortania 也编写了许多 ACPI 有关的教程。但是请注意,这些教程和 OpenCore 无关,他们提供的解决方法也不一定有用。

译者注:对于中国黑苹果玩家,强烈推荐 OC-little 项目,提供了众多 SSDT 范例和相关指导;笔记本用户电池修补请参考 这篇教程。

4.2 属性列表

1. Add

Type: plist array
Failsafe: Empty
Description: 从 OC/ACPI 目录加载指定的 ACPI 表。

设计为用 plist dict 值填充以描述每个块级项目。请参阅下面 4.3 Add 属性 章节。

2. Delete

Type: plist array
Failsafe: Empty
Description: 从 ACPI 栈中删除选定的表。

设计为用 plist dict 值填充以描述每个块级项目。请参阅下面 4.4 Delete 属性 章节。

3. Patch

Type: plist array
Failsafe: Empty
Description: 在添加或删除 ACPI 表之前执行的二进制修补。

设计为用 plist dictionary 值填充以描述每个块级项目。请参阅下面 4.5 Patch 属性 章节。

4. Quirks

Type: plist dict
Description: 应用下文 4.6 Quirks 属性 章节中描述的 Quirks。

4.3 Add 属性

1. Comment

Type: plist string
Failsafe: Empty string
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

2. Enabled

Type: plist boolean
Failsafe: false
Description: 除非此值为 true,否则此 ACPI 表不会被添加。

3. Path

Type: plist string
Failsafe: Empty string
Description: 需要加载的 ACPI 表所在的路径。示例值如 DSDT.amlSubDir/SSDT-8.amlSSDT-USBX.aml

所有 ACPI 表都从 OC/ACPI 目录加载,加载顺序遵循数组中的项目顺序。

: 除具有 DSDT 表标识符(由解析得到的数据、而非由其文件名决定)的表外,所有表都将作为新表插入 ACPI 栈。而 DSDT 表与其余的表不同,将会执行 DSDT 表的替换。

4.4 Delete 属性

1. All

Type: plist boolean
Failsafe: false
Description: 如果设置为 true,则所有符合条件的 ACPI 表都会被舍弃。 否则,只舍弃第一个匹配到的。

2. Comment

Type: plist string
Failsafe: Empty string
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

3. Enabled

Type: plist boolean
Failsafe: false
Description: 除非此值为 true,否则此 ACPI 表不会被舍弃。

4. OemTableId

Type: plist data, 8 bytes
Failsafe: All zero
Description: 将表的 OEM ID 匹配为此处所填的值,全部为 0 时忽略。

5. TableLength

Type: plist integer
Failsafe: 0
Description: 将表的大小匹配为此处所填的值,填 0 时忽略。

6. TableSignature

Type: plist data, 4 bytes
Failsafe: All zero
Description: 将表的签名匹配为此处的值,全部为 0 时忽略。

:当序列需要在多处替换的时候,务必注意不要指定表的签名,尤其是在进行不同类型的重命名操作的时候。

4.5 Patch 属性

1. Base

Type: plist string
Failsafe: Empty string
Description: 为重命名补丁指定一个 ACPI 路径,让 OC 通过取得该路径的偏移量来查找(或替换)重命名补丁。留空时忽略。

只有正确的绝对路径被支持(例如:\_SB.PCI0.LPCB.HPET)。目前支持的 Object 类型有:DeviceFieldMethod

:应谨慎使用,并非所有 OEM 的 ACPI 表都能被正确处理。如果遇到问题,可使用 Utilities 中的 ACPIe 工具来进行调错。使用 DEBUG=1 参数来编译 ACPIe 将会使该工具输出有助于调试的 ACPI 路径查找过程。

2. BaseSkip

Type: plist integer
Failsafe: 0
Description: 在重命名补丁被应用之前跳过多少次 Base 指定的路径。如果将此值设置为 0,补丁将会被应用于指定 Base 中的所有匹配。

3. Comment

Type: plist string
Failsafe: Empty string
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

4. Count

Type: plist integer
Failsafe: 0
Description: 补丁应用的次数。如果将此值设置为 0,补丁将会被应用于所有匹配。

5. Enabled

Type: plist boolean
Failsafe: false
Description: 除非设置为 true,否则此处的 ACPI 补丁不会生效。

6. Find

Type: plist data
Failsafe: Empty data
Description: 需要寻找的 Data,长度必须和 Replace 相等。

7. Limit

Type: plist integer
Failsafe: 0
Description: 要搜索的最大字节数。当此值为 0 时会遍历整个 ACPI 表。

8. Mask

Type: plist data
Failsafe: Empty data
Description: 查找比较期间使用的数据按位掩码。 通过忽略未屏蔽(设置为零)位来进行模糊搜索。可以设置为空数据以忽略,否则此值的长度必须和 Replace 的长度相等。

9. OemTableId

Type: plist data, 8 bytes
Failsafe: All zero
Description: 将表的 OEM ID 匹配为此处所填的值,全部为 0 时忽略。

10. Replace

Type: plist data
Failsafe: Empty data
Description: 一个或多个字节的替换数据。

11. ReplaceMark

Type: plist data
Failsafe: Empty data
Description: 替换数据期间使用的数据按位掩码。 通过忽略未屏蔽(设置为零)位来进行模糊搜索。可以设置为空数据以忽略,否则此值的长度必须和 Replace 的长度相等。

12. Skip

Type: plist integer
Failsafe: 0
Description: 完成替换之前要跳过的匹配数。

13. TableLength

Type: plist integer
Failsafe: 0
Description: 将表的大小匹配为此处所填的值,填 0 时忽略。

14. TableSignature

Type: plist data, 4 bytes
Failsafe: All zero
Description: 将表的签名匹配为此处的值,全部为 0 时忽略。

大多数情况下,ACPI 补丁是有害而无益的:

  • 避免用 ACPI 补丁重命名设备。这样做可能会使设备重命名失败,或者会对不相关的设备进行错误地重命名(如 ECEC0)。为了保证 ACPI 的一致性,在 I/O 注册表级别重命名设备会更加安全,比如 WhateverGreen 的做法。
  • 尽量避免为了支持更高级的功能集而给 _OSI 打补丁,除非你非常需要。这样做通常会侵入 APTIO 固件,从而导致需要用打更多的补丁去填坑。现代的固件基本不需要,而真正需要的那些固件只要打一些更小的补丁就可以了。然而,笔记本厂商通常依靠这种方法来确定是否有现代 I2C 输入支持、散热调节功能,或用来添加其他自定义功能。
  • 避免为了启用亮度调节键而给 EC 事件 _Qxx 打补丁。传统的方法通常需要在 DSDT 和 SSDT 上进行大量的修改,而且新系统上的 debug kext 并不稳定。请改用 BrightnessKeys 内置亮度调节键检测机制。
  • 尽量避免重命名 _PRW_DSM 之类的魔改举动。

在某些情况下,打补丁确实是有意义的:

  • 刷新 HPET(或其他设备)的 method header 来避免老硬件上的 _OSI 兼容性检查。可通过将 A0 10 93 4F 53 46 4C 00 替换为 A4 0A 0F A3 A3 A3 A3 A3 的办法,使带有 if ((OSFL () == Zero)) { If (HPTE) ... Return (Zero)_STA method 达到强制返回 0xF 的目的。
  • 在 SSDT 中实现自定义 method,比如在某些计算机上注入关机修复,可以通过将 _PTS 替换为 ZPTS,把原来的 method 替换为一个假的名字,并添加一个 callback 回调到原 method 中。

TianoCore 源文件 AcpiAml.h 可能会对于理解 ACPI 操作码有所帮助。

FindReplace 的长度 必须完全一样,否则 ACPI 表可能会被破坏、导致系统不稳定。必要时请使用「代理」补丁的方法、或使用 NOP 填充剩余区域

4.6 Quirks 属性

1. FadtEnableReset

Type: plist boolean
Failsafe: false
Description: 在 FADT 表中提供寄存器复位标志,用于修复旧硬件的重启和关机。除非需要,否则不建议启用。

只有在传统硬件和少数笔记本上需要。这一 Quirk 也可以修复电源快捷键(译者注:Command + 电源键)。不建议启用,除非不启用就无法关机和重启。

2. NormalizeHeaders

Type: plist boolean
Failsafe: false
Description: 清理 ACPI 表头字段以解决 macOS ACPI 实现错误导致的引导崩溃。参考:由 Alex James(theracermaster)在调试 AppleACPIPlatform 时发现。从 macOS Mojave (10.14) 开始,这个错误已经被修复。

3. RebaseRegions

Type: plist boolean
Failsafe: false
Description: 尝试试探性地重定位 ACPI 内存区域。不建议启用这一选项,除非你需要自定义 DSDT。

ACPI 表通常由底层固件动态生成。在与位置无关的代码中,ACPI 表可能包含用于设备配置的 MMIO 区域的物理地址,通常按区域(例如 OperationRegion)分组。 更改固件设置或硬件配置,升级或修补固件不可避免地会导致动态生成的 ACPI 代码发生变化,这有时会导致上述 OperationRegion 结构中的地址发生变化。

因此,对 ACPI 表进行任何形式的修改都是非常危险的。最合理的方法是对 ACPI 进行尽可能少的更改,并尝试不替换任何表,尤其是 DSDT。

如果无法不得不替换 DSDT,则至少应尝试确保自定义 DSDT 基于最新的 DSDT 或避免对受影响区域的读写。如果没有其他帮助,可以尝试通过尝试修复 ACPI 地址来避免在 macOS 引导的 PCI Configuration Begin 阶段出现停顿的情况。

4. ResetHwSig

Type: plist boolean
Failsafe: false
Description: 将 FACS 表中 HardwareSignature 的值重置为 0

启用这一选项可以解决固件无法在重新启动过程中保持硬件签名导致的休眠唤醒问题。

5. ResetLogoStatus

Type: plist boolean
Failsafe: false
Description: 将 BGRT 表中 Displayed 状态字段重置为 false

这适用于提供 BGRT 表、但随后无法处理屏幕更新的固件。如果在开机时无法显示 OEM Windows 标志可以尝试开启。

Booter

5.1 简介

本部分允许在 Apple BootLoader(boot.efi)上应用不同种类的 UEFI 修改。目前,这些修改为不同的固件提供了各种补丁和环境更改。其中一些功能最初是作为 AptioMemoryFix.efi 的一部分,如今 AptioMemoryFix.efi 已经不再维护。如果你还在使用,请参考 技巧和窍门 章节提供的迁移步骤。

如果您是第一次在自定义固件上使用此功能,则首先需要执行一系列检查。开始之前,请确保您符合以下条件:

  • 具有最新版本的 UEFI 固件(去主板厂家的官网上看看)。
  • 禁用了 Fast BootHardware Fast Boot。如果 BIOS 里有相关选项,禁用掉。
  • 如果有 Above 4G Decoding 或类似功能,请在固件设置中启用。注意,在某些主板上(特别是 ASUS WS-X299-PRO)这个选项会造成不良影响,必须禁用掉。虽然目前还不知道是不是其他主板也有同样问题,但是如果你遇到了不稳定的启动故障,可以首先考虑检查一下这个选项。
  • 启用了 DisableIoMapper Quirk、或者在 BIOS 中禁用 VT-d、或者删去了 ACPI DMAR 表。
  • 启动参数中 没有 slide。 除非你没法开机、并且在日志里看见了 No slide values are usable! Use custom slide!,否则不论如何也不要使用这个启动参数。
  • CFG Lock (MSR 0xE2 写保护) 在 BIOS 中被禁用。如果 BIOS 中没有、而且你心灵手巧,你可以考虑 手动打补丁将其禁用 。更多细节请参考 VerifyMsrE2。
  • 在 BIOS 中禁用 CSM (Compatibility Support Module)。NVIDIA 6xx / AMD 2xx 或更老的平台可能需要刷新 GOP ROM,具体步骤参考 GopUpdate 或者 AMD UEFI GOP MAKER。
  • 如果有 EHCI / XHCI Hand-off 功能,建议仅在出现 USB 设备连接时启动停滞的情况下启用。
  • 在 BIOS 中启用 VT-xHyper ThreadingExecute Disable Bit
  • 有时你还可能需要在 BIOS 中禁用 Thunderbolt SupportIntel SGXIntel Platform Trust。但是这一操作不是必须的。

在调试

相关文章