Post

Replies

Boosts

Views

Activity

Reply to DriverKit IOUserSerial Driver
Hello Quinn "The Eskimo!" ;) thank you for you response. Okay, I'm inside the DEXT 'kernel' space. You suggestion is my doing. Let us restart to my first question context. My question is, how can I obtain the data in the method IOUserSerial::TxAvailable which has been called by the OS even if the user client app send data like: echo 'Welcome' > /dev/cu.serial-100000A5E ?? Second question ist, can I write you an email too? [ WHERE THE DATA 'Welcome' ? ] ------------------------ 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: TxDataAvailable called. 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: TxDataAvailable: Dump m_txqmd ------------- 2025-02-05 08:33:00.866 Df kernel[0:e27] (IOUserSerial) IOUserSerial::handleEventFlowControl: 1042 ==>0 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory called. md=0x600002c58d48 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory: CreateMapping. 2025-02-05 08:33:00.866 Df kernel[0:e27] (IOUserSerial) IOUserSerial::hwSendBreak: 1083 <== 2025-02-05 08:33:00.866 Df kernel[0:e27] (IOUserSerial) IOUserSerial::hwSendBreak: 1083 locklevel = 1 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory: GetAddress + GetLength. 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory: dump mapped buffer 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff=0x1025c8000 mapSize=16384 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[0]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[1]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[2]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[3]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[4]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[5]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[6]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[7]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[8]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[9]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[10]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[11]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[12]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[13]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[14]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: CopyMemory MAP> mapBuff[15]=0x00 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: TxFreeSpaceAvailable called. 2025-02-05 08:33:00.866 Df kernel[0:9d4f] () [VSPSerialPort]: RxDataAvailable called. [ SNIPPET : END ] --------------------------------------- This is the source of the CopyMemory method which is called from IOUserSerial::TxDataAvailable implementation in my driver extension: // -------------------------------------------------------------------- // CopyMemory_Impl(IOMemoryDescriptor* md) // ??? Called by TxDataAvailable() and here we get always 0x00 in MD // ??? mapped buffer of the IOMemoryDescriptors m_txqmd // IOReturn IMPL(VSPSerialPort, CopyMemory) { IOMemoryMap* map = nullptr; IOReturn ret; VSPLog(LOG_PREFIX, "CopyMemory called. md=0x%llx\n", (uint64_t)md); if (md == nullptr) { VSPLog(LOG_PREFIX, "copy_md_memory: Invalid memory descriptor (nullptr).\n"); return kIOReturnBadArgument; } VSPLog(LOG_PREFIX, "CopyMemory: CreateMapping.\n"); // Access memory of TX IOMemoryDescriptor uint64_t mapFlags = kIOMemoryMapGuardedDefault | kIOMemoryMapCacheModeDefault | kIOMemoryMapReadOnly; ret = md->CreateMapping(mapFlags, 0, 0, 0, 0, &map); if (ret != kIOReturnSuccess) { VSPLog(LOG_PREFIX, "copy_md_memory: Failed to get memory map. code=%d\n", ret); return ret; } VSPLog(LOG_PREFIX, "CopyMemory: GetAddress + GetLength.\n"); // get mapped data... const uint64_t mapSize = map->GetLength(); const uint8_t* mapBuff = (uint8_t*)(map->GetAddress()); VSPLog(LOG_PREFIX, "CopyMemory: dump mapped buffer\n"); VSPLog(LOG_PREFIX, "CopyMemory MAP> mapBuff=0x%llx mapSize=%llu\n", (uint64_t) mapBuff, mapSize); // !! Debug .... for (uint64_t i = 0; i < mapSize && i < 16; i++) { VSPLog(LOG_PREFIX, "CopyMemory MAP> mapBuff[%lld]=0x%02x %c\n", i, mapBuff[i], mapBuff[i]); } OSSafeReleaseNULL(map); return kIOReturnSuccess; } Best Regards.
Topic: App & System Services SubTopic: Core OS Tags:
Feb ’25
Reply to DriverKit IOUserSerial Driver
Hello DTS Engineer, Yes, you're right, it's confusing. I forgot to mention the purpose of the extension. Sorry. The purpose of the extension is to: Use the DEXT to create nodes in '/dev' for serial ports (/dev/(tty&cu)-serail-xxxx. A user application (UI) should control the creation and linking of the serial ports. A measurement and control simulation (UI) should use the serial ports to simulate measurement and control devices 'at device level', while a second application uses the serial ports as a 'normal' interface to use the simulated measurement and control devices with different protocols . Final goal: It should be used to check whether the entire communication path works in a software framework. In order to route the data from the user application (3) to the user application (4) and vice versa, I need to know exactly: How do I get the data from the IOMemoryDescriptor in the IOUserSerial instance? What is the mechanism for reading the incoming data reported by TxAvailable?
Topic: App & System Services SubTopic: Core OS Tags:
Feb ’25
Reply to DriverKit IOUserSerial Driver
Here my methods: Called from Start()... IOReturn VSPDriverPrivate::ConnectDriverQueues() { IOReturn ret; ret = m_driver->ConnectQueues(&m_itBuffer, &m_rxBuffer, &m_txBuffer, nullptr, nullptr, 0, 0, 8, 8); if (ret != kIOReturnSuccess) { VSPLog(LOG_PREFIX, "ConnectQueues failed to allocate IF/RX/TX buffers.\n"); return ret; } if (m_itBuffer == nullptr) { VSPLog(LOG_PREFIX, "Invalid interrupt buffer detected.\n"); ret = kIOReturnInvalid; return ret; } if (m_rxBuffer == nullptr) { VSPLog(LOG_PREFIX, "Invalid RX buffer detected.\n"); return kIOReturnInvalid; } if (m_txBuffer == nullptr) { VSPLog(LOG_PREFIX, "Invalid TX buffer detected.\n"); return kIOReturnInvalid; } return kIOReturnSuccess; } Inside TxDataAvailable() IOReturn VSPDriverPrivate::TxDataAvailable() { IOReturn ret = kIOReturnSuccess; IOMemoryMap* map = nullptr; VSPLog(LOG_PREFIX, "TxDataAvailable called.\n"); if (m_txBuffer == nullptr) { return kIOReturnBadArgument; } // Access memory of RX IOMemoryDescriptor ret = m_txBuffer->CreateMapping(kIOMemoryMapReadOnly, 0, 0, 0, 0, &map); if (ret != kIOReturnSuccess) { VSPLog(LOG_PREFIX, "TxDataAvailable: Failed to get memory map. code=%d\n", ret); return ret; } // Send data to ... const char* buffer = reinterpret_cast<char*>(map->GetAddress()); const uint64_t size = map->GetLength(); VSPLog(LOG_PREFIX, "TxDataAvailable: address=0x%llx length=%llu\n", (uint64_t) buffer, size); VSPLog(LOG_PREFIX, "TxDataAvailable: debug TX buffer\n"); // !! Debug .... for (uint64_t i = 0; i < size && i < 16; i++) { VSPLog(LOG_PREFIX, "TxDataAvailable: TX> 0x%02x %c\n", buffer[i], buffer[i]); } // copy data to send into tx FIFO buffer memcpy(m_fifo.tx.buffer, buffer, (size < m_fifo.tx.size ? size : m_fifo.tx.size)); // !! cleanup OSSafeReleaseNULL(map); return kIOReturnSuccess;
Topic: App & System Services SubTopic: Core OS Tags:
Feb ’25