Xcode 1300, Xcode 1304, Xcode 1321
#include <os/log.h>
#include <time.h>
#include <DriverKit/DriverKit.h>
#include <DriverKit/IOUserServer.h>
#include <DriverKit/IOLib.h>
#include <DriverKit/IOKitKeys.h>
#include <DriverKit/storage/IOStorageProtocolCharacteristics.h>
#include <DriverKit/storage/IOStorageDeviceCharacteristics.h>
#include <PCIDriverKit/IOPCIDevice.h>
#include <PCIDriverKit/IOPCIFamilyDefinitions.h>
#include <SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController.h>
#include <SCSIControllerDriverKit/IOSCSIParallelControllerCharacteristics.h>
Post
Replies
Boosts
Views
Activity
I found out that the cause of the kernel panic is from my code "OSSafeReleaseNULL(ivars->pciDevice);"
But after removing it, the system is still not as expected.
After a hot unplug, the Thunderbolt cable was plugged in again and the PCIe Device Controller never came back.
My DEXT user space driver is never loaded again. Only reboot the system once.
Your dext driver needs to create two iigs, one for your user space driver and one for your iouserclient.
Your user space driver can be written like this. . . .
kern_return_t IMPL( MyUserSpaceDriver, NewUserClient )
{
if(ivars->MyIoUserClient==NULL)
{
IOService *client = nullptr;
if(IOService::Create(this /* provider */, "MyIOUserClientProperty" /* IOPropertyName */, &client)!=kIOReturnSuccess)
{
return (kIOReturnError);
}
ivars->MyIoUserClient = (MyIOUserClient *) OSDynamicCast(IOUserClient, client);
if(ivars->MyIoUserClient==NULL)
{
client->release();
return kIOReturnError;
}
}
*userClient = ivars->MyIoUserClient;
return (kIOReturnSuccess);
}
kern_return_t IMPL( MyUserSpaceDriver, Start )
{
........
if(ivars->MyIoUserClient==NULL)
{
IOService *client = nullptr;
if(IOService::Create(this /* provider */, "MyIOUserClientProperty" /* IOPropertyName */, &client)!=kIOReturnSuccess)
{
goto start_fail;
}
ivars->MyIoUserClient = (MyIOUserClient *) OSDynamicCast(IOUserClient, client);
if(ivars->MyIoUserClient==NULL)
{
client->release();
goto start_fail;
}
ivars->MyIoUserClient->Start(this);
}
.....
}
If it is simply the Class used by the user space driver, it can be called in the form of namespace.
namespace
{
class RingBuffer
{
public:
void init(int desiredSize)
{
size=desiredSize + 1;
data=(char *)IOMalloc(size);
head=0;
tail=0;
return;
}
void deinit(void)
{
if(data != NULL)
{
IOFree(data, size);
data=NULL;
}
return;
}
private:
int head, tail, size;
char *data;
}
}
The dext user space driver I wrote has loaded and got my SCSI controller working. Although there are still some imperfections, on the whole, such a new development environment really requires some patience to adapt.
I got the same error in Xcode 14
"Xcode 14 and later requires a DriverKit development profile enabled for iOS and macOS. Visit the developer website to create or download a DriverKit profile."
Must be a bug in Xcode14 Beta 3, the old DriverKit profile is recognized in Xcode 13 but not in Xcode 14.
Hi, Drewbadour
You said "XCode14 DriverKit profiles have changed to support DriverKit on iPadOS"
Causes the "provisioning profiles" we used in XCode13 to produce "Platform: maOS" in Xcode14
"Doesn't match platform DriverKit" and cannot be used.
So does Apple know about this problem and how to fix it?
I tried make a new Distribution DriverKit provisioning profiles for Xcode 14, but failed.
If Asix, or anyone else, has found a solution to this problem, I hope to respond, thank you!
uint16_t scsi_id = (uint16_t)parallelTask.fTargetID;/*uint64_t */
uint16_t scsi_lun = (uint16_t)parallelTask.fLogicalUnitBytes[1];/*uint8_t */
I got the same error in my thunderbolt SCSI controller project.
I've reported this bug to Apple for a long time, but haven't gotten any response until now.
/*
**********************************************************************************
** create a memory descriptor and map its address
**********************************************************************************
*/
kern_return_t arcsas_userclient_create_memory_descriptor_and_map_address(const void* address, size_t length, IOMemoryDescriptor** memory_descriptor)
{
IOBufferMemoryDescriptor *buffer_memory_descriptor = nullptr;
uint64_t buffer_address;
uint64_t len;
#if ARCSAS_DEBUG_IO_USER_CLIENT
arcsas_debug_print("ArcSASIOUserClient: *******************************************************\n");
arcsas_debug_print("ArcSASIOUserClient: ** IOUserClient IOMemoryDescriptor create_with_bytes \n");
arcsas_debug_print("ArcSASIOUserClient: *******************************************************\n");
#endif
if (!address || !memory_descriptor)
{
return kIOReturnBadArgument;
}
if (IOBufferMemoryDescriptor::Create(kIOMemoryDirectionInOut, length, 0, &buffer_memory_descriptor) != kIOReturnSuccess)
{
if (buffer_memory_descriptor)
{
OSSafeReleaseNULL(buffer_memory_descriptor);
}
return kIOReturnError;
}
if (buffer_memory_descriptor->Map(0, 0, 0, 0, &buffer_address, &len) != kIOReturnSuccess)
{
if (buffer_memory_descriptor)
{
OSSafeReleaseNULL(buffer_memory_descriptor);
}
return kIOReturnError;
}
if (length != len)
{
if (buffer_memory_descriptor)
{
OSSafeReleaseNULL(buffer_memory_descriptor);
}
return kIOReturnNoMemory;
}
memcpy(reinterpret_cast<void*>(buffer_address), address, length);
*memory_descriptor = buffer_memory_descriptor;
return kIOReturnSuccess;
}
IODMACommandSpecification dmaSpecification;
IOAddressSegment dma_physical_address_segment = {0};
IOAddressSegment dma_virtual_address_segment;
uint64_t dma_resource_phsical, dmaFlags = kIOMemoryDirectionInOut;
uint32_t dmaSegmentCount = 1;/* for get Physical Address, we need only one large Segment */
.....
bzero(&dmaSpecification, sizeof(dmaSpecification));
dmaSpecification.options = kIODMACommandSpecificationNoOptions;
dmaSpecification.maxAddressBits = 64;
if(IODMACommand::Create(ivars->pciDevice, kIODMACommandCreateNoOptions, &dmaSpecification, &ivars->dma_resource_iodmacommand) != kIOReturnSuccess)
{
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************* \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ** pciDevice IODMACommand Create Failed \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************* \n", ivars->adapter_index);
return false;
}
if(ivars->dma_resource_iodmacommand->PrepareForDMA(kIODMACommandPrepareForDMANoOptions, ivars->dma_resource_descriptor, 0/*offset /, dma_resource_size/length/, &dmaFlags, &dmaSegmentCount, &dma_physical_address_segment) != kIOReturnSuccess)
{
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************************** \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ** IODMACommand PrepareForDMA try to get Memory Physical Address Failed \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************************** \n", ivars->adapter_index);
return false;
}
/ physical /
dma_resource_phsical = (uint64_t)dma_physical_address_segment.address;
dma_resource->Physical_Address.parts.low = (uint32_t)(dma_resource_phsical & 0xFFFFFFFF);
dma_resource->Physical_Address.parts.high = (uint32_t)(dma_resource_phsical>> 32);
/ virtual */
dma_resource->Virtual_Address = reinterpret_cast < uint8_t *> (dma_virtual_address_segment.address);
memset(dma_resource->Virtual_Address, 0, dma_resource_size);
If you try to install Xcode 14 beta, it is limited by hardware and MacOS version.
You can use Xcode 12 with MacOS Big Sur.
PCIDriverKit support PCI Device PNP is ready for Intel x86 base.
But Not yet Ready for M1 (arm64)
My project can be compiled on other operating systems
But there are some systems that have the same problem as you
I have the same problem as you
After a few experiences
I just realized that this is because
I use the same hard drive to compile my project programs back and forth between MacOS X86 / ARM64(M1)
Such behavior leads to
Exception Type: EXC_CRASH (SIGKILL (Code Signature Invalid))
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ********************************************************************** \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** 【Get system status notification service】 \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** Call this function to get system "shutdown or restart" notification \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** If our driver gets this service \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** It will cause our IMPL (ArcMSRUserSpaceDriver, Stop) \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** to be called during the system "shutdown or restart" phase \n", ivars->adapter_index);
arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ********************************************************************** \n", ivars->adapter_index);
/*
**************************************************************************************************************
**
** If your system is MacOS11.52 .
** This Function would cause IOSerrvice::ClientCrashed(IOService * client, uint64_t options);
** This Function could supported from MacOS12.03 , ready for shutdown and restart notification from MacOS12.60
**
** ===========================================================================================
** Obtain the system state notification service
**
** To Let our Stop() is called when the system shuts down or restarts.
**
** IOServiceStateNotificationDispatchSource for got "System Shutdown or Restart Notify"
**
** this function "StateNotificationItemCopy" should be call
**
** values for OSNumber kIOSystemStateHaltDescriptionKey:kIOSystemStateHaltDescriptionHaltStateKey
**
** enum
** {
** kIOServiceHaltStatePowerOff = 0x00000001,
** kIOServiceHaltStateRestart = 0x00000002,
** };
**
** virtual kern_return_t StateNotificationItemCopy(OSString * itemName, OSDictionary ** value);
**
**************************************************************************************************************
*/
if(IOService::CopySystemStateNotificationService(&ivars->ArcmsrSystemStateNotificationService) != kIOReturnSuccess)/* Register the service with the system. Obtain the system state notification service */
{
goto initialize_fail;
}