Jump to content

NVMe Express digging


jan-munich
 Share

117 posts in this topic

Recommended Posts

Hey all, since many of us are interested in getting our NVMe drives running I started to dig a little bit in Apple's NVMe driver.

 

Since im not an expert on debugging I could need some help here and there.

 

My finding so far:

 

Hardware IDs: from my Samsung 950 Pro

0:107  0:000  PCI (00|0B:00.00) : 144D A802 class=010802

 

mapped via:

PciRoot(0x0)\Pci(0x1D,0x0)\Pci(0x0,0x0)\VenHw(CF31FAC5-C24E-11D2-85F3-00A0C93EC93B,80)

 

Whereas for my board i got the following sunrise point connectors for pci express:

 

Device 8086:A102
Sunrise Point-H SATA controller [AHCI mode]
Device 8086:a118
Sunrise Point-H PCI Express Root Port
Device 8086:A115
Sunrise Point-H PCI Express Root Port #6
Device 8086:A114
Sunrise Point-H PCI Express Root Port #5
Device 8086:A110
Sunrise Point-H PCI Express Root Port #1

 

Apples SSD Controller is:

 

Model: "Apple Storage controller"
  Vendor: pci 0x106b "Apple Inc."
  Device: pci 0x2001

 

Lets get to the fun part:

 

I found at least one check to determine if there is an Apple SSD inserted to stop the NVMe Driver from working:

 

00000000000028be         add        rbx, 0x18
00000000000028c2         lea        r15, qword [ds:0xe3ad]                      ; "APPLE SSD"
00000000000028c9         mov        rdi, r15                                    ; argument "s" for method _strlen
00000000000028cc         call       _strlen
00000000000028d1         mov        rdi, r15                                    ; argument "s1" for method _strncmp
00000000000028d4         mov        rsi, rbx                                    ; argument "s2" for method _strncmp
00000000000028d7         mov        rdx, rax                                    ; argument "n" for method _strncmp
00000000000028da         call       _strncmp
00000000000028df         test       eax, eax
00000000000028e1         je         0x290b
 

0xe3ad = "APPLE SSD"

 

 

Bascially the method IsBarrierSupported()

takes the length of the device descriptor cuts it at a length of "APPLE SSD"[0-8]

and does a string comparsion with "APPLE SSD" and it does even more..

 

But it looks like the controller is not even properly initialized maybe because of the device/vendor ids

 

If anyone of you is more skilled in osx debugging maybe someone can help me out to get my IONVMeFamily up and running in debug mode would be superb to see where the actual load of the kext is failing.

 

Btw. it seems the kext is not automatically loaded I had to start it manually, so we definitly need to forceKextLoad it with clover. (maybe it is started with macbook 13 retina smbios?)

 

Regards

Jan

 

 

  • Like 3
Link to comment
Share on other sites

@Rehabman do you think we can inject a FakeID for PCI including "APPLE SDD"to see how the driver behaves now?

 

Im gonna give a try tomorrow -> hence i still need to find out how i can properly debug the driver to get some outputs like - wrong ssd or so..

 

Cheers

Jan

Link to comment
Share on other sites

I can do soon Ramalama,

 

i had to buy another SSD to install my OSX to -> on the go right now..

for some weird reasons my intel 10 chipset did not recognize my old intel SATA SSDs.. 

 

(problem being i just have one m.2 slot on my board..)

 

So im cloning my M.2 right know to a sata ssd and than i can start digging while being in osx.

 

Regards

Link to comment
Share on other sites

maybe you can just change string IOAHCIBlockStorage of the trim enabler patch for clover to suite your kext as it also searches for Apple SSD to enable trim

<dict>
<key>Name</key>
<string>IOAHCIBlockStorage</string>
<key>Find</key>
<data>QVBQTEUgU1NEAA==</data>
<key>Replace</key>
<data>AAAAAAAAAAAAAA==</data>
</dict>

QVBQTEUgU1NEAA== in base 64 is equal to APPLE SSD∅ in ascii and by nulling APPLE SSD it enables trim.

you can use this to convert http://www.hcidata.info/base64.htm

Link to comment
Share on other sites

maybe you can just change string IOAHCIBlockStorage of the trim enabler patch for clover to suite your kext as it also searches for Apple SSD to enable trim

<dict>
<key>Name</key>
<string>IOAHCIBlockStorage</string>
<key>Find</key>
<data>QVBQTEUgU1NEAA==</data>
<key>Replace</key>
<data>AAAAAAAAAAAAAA==</data>
</dict>

QVBQTEUgU1NEAA== in base 64 is equal to APPLE SSD∅ in ascii and by nulling APPLE SSD it enables trim.

you can use this to convert http://www.hcidata.info/base64.htm

 

thx bronxteck for your input im going to check that out,

 

it seems nvme is also using IOBlockdevice but has that check also inside the driver..

Im going to grab a new macbook for testing and report what ill find here.

Link to comment
Share on other sites

Ok some head-up:
 

I looked into the method on how trim is enabled and how apple looks in the IONVMeFamily.kext for the Apple SSD.

The methods are alike so this fix applied on

IONVMeFamily and/or IONVMeController inside the familiy.kext should help.

 

I tried that but nothing happened, than I created a FAKEPCIID using Rehabsman repo to match apples given SSD:

(matching device id vendor id classcode subsystem-vendor-id name)

-> Can anyone tell me if its normal that there is a RM,xxx in front of every manipulation in ioregexplorer? if i remove RM, it seems nothing gets injected.

 

 

I attached 2 screenshots from the samsung ssd an the apple ssd from the new macbook retina thx to apple store. :)

 

What you can see is that apple twisted up the PCI classcode:

 

Apple:      018002       -> SSD0   -> they match "IOPCIClassMatch" = "0x01800200&0xffffff00" also in their IONVMeFamily.kext

Samsung: 010802      -> PXSX

 

Looking up PCI class codes:

 

Samsung:

Device subclass 01:08 
01 mass storage controller
08 Non-Volatile memory controller
02 NVM Express
 
Apple:
Device subclass 01:80 
01 mass storage controller
80 Mass storage controller
02 *not found*
 
In addition I read into the NVMe Specification and there is also a part where they do namespace structure identification:
 
IDENTIFY controller and namespace structure (NVMe 1.1 decoding)
 
Command code 8 
 
bits:
0 - 8 
9 - 10  -> 10:09 Vendor ID
11 - 30 -> 30:11 -> serial number
31 8 bit CRC calculated over slave dress command code, second slave address and returned data -> algorithm is in SMBus Specification
 
since I still not able to get any debug output from the IONVMeFamily its hard to determine what actually happens,
its also likely that the apple driver just does not work with an UBX controller from Samsung. If someone is more capable in driver programming than I am it would be nice to get in touch maybe we can port the linux nvme drivers?
 
Regards
Jan
 
 
edit:
 
ioreg macbook retina + mine attached.
there are plenty ioregs around. Im curious what you will tell me now from my ioreg which hasn't been in the screenshots before.

post-1615419-0-43981400-1447416531_thumb.png

post-1615419-0-41780100-1447416538_thumb.png

ioregs.zip

Edited by jan-munich
Link to comment
Share on other sites

 

Ok some head-up:

 

I looked into the method on how trim is enabled and how apple looks in the IONVMeFamily.kext for the Apple SSD.

The methods are alike so this fix applied on

IONVMeFamily and/or IONVMeController inside the familiy.kext should help.

 

I tried that but nothing happened, than I created a FAKEPCIID using Rehabsman repo to match apples given SSD:

(matching device id vendor id classcode subsystem-vendor-id name)

-> Can anyone tell me if its normal that there is a RM,xxx in front of every manipulation in ioregexplorer? if i remove RM, it seems nothing gets injected.

 

 

I attached 2 screenshots from the samsung ssd an the apple ssd from the new macbook retina thx to apple store. :)

 

What you can see is that apple twisted up the PCI classcode:

 

Apple:      018002       -> SSD0   -> they match "IOPCIClassMatch" = "0x01800200&0xffffff00" also in their IONVMeFamily.kext

Samsung: 010802      -> PXSX

 

Looking up PCI class codes:

 

Samsung:

Device subclass 01:08 
01 mass storage controller
08 Non-Volatile memory controller
02 NVM Express
 
Apple:
Device subclass 01:80 
01 mass storage controller
80 Mass storage controller
02 *not found*
 
In addition I read into the NVMe Specification and there is also a part where they do namespace structure identification:
 
IDENTIFY controller and namespace structure (NVMe 1.1 decoding)
 
Command code 8 
 
bits:
0 - 8 
9 - 10  -> 10:09 Vendor ID
11 - 30 -> 30:11 -> serial number
31 8 bit CRC calculated over slave dress command code, second slave address and returned data -> algorithm is in SMBus Specification
 
since I still not able to get any debug output from the IONVMeFamily its hard to determine what actually happens,
its also likely that the apple driver just does not work with an UBX controller from Samsung. If someone is more capable in driver programming than I am it would be nice to get in touch maybe we can port the linux nvme drivers?
 
Regards
Jan
 
 

 

an ioreg would help more as your useless write-ups here...

sry...

Link to comment
Share on other sites

Link to comment
Share on other sites

see attachment above.

aah perfect, I will look into it later and give you some advises, cheers:-)

Jan? Do you have a custom dsdt?

 

So i mean, can i send you code snippets? or you can share your dsdt, and i will send you some test files... would be easiest if i can send you always your modified dsdt, that you can test...

 

If not, we can try the fakepci kext method... but i not a fan of it...

 

Cheers :-)

Link to comment
Share on other sites

sure you can.

im not "really"using a patched DSDT, the only patch i have is from pike to fix cpu stepping : https://github.com/Piker-Alpha/ssdtPRGen.sh

 

which can be removed easily.

 

attached you can find my factory dsdt extracted with clover.

 

I also tried the FakePCI Method I attach the changes I made to have a look if you like:

 

DSDT.aml.zip

FakePCIID_SamsungToAppleSSD.kext.zip

Link to comment
Share on other sites

sure you can.

im not "really"using a patched DSDT, the only patch i have is from pike to fix cpu stepping : https://github.com/Piker-Alpha/ssdtPRGen.sh

 

which can be removed easily.

 

attached you can find my factory dsdt extracted with clover.

 

I also tried the FakePCI Method I attach the changes I made to have a look if you like:

 

Do you use clover auto patching?

if yes, we can do the same with comfig.plist if you want

Link to comment
Share on other sites

nope

well i'm trying to port the linux/bsd driver to mac - but that could take a while since I have a lot of coding to do at work anyway.

 

i gave up on modifying the existing apple driver hence it seems they do some things quite different than the linux derivate.

 

im willing to test dsdt + fakepci patches if your willing to provide.

Link to comment
Share on other sites

@Jan

Im sorry, i was very busy last days... have very much todo...

 

Can you try this dsdt? but i don't know which graphics you use...

i hope you didn't get a black screen... you can add the DSM for your graphics or maybe clover does it...

 

Im sry, that im so slow...

but we will definitive dig in!

 

Because i want to buy nvme ssds for my laptop and have already included the necessary modules into bios...

but there are no M.2 2260 NVME Modules out yet... and 2280 doesn't fit my laptop...

 

However, here is your DSDT but don't forget check about graphics...

 

Cheers :-)

DSDT.aml.zip

 

PS: Can you send me an ioreg with this dsdt, that i can check?

Link to comment
Share on other sites

@r-lind not yet. 

 

im going to push my local repo up when i have more than a wrapper for IOPCIDevice.

thats my actual state right know.

 

@ramalama

i can test it yep. using a z170 chipset and a gfx 970 gtx.

 

reporting soon.


io-reg attached.

 

doesn't look like any changes applied to PSXS ->samsung pci 

jan’s iMac - modifiedDSDT.zip

  • Like 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...