From 57b4f2e6b00a63f9b212329657c57bc0b9407e54 Mon Sep 17 00:00:00 2001 From: hrx114514x Date: Fri, 7 Aug 2026 11:37:28 +0800 Subject: [PATCH] Release PC711Probe 1.2.0 with legacy MSI-X support --- .github/FUNDING.yml | 2 + CHANGELOG.md | 9 +++ CONTRIBUTING.md | 4 ++ Driver/Info.plist | 19 +++++- Driver/PC711Probe.cpp | 137 ++++++++++++++++++++++++++++++-------- LICENSE | 103 +++++++++++++++++++--------- README.md | 47 ++++++++++--- README_EN.md | 47 ++++++++++--- RELEASE_NOTES_1.2.0.md | 19 ++++++ SUPPORT.md | 59 ++++++++++++++++ Scripts/build.sh | 2 +- Scripts/verify.sh | 20 ++++-- Support/KmodInfo.c | 4 +- THIRD_PARTY_NOTICES.md | 2 +- docs/DEVELOPMENT.en.md | 18 +++-- docs/DEVELOPMENT.zh-CN.md | 18 +++-- docs/INSTALL.en.md | 6 +- docs/INSTALL.zh-CN.md | 6 +- 18 files changed, 412 insertions(+), 110 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 RELEASE_NOTES_1.2.0.md create mode 100644 SUPPORT.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ac27256 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +custom: + - "https://github.com/hrx114514x/PC711Probe/blob/main/SUPPORT.md" diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b34caa..302a04f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.2.0 — 2026-08-07 + +- Added early, PC711-only MSI-X allocation for Darwin 20–22 without taking ownership away from Apple `IONVMeFamily`. +- Removed the direct dependency on the unexported legacy `IOPCIDevice::configureInterrupts` symbol. +- Added a legacy `CreateDeviceInterrupt` route for Darwin 20–22. +- Hardware-validated macOS 13.4.1 Recovery; macOS 11.6 remains unresolved. +- Changed the v1.2.0-and-later project license to PolyForm Noncommercial 1.0.0. +- Added bilingual voluntary cryptocurrency support information. + ## 1.0.0 — 2026-08-07 - Enabled automatic operation without `-pc711pcompat`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e172bea..0742653 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,3 +22,7 @@ Before opening a pull request / 提交 PR 前: git submodule update --init --recursive ./Scripts/verify.sh ``` + +Unless explicitly agreed otherwise in writing, contributions accepted into the v1.2.0-and-later development line are provided under the project's [PolyForm Noncommercial License 1.0.0](LICENSE). + +除非另有明确书面约定,合入 v1.2.0 及后续开发分支的贡献均按本项目的 [PolyForm Noncommercial License 1.0.0](LICENSE) 提供。 diff --git a/Driver/Info.plist b/Driver/Info.plist index c97630a..97c3031 100644 --- a/Driver/Info.plist +++ b/Driver/Info.plist @@ -15,11 +15,24 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 1.0.0 + 1.2.0 CFBundleVersion - 1.0.0 + 1.2.0 IOKitPersonalities + PC711EarlyMSIX + + CFBundleIdentifier + com.stationk9.driver.PC711Probe + IOClass + PC711EarlyMSIX + IOPCIPrimaryMatch + 0x174A1C5C + IOProbeScore + 100000 + IOProviderClass + IOPCIDevice + PC711Probe CFBundleIdentifier @@ -35,7 +48,7 @@ NSHumanReadableCopyright - Copyright 2026 StationK9. BSD-3-Clause. + Copyright 2026 PC711Probe contributors. PolyForm Noncommercial 1.0.0. OSBundleCompatibleVersion 0.1.2 OSBundleLibraries diff --git a/Driver/PC711Probe.cpp b/Driver/PC711Probe.cpp index b780eff..295c890 100644 --- a/Driver/PC711Probe.cpp +++ b/Driver/PC711Probe.cpp @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 #include #include @@ -17,9 +17,84 @@ constexpr uint16_t kPC711Device {0x174A}; constexpr uint32_t kNvmeClassRevisionMask {0xFFFFFF00U}; constexpr uint32_t kNvmeClassRevisionValue {0x01080200U}; constexpr uint32_t kInterruptTypeMSIX {0x00020000U}; +constexpr size_t kConfigureInterruptsVtableSlot {0x960 / sizeof(uintptr_t)}; constexpr size_t kControllerFlagsOffset {0x191}; constexpr uint8_t kLegacyMSIXPathFlag {0x10}; +using ConfigureInterrupts = IOReturn (*)(IOPCIDevice *device, + uint32_t interruptType, uint32_t numRequired, uint32_t numRequested, + IOOptionBits options); + +bool isPC711Device(IOPCIDevice *pci) { + if (!pci) + return false; + + const auto vendor = pci->configRead16(kIOPCIConfigVendorID); + const auto device = pci->configRead16(kIOPCIConfigDeviceID); + const auto classRevision = pci->configRead32(kIOPCIConfigRevisionID); + return vendor == kPC711Vendor && device == kPC711Device && + (classRevision & kNvmeClassRevisionMask) == kNvmeClassRevisionValue; +} + +IOReturn configurePC711MSIX(IOPCIDevice *pci) { + if (!pci) + return kIOReturnBadArgument; + + auto vtable = *reinterpret_cast(pci); + if (!vtable) + return kIOReturnUnsupported; + + auto configure = reinterpret_cast( + vtable[kConfigureInterruptsVtableSlot]); + return configure ? configure(pci, kInterruptTypeMSIX, 1, 1, 0) : + kIOReturnUnsupported; +} + +} // namespace + +// Darwin 20-22 may have resolved a different PCI interrupt allocation before +// IONVMeFamily creates its event source. Request MSI-X while the PC711 PCI nub +// is still being probed, then decline attachment so Apple's driver takes over. +class PC711EarlyMSIX : public IOService { + OSDeclareDefaultStructors(PC711EarlyMSIX) + +public: + IOService *probe(IOService *provider, SInt32 *score) override; +}; + +OSDefineMetaClassAndStructors(PC711EarlyMSIX, IOService) + +IOService *PC711EarlyMSIX::probe(IOService *provider, SInt32 *) { + if (getKernelVersion() > KernelVersion::Ventura) + return nullptr; + + auto pci = OSDynamicCast(IOPCIDevice, provider); + if (!isPC711Device(pci)) + return nullptr; + + const auto result = configurePC711MSIX(pci); + pci->setProperty("PC711CompatEarlyMSIXRequested", true); + pci->setProperty("PC711CompatEarlyConfigureInterruptsResult", + static_cast(static_cast(result)), 32); + SYSLOG("probe", "early PC711 MSI-X request completed: %x", + static_cast(result)); + return nullptr; +} + +namespace { + +// CreateDeviceInterrupt is exported on Darwin 23-24 but stripped from the +// Darwin 20-22 symbol table. This stable function prologue identifies the +// older implementation without tying the route to a fixed load address. +constexpr uint8_t kLegacyCreateDeviceInterruptPattern[] { + 0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, + 0x41, 0x55, 0x41, 0x54, 0x53, 0x48, 0x83, 0xEC, + 0x18, 0x49, 0x89, 0xCD, 0x49, 0x89, 0xD6, 0x49, + 0x89, 0xF7, 0x49, 0x89, 0xFC, 0x48, 0x8D, 0x55, + 0xD4, 0xC7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x8B, 0x01 +}; + constexpr const char *kCreateDeviceInterruptSymbol { "__ZN16IONVMeController21CreateDeviceInterruptEPFvP8OSObjectP22IOInterruptEventSourceiEPFbS1_P28IOFilterInterruptEventSourceEP9IOService" }; @@ -33,7 +108,6 @@ class PC711ProbePlugin { using CreateDeviceInterrupt = IOFilterInterruptEventSource *(*)(void *controller, IOInterruptEventAction action, IOFilterInterruptAction filter, IOService *provider); - static void processKext(void *context, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size); static IOFilterInterruptEventSource *wrapCreateDeviceInterrupt(void *controller, @@ -41,7 +115,6 @@ class PC711ProbePlugin { IOService *provider); bool isPC711(IOService *controller, IOPCIDevice *&pci) const; - CreateDeviceInterrupt originalCreateDeviceInterrupt {nullptr}; const char *kextPath { @@ -60,13 +133,6 @@ class PC711ProbePlugin { PC711ProbePlugin plugin; -// Darwin 25 calls this before IONVMeFamily enumerates interrupt sources. -// Reuse the exported IOPCIFamily implementation on older kernels. -extern "C" IOReturn IOPCIDeviceConfigureInterrupts(IOPCIDevice *device, - uint32_t interruptType, uint32_t numRequired, uint32_t numRequested, - IOOptionBits options) - __asm("__ZN11IOPCIDevice19configureInterruptsEjjjj"); - PC711ProbePlugin &PC711ProbePlugin::globalPlugin() { return plugin; } @@ -80,11 +146,7 @@ bool PC711ProbePlugin::isPC711(IOService *controller, IOPCIDevice *&pci) const { if (!pci) return false; - const auto vendor = pci->configRead16(kIOPCIConfigVendorID); - const auto device = pci->configRead16(kIOPCIConfigDeviceID); - const auto classRevision = pci->configRead32(kIOPCIConfigRevisionID); - return vendor == kPC711Vendor && device == kPC711Device && - (classRevision & kNvmeClassRevisionMask) == kNvmeClassRevisionValue; + return isPC711Device(pci); } IOFilterInterruptEventSource *PC711ProbePlugin::wrapCreateDeviceInterrupt( @@ -100,8 +162,7 @@ IOFilterInterruptEventSource *PC711ProbePlugin::wrapCreateDeviceInterrupt( filter, provider) : nullptr; } - const auto result = IOPCIDeviceConfigureInterrupts(pci, - kInterruptTypeMSIX, 1, 1, 0); + const auto result = configurePC711MSIX(pci); pci->setProperty("PC711CompatMSIXRequested", true); pci->setProperty("PC711CompatConfigureInterruptsResult", static_cast(static_cast(result)), 32); @@ -110,15 +171,19 @@ IOFilterInterruptEventSource *PC711ProbePlugin::wrapCreateDeviceInterrupt( instance.originalCreateDeviceInterrupt(controllerPointer, action, filter, provider) : nullptr; - auto flags = reinterpret_cast(controllerPointer) + - kControllerFlagsOffset; - const uint8_t flagsBefore = *flags; - *flags = static_cast(flagsBefore & ~kLegacyMSIXPathFlag); - const uint8_t flagsAfter = *flags; - pci->setProperty("PC711CompatLegacyMSIXFlagBefore", - static_cast(flagsBefore), 8); - pci->setProperty("PC711CompatLegacyMSIXFlagAfter", - static_cast(flagsAfter), 8); + uint8_t flagsBefore {0}; + uint8_t flagsAfter {0}; + if (getKernelVersion() >= KernelVersion::Sonoma) { + auto flags = reinterpret_cast(controllerPointer) + + kControllerFlagsOffset; + flagsBefore = *flags; + *flags = static_cast(flagsBefore & ~kLegacyMSIXPathFlag); + flagsAfter = *flags; + pci->setProperty("PC711CompatLegacyMSIXFlagBefore", + static_cast(flagsBefore), 8); + pci->setProperty("PC711CompatLegacyMSIXFlagAfter", + static_cast(flagsAfter), 8); + } pci->setProperty("PC711CompatEventSourceCreated", eventSource != nullptr); SYSLOG("probe", "PC711 interrupt compatibility applied; configure=%x flags=%02x->%02x event=%d", @@ -128,15 +193,29 @@ IOFilterInterruptEventSource *PC711ProbePlugin::wrapCreateDeviceInterrupt( } void PC711ProbePlugin::processKext(void *context, KernelPatcher &patcher, - size_t index, mach_vm_address_t, size_t) { + size_t index, mach_vm_address_t address, size_t size) { auto instance = static_cast(context); if (!instance || index != instance->kextInfo.loadIndex) return; KernelPatcher::RouteRequest request { - kCreateDeviceInterruptSymbol, wrapCreateDeviceInterrupt, + nullptr, wrapCreateDeviceInterrupt, instance->originalCreateDeviceInterrupt }; + + if (getKernelVersion() >= KernelVersion::Sonoma) { + request.symbol = kCreateDeviceInterruptSymbol; + } else { + size_t offset {0}; + if (!KernelPatcher::findPattern(kLegacyCreateDeviceInterruptPattern, + nullptr, sizeof(kLegacyCreateDeviceInterruptPattern), + reinterpret_cast(address), size, &offset)) { + SYSLOG("probe", "failed to locate legacy CreateDeviceInterrupt"); + return; + } + request.from = address + offset; + } + if (!patcher.routeMultiple(index, &request, 1)) { SYSLOG("probe", "failed to install PC711 interrupt compatibility route"); return; @@ -166,7 +245,7 @@ PluginConfiguration ADDPR(config) { arrsize(bootargDebug), nullptr, 0, - KernelVersion::Tiger, + KernelVersion::BigSur, KernelVersion::Sequoia, []() { PC711ProbePlugin::globalPlugin().init(); diff --git a/LICENSE b/LICENSE index c1ea384..5ecc88c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,30 +1,73 @@ -BSD 3-Clause License - -Copyright (c) 2026, StationK9 -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +# PolyForm Noncommercial License 1.0.0 + + + +## Acceptance + +In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses. + +## Copyright License + +The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license). + +## Distribution License + +The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license). + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example: + +> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) + +## Changes and New Works License + +The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose. + +## Patent License + +The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software. + +## Noncommercial Purposes + +Any noncommercial purpose is a permitted purpose. + +## Personal Uses + +Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose. + +## Noncommercial Organizations + +Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding. + +## Fair Use + +You may have "fair use" rights for the software under the law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms. + +**You** refers to the individual or entity agreeing to these terms. + +**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. + +**Your licenses** are all the licenses granted to you for the software under these terms. + +**Use** means anything you do with the software requiring one of your licenses. diff --git a/README.md b/README.md index e2e5c58..c776f71 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,18 @@ > **新发现:PC711 在 macOS 26 已经原生免驱。** 同一块实机 PC711 在 macOS 26.5.1(25F80 / Darwin 25.5.0)中可由 Apple `IONVMeFamily` 正常完成识别、读写和睡眠唤醒,不需要 PC711Probe 或 NVMeFix。PC711Probe 不在 macOS 26 加载。 +> [!NOTE] +> ## ❤️ 支持 PC711Probe +> +> PC711Probe 免费提供给个人和非商业用途。如果它解决了你的 PC711 Kernel Panic,欢迎自愿支持后续开发与硬件测试。 +> +> **[查看赞助方式](SUPPORT.md)** +> +> 赞助不构成软件购买,也不授予商业使用权。 + ## 已验证结果 -PC711Probe 的中断兼容补丁已在 macOS 15.6.1 Recovery(24G90 / Darwin 24.6.0)完成硬件验证:系统进入磁盘工具,PC711 型号及五个既有分区全部被枚举,原先约 75 秒后的第一条 Identify 超时 KP 不再出现。 +PC711Probe 已在同一块 PC711 上通过 macOS 13.4.1 与 macOS 15.6.1 Recovery 硬件启动验证:系统进入磁盘工具,型号及五个既有分区全部被枚举,原先约 75 秒后的 NVMe 命令超时 KP 不再出现。macOS 11.6 目前仍会 KP,尚未支持。 ![macOS 15.6.1 Recovery 中识别 PC711](docs/images/recovery-success.jpg) @@ -17,30 +26,33 @@ PC711Probe 的中断兼容补丁已在 macOS 15.6.1 Recovery(24G90 / Darwin 24 | 控制器 | SK hynix `1C5C:174A`,NVMe class `01:08:02` | | 型号 | `SKHynix_HFS512GDE9X084N`(PC711) | | 固件 | `41010C22` | -| 故障系统 | macOS 15.6.1,Build 24G90,Darwin 24.6.0 | +| v1.2.0 验证成功 | macOS 13.4.1,Build 22F82,Darwin 22.5.0 | +| 既有验证成功 | macOS 15.6.1,Build 24G90,Darwin 24.6.0 | +| 本机启动正常 | macOS 12.5.1(21G83)、macOS 14.6.1(23G93)Recovery | +| 当前未支持 | macOS 11.6(20G165),仍发生原始 NVMe 超时 KP | | 原生系统 | macOS 26.5.1,Build 25F80,Darwin 25.5.0 | | 引导环境 | OpenCore 1.0.8,Lilu 1.7.3 | ## 自动匹配范围 -1.0.0 不需要 `-pc711pcompat` 或任何其他启用参数。Kext 加入 OpenCore 后自动运行,只对以下控制器应用补丁: +1.2.0 不需要任何启用参数。Kext 加入 OpenCore 后自动运行,只对以下控制器应用补丁: - PCI Vendor/Device:`1C5C:174A`; - NVMe class:`01:08:02`。 PC711 的型号字符串必须等第一次 Identify 成功后才能读取,因此插件使用其已知 PCI 控制器 ID 进行预先匹配;不同容量和 OEM 型号不依赖字符串判断。其他 PCI ID 的 NVMe 保持 Apple 原始行为。 -插件声明的自动运行范围为 Darwin 8–24(macOS 10.4–15),并在系统存在相应 `IONVMeFamily` 符号时安装路由。Darwin 25/macOS 26 不加载插件。 +插件声明的自动运行范围为 Darwin 20–24(macOS 11–15)。Darwin 25/macOS 26 不加载插件。macOS 11 虽在加载范围内,但目前实测仍会 KP。 ## 原理 macOS 15.6.1 中,PC711 控制器已经 Ready(`CSTS=1`),但第一条 Identify Controller 命令无法通过旧中断完成路径返回,最终超时 KP。 -对比 macOS 15 与 macOS 26 的 Apple `IONVMeFamily` 后发现,新系统会在创建中断源前请求一个 MSI-X 向量,并移除了旧 MSI-X 特殊路径。PC711Probe 对匹配的 PC711: +对比旧版与 macOS 26 的 Apple `IONVMeFamily` 后发现,新系统会在创建中断源前请求一个 MSI-X 向量,并移除了旧 MSI-X 特殊路径。PC711Probe 对匹配的 PC711: -1. 调用 `IOPCIDevice::configureInterrupts(0x20000, 1, 1, 0)`; -2. 调用 Apple 原始 `CreateDeviceInterrupt`; -3. 清除旧中断路径选择位; +1. 在 macOS 11–13 的 PCI 匹配早期请求一个 MSI-X 向量,随后主动放弃设备绑定; +2. Apple `IONVMeFamily` 继续作为真正的 NVMe 驱动接管设备; +3. 在 macOS 14–15 创建中断源时请求 MSI-X,并清除旧中断路径选择位; 4. 其余 Identify、队列、namespace 和存储 I/O 继续由 Apple 驱动完成。 [查看简明开发过程](docs/DEVELOPMENT.zh-CN.md) @@ -53,7 +65,7 @@ macOS 15.6.1 中,PC711 控制器已经 Ready(`CSTS=1`),但第一条 Iden - `BundlePath`: `PC711Probe.kext` - `ExecutablePath`: `Contents/MacOS/PC711Probe` - `PlistPath`: `Contents/Info.plist` - - `MinKernel`: `8.0.0` + - `MinKernel`: `20.0.0` - `MaxKernel`: `24.99.99` 4. 停用通过 `_STA=0`、伪造 class/vendor/device 等方式隐藏 PC711 的 AML/SSDT。 5. 不需要添加任何 PC711Probe 启动参数。 @@ -74,6 +86,19 @@ cd PC711Probe ## 当前验证边界 -已验证控制器初始化、Identify、namespace 和分区发布。macOS 15 的完整安装、持续读写、TRIM、睡眠唤醒,以及其他固件和平台尚未完成硬件验证。首次使用请保留回滚 EFI 和数据备份。 +已验证 macOS 13/15 Recovery 中的控制器初始化、Identify、namespace 和分区发布;macOS 12/14 Recovery 在本机启动正常。macOS 11 尚未修复,完整安装、持续读写、TRIM、睡眠唤醒,以及其他固件和平台也未完成硬件验证。首次使用请保留回滚 EFI 和数据备份。 + +## 许可 + +PC711Probe v1.2.0 及后续版本以源码公开形式按照 [PolyForm Noncommercial License 1.0.0](LICENSE) 提供。个人学习、研究、实验、业余项目及其他非商业用途可以使用、修改和分发。 + +未经版权持有人单独书面授权,不允许任何商业用途,包括但不限于: + +- 销售 PC711Probe 或修改版; +- 捆绑进收费 EFI 或其他付费软件包; +- 用于收费黑苹果安装、维修或技术服务; +- 以其他方式进行商业分发或商业利用。 + +此前已经按照 BSD 3-Clause 发布的 v0.6.0 和 v1.0.0 继续适用其原许可证;本次变更不追溯撤销已经授予的权利。 -本项目使用 [BSD 3-Clause](LICENSE) 许可证。第三方依赖见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md),仓库不包含 Apple Kernel Collection 或 `IONVMeFamily` 二进制。 +第三方依赖继续适用各自许可证,详见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。仓库不包含 Apple Kernel Collection 或 `IONVMeFamily` 二进制。 diff --git a/README_EN.md b/README_EN.md index fa49160..2fef11e 100644 --- a/README_EN.md +++ b/README_EN.md @@ -6,9 +6,18 @@ An automatic Lilu compatibility plugin that fixes an `IONVMeFamily` Identify-tim > **New finding: PC711 works natively on macOS 26.** The same physical PC711 was identified by Apple `IONVMeFamily` on macOS 26.5.1 (25F80 / Darwin 25.5.0), with working I/O and sleep/wake. Neither PC711Probe nor NVMeFix was required. PC711Probe does not load on macOS 26. +> [!NOTE] +> ## ❤️ Support PC711Probe +> +> PC711Probe is free for personal and noncommercial use. If it fixed the PC711 kernel panic on your machine, consider supporting continued development and hardware testing. +> +> **[Support the project](SUPPORT.md)** +> +> Donations do not constitute a purchase or grant commercial usage rights. + ## Verified result -The interrupt compatibility patch was hardware-tested with macOS 15.6.1 Recovery (24G90 / Darwin 24.6.0). Disk Utility opened, the PC711 model and all five existing partitions were enumerated, and the former first-Identify timeout panic after roughly 75 seconds did not recur. +PC711Probe has passed hardware boot tests on the same PC711 with macOS 13.4.1 and macOS 15.6.1 Recovery. Disk Utility opened, the model and all five existing partitions were enumerated, and the former NVMe command-timeout panic after roughly 75 seconds did not recur. macOS 11.6 still panics and is not currently supported. ![PC711 enumerated in macOS 15.6.1 Recovery](docs/images/recovery-success.jpg) @@ -17,30 +26,33 @@ The interrupt compatibility patch was hardware-tested with macOS 15.6.1 Recovery | Controller | SK hynix `1C5C:174A`, NVMe class `01:08:02` | | Model | `SKHynix_HFS512GDE9X084N` (PC711) | | Firmware | `41010C22` | -| Failing OS | macOS 15.6.1, build 24G90, Darwin 24.6.0 | +| v1.2.0 verified | macOS 13.4.1, build 22F82, Darwin 22.5.0 | +| Previously verified | macOS 15.6.1, build 24G90, Darwin 24.6.0 | +| Booted normally here | macOS 12.5.1 (21G83) and macOS 14.6.1 (23G93) Recovery | +| Currently unsupported | macOS 11.6 (20G165), original NVMe timeout panic remains | | Native OS | macOS 26.5.1, build 25F80, Darwin 25.5.0 | | Boot environment | OpenCore 1.0.8, Lilu 1.7.3 | ## Automatic matching -Version 1.0.0 requires no `-pc711pcompat` or other activation argument. Once enabled in OpenCore, it automatically patches only controllers matching: +Version 1.2.0 requires no activation argument. Once enabled in OpenCore, it automatically patches only controllers matching: - PCI Vendor/Device: `1C5C:174A`; and - NVMe class: `01:08:02`. The PC711 model string is not available until the first Identify succeeds, so the plugin uses its known PCI controller identity before that command. Different capacities and OEM model strings do not affect matching. NVMe controllers with other PCI IDs retain Apple's original behavior. -The declared automatic range is Darwin 8–24 (macOS 10.4–15); the route is installed when the corresponding `IONVMeFamily` symbol exists. The plugin does not load on Darwin 25/macOS 26. +The declared automatic range is Darwin 20–24 (macOS 11–15). The plugin does not load on Darwin 25/macOS 26. macOS 11 is within the load range but still panics on the tested machine. ## How it works On macOS 15.6.1, the PC711 controller reaches Ready state (`CSTS=1`), but the first Identify Controller command never returns through the older interrupt completion path and eventually panics. -Comparison of Apple `IONVMeFamily` between macOS 15 and macOS 26 showed that the newer OS requests one MSI-X vector before creating the interrupt source and removes an older MSI-X-specific path. For the matched PC711, PC711Probe: +Comparison of older Apple `IONVMeFamily` builds with macOS 26 showed that the newer OS requests one MSI-X vector before creating the interrupt source and removes an older MSI-X-specific path. For the matched PC711, PC711Probe: -1. calls `IOPCIDevice::configureInterrupts(0x20000, 1, 1, 0)`; -2. calls Apple's original `CreateDeviceInterrupt`; -3. clears the old interrupt-path selector; and +1. requests one MSI-X vector during early PCI matching on macOS 11–13, then declines attachment; +2. leaves Apple `IONVMeFamily` as the actual NVMe driver; +3. requests MSI-X and clears the old interrupt-path selector during interrupt-source creation on macOS 14–15; and 4. leaves Identify, queues, namespaces, and storage I/O to Apple's driver. [Read the concise development process](docs/DEVELOPMENT.en.md) @@ -53,7 +65,7 @@ Comparison of Apple `IONVMeFamily` between macOS 15 and macOS 26 showed that the - `BundlePath`: `PC711Probe.kext` - `ExecutablePath`: `Contents/MacOS/PC711Probe` - `PlistPath`: `Contents/Info.plist` - - `MinKernel`: `8.0.0` + - `MinKernel`: `20.0.0` - `MaxKernel`: `24.99.99` 4. Disable AML/SSDT code that hides the PC711 through `_STA=0` or spoofed class/vendor/device values. 5. Do not add a PC711Probe activation boot argument. @@ -74,6 +86,19 @@ Output: `build/Debug/PC711Probe.kext` ## Current validation boundary -Controller initialization, Identify, namespace discovery, and partition publication are verified. A full macOS 15 installation, sustained I/O, TRIM, sleep/wake, other firmware, and other platforms have not yet completed hardware validation. Keep a rollback EFI and data backup for the first test. +Controller initialization, Identify, namespace discovery, and partition publication are verified in macOS 13/15 Recovery; macOS 12/14 Recovery booted normally here. macOS 11 remains unresolved. Full installation, sustained I/O, TRIM, sleep/wake, other firmware, and other platforms have not completed hardware validation. Keep a rollback EFI and data backup for the first test. + +## License + +PC711Probe v1.2.0 and later are source-available under the [PolyForm Noncommercial License 1.0.0](LICENSE). Use, modification, and distribution are permitted for personal study, research, experimentation, hobby projects, and other noncommercial purposes. + +Commercial use is prohibited without separate written permission from the copyright holder, including but not limited to: + +- selling PC711Probe or modified builds; +- bundling it with paid EFI or other commercial packages; +- using it in paid Hackintosh installation, repair, or support services; and +- any other commercial distribution or exploitation. + +Previously published v0.6.0 and v1.0.0 releases remain available under the BSD 3-Clause license that accompanied them. This change does not retroactively withdraw rights already granted. -This project is licensed under [BSD 3-Clause](LICENSE). See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for dependencies. No Apple Kernel Collection or `IONVMeFamily` binary is redistributed. +Third-party dependencies remain under their own licenses; see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). No Apple Kernel Collection or `IONVMeFamily` binary is redistributed. diff --git a/RELEASE_NOTES_1.2.0.md b/RELEASE_NOTES_1.2.0.md new file mode 100644 index 0000000..26b145e --- /dev/null +++ b/RELEASE_NOTES_1.2.0.md @@ -0,0 +1,19 @@ +# PC711Probe 1.2.0 + +Legacy macOS interrupt-timing update. / 旧版 macOS 中断时机更新。 + +## Changes / 变化 + +- Requests one MSI-X vector during early PCI matching on Darwin 20–22, then leaves Apple `IONVMeFamily` in control. / 在 Darwin 20–22 的 PCI 匹配早期申请一个 MSI-X 向量,随后仍由 Apple 驱动接管。 +- Removes the direct dependency on the legacy unexported `IOPCIDevice::configureInterrupts` symbol. / 不再直接依赖旧系统未导出的符号。 +- Keeps matching restricted to SK hynix `1C5C:174A` with NVMe class `01:08:02`. / 仍只匹配该 PC711 控制器身份。 +- Changes the project-authored v1.2.0 code to PolyForm Noncommercial 1.0.0. / v1.2.0 项目代码改用 PolyForm 非商业许可。 + +## Hardware results / 实机结果 + +- macOS 13.4.1 Recovery (22F82): boots and enumerates the PC711 and its existing partitions. / 启动成功并识别 PC711 及既有分区。 +- macOS 15.6.1 Recovery (24G90): previously verified and retained. / 既有验证保持正常。 +- macOS 12.5.1 and 14.6.1 Recovery: booted normally in the multi-version test. / 多版本测试中启动正常。 +- macOS 11.6 Recovery (20G165): still hits the original NVMe timeout panic and is not supported. / 仍发生原始 NVMe 超时 KP,目前不支持。 + +Back up EFI and data and use a rollback-capable USB EFI for the first boot. / 首次启动请备份 EFI 与数据,并使用可回滚的 U 盘 EFI。 diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..35d43bc --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,59 @@ +# Support PC711Probe / 支持 PC711Probe + +## Cryptocurrency + +If PC711Probe helped you, you can voluntarily support continued development, hardware testing, firmware coverage, and macOS compatibility research. + +### USDC — Solana Mainnet + +Recommended for small donations. + +`AQN5JyVaR2W3ERTUGSnzV45cwPLaES8N8dWt3CzpFeCW` + +### SOL — Solana Mainnet + +`AQN5JyVaR2W3ERTUGSnzV45cwPLaES8N8dWt3CzpFeCW` + +### Bitcoin — Bitcoin Mainnet + +`bc1q3fjl8tr7jcr9urlqynvg96tzkl9gqpnl933gqu` + +### Ethereum — Ethereum Mainnet + +`0x34f88c21431d6E317AfD05Cd766F0dd1829876C0` + +> [!IMPORTANT] +> Verify the network and complete destination address before sending. The USDC address is for **USDC on Solana**; do not use Ethereum, Base, Arbitrum, or another network. Cryptocurrency transfers are generally irreversible. + +Donations are voluntary. They do not constitute a purchase, warranty, compatibility promise, development commitment, priority support, or commercial license. + +--- + +## 支持 PC711Probe + +如果 PC711Probe 对你有帮助,欢迎自愿支持后续开发、硬件测试、不同固件验证以及 macOS 兼容性研究。 + +### USDC — Solana 主网 + +推荐用于小额赞助。 + +`AQN5JyVaR2W3ERTUGSnzV45cwPLaES8N8dWt3CzpFeCW` + +### SOL — Solana 主网 + +`AQN5JyVaR2W3ERTUGSnzV45cwPLaES8N8dWt3CzpFeCW` + +### Bitcoin — Bitcoin 主网 + +`bc1q3fjl8tr7jcr9urlqynvg96tzkl9gqpnl933gqu` + +### Ethereum — Ethereum 主网 + +`0x34f88c21431d6E317AfD05Cd766F0dd1829876C0` + +> [!IMPORTANT] +> 转账前请核对网络和完整地址。上面的 USDC 仅用于 **Solana 网络上的 USDC**,请勿通过 Ethereum、Base、Arbitrum 或其他网络发送。链上转账通常无法撤销。 + +赞助完全自愿,不构成软件购买、担保、兼容性承诺、开发进度承诺、优先技术支持或商业授权。 + +**永远不要向任何人提供助记词、Recovery Phrase 或私钥。** diff --git a/Scripts/build.sh b/Scripts/build.sh index 7faae36..da855bd 100755 --- a/Scripts/build.sh +++ b/Scripts/build.sh @@ -29,7 +29,7 @@ plutil -lint "$project_dir/Driver/Info.plist" mkdir -p "$binary_dir" common_cxx_flags="-arch x86_64 -std=c++14 -fapple-kext -fno-builtin -fno-exceptions -fno-rtti -fno-asynchronous-unwind-tables" -common_defines="-DKERNEL -DKERNEL_PRIVATE -D__KERNEL__ -DPRODUCT_NAME=PC711Probe -DMODULE_VERSION=1.0.0 -DMACH_ASSERT=1" +common_defines="-DKERNEL -DKERNEL_PRIVATE -D__KERNEL__ -DPRODUCT_NAME=PC711Probe -DMODULE_VERSION=1.2.0 -DMACH_ASSERT=1" xcrun clang++ $common_cxx_flags \ -c \ diff --git a/Scripts/verify.sh b/Scripts/verify.sh index 267f3f6..fe12183 100755 --- a/Scripts/verify.sh +++ b/Scripts/verify.sh @@ -5,11 +5,12 @@ project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) binary="$project_dir/build/Debug/PC711Probe.kext/Contents/MacOS/PC711Probe" plist="$project_dir/build/Debug/PC711Probe.kext/Contents/Info.plist" source="$project_dir/Driver/PC711Probe.cpp" +license="$project_dir/LICENSE" "$project_dir/Scripts/build.sh" plutil -lint "$plist" -test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$plist")" = "1.0.0" +test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$plist")" = "1.2.0" test "$(/usr/libexec/PlistBuddy -c 'Print :OSBundleLibraries:com.apple.iokit.IOPCIFamily' "$plist")" = "2.9" file "$binary" | grep -q "Mach-O 64-bit kext bundle x86_64" nm -g "$binary" | grep -q ' _kmod_info$' @@ -20,20 +21,31 @@ nm "$binary" | grep -q ' _PC711Probe_kern_start$' nm "$binary" | grep -q ' _PC711Probe_kern_stop$' nm -u "$binary" | grep -q '__ZN7LiluAPI10onKextLoad' strings -a "$binary" | grep -q '__ZN16IONVMeController21CreateDeviceInterruptEPFvP8OSObjectP22IOInterruptEventSourceiEPFbS1_P28IOFilterInterruptEventSourceEP9IOService' -nm -u "$binary" | grep -q '__ZN11IOPCIDevice19configureInterruptsEjjjj' +if nm -u "$binary" | grep -q '__ZN11IOPCIDevice19configureInterruptsEjjjj'; then + echo "configureInterrupts must be invoked through its stable virtual slot" >&2 + exit 1 +fi grep -q 'kPC711Vendor {0x1C5C}' "$source" grep -q 'kPC711Device {0x174A}' "$source" grep -q 'kNvmeClassRevisionValue {0x01080200U}' "$source" -grep -q 'kInterruptTypeMSIX, 1, 1, 0' "$source" +grep -q 'kConfigureInterruptsVtableSlot {0x960 / sizeof(uintptr_t)}' "$source" +grep -q 'kLegacyCreateDeviceInterruptPattern' "$source" +grep -q 'configure(pci, kInterruptTypeMSIX, 1, 1, 0)' "$source" +grep -q 'class PC711EarlyMSIX' "$source" +grep -q 'PC711CompatEarlyMSIXRequested' "$source" +grep -q '0x174A1C5C' "$plist" grep -q 'kControllerFlagsOffset {0x191}' "$source" grep -q 'PC711CompatConfigureInterruptsResult' "$source" grep -q 'PC711CompatLegacyMSIXFlagAfter' "$source" grep -q 'PC711CompatEventSourceCreated' "$source" grep -q 'AllowNormal | LiluAPI::AllowInstallerRecovery' "$source" -grep -q 'KernelVersion::Tiger' "$source" +grep -q 'KernelVersion::BigSur' "$source" grep -q 'KernelVersion::Sequoia' "$source" grep -q 'PC711ProbePlugin::globalPlugin().init()' "$source" +grep -q '^// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0$' "$source" +grep -q '^# PolyForm Noncommercial License 1.0.0$' "$license" +grep -q 'PolyForm Noncommercial 1.0.0' "$plist" if grep -q -- '-pc711pcompat\|-pc711pstage' "$source"; then echo "Manual activation or diagnostic-stage boot argument found" >&2 diff --git a/Support/KmodInfo.c b/Support/KmodInfo.c index c911c0b..b76e116 100644 --- a/Support/KmodInfo.c +++ b/Support/KmodInfo.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 #include @@ -16,7 +16,7 @@ extern kern_return_t _stop(kmod_info_t *info, void *data); * setup (including OSKextGetCurrentIdentifier) and can leave the IOKit * personality unable to instantiate. */ -KMOD_EXPLICIT_DECL(com.stationk9.driver.PC711Probe, "0.1.2", _start, _stop) +KMOD_EXPLICIT_DECL(com.stationk9.driver.PC711Probe, "1.2.0", _start, _stop) kmod_start_func_t *_realmain = PC711Probe_kern_start; kmod_stop_func_t *_antimain = PC711Probe_kern_stop; diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 800145c..42b3210 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -8,6 +8,6 @@ PC711Probe uses the following source dependencies as pinned Git submodules: - **MacKernelSDK** — Contains headers and build support distributed under the licenses retained in that submodule, including the Apple Public Source License where applicable. -The PC711Probe project license applies only to project-authored files. It does not replace or restrict third-party licenses. +The PolyForm Noncommercial license for PC711Probe applies only to project-authored files in the v1.2.0-and-later development line. It does not replace or restrict third-party licenses. No Apple Kernel Collection, kernel, or `IONVMeFamily` binary is included in this repository. Development documentation describes independently observed symbols and behavior for interoperability research. diff --git a/docs/DEVELOPMENT.en.md b/docs/DEVELOPMENT.en.md index 790acbc..0065883 100644 --- a/docs/DEVELOPMENT.en.md +++ b/docs/DEVELOPMENT.en.md @@ -27,14 +27,16 @@ IOPCIDevice::configureInterrupts(0x20000, 1, 1, 0); `0x20000` requests MSI-X. Darwin 25 also removed the older MSI-X-specific path selected by bit `0x10` at controller offset `0x191`, consistently using the standard event-source path instead. +Further comparison of Darwin 20–22 showed that `CreateDeviceInterrupt` is not exported in those kernel collections, and requesting MSI-X only when that function runs is already too late on Ventura. Older `IOPCIFamily` may have resolved a different interrupt allocation and refuse a second configuration request. + ## 3. Implement the minimal compatibility patch -PC711Probe uses Lilu to route only `CreateDeviceInterrupt`: +PC711Probe keeps two version-bounded compatibility entry points: 1. PCI identity `1C5C:174A` with NVMe class `01:08:02` is matched automatically; -2. one MSI-X vector is requested; -3. Apple's original implementation creates the event source; and -4. the old MSI-X path-selector bit `0x10` is cleared. +2. on Darwin 20–22, a high-score PCI probe requests one MSI-X vector early and returns null without claiming the device; +3. on Darwin 23–24, `CreateDeviceInterrupt` is routed to request MSI-X and clear the old path-selector bit `0x10`; and +4. Apple `IONVMeFamily` remains responsible for the actual device attachment and storage I/O. Identify, queues, namespaces, and storage I/O remain handled by Apple `IONVMeFamily`. Other PCI IDs retain Apple's original behavior. The tested PC711 works natively on macOS 26, so the plugin loads only through Darwin 24. @@ -44,13 +46,15 @@ The project was built with pinned Lilu and MacKernelSDK revisions, followed by: - static, architecture, and `Info.plist` checks; - boot testing from an independent USB EFI; -- controller, model, namespace, and five existing-partition enumeration on macOS 15.6.1; and +- controller, model, namespace, and five existing-partition enumeration on macOS 13.4.1 and 15.6.1; +- normal Recovery boots on macOS 12.5.1 and 14.6.1; +- an explicit unsupported result for macOS 11.6, where the original timeout panic remains; and - a return to macOS 26 to confirm PCIe x4 / 8.0 GT/s, verified SMART status, and no regression on the other NVMe drive. No existing PC711 partition was erased or modified during validation, and the repository redistributes no Apple binaries. ## 5. Current conclusion -The combined patch removes the first-Identify timeout and publishes the controller, namespace, and partitions in the verified hardware and OS environment. +The combined patch removes the timeout and publishes the controller, namespace, and partitions in the verified macOS 13.4.1 and 15.6.1 hardware tests. -Other macOS 15 builds, firmware revisions, and platforms remain untested, as do a full macOS 15 installation, sustained I/O, TRIM, and sleep/wake. PC711Probe is therefore a narrowly scoped, hardware-verified compatibility patch rather than a generic PC711 driver. +macOS 11 remains unresolved. Other builds, firmware revisions, platforms, full installation, sustained I/O, TRIM, and sleep/wake also remain untested. PC711Probe is therefore a narrowly scoped, hardware-verified compatibility patch rather than a generic PC711 driver. diff --git a/docs/DEVELOPMENT.zh-CN.md b/docs/DEVELOPMENT.zh-CN.md index 0935fe3..7bfc852 100644 --- a/docs/DEVELOPMENT.zh-CN.md +++ b/docs/DEVELOPMENT.zh-CN.md @@ -27,14 +27,16 @@ IOPCIDevice::configureInterrupts(0x20000, 1, 1, 0); 其中 `0x20000` 请求 MSI-X。Darwin 25 同时删除了 Darwin 24 中由控制器偏移 `0x191` 的 bit `0x10` 选择的旧 MSI-X 特殊路径,统一使用标准事件源路径。 +随后对 Darwin 20–22 继续对比发现:`CreateDeviceInterrupt` 符号在旧 Kernel Collection 中未导出,而且到该函数执行时再申请 MSI-X 对 Ventura 已经太晚。旧版 `IOPCIFamily` 可能已解析其他中断分配,并拒绝第二次配置。 + ## 3. 实现最小兼容补丁 -PC711Probe 通过 Lilu 只路由 `CreateDeviceInterrupt`: +PC711Probe 保留两个受版本限制的兼容入口: 1. 自动匹配 PCI 身份 `1C5C:174A` 和 NVMe class `01:08:02`; -2. 请求一个 MSI-X 向量; -3. 调用 Apple 原始实现创建事件源; -4. 清除旧 MSI-X 路径选择位 `0x10`。 +2. Darwin 20–22 通过高优先级 PCI probe 提前申请一个 MSI-X 向量,然后返回空值,不占用设备; +3. Darwin 23–24 路由 `CreateDeviceInterrupt`,申请 MSI-X 并清除旧路径选择位 `0x10`; +4. Apple 原始 `IONVMeFamily` 始终负责真正的设备绑定与存储 I/O。 Identify、队列、namespace 和存储 I/O 仍由 Apple `IONVMeFamily` 完成。其他 PCI ID 保持 Apple 原始行为。macOS 26 已原生支持实测 PC711,因此插件最高只加载到 Darwin 24。 @@ -44,13 +46,15 @@ Identify、队列、namespace 和存储 I/O 仍由 Apple `IONVMeFamily` 完成 - 静态检查、架构检查和 `Info.plist` 校验; - 独立 USB EFI 启动验证; -- macOS 15.6.1 中控制器、型号、namespace 与五个既有分区枚举; +- macOS 13.4.1 与 15.6.1 中控制器、型号、namespace 与五个既有分区枚举; +- macOS 12.5.1 与 14.6.1 Recovery 启动正常; +- macOS 11.6 仍复现原始超时 KP,明确标记为未支持; - 重启至 macOS 26,确认 PC711 仍为 PCIe x4 / 8.0 GT/s、SMART Verified,且另一块 NVMe 无回归。 验证中没有抹除或修改 PC711 的现有分区,仓库也不分发任何 Apple 二进制。 ## 5. 当前结论 -已证明该组合补丁可在上述硬件与系统环境中消除第一条 Identify 超时,并发布控制器、namespace 和分区。 +已证明该组合补丁可在 macOS 13.4.1 与 15.6.1 的上述实机环境中消除超时,并发布控制器、namespace 和分区。 -尚未覆盖其他 macOS 15 build、其他固件或平台,以及 macOS 15 的完整安装、持续读写、TRIM 和睡眠唤醒。因此它是一个经过硬件验证的窄范围兼容补丁,不是通用 PC711 驱动。 +macOS 11 尚未修复;其他 build、固件或平台,以及完整安装、持续读写、TRIM 和睡眠唤醒也未覆盖。因此它是一个经过硬件验证的窄范围兼容补丁,不是通用 PC711 驱动。 diff --git a/docs/INSTALL.en.md b/docs/INSTALL.en.md index cbf9e77..4a2264f 100644 --- a/docs/INSTALL.en.md +++ b/docs/INSTALL.en.md @@ -19,14 +19,16 @@ English | [简体中文](INSTALL.zh-CN.md) | BundlePath | `PC711Probe.kext` | | ExecutablePath | `Contents/MacOS/PC711Probe` | | PlistPath | `Contents/Info.plist` | - | MinKernel | `8.0.0` | + | MinKernel | `20.0.0` | | MaxKernel | `24.99.99` | -3. Do not add `-pc711pcompat`; version 1.0.0 automatically matches the `1C5C:174A` PC711. +3. Do not add an activation argument; version 1.2.0 automatically matches the `1C5C:174A` PC711. 4. Disable AML/SSDT code that hides the PC711 through `_STA=0` or spoofed class/vendor/device values. 5. Temporarily disable NVMeFix for the first test so results are not mixed. 6. Validate the configuration with the `ocvalidate` matching the OpenCore version. +> macOS 11 is within the kext load range, but the tested machine still hits the original NVMe timeout panic and must not be considered supported yet. + ## First boot 1. Boot the older macOS release or Recovery through the test USB. diff --git a/docs/INSTALL.zh-CN.md b/docs/INSTALL.zh-CN.md index e4847b5..9b69511 100644 --- a/docs/INSTALL.zh-CN.md +++ b/docs/INSTALL.zh-CN.md @@ -19,14 +19,16 @@ | BundlePath | `PC711Probe.kext` | | ExecutablePath | `Contents/MacOS/PC711Probe` | | PlistPath | `Contents/Info.plist` | - | MinKernel | `8.0.0` | + | MinKernel | `20.0.0` | | MaxKernel | `24.99.99` | -3. 不要添加 `-pc711pcompat`;1.0.0 会自动匹配 `1C5C:174A` PC711。 +3. 不要添加启用参数;1.2.0 会自动匹配 `1C5C:174A` PC711。 4. 停用隐藏 PC711 的 AML/SSDT,包括 `_STA=0` 或伪造 class/vendor/device 的规则。 5. 首次验证时暂时停用 NVMeFix,避免混淆结果。 6. 使用与 OpenCore 版本匹配的 `ocvalidate` 检查配置。 +> macOS 11 虽在 Kext 加载范围内,但目标实机仍会发生原始 NVMe 超时 KP,目前不应视为已支持。 + ## 首次启动 1. 从测试 USB 启动旧版 macOS 或 Recovery。