跳到主要內容

[指南] HackrNVMeFamily使用類代碼欺騙與IONVMeFamily共存(RehabMan)

概述

本指南的目的是解釋如何使用類代碼欺騙技術來保護未修補的IONVMeFamily.kext(與大多數PC NVMe SSD不兼容),以便在EFI / Clover中將HackrNVMeFamily與其一起使用kexts或安裝到系統卷(/ Library / Extensions,/ System / Library / Extensions)。

我首先 在insanelymac 上發布了這項技術:http//www.insanelymac.com/forum/to...er-macos-sierra-is-ready/page-29#entry2322636

你應該熟悉patch_nvme.sh腳本在github上的patch-nvme README中討論過:https//github.com/RehabMan/patch-nvme

儘管有許多方法可以修補IONVMeFamily,但這裡只討論類代碼欺騙和HackrNVMeFamily。我認為這是最好的方式。保持這篇文章僅關注從安裝到安裝後使用的這種單一技術,是解決該主題的最簡單方法。

有實行分類代碼惡搞兩種不同的方式:
- SSDT與_DSM方法注入修飾類代碼
OR 
-使用config.plist /設備/任意注入修改後的類代碼

,因為使用config.plist /設備/任意排除使用一些常用的Clover功能(config.plist / Graphics / Inject),這篇文章將僅討論SSDT方法。

假設:
- 在目標上安裝Windows 10
- 在現有的hack或Mac上運行安裝macOS / OS X(與你計劃的目標版本相同)
- 基本的config.plist編輯技巧
- 基本的MaciASL用法
- 基本的Clover知識
- 安裝/注入kexts 

基本知識MaciASL使用的本指南可在此處獲取:https
//bitbucket.org/RehabMan/os-x-maciasl-patchmatic/downloads 確保在MaciASL-> Preferences-> iASL中選擇了ACPI 6.1。

注意:在10.13 High Sierra中,對512塊大小的NVMe SSD有更好的支持。因此,使用10.13,您不需要這麼大的補丁。


確定NVMe設備的ACPI路徑

要創建SSDT以注入類代碼,您必須知道描述SSD位於ACPI名稱空間中的位置的ACPI路徑。您可以使用Windows設備管理器,或者高級用戶可以從ioreg確定它。這兩種方法都在patch-nvme README中提供的insanelymac鏈接中描述。

由於本指南旨在在安裝之前使用,因此它將使用Windows設備管理器。您將在Windows設備管理器中的“存儲控制器” - >“標準NVM Express控制器”下找到您的NVMe設備。右鍵單擊並選擇“屬性”。然後單擊“詳細信息”選項卡。然後在“Property”下拉列表中找到“BIOS device name”。選擇它。您的NVMe SSD ACPI路徑將顯示在“值”框中。

後1031260-0-50712400-1479777087.png 



注意:您的SSD也可能沒有ACPI標識。我目前沒有這樣的計算機(情況可能很少),但在這種情況下,您可能只能確定父母的ACPI身份(在我的NUC的情況下,父親是_SB。 PCI0.RP13),並且必須創建稍微不同的SSDT。如果您沒有看到“BIOS設備名稱”,則SSD路徑可能沒有一個或多個ACPI標識。在這種情況下,查找“位置路徑”並記錄以“ACPI(_SB_)”開頭的路徑。請務必閱讀“ACPI身份不完整的示例”以獲取更多信息和說明。


創建SSDT_NVMe-Pcc.aml

下面你會找到一個模板,你可以使用你自己的SSDT注入類代碼。這是我在NUC6i7KYK上使用三星950 Pro NVMe SSD的實際SSDT:
代碼:

// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.RP13.PXSX, DeviceObj)
    Method(_SB.PCI0.RP13.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF

上面顯示的路徑_SB.PCI0.RP13.PXSX是我的NUC6i7KYK使用的路徑。您會注意到Windows設備管理器中的圖像中顯示了相同的路徑。您需要在上面的SSDT中替換它的兩個實例,以匹配您自己的NVMe SSD的路徑。

關於“內置”的注意事項:在我的所有經驗中,只有擁有ACPI標識才能使設備看起來是內置的,而不是外部的。但有些人報告他們的設備顯示為外部...所以我添加“內置”,因為我們從不希望M.2 SSD出現在外部。

如果您的SSD沒有ACPI標識(例如,M.2端口/設備沒有ACPI標識),則需要創建一個。例如,如果OEM遺漏了PXSX標識,則需要添加一個:

代碼:

// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.RP13, DeviceObj)
    // Add PXSX device under RP13
    Device(_SB.PCI0.RP13.PXSX) { Name(_ADR, 0) }
    /// Now we can inject the method at RP13.PXSX
    Method(_SB.PCI0.RP13.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF
 
在這種情況下,我不知道Windows設備管理器中顯示的內容,儘管可以預測ioreg會是什麼樣子。當然,這裡的想法是在安裝macOS之前創建SSD,所以如果您的SSD沒有ACPI身份,請告訴我。

如果您有多個NVMe SSD,則必須為每個SSD創建一個_DSM方法。例如,我的NUC在RP09上也有一個用於SSD的M.2端口。目前,我在那里安裝了SM951 / AHCI,因此它不是NVMe。但如果它是一個NVMe驅動器,我的SSDT必須修改為包含一個_DSM方法:

代碼:
// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.RP09.PXSX, DeviceObj)
    Method(_SB.PCI0.RP09.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
    External(_SB.PCI0.RP13.PXSX, DeviceObj)
    Method(_SB.PCI0.RP13.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF
 

要使用此SSDT,必須將其編譯為AML。您應該使用我上面鏈接的MaciASL版本。確保將MaciASL-> Preferences-> iASL設置為ACPI 6.1。

運行MaciASL後,關閉默認窗口(具有DSDT),然後選擇File-> New創建一個空文檔。粘貼代碼並根據您的ACPI路徑進行編輯,然後使用File.Save As,“SSDT_NVMe-Pcc.aml”,格式:ACPI機器語言二進製文件。保存到您可以找到的位置,例如桌面。

現在您可以復制SSDT_NVMe-Pcc.aml文件,以便Clover可以加載它。如果您正在準備USB,則將其置於EFI for USB上,否則它將位於EFI上用於啟動驅動器。在任何情況下,它都轉到EFI / Clover / ACPI / patched / SSDT_NVMe-Pcc.aml。

注意:如果您正在使用config.plist / ACPI / SortedOrder(為已修補的OEM SSDT設置SSDT加載順序),則必須確定SSDT_NVMe-Pcc.aml位於SortedOrder列表中。指定SortedOrder時,Clover會忽略ACPI / patched中不在SortedOrder中的SSDT。對於使用Clover ACPI熱修補的大多數桌面方案和筆記本電腦方案,將不指定SortedOrder並將文件複製到ACPI / patched足以導致它被加載。


ACPI身份不完整的示例

如上面“確定NVMe設備的ACPI路徑”中所述,您的SSD路徑可能不完整,因此沒有ACPI標識一直引導到SSD的葉節點。如果沒有可用的完整ACPI路徑,則無法注入屬性(即使使用config.plist / Devices / Arbitrary也是如此)。在這種情況下,我們必須為路徑中的每個節點(包括代表SSD的葉節點)完成缺少的ACPI標識。

這是一個簡單的示例,它顯示了一直到SSD父級的ACPI標識,但SSD葉節點沒有ACPI標識: 我們可以從ACPI(_SB _)#ACPI(PCI0)#導出父路徑ACPI(POP4)為_SB.PCI0.POP4,但是葉節點代表SSD,#PCI(000),我們需要定義自己,因為它在OEM ACPI代碼中不存在。
ssd.jpg 
結果如下:

代碼:
// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.P0P4, DeviceObj)
    Device(_SB.PCI0.P0P4.SSD0) { Name(_ADR, 0) } // adding SSD0 identity under _SB.PCI0.P0P4
    Method(_SB.PCI0.P0P4.SSD0._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF
 

這是PCI橋後面的SSD的一個更複雜的例子。PCI橋接器#PCI(0800)沒有ACPI身份,因為SSD,#PCI(000)本身: PCI橋接器的父路徑可以從ACPI(_SB _)#ACPI(PCI0)派生#ACPI(PEG0)#ACPI(PEGP)為_SB.PCI0.PEG0.PEGP,但對於#PCI(0800)#PCI(0000),我們必須創建ACPI身份。 結果如下:
Capture4.PNG 

We can derive the path of the parent from ACPI(_SB_)#ACPI(PCI0)#ACPI(POP4) as _SB.PCI0.POP4, but the leaf node representing the SSD, #PCI(000), we will need to define ourselves as it doesn't exist in the OEM ACPI code.

The result is this:

代碼:

// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.PEG0.PEGP, DeviceObj)
    // create identities for the bridge @8 and SSD0 @0
    Device(_SB.PCI0.PEG0.PEGP.PBR8)
    {
        Name(_ADR, 0x00080000)  // corresponds to #PCI(0800), MSW byte reversed
        Device(SSD0) { Name(_ADR, 0) } // corresponds to #PCI(0000)
    }
    // now we can inject the _DSM at the newly created ACPI path
    Method(_SB.PCI0.PEG0.PEGP.PBR8.SSD0._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF
 


10.11.x和三星960 EVO(或其他144d:a804 NVMe設備)所需的特殊注射

因為10.11.x IONVMeFamily.kext與pci144d,a804具有直接的IOName匹配,這恰好是Samsung 960的設備ID EVO,如果你有這個組合(10.11.x + 960 EVO),你必須注入一些額外的屬性來防止加載本機IONVMeFamily.kext。

例如:

代碼:

// Inject bogus class-code for NVMe SSD to prevent IONVMeFamily.kext from loading
DefinitionBlock("", "SSDT", 2, "hack", "NVMe-Pcc", 0)
{
    External(_SB.PCI0.RP09.PXSX, DeviceObj)
    Method(_SB.PCI0.RP09.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
    External(_SB.PCI0.RP13.PXSX, DeviceObj)
    Method(_SB.PCI0.RP13.PXSX._DSM, 4)
    {
        If (!Arg2) { Return (Buffer() { 0x03 } ) }
        Return(Package()
        {
            "class-code", Buffer() { 0xff, 0x08, 0x01, 0x00 },
            "built-in", Buffer() { 0 },
        })
    }
}
//EOF


我的初始/完整說明如下https://www.tonymacx86.com/threads/...stall-el-capitan-on-nvme.210837/#post-1409008

您的OEM已經定義了一個ACPI路徑中的_DSM方法,用於在ACPI名稱空間中定義NVMe SSD。ACPI不允許在同一路徑上使用重複符號,因此如果您有現有的_DSM,我們嘗試通過SSDT_NVMe-Pcc.aml添加的_DSM將被忽略。

雖然您可以修補DSDT(或任何可能有違規的_DSM的OEM SSDT),但我喜歡使用Clover補丁將所有_DSM方法重命名為XDSM。Clover ACPI補丁在config.plist / ACPI / DSDT / Patches中指定。

_DSM-> XDSM的條目是:
註釋:所有_DSM更改為XDSM 
查找:<5f44534d> 
替換:<5844534d>

正如Xcode中所示: 將所有_DSM重命名為XDSM可確保NVMe SSD路徑上不存在現有的_DSM。如果該路徑上存在現有的_DSM,則通過SSDT_NVMe-Pcc.aml注入_DSM將無效。 您可以在patch-nvme github項目的config_patches.plist中找到_DSM到XDSM補丁。它可以輕鬆複製/粘貼到您自己的config.plist中。 注意:如果您已在ACPI / patched中使用靜態修補的DSDT.aml,則不應使用_DSM-> XDSM修補程序。相反,請確保在ACPI / patched / DSDT.aml中修補的DSDT(或修補的SSDT)中的路徑(或重命名為XDSM)上刪除了_DSM。通常,這可以通過根據我的筆記本電腦ACPI修補指南應用“刪除_DSM方法”或“將_DSM方法重命名為XDSM”來完成。
屏幕截圖2016-12-20 at 5.03.33 PM.png 

Renaming all _DSM to XDSM insures no existing _DSM at the NVMe SSD path. The _DSM injection via SSDT_NVMe-Pcc.aml will not work if there is an existing _DSM at that path.

You can find the _DSM to XDSM patch in config_patches.plist in the patch-nvme github project. It makes for easy copy/paste into your own config.plist.

Note: If you already have a statically patched DSDT.aml in ACPI/patched, you should not use the _DSM->XDSM patch. Instead, make sure you removed the _DSM at the path (or renamed to XDSM) in your patched DSDT (or patched SSDTs) at ACPI/patched/DSDT.aml. Typically, this would be done by applying "Remove _DSM methods", or "Rename _DSM methods to XDSM" as per my laptop ACPI patching guide.

使用欺騙性類代碼創建HackrNVMeFamily * .kext

這在patch-nvme README中非常清楚地描述,但這裡是一個快速概述,特別關注--spoof選項。

根據patch-nvme README,我們必須複製github項目:

代碼:

mkdir ~/Projects
cd Projects
git clone https://github.com/RehabMan/patch-nvme.git patch-nvme.git
cd patch-nvme.git

由於您的NVMe SSD將不使用標準類代碼,而是使用非標準類代碼,因此生成的HackrNVMeFamily * .kext必須使用非標準IOPCIClassMatch而不是標準類。

為此,我們使用--spoof選項。例如,要為10.12.2創建HackrNVMeFamily:

代碼:

cd ~/Projects/patch-nvme.git
./patch_nvme.sh --spoof
 

如果您正在運行10.12.2,結果將是HackrNVMeFamily-10_12_2-spoof.kext,它可以放置在EFI / Clover / kexts / Other中以通過Clover(安裝程序或恢復方案)進行注入,或者安裝到系統卷(安裝後方案)。

您可以使用Terminal輕鬆安裝kexts。例如,要安裝生成的HackrNVMeFamily-10_12_2-spoof.kext:

代碼:

cd ~/Projects/patch-nvme.git
sudo cp -R HackrNVMeFamily-10_12_2-spoof.kext /Library/Extensions

您可以重建緩存以驗證是否可以構建緩存而不會出現錯誤:

代碼:

sudo kextcache -i /

總結

要使用生成的HackrNVMeFamily * .kext:
- 確保SSDT_NVMe-Pcc.aml處於EFI / Clover / ACPI / 
patched中 - 確保重命名或刪除NVMe SSD ACPI路徑中的現有_DSM方法
- 確保使用--spoof選項生成HackrNVMeFamily * .kext 
- 安裝HackrNVMeFamily * .kext或通過EFI / Clover / kexts注入它

注意:請記住,因為Clover通常配置了config.plist / SystemParameters / InjectKexts =“Detect”,一旦將FakeSMC.kext安裝到系統卷(通常),Clover將忽略EFI / Clover / kexts。因此,在安裝後,您應始終將HackrNVMeFamily * .kext安裝到系統卷。在此方案中僅安裝沒有HackrNVMeFamily * .kext的FakeSMC.kext將導致系統無法啟動。

通過使用SSDT,我們注入了一個虛假的類代碼,使得IONVMeFamily.kext不匹配,因此不會加載。但是由於patch_nvme.sh腳本使用--spoof選項創建的HackrNVMeFamily Info.plist中修改了IOPCIClassMatch,它在修改後的類代碼上匹配,並針對典型PC NVMe使用的512字節塊大小進行修補固態硬盤。

通過從一開始就使用類代碼欺騙,您在安裝和安裝後使用相同的機制。一旦實現了類代碼欺騙,IONVMeFamily.kext就不會出現任何問題。更新也得到了簡化,因為在更新後您有機會創建新的HackrNVMeFamily之前,您很可能會使用先前的HackrNVMeFamily來更新系統。並且因為永遠不會刪除IONVMeFamily,所以在更新完成後創建新的HackrNVMeFamily * .kext總是很容易,並且該版本的補丁集可用。

系統更新
一旦你有類代碼欺騙,系統更新就會簡化,因為沒有必要刪除IONVMeFamily.kext。但您仍應計劃更新HackrNVMeFamily * .kext* *每次更新,您有當前的NVMe驅動程序代碼。

這些程序有點明顯,但在此處列出(更新從10.12.2到10.12.3的示例):

- 通過App Store更新
- 等待RehabMan更新patch-nvme github項目
- 更新你的patch-nvme副本github repo

代碼:

cd ~/Projects/patch-nvme.git
git pull

- 創建新的HackrNVMeFamily * .kext

代碼:

./patch_nvme.sh --spoof

- 刪除以前的HackrNVMeFamily * .kext(例如HackrNVMeFamily-10_12_2-spoof.kext)
代碼:

sudo rm -Rf /Library/Extensions/HackrNVMeFamily*.kext

- 安裝新的HackrNVMeFamily-10_12_3.kext
代碼:

sudo cp -R HackrNVMeFamily-10_12_3-spoof.kext /Library/Extensions


問題報告

提供問題的詳細和簡明描述。

如果macOS / OS X安裝程序無法識別您的驅動器,或者您感到恐慌... 

從Windows設備管理器提供顯示SSD的ACPI命名空間路徑的圖像。

將EFI / Clover文件夾作為ZIP附加(在收集前按主Clover屏幕上的F4)。刪除'themes'目錄僅提供EFI / Clover,而不是整個EFI文件夾。

感謝RehabMan,為本指南。好消息是指南在github上你的補丁-nvme自述文件澄清了很多信息:https//github.com/RehabMan/patch-nvme對於我們這些沒有你深入了解的人。

留言

這個網誌中的熱門文章

第八代『黑蘋果』主機全部安裝教程

HIGH SIERRA GUIDE  For  ASUS  STRIX Z370 -G  ROG ( Micro-ATX ) ** UPDATE   5th Jan 2018  /   Clover v2.4k r4359 ** 硬體配置規格 Asus ROG Strix Z370-G Gaming (Wi-Fi AC) ( Micro ATX )  i7 8700 3.2GHz  Corsair Vengeance LPX 8GB (1 x 8GB) DDR4 DRAM 2400MHz (PC4-19200) C14 Memory Kit - Black  Samsung Evo 960 250GB NVMe SSD  NVIDIA GeForce GTX 1080ti (or a GTX 1050 / 1060 / 1070 will work  ) ABWB 802.11AC WI-FI with Bluetooth 4.0 PCI-Express  BitFenix Phenom – Tower – micro ATX  Noctua NH-L9x65 - NH-L9x65 Low Profile Performance CPU Cooler  EVGA SuperNOVA 750 G3, 80 Plus Gold 750W  Corsair UK K65 Rapidfire Cherry MX Speed Performance Multi-Colour RGB Backlit 10 Keyless  Samsung 850 EVO 500GB  Dell UltraSharp U2717D (2560x1440DP) IPS LED 27-Inch Infinity Edge 成功運行的功能 Wi-Fi ( Onboard WiFi card was replaced, see components list above )   Bluetooth Ethernet ...

雖然我沒有4K螢幕,但卻可以4K輸出(4K)

FRESH INSTALLING MACOS HIGH SIERRA ON AMD RYZEN HACKINTOSH GUIDE (10.13)

This guide will show you the steps to install Sierra on a AMD Ryzen PC using a VMWare Virtual Machine. I’m making this guide for those who don’t have access to a Mac and need macOS to either try out for a bit or create a macOS boot loader installer for a AMD hackintosh build. There is another VMWare Sierra guide on this site, but  with AMD system a modified VMWare image is required to even be able to boot macOS so this AMD VMWare guide has to be used instead. WHY NOT A HIGH SIERRA VM? So getting High Sierra running as a virtual machine in Windows or Linux is actually pretty difficult with a Ryzen PC. Some will manage to get it working, butt not for others with there being all sorts of errors that can potentially popup on the screen. I actually spent half a day trying to get High Sierra working on VMWare player and wasn’t able to do it, so I had to resort to using Sierra, which I posted the steps for here. You can still use a Sierra VM to download High Sierra and create a Hig...