Jump to content

Patch for using NVMe under macOS Sierra is ready.


1,382 posts in this topic

Recommended Posts

Important also to change the bundle-id/bundle-name in the Info.plist

Was. I made a "USE_CONTROLLER_PATCH" macro set to 0 to switch back to this mode, but default for me is this new mode of increasing the version number and now the Info.plist is "less" patched and almost vanilla (IOPCIClassMatch is now standard for PCs).

Link to comment
Share on other sites

Was. I made a "USE_CONTROLLER_PATCH[/size]" macro set to 0 to switch back to this mode, but default for me is this new mode of increasing the version number and now the Info.plist is "less" patched and almost vanilla (IOPCIClassMatch is now standard for PCs).

I prefer to patch the bundle-id/bundle-name... I think it is better that way.

Link to comment
Share on other sites

Repo updated.

 

 

I prefer to patch the bundle-id/bundle-name... I think it is better that way.

 

Is still compatible by enabling a macro for me, but this way the same user was experience a kp have its nvme ssd working. I'll provide both binaries in the download section.

Link to comment
Share on other sites

Is still compatible by enabling a macro for me, but this way the same user was experience a kp have its nvme ssd working. I'll provide both binaries in the download section.

I suppose... there is plenty of evidence that the version hack works (dummyHDA technique), but I'd rather not use it as Apple doesn't document it that way...

  • Like 1
Link to comment
Share on other sites

Off course, but also a binary patch is not documented  ^_^ (quip)

Ha ha... for me they are in a bit different category. It is documented that the code the system will run is in the binary inside MacOS subdir...

Link to comment
Share on other sites

Jokes aside the Info.plist loaded in the memory-map and later unserialized in OSKext.cpp inside the XNU kernel ...and you can see specific rules:

/* If we have a kext with this identifier that's already loaded/prelinked,
* we can't use the new one, but let's be really thorough and check how
* the two are related for a precise diagnostic log message.
*
* Note that user space can't find out about nonloaded prelinked kexts,
* so in this case we log a message when new & existing are equivalent
* at the step rather than warning level, because we are always going
* be getting a copy of the kext in the user load request mkext.
*/
if (existingIsLoaded || existingIsPrelinked) {
bool sameVersion = (newVersion == existingVersion);
bool sameExecutable = true; // assume true unless we have UUIDs

/* Only get the UUID if the existing kext is loaded. Doing so
* might have to uncompress an mkext executable and we shouldn't
* take that hit when neither kext is loaded.
*/
newUUID = copyUUID();
existingUUID = existingKext->copyUUID();

/* I'm entirely too paranoid about checking equivalence of executables,
* but I remember nasty problems with it in the past.
*
* - If we have UUIDs for both kexts, compare them.
* - If only one kext has a UUID, they're definitely different.
*/
if (newUUID && existingUUID) {
sameExecutable = newUUID->isEqualTo(existingUUID);
} else if (newUUID || existingUUID) {
sameExecutable = false;
}

if (!newUUID && !existingUUID) {

/* If there are no UUIDs, we can't really tell that the executables
* are *different* without a lot of work; the loaded kext's
* unrelocated executable is no longer around (and we never had it
* in-kernel for a prelinked kext). We certainly don't want to do
* a whole fake link for the new kext just to compare, either.
*/

OSKextVersionGetString(version, newVersionCString,
sizeof(newVersionCString));
OSKextLog(this,
kOSKextLogWarningLevel |
kOSKextLogKextBookkeepingFlag,
"Notice - new kext %s, v%s matches %s kext "
"but can't determine if executables are the same (no UUIDs).",
getIdentifierCString(),
newVersionCString,
(existingIsLoaded ? "loaded" : "prelinked"));
}

if (sameVersion && sameExecutable) {
OSKextLog(this,
(existingIsLoaded ? kOSKextLogWarningLevel : kOSKextLogStepLevel) |
kOSKextLogKextBookkeepingFlag,
"Refusing new kext %s, v%s: a %s copy is already present "
"(same version and executable).",
getIdentifierCString(), newVersionCString,
(existingIsLoaded ? "loaded" : "prelinked"));
} else {
if (!sameVersion) {
/* This condition is significant so log it under warnings.
*/
OSKextLog(this,
kOSKextLogWarningLevel |
kOSKextLogKextBookkeepingFlag,
"Refusing new kext %s, v%s: already have %s v%s.",
getIdentifierCString(),
newVersionCString,
(existingIsLoaded ? "loaded" : "prelinked"),
existingVersionCString);
} else {
/* This condition is significant so log it under warnings.
*/
OSKextLog(this,
kOSKextLogWarningLevel | kOSKextLogKextBookkeepingFlag,
"Refusing new kext %s, v%s: a %s copy with a different "
"executable UUID is already present.",
getIdentifierCString(), newVersionCString,
(existingIsLoaded ? "loaded" : "prelinked"));
}
}
goto finish;
} /* if (existingIsLoaded || existingIsPrelinked) */

So is clearly documented, and from this was the message I was talking about today, and IMHO is perfectly fine.

  • Like 1
Link to comment
Share on other sites

Jokes aside the Info.plist loaded in the memory-map and later unserialized in OSKext.cpp inside the XNU kernel ...and you can see specific rule:

if (sameVersion && sameExecutable) {
            OSKextLog(this,
                (existingIsLoaded ? kOSKextLogWarningLevel : kOSKextLogStepLevel) |
                kOSKextLogKextBookkeepingFlag,
                "Refusing new kext %s, v%s: a %s copy is already present "
                "(same version and executable).",
                getIdentifierCString(), newVersionCString,
                (existingIsLoaded ? "loaded" : "prelinked"));
        } 
So is clearly documented, and this was the message I was talking about today... so now I'm also sure that this messagge will not show up because two kexts must be the same (the case a secondary kext is just renamed)

 

I was aware of that message. It happens more commonly when people are mistakenly injecting kexts that they also have installed to the system volume... But that particular message will never happen with the bundle-id/bundle-name renamed (because there is no duplicate).

 

But that is not the "undocumented" part I was referring to...

 

The undocumented part (AFAIK), is the fact that when kextcache encounters duplicate kexts, it will place the one with the larger version# in the kernel cache. The documentation Apple provides on kernel development implies the behavior is not deterministic. Note: I haven't searched for source to kextcache, and it has been a while since I read Apple's kernel docs (and probably a longer time since they have updated them too...)

  • Like 1
Link to comment
Share on other sites

Is here:https://opensource.apple.com/source/kext_tools/kext_tools-426.60.1/kextcache_main.c

if (myKextVersion > 0 && myKextVersion > theKextVersion ) {
                // already have newer version of this kext, do not add it
                OSKextLogCFString(NULL,
                                  kOSKextLogDebugLevel | kOSKextLogArchiveFlag,
                                  CFSTR("%s: found newer, skipping %@"),
                                  __func__, theKext);
                return;
            }

Ok, it's time for me to dedicate time to other ...  go to BAR   :)

  • Like 1
Link to comment
Share on other sites

Is here:https://opensource.apple.com/source/kext_tools/kext_tools-426.60.1/kextcache_main.c

if (myKextVersion > 0 && myKextVersion > theKextVersion ) {
                // already have newer version of this kext, do not add it
                OSKextLogCFString(NULL,
                                  kOSKextLogDebugLevel | kOSKextLogArchiveFlag,
                                  CFSTR("%s: found newer, skipping %@"),
                                  __func__, theKext);
                return;
            }
Ok, it's time for me to dedicate time to other ...  go to BAR   :)

 

And it will also remove an older kext already present and replace it with a newer one when encountered.

 

           ...
            if (myKextVersion > 0 && myKextVersion == theKextVersion ) {
                // already have same version of this kext, do not add it
                OSKextLogCFString(NULL,
                                  kOSKextLogDebugLevel | kOSKextLogArchiveFlag,
                                  CFSTR("%s: found dup, skipping %@"),
                                  __func__, theKext);
                return;
            }
            if (myKextVersion > 0 && myKextVersion < theKextVersion ) {
                // found older version of this kext, remove it and add this one
                OSKextLogCFString(NULL,
                                  kOSKextLogDebugLevel | kOSKextLogArchiveFlag,
                                  CFSTR("%s: found older, removing %@"),
                                  __func__, myKext);
                CFArrayRemoveValueAtIndex(theArray, i);
                break;
            }
Note that two kexts named the same, different, but with same version, the first one encountered will be kept... no additional checks for file timestamps/etc, which means it is rather non-deterministic.

 

But of course, as far as "documentation" I was referring to written documentation in the kernel developers guide that guarantees the behavior now and in the future.

 

Enjoy the beer!

  • Like 1
Link to comment
Share on other sites

Sorry to break the mood but with the 3 versions of NVMeP 2.3, A, test and B, the generated IONVMEFamilyBorg.kext result in a KP at boot (install in S/L/E or in EFI/CLOVER/kexts/Other).

For info, patch from Piker-Alpha blog works great with Clover KextsToPatch.

 

What I am doing wrong ?

 

System : Sierra GM (16A319), Gigabyte Z170MX-Gaming 5, Samsung 950 Pro

Link to comment
Share on other sites

Sorry to break the mood but with the 3 versions of NVMeP 2.3, A, test and B, the generated IONVMEFamilyBorg.kext result in a KP at boot (install in S/L/E or in EFI/CLOVER/kexts/Other).

For info, patch from Piker-Alpha blog works great with Clover KextsToPatch.

 

What I am doing wrong ?

 

System : Sierra GM (16A319), Gigabyte Z170MX-Gaming 5, Samsung 950 Pro

can you attached pic of kP?

Link to comment
Share on other sites

Oups, you're right. It was not the good config.plist and it won't load the ACPI patch... (and I don't boot on USB stick ;))

 

So now, with the good one, it KP :/

https://www.dropbox.com/s/e1k3yw1mk6blv9m/IMG_7023.MOV?dl=0

 

I put the kext in /EFI/CLOVER/kexts/other and remove the patch from the plist, that's right ?

Link to comment
Share on other sites

 Share

×
×
  • Create New...