Understand the role of drivers in bridging the gap between software and hardware, ensuring smooth hardware functionality.

Drivers Documentation

Posts under Drivers subtopic

Post

Replies

Boosts

Views

Activity

Show / Hide HAL Virtual Audio Device Based on App State
I am developing a macOS virtual audio device using an Audio Server Plug-In (HAL). I want the virtual device to be visible to all applications only when my main app is running, and completely hidden from all apps when the app is closed. The goal is to dynamically control device visibility based on app state without reinstalling the driver.What is the recommended way for the app to notify the HAL plug-in about its running or closed state ? Any guidance on best-practice architecture for this scenario would be appreciated.
1
0
215
Jan ’26
How to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Hello! We develop a SAS driver and a service application for DAS devices. When users in our application create a RAID array on the device: On the 1st step, our dext driver mounts a new volume. At this step DiskUtil automatically tries to mount it. As there is no file system on the new volume - the MacOS system popup appears "The disk you attached was not readable by the computer" On the 2nd step our application creates the file system on this new volume. So we do not need this MacOS system popup to appear (as it may frustrate our users). We found a way to disable the global auto mount but this solution also impacts on other devices (which is not good). Are there any other possibilities to prevent the popup "The disk you attached was not readable by the computer" from appearing?
3
0
278
Jan ’26
DriverKit Dext fails to load with "Exec format error" (POSIX 8) on macOS 26.2 (Apple Silicon) when SIP is enabled
1. 环境描述 (Environment) OS: macOS 26.2 Hardware: Apple Silicon (M1/M2/M3) DriverKit SDK: DriverKit 19.0 / 20.0 Arch: Universal (x86_64, arm64, arm64e) SIP Status: Enabled (Works perfectly when Disabled) 2. 问题现象 (Problem Description) 在开启 SIP 的环境下,USB 驱动扩展(Dext)能安装,但插入设备时无法连接设备(驱动的Start方法未被调用)。 驱动状态: MacBook-Pro ~ % systemextensionsctl list 1 extension(s) --- com.apple.system_extension.driver_extension (Go to 'System Settings > General > Login Items & Extensions > Driver Extensions' to modify these system extension(s)) enabled active teamID bundleID (version) name [state] * * JK9U78YRLU com.ronganchina.usbapp.MyUserUSBInterfaceDriver (1.3/4) com.ronganchina.usbapp.MyUserUSBInterfaceDriver [activated enabled] 关键日志证据 (Key Logs) KernelManagerd: Error Domain=NSPOSIXErrorDomain Code=8 "Exec format error" Syspolicyd: failed to fetch ... /_CodeSignature/CodeRequirements-1 error=-10 AppleSystemPolicy: ASP: Security policy would not allow process DriverKit Kernel: DK: MyUserUSBInterfaceDriver user server timeout dext的 embedded.provisionprofile 已包含: com.apple.developer.driverkit com.apple.developer.driverkit.transport.usb (idVendor: 11977)
2
0
305
Jan ’26
Basic introduction to DEXT Matching and Loading
Note: This document is specifically focused on what happens after a DEXT has passed its initial code-signing checks. Code-signing issues are dealt with in other posts. Preliminary Guidance: Using and understanding DriverKit basically requires understanding IOKit, something which isn't entirely clear in our documentation. The good news here is that IOKit actually does have fairly good "foundational" documentation in the documentation archive. Here are a few of the documents I'd take a look at: IOKit Fundamentals IOKit Device Driver Design Guidelines Accessing Hardware From Applications Special mention to QA1075: "Making sense of IOKit error codes",, which I happened to notice today and which documents the IOReturn error format (which is a bit weird on first review). Those documents do not cover the full DEXT loading process, but they are the foundation of how all of this actually works. Understanding the IOKitPersonalities Dictionary The first thing to understand here is that the "IOKitPersonalities" is called that because it is in fact a fully valid "IOKitPersonalities" dictionary. That is, what the system actually uses that dictionary "for" is: Perform a standard IOKit match and load cycle in the kernel. The final driver in the kernel then uses the DEXT-specific data to launch and run your DEXT process outside the kernel. So, working through the critical keys in that dictionary: "IOProviderClass"-> This is the in-kernel class that your in-kernel driver loads "on top" of. The IOKit documentation and naming convention uses the term "Nub", but the naming convention is not consistent enough that it applies to all cases. "IOClass"-> This is the in-kernel class that your driver loads on top of. This is where things can become a bit confused, as some families work by: Routing all activity through the provider reference so that the DEXT-specific class does not matter (PCIDriverKit). Having the DEXT subclass a specific subclass which corresponds to a specific kernel driver (SCSIPeripheralsDriverKit). This distinction is described in the documentation, but it's easy to overlook if you don't understand what's going on. However, compare PCIDriverKit: "When the system loads your custom PCI driver, it passes an IOPCIDevice object as the provider to your driver. Use that object to read and write the configuration and memory of your PCI hardware." Versus SCSIPeripheralsDriverKit: Develop your driver by subclassing IOUserSCSIPeripheralDeviceType00 or IOUserSCSIPeripheralDeviceType05, depending on whether your device works with SCSI Block Commands (SBC) or SCSI Multimedia Commands (SMC), respectively. In your subclass, override all methods the framework declares as pure virtual. The reason these differences exist actually comes from the relationship and interactions between the DEXT families. Case in point, PCIDriverKit doesn't require a specific subclass because it wants SCSIControllerDriverKit DEXTs to be able to directly load "above" it. Note that the common mistake many developers make is leaving "IOUserService" in place when they should have specified a family-specific subclass (case 2 above). This is an undocumented implementation detail, but if there is a mismatch between your DEXT driver ("IOUserSCSIPeripheralDeviceType00") and your kernel driver ("IOUserService"), you end up trying to call unimplemented kernel methods. When a method is "missing" like that, the codegen system ends up handling that by returning kIOReturnUnsupported. One special case here is the "IOUserResources" provider. This class is the DEXT equivalent of "IOResources" in the kernel. In both cases, these classes exist as an attachment point for objects which don't otherwise have a provider. It's specifically used by the sample "Communicating between a DriverKit extension and a client app" to allow that sample to load on all hardware but is not something the vast majority of DEXT will use. Following on from that point, most DEXT should NOT include "IOMatchCategory". Quoting IOKit fundamentals: "Important: Any driver that declares IOResources as the value of its IOProviderClass key must also include in its personality the IOMatchCategory key and a private match category value. This prevents the driver from matching exclusively on the IOResources nub and thereby preventing other drivers from matching on it. It also prevents the driver from having to compete with all other drivers that need to match on IOResources. The value of the IOMatchCategory property should be identical to the value of the driver's IOClass property, which is the driver’s class name in reverse-DNS notation with underbars instead of dots, such as com_MyCompany_driver_MyDriver." The critical point here is that including IOMatchCategory does this: "This prevents the driver from matching exclusively on the IOResources nub and thereby preventing other drivers from matching on it." The problem here is that this is actually the exceptional case. For a typical DEXT, including IOMatchCategory means that a system driver will load "beside" their DEXT, then open the provider blocking DEXT access and breaking the DEXT. DEXT Launching The key point here is that the entire process above is the standard IOKit loading process used by all KEXT. Once that process finishes, what actually happens next is the DEXT-specific part of this process: IOUserServerName-> This key is the bundle ID of your DEXT, which the system uses to find your DEXT target. IOUserClass-> This is the name of the class the system instantiates after launching your DEXT. Note that this directly mimics how IOKit loading works. Keep in mind that the second, DEXT-specific, half of this process is the first point your actual code becomes relevant. Any issue before that point will ONLY be visible through kernel logging or possibly the IORegistry. __ Kevin Elliott DTS Engineer, CoreOS/Hardware
1
0
276
2w
Missing "Dolby Vision Profile" Option in Deliver Page - DaVinci Resolve 20 on iPadOS 26
Dear Support Team, ​I am writing to seek technical assistance regarding a persistent issue with Dolby Vision exporting in DaVinci Resolve 20 on my iPad Pro 12.9-inch (2021, M1 chip) running iPadOS 26.0.1. ​The Issue: Despite correctly configuring the project for a Dolby Vision workflow and successfully completing the dynamic metadata analysis, the "Dolby Vision Profile" dropdown menu (and related embedding options) is completely missing from the Advanced Settings in the Deliver page. ​My Current Configuration & Steps Taken: ​Software Version: DaVinci Resolve Studio 20 (Studio features like Dolby Vision analysis are active and functional). ​Project Settings: Color Science: DaVinci YRGB Color Managed. ​Dolby Vision: Enabled (Version 4.0) with Mastering Display set to 1000 nits. ​Output Color Space: Rec.2100 ST2084. ​Color Page: Dynamic metadata analysis has been performed, and "Trim" controls are functional. ​Export Settings: ​Format: QuickTime / MP4. ​Codec: H.265 (HEVC). ​Encoding Profile: Main 10. ​The Problem: Under "Advanced Settings," there is no option to select a Dolby Vision Profile (e.g., Profile 8.4) or to "Embed Dolby Vision Metadata." ​Potential Variables: ​System Version: I am currently running iPadOS 26. ​Apple ID: My iPad is currently not logged into an Apple ID. I suspect this might be preventing the app from accessing certain system-level AVFoundation frameworks or Dolby DRM/licensing certificates required for metadata embedding. ​Could you please clarify if the "Dolby Vision Profile" option is dependent on a signed-in Apple ID for hardware-level encoding authorization, or if this is a known compatibility issue with the current iPadOS 26 build? ​I look forward to your guidance on how to resolve this. ​Best regards, INSOFT_Fred
0
0
173
Feb ’26
iOS printing – Finishing (Punch) options not applied for images unless a preset is selected
When printing image/photo files via AirPrint, selected finishing options (e.g., Punch) are not applied unless a preset is chosen. reproduction steps: Select an image on iOS Tap Print → choose printer/server Set Finishing Options → Punch Print Observed: Finishing options not applied IPP trace shows no finisher attributes in the request working scenario: Select any Preset (e.g., Color) before printing Finishing options are then included in IPP and applied Note: Issue does not occur when printing PDFs from iOS; finisher attributes are sent correctly. Is this expected AirPrint behavior for image jobs, or could this be a bug in how iOS constructs the IPP request for photos?
3
0
159
4d
macOS 26.4 Beta breaks keyboard remapping for built-in MacBook keyboards – significant ecosystem impact
Since macOS 26.4 Beta 1, virtual HID devices created via DriverKit can no longer intercept key events from the built-in MacBook keyboard. External keyboards still work. This is confirmed and tracked here: https://github.com/pqrs-org/Karabiner-Elements/issues/4402 One possible lead (from LLM-assisted analysis of Apple's open-source IOHIDFamily code and cross-referencing community reports): macOS 26.4 Beta may have introduced or modified a security policy referred to as com.apple.iohid.protectedDeviceAccess, which could block IOHIDDeviceOpen for the Apple Internal Keyboard connected via SPI transport (AppleHIDTransportHIDDevice). This appears related to a "GamePolicy" check in IOHIDDeviceClass.m that gates whether processes can open HID devices. This has not been independently verified and may or may not be the root cause. This has far-reaching consequences. Karabiner-Elements alone has over 21,000 GitHub stars and is used by hundreds of thousands of macOS users for keyboard customization, accessibility workflows, ergonomic setups, and multilingual input. This change completely breaks its core functionality on any MacBook. Beyond Karabiner, this affects every developer building keyboard remapping, input customization, or accessibility tooling via DriverKit virtual HID devices — including commercial applications currently in development. I'd argue that the power and flexibility of keyboard customization on macOS is a genuine competitive advantage for the platform. Developers and power users choose Macs partly because tools like this exist. Restricting this capability would be detrimental to the ecosystem and to Apple's appeal among professional users. I'd like to understand: is this an intentional security change or a regression? If intentional, is there a migration path?
1
0
124
2w
Can't get USBSerialDriverKit driver loaded
I am writing a DriverKit driver for the first that uses the USBSerialDriverKit. The driver its purpose is to expose the device as serial interface (/dev/cu.tetra-pei0 or something like this). My problem: I don't see any logs from that driver in the console and I tried like 40 different approaches and checked everything. The last message I see is that the driver get successfully added to the system it is in the list of active and enabled system driver extensions but when I plug the device in none of my logs appear and it doesn't show up in ioreg. So without my driver the target device looks like this: +-o TETRA PEI interface@02120000 <class IOUSBHostDevice, id 0x10000297d, registered, matched, active, busy 0 (13 ms), retain 30> | { | "sessionID" = 268696051410 | "USBSpeed" = 3 | "UsbLinkSpeed" = 480000000 | "idProduct" = 36886 | "iManufacturer" = 1 | "bDeviceClass" = 0 | "IOPowerManagement" = {"PowerOverrideOn"=Yes,"DevicePowerState"=2,"CurrentPowerState"=2,"CapabilityFlags"=32768,"MaxPowerState"=2,"DriverPowerState"=0} | "bcdDevice" = 9238 | "bMaxPacketSize0" = 64 | "iProduct" = 2 | "iSerialNumber" = 0 | "bNumConfigurations" = 1 | "UsbDeviceSignature" = <ad0c16901624000000ff0000> | "USB Product Name" = "TETRA PEI interface" | "locationID" = 34734080 | "bDeviceSubClass" = 0 | "bcdUSB" = 512 | "USB Address" = 6 | "kUSBCurrentConfiguration" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "UsbPowerSinkAllocation" = 500 | "bDeviceProtocol" = 0 | "USBPortType" = 0 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "USB Vendor Name" = "Motorola Solutions, Inc." | "Device Speed" = 2 | "idVendor" = 3245 | "kUSBProductString" = "TETRA PEI interface" | "kUSBAddress" = 6 | "kUSBVendorString" = "Motorola Solutions, Inc." | } | +-o AppleUSBHostCompositeDevice <class AppleUSBHostCompositeDevice, id 0x100002982, !registered, !matched, active, busy 0, retain 5> | { | "IOProbeScore" = 50000 | "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOProviderClass" = "IOUSBHostDevice" | "IOClass" = "AppleUSBHostCompositeDevice" | "IOPersonalityPublisher" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "bDeviceSubClass" = 0 | "CFBundleIdentifierKernel" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOMatchedAtBoot" = Yes | "IOMatchCategory" = "IODefaultMatchCategory" | "IOPrimaryDriverTerminateOptions" = Yes | "bDeviceClass" = 0 | } | +-o lghub_agent <class AppleUSBHostDeviceUserClient, id 0x100002983, !registered, !matched, active, busy 0, retain 7> | { | "IOUserClientCreator" = "pid 1438, lghub_agent" | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@0 <class IOUSBHostInterface, id 0x100002986, registered, matched, active, busy 0 (5 ms), retain 9> | | { | | "USBPortType" = 0 | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | "USB Vendor Name" = "Motorola Solutions, Inc." | | "bcdDevice" = 9238 | | "USBSpeed" = 3 | | "idProduct" = 36886 | | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | | "bInterfaceSubClass" = 0 | | "bConfigurationValue" = 1 | | "locationID" = 34734080 | | "USB Product Name" = "TETRA PEI interface" | | "bInterfaceProtocol" = 0 | | "iInterface" = 0 | | "bAlternateSetting" = 0 | | "idVendor" = 3245 | | "bInterfaceNumber" = 0 | | "bInterfaceClass" = 255 | | "bNumEndpoints" = 2 | | } | | | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x100002988, !registered, !matched, active, busy 0, retain 6> | { | "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} | "IOUserClientCreator" = "pid 1438, lghub_agent" | "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@1 <class IOUSBHostInterface, id 0x100002987, registered, matched, active, busy 0 (5 ms), retain 9> | { | "USBPortType" = 0 | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "USB Vendor Name" = "Motorola Solutions, Inc." | "bcdDevice" = 9238 | "USBSpeed" = 3 | "idProduct" = 36886 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "bInterfaceSubClass" = 0 | "bConfigurationValue" = 1 | "locationID" = 34734080 | "USB Product Name" = "TETRA PEI interface" | "bInterfaceProtocol" = 0 | "iInterface" = 0 | "bAlternateSetting" = 0 | "idVendor" = 3245 | "bInterfaceNumber" = 1 | "bInterfaceClass" = 255 | "bNumEndpoints" = 2 | } | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x10000298a, !registered, !matched, active, busy 0, retain 6> { "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} "IOUserClientCreator" = "pid 1438, lghub_agent" "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} "IOUserClientDefaultLocking" = Yes } more details in my comment.
6
0
173
2w
Kernel Panic: Power state transition (0 -> 2) timeout during DriverKit (DEXT) load sequence (IOUserSCSIParallelInterfaceController)
Hi Everyone, We are currently migrating a mature legacy KEXT to DriverKit for our PCIe SCSI storage controller (connected via Thunderbolt 3). During the DEXT load sequence, we have observed that the system automatically triggers a power state transition from State 0 (Off) to State 2 (On). However, this process results in a Kernel Panic due to a timeout after approximately 21 seconds. We have verified that our implementation of Start_Impl, UserInitializeController_Impl, and SetPowerState_Impl executes extremely fast, with a total execution time of less than one second. Specifically, SetPowerState_Impl returns kIOReturnSuccess immediately upon being called. Furthermore, our current Info.plist does not contain any IOPowerManagement dictionary or related keys. Despite the fast execution and the absence of explicit power management declarations in the plist, the kernel power management state machine (IOServicePM) still generates a 21-second timeout, leading to the following panic: Panic Log: panic(cpu 7 caller 0xfffffe0020be8fec): MySCSIDriver::setPowerState(0xfffffe2fb1a65c00 : 0xfffffe0020bfed88, 0 -> 2) timed out after 21257 ms @IOServicePM.cpp:5609 com.example.driver.dext: ( id: com.example.driver.dext; path: /Library/SystemExtensions/[UUID]/com.example.driver.dext; state: loaded ) Note on Previous Discussion: I would like to express my gratitude to Kevin from Apple DTS for the helpful discussion regarding the implementation of BundleParallelTask on the forums. Since then, we have shifted our development focus toward completing the overall management ecosystem, delivering a comprehensive operational interface for users, and handling specific user environments and behaviors. Our current priority is ensuring system stability—specifically resolving these Thunderbolt-related power management issues (sleep/wake)—to prepare the product for upcoming testing. I remain very grateful for the guidance provided on batch task optimization and intend to resume those optimizations once this critical stability baseline is secured. Technical Guidance Needed for PM Migration In our legacy KEXT, we utilized PMinit(), registerPowerDriver(), and joinPMtree() to precisely control the timing of power management registration. In transitioning to the DriverKit SDK, we have not found clear guidance on several key points: Standardized Migration Path: What is the recommended way to implement equivalent power management initialization (formerly PMinit) within a DriverKit subclass? In DriverKit, how should we replicate the behavior of manually calling registerPowerDriver and joinPMtree to ensure the driver is only monitored once the hardware is ready? Implicit Power Registration: Why does the system enforce a setPowerState(0 -> 2) transition on a subclass of IOUserSCSIParallelInterfaceController even when no IOPowerManagement dictionary is defined in the Info.plist? Is this a default behavior of the SCSI or PCI transport framework? Thunderbolt Specifics: Are there specific power proxying requirements or configurations for PCIe devices over Thunderbolt to avoid conflicts with the default IOPCIFamily power policies? Best Regards, Charles
1
0
77
1w
DriverKit Entitlement Model Has No Viable Path for Open Source and Community-Maintained Drivers
While I welcome the arrival of a userspace implementation of drivers, DriverKit as it stands has some notable flaws. My main concern is the ability of open-source projects like HoRNDIS being able to access paid developer accounts and the limited entitlement scope (plus the waiting period) for what is essentially a hobbyist free project. Even if the developer is a professional company, some legacy hardware will go unsupported because of a lack of support from the vendor. Providing a way for users who need access to older hardware would be needed. Three concrete requests: A class-level or wildcard VID/PID entitlement for open source projects with a verifiable public repository A free or reduced-cost entitlement path for non-commercial volunteer-maintained drivers Published approval criteria and timelines so projects can plan accordingly Depreciating kexts without providing an accessible successor for community projects isn't security, it is gatekeeping access to hardware that is critically needed. Is this use case on the roadmap at all? Developers deserve a clear answer.
1
0
44
2d
iOS AirPrint sends print-quality=high when file-type is photo even if user selects “normal”
Hi everyone, I observed a behavior with AirPrint from an iPhone and wanted to confirm if this is expected behavior from iOS. Scenario tested: File type: Photo Print-quality selected by the user: Normal Observation (from packet capture): When checking the PCAP for the request sent from the iPhone, the print-quality attribute is always sent as high, even though the user selected Normal in the UI. Question: Is this an expected behavior in iOS/AirPrint where photos are always sent with print-quality=high regardless of the user-selected print quality? Or could this be a bug?
0
0
17
5d
Why don't my os_log entries show up until the second time my driver loads?
I'm in the process of writing a DriverKit USBHostInterface driver, and while I'm finally starting to get there, I've run into a bit of a frustration with logging. Naturally I have a liberal amount of os_log calls that I'm using to troubleshoot my driver. However I've noticed that they don't show up until after the first time my driver has loaded. Meaning, for example, suppose I make a new build of my driver and it's bundled user-mode app, install the bundle to /Applications, run the installer, verify it took with systemextensionsctl list, fire up Console and start streaming log entries, then plug in my device. I can see the log entries that show that my driver is loaded, etc., then a bunch of kernel -> log entries, but none of my Start method log entries. If I unplug my device and plug it in again, my log entries show up as expected. Why is this and, more importantly, how can I fix it? I'd like to see those log entries the first time the driver loads, if I could.
0
0
16
1d
How to Symbolicate an Apple Silicon Panic?
Investigating a kernel panic, I discovered that Apple Silicon Panic traces are not working with how I know to symbolicate the panic information. I have not found proper documentation that corrects this situation. Attached file is an indentity-removed panic, received from causing an intentional panic (dereferencing nullptr), so that I know what functions to expect in the call stack. This is cut-and-pasted from the "Report To Apple" dialog that appears after the reboot: panic_1_4_21_b.txt To start, I download and install the matching KDK (in this case KDK_14.6.1_23G93.kdk), identified from this line: OS version: 23G93 Kernel version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8122 Then start lldb from Terminal, using this command: bash_prompt % lldb -arch arm64e /Library/Developer/KDKs/KDK_14.6.1_23G93.kdk/System/Library/Kernels/kernel.release.t8122 Next I load the remaining scripts per the instructions from lldb: (lldb) settings set target.load-script-from-symbol-file true I need to know what address to load my kext symbols to, which I read from this line of the panic log, after the @ symbol: com.company.product(1.4.21d119)[92BABD94-80A4-3F6D-857A-3240E4DA8009]@0xfffffe001203bfd0->0xfffffe00120533ab I am using a debug build of my kext, so the DWARF symbols are part of the binary. I use this line to load the symbols into the lldb session: (lldb) addkext -F /Library/Extensions/KextName.kext/Contents/MacOS/KextName 0xfffffe001203bfd0 And now I should be able to use lldb image lookup to identify pointers on the stack that land within my kext. For example, the current PC at the moment of the crash lands within the kext (expected, because it was intentional): (lldb) image lookup -a 0xfffffe001203fe10 Which gives the following incorrect result: Address: KextName[0x0000000000003e40] (KextName.__TEXT.__cstring + 14456) Summary: "ffer has %d retains\n" That's not even a program instruction - that's within a cstring. No, that cstring isn't involved in anything pertaining to the intentional panic I am expecting to see. Can someone please explain what I'm doing wrong and provide instructions that will give symbol information from a panic trace on an Apple Silicon Mac? Disclaimers: Yes I know IOPCIFamily is deprecated, I am in process of transitioning to DriverKit Dext from IOKit kext. Until then I must maintain the kext. Terminal command "atos" provides similar incorrect results, and seems to not work with debug-built-binaries (only dSYM files) Yes this is an intentional panic so that I can verify the symbolicate process before I move on to investigating an unexpected panic I have set nvram boot-args to include keepsyms=1 I have tried (lldb) command script import lldb.macosx but get a result of error: no images in crash log (after the nvram settings)
5
0
1.9k
Apr ’25
Peripheral Devices control on macOS
We are looking for a solution (API, Frameworks) that would allow us to block any type of external device, including storage devices, HIDs, network adapters, and Bluetooth devices according with dynamic rules that comes from management server . This feature is important for endpoint security solutions vendors, and it can be implemented on other platforms and older versions of macOS using the IOKit framework and kexts. I have found one solution that can control the usage only of "storage" devices with the EndpointSecurity framework in conjunction with the DiskArbitration framework. This involves monitoring the MOUNT and OPEN events for /dev/disk files, checking for devices as they appear, and ejecting them if they need to be blocked.. Also, I have found the ES_EVENT_TYPE_AUTH_IOKIT_OPEN event in EndpointSecurity.framework, but it doesn't seem to be useful, at least not for my purposes, because ES doesn't provide AUTH events for some system daemons, such as configd (it only provides NOTIFY events). Furthermore, there are other ways to communicate with devices and their drivers apart from IOKit. DriverKit.framework does not provide the necessary functionality either, as it requires specific entitlements that are only available to certain vendors and devices. Therefore, it cannot be used to create universal drivers for all devices, which should be blocked. Any advice would be greatly appreciated!
2
0
745
Jun ’25
DriverKit - IOUSBHostDevice::SetProperties
I am trying to add a few properties to an IOUSBHostDevice but the SetProperties is returning kIOReturnUnsupported. The reason I am trying to modify the IOUSBHostDevice's properties is so we can support a MacBook Air SuperDrive when it is attached to our docking station devices. The MacBook Air SuperDrive needs a high powered port to run and this driver will help the OS realize that our dock can support it. I see that the documentation for SetProperties says: The default implementation of this method returns kIOReturnUnsupported. You can override this method and use it to modify the set of properties and values as needed. The changes you make apply only to the current service. Do I need to override IOUSBHostDevice? This is my current Start implementation (you can also see if in the Xcode project): kern_return_t IMPL(MyUserUSBHostDriver, Start) { kern_return_t ret = kIOReturnSuccess; OSDictionary * prop = NULL; OSDictionary * mergeProperties = NULL; bool success = true; os_log(OS_LOG_DEFAULT, "&gt; %s", __FUNCTION__); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = Start(provider, SUPERDISPATCH); __Require(kIOReturnSuccess == ret, Exit); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ivars-&gt;host = OSDynamicCast(IOUSBHostDevice, provider); __Require_Action(NULL != ivars-&gt;host, Exit, ret = kIOReturnNoDevice); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = ivars-&gt;host-&gt;Open(this, 0, 0); __Require(kIOReturnSuccess == ret, Exit); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = CopyProperties(&amp;prop); __Require(kIOReturnSuccess == ret, Exit); __Require_Action(NULL != prop, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); mergeProperties = OSDynamicCast(OSDictionary, prop-&gt;getObject("IOProviderMergeProperties")); mergeProperties-&gt;retain(); __Require_Action(NULL != mergeProperties, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); OSSafeReleaseNULL(prop); ret = ivars-&gt;host-&gt;CopyProperties(&amp;prop); __Require(kIOReturnSuccess == ret, Exit); __Require_Action(NULL != prop, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); os_log(OS_LOG_DEFAULT, "%s : %s", "USB Product Name", ((OSString *) prop-&gt;getObject("USB Product Name"))-&gt;getCStringNoCopy()); os_log(OS_LOG_DEFAULT, "%s : %s", "USB Vendor Name", ((OSString *) prop-&gt;getObject("USB Vendor Name"))-&gt;getCStringNoCopy()); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); success = prop-&gt;merge(mergeProperties); __Require_Action(success, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = ivars-&gt;host-&gt;SetProperties(prop); // this is no working __Require(kIOReturnSuccess == ret, Exit); Exit: OSSafeReleaseNULL(mergeProperties); OSSafeReleaseNULL(prop); os_log(OS_LOG_DEFAULT, "err ref %d", kIOReturnUnsupported); os_log(OS_LOG_DEFAULT, "&lt; %s %d", __FUNCTION__, ret); return ret; }
2
0
1.3k
Jan ’26
How to implement mouse (pointing) acceleration function in DriverKit?
Hello every one good day :) My project uses a mouse driver handling all events from the mouse produced by our company. In the past the driver is a kext, which implement acceleration by HIDPointerAccelerationTable, we prepare data in the driver's info.plist, while our app specifies a value to IOHIDSystem with key kIOHIDPointerAccelerationKey, the driver will call copyAccelerationTable() to lookup the HIDPointerAccelerationTable and return a value. In current DriverKit area, the process above is deprecated. Now I don't know to do. I've read some document: https://developer.apple.com/documentation/hiddriverkit/iohidpointereventoptions/kiohidpointereventoptionsnoacceleration?changes=__7_8 https://developer.apple.com/documentation/hiddriverkit/kiohidmouseaccelerationtypekey?changes=__7_8 https://developer.apple.com/documentation/hiddriverkit/kiohidpointeraccelerationkey?changes=__7_8 but no any description in those articles. Please help!
6
0
553
Jun ’25
How to setup DriverKit Timer Event with OSAction Callback Binding
Hello Everyone, I'm encountering an issue while setting up a timer event in DriverKit and would appreciate any guidance. Here's my current implementation: void DRV_MAIN_CLASS_NAME::SetupEventTimer() { // 1. Create dispatch queue kern_return_t ret = IODispatchQueue::Create("TimerQueue", 0, 0, &ivars->dispatchQueue); if (ret != kIOReturnSuccess) { LogErr("Failed to create dispatch queue: 0x%x", ret); return; } // 2. Create timer source ret = IOTimerDispatchSource::Create(ivars->dispatchQueue, &ivars->dispatchSource); if (ret != kIOReturnSuccess) { LogErr("Failed to create timer: 0x%x", ret); OSSafeReleaseNULL(ivars->dispatchQueue); return; } /*! * @brief Create an instance of OSAction. * @discussion Methods to allocate an OSAction instance are generated for each method defined in a class with * a TYPE attribute, so there should not be any need to directly call OSAction::Create(). * @param target OSObject to receive the callback. This object will be retained until the OSAction is * canceled or freed. * @param targetmsgid Generated message ID for the target method. * @param msgid Generated message ID for the method invoked by the receiver of the OSAction * to generate the callback. * @param referenceSize Size of additional state structure available to the creator of the OSAction * with GetReference. * @param action Created OSAction with +1 retain count to be released by the caller. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ // 3: Create an OSAction for the TimerOccurred method // THIS IS WHERE I NEED HELP OSAction* timerAction = nullptr; ret = OSAction::Create(this, 0, 0, 0, &timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to create OSAction: 0x%x", ret); goto cleanup; } // 4. Set handler ret = ivars->dispatchSource->SetHandler(timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to set handler: 0x%x", ret); goto cleanup; } // 5. Schedule timer (1 second) uint64_t deadline = mach_absolute_time() + NSEC_PER_SEC; ivars->dispatchSource->WakeAtTime(0, deadline, 0); cleanup: if (ret != kIOReturnSuccess) { OSSafeReleaseNULL(timerAction); OSSafeReleaseNULL(ivars->dispatchSource); OSSafeReleaseNULL(ivars->dispatchQueue); } } Problem: The code runs but the OSAction callback binding seems incorrect (Step 3). According to the OSAction documentation, I need to use the TYPE macro to properly bind the callback method. But I try to use TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; TYPE(TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; kern_return_t TimerOccurred() TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) LOCALONLY; All results in Out-of-line definition of 'TimerOccurred' does not match any declaration in 'DRV_MAIN_CLASS_NAME' Questions: What is the correct way to declare a timer callback method using TYPE? How to get the values targetmsgid & msgid generated by Xcode? Any help would be greatly appreciated! Best Regards, Charles
6
0
421
Apr ’25
Show / Hide HAL Virtual Audio Device Based on App State
I am developing a macOS virtual audio device using an Audio Server Plug-In (HAL). I want the virtual device to be visible to all applications only when my main app is running, and completely hidden from all apps when the app is closed. The goal is to dynamically control device visibility based on app state without reinstalling the driver.What is the recommended way for the app to notify the HAL plug-in about its running or closed state ? Any guidance on best-practice architecture for this scenario would be appreciated.
Replies
1
Boosts
0
Views
215
Activity
Jan ’26
How to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Hello! We develop a SAS driver and a service application for DAS devices. When users in our application create a RAID array on the device: On the 1st step, our dext driver mounts a new volume. At this step DiskUtil automatically tries to mount it. As there is no file system on the new volume - the MacOS system popup appears "The disk you attached was not readable by the computer" On the 2nd step our application creates the file system on this new volume. So we do not need this MacOS system popup to appear (as it may frustrate our users). We found a way to disable the global auto mount but this solution also impacts on other devices (which is not good). Are there any other possibilities to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Replies
3
Boosts
0
Views
278
Activity
Jan ’26
DriverKit Dext fails to load with "Exec format error" (POSIX 8) on macOS 26.2 (Apple Silicon) when SIP is enabled
1. 环境描述 (Environment) OS: macOS 26.2 Hardware: Apple Silicon (M1/M2/M3) DriverKit SDK: DriverKit 19.0 / 20.0 Arch: Universal (x86_64, arm64, arm64e) SIP Status: Enabled (Works perfectly when Disabled) 2. 问题现象 (Problem Description) 在开启 SIP 的环境下,USB 驱动扩展(Dext)能安装,但插入设备时无法连接设备(驱动的Start方法未被调用)。 驱动状态: MacBook-Pro ~ % systemextensionsctl list 1 extension(s) --- com.apple.system_extension.driver_extension (Go to 'System Settings > General > Login Items & Extensions > Driver Extensions' to modify these system extension(s)) enabled active teamID bundleID (version) name [state] * * JK9U78YRLU com.ronganchina.usbapp.MyUserUSBInterfaceDriver (1.3/4) com.ronganchina.usbapp.MyUserUSBInterfaceDriver [activated enabled] 关键日志证据 (Key Logs) KernelManagerd: Error Domain=NSPOSIXErrorDomain Code=8 "Exec format error" Syspolicyd: failed to fetch ... /_CodeSignature/CodeRequirements-1 error=-10 AppleSystemPolicy: ASP: Security policy would not allow process DriverKit Kernel: DK: MyUserUSBInterfaceDriver user server timeout dext的 embedded.provisionprofile 已包含: com.apple.developer.driverkit com.apple.developer.driverkit.transport.usb (idVendor: 11977)
Replies
2
Boosts
0
Views
305
Activity
Jan ’26
Basic introduction to DEXT Matching and Loading
Note: This document is specifically focused on what happens after a DEXT has passed its initial code-signing checks. Code-signing issues are dealt with in other posts. Preliminary Guidance: Using and understanding DriverKit basically requires understanding IOKit, something which isn't entirely clear in our documentation. The good news here is that IOKit actually does have fairly good "foundational" documentation in the documentation archive. Here are a few of the documents I'd take a look at: IOKit Fundamentals IOKit Device Driver Design Guidelines Accessing Hardware From Applications Special mention to QA1075: "Making sense of IOKit error codes",, which I happened to notice today and which documents the IOReturn error format (which is a bit weird on first review). Those documents do not cover the full DEXT loading process, but they are the foundation of how all of this actually works. Understanding the IOKitPersonalities Dictionary The first thing to understand here is that the "IOKitPersonalities" is called that because it is in fact a fully valid "IOKitPersonalities" dictionary. That is, what the system actually uses that dictionary "for" is: Perform a standard IOKit match and load cycle in the kernel. The final driver in the kernel then uses the DEXT-specific data to launch and run your DEXT process outside the kernel. So, working through the critical keys in that dictionary: "IOProviderClass"-> This is the in-kernel class that your in-kernel driver loads "on top" of. The IOKit documentation and naming convention uses the term "Nub", but the naming convention is not consistent enough that it applies to all cases. "IOClass"-> This is the in-kernel class that your driver loads on top of. This is where things can become a bit confused, as some families work by: Routing all activity through the provider reference so that the DEXT-specific class does not matter (PCIDriverKit). Having the DEXT subclass a specific subclass which corresponds to a specific kernel driver (SCSIPeripheralsDriverKit). This distinction is described in the documentation, but it's easy to overlook if you don't understand what's going on. However, compare PCIDriverKit: "When the system loads your custom PCI driver, it passes an IOPCIDevice object as the provider to your driver. Use that object to read and write the configuration and memory of your PCI hardware." Versus SCSIPeripheralsDriverKit: Develop your driver by subclassing IOUserSCSIPeripheralDeviceType00 or IOUserSCSIPeripheralDeviceType05, depending on whether your device works with SCSI Block Commands (SBC) or SCSI Multimedia Commands (SMC), respectively. In your subclass, override all methods the framework declares as pure virtual. The reason these differences exist actually comes from the relationship and interactions between the DEXT families. Case in point, PCIDriverKit doesn't require a specific subclass because it wants SCSIControllerDriverKit DEXTs to be able to directly load "above" it. Note that the common mistake many developers make is leaving "IOUserService" in place when they should have specified a family-specific subclass (case 2 above). This is an undocumented implementation detail, but if there is a mismatch between your DEXT driver ("IOUserSCSIPeripheralDeviceType00") and your kernel driver ("IOUserService"), you end up trying to call unimplemented kernel methods. When a method is "missing" like that, the codegen system ends up handling that by returning kIOReturnUnsupported. One special case here is the "IOUserResources" provider. This class is the DEXT equivalent of "IOResources" in the kernel. In both cases, these classes exist as an attachment point for objects which don't otherwise have a provider. It's specifically used by the sample "Communicating between a DriverKit extension and a client app" to allow that sample to load on all hardware but is not something the vast majority of DEXT will use. Following on from that point, most DEXT should NOT include "IOMatchCategory". Quoting IOKit fundamentals: "Important: Any driver that declares IOResources as the value of its IOProviderClass key must also include in its personality the IOMatchCategory key and a private match category value. This prevents the driver from matching exclusively on the IOResources nub and thereby preventing other drivers from matching on it. It also prevents the driver from having to compete with all other drivers that need to match on IOResources. The value of the IOMatchCategory property should be identical to the value of the driver's IOClass property, which is the driver’s class name in reverse-DNS notation with underbars instead of dots, such as com_MyCompany_driver_MyDriver." The critical point here is that including IOMatchCategory does this: "This prevents the driver from matching exclusively on the IOResources nub and thereby preventing other drivers from matching on it." The problem here is that this is actually the exceptional case. For a typical DEXT, including IOMatchCategory means that a system driver will load "beside" their DEXT, then open the provider blocking DEXT access and breaking the DEXT. DEXT Launching The key point here is that the entire process above is the standard IOKit loading process used by all KEXT. Once that process finishes, what actually happens next is the DEXT-specific part of this process: IOUserServerName-> This key is the bundle ID of your DEXT, which the system uses to find your DEXT target. IOUserClass-> This is the name of the class the system instantiates after launching your DEXT. Note that this directly mimics how IOKit loading works. Keep in mind that the second, DEXT-specific, half of this process is the first point your actual code becomes relevant. Any issue before that point will ONLY be visible through kernel logging or possibly the IORegistry. __ Kevin Elliott DTS Engineer, CoreOS/Hardware
Replies
1
Boosts
0
Views
276
Activity
2w
Missing "Dolby Vision Profile" Option in Deliver Page - DaVinci Resolve 20 on iPadOS 26
Dear Support Team, ​I am writing to seek technical assistance regarding a persistent issue with Dolby Vision exporting in DaVinci Resolve 20 on my iPad Pro 12.9-inch (2021, M1 chip) running iPadOS 26.0.1. ​The Issue: Despite correctly configuring the project for a Dolby Vision workflow and successfully completing the dynamic metadata analysis, the "Dolby Vision Profile" dropdown menu (and related embedding options) is completely missing from the Advanced Settings in the Deliver page. ​My Current Configuration & Steps Taken: ​Software Version: DaVinci Resolve Studio 20 (Studio features like Dolby Vision analysis are active and functional). ​Project Settings: Color Science: DaVinci YRGB Color Managed. ​Dolby Vision: Enabled (Version 4.0) with Mastering Display set to 1000 nits. ​Output Color Space: Rec.2100 ST2084. ​Color Page: Dynamic metadata analysis has been performed, and "Trim" controls are functional. ​Export Settings: ​Format: QuickTime / MP4. ​Codec: H.265 (HEVC). ​Encoding Profile: Main 10. ​The Problem: Under "Advanced Settings," there is no option to select a Dolby Vision Profile (e.g., Profile 8.4) or to "Embed Dolby Vision Metadata." ​Potential Variables: ​System Version: I am currently running iPadOS 26. ​Apple ID: My iPad is currently not logged into an Apple ID. I suspect this might be preventing the app from accessing certain system-level AVFoundation frameworks or Dolby DRM/licensing certificates required for metadata embedding. ​Could you please clarify if the "Dolby Vision Profile" option is dependent on a signed-in Apple ID for hardware-level encoding authorization, or if this is a known compatibility issue with the current iPadOS 26 build? ​I look forward to your guidance on how to resolve this. ​Best regards, INSOFT_Fred
Replies
0
Boosts
0
Views
173
Activity
Feb ’26
iOS printing – Finishing (Punch) options not applied for images unless a preset is selected
When printing image/photo files via AirPrint, selected finishing options (e.g., Punch) are not applied unless a preset is chosen. reproduction steps: Select an image on iOS Tap Print → choose printer/server Set Finishing Options → Punch Print Observed: Finishing options not applied IPP trace shows no finisher attributes in the request working scenario: Select any Preset (e.g., Color) before printing Finishing options are then included in IPP and applied Note: Issue does not occur when printing PDFs from iOS; finisher attributes are sent correctly. Is this expected AirPrint behavior for image jobs, or could this be a bug in how iOS constructs the IPP request for photos?
Replies
3
Boosts
0
Views
159
Activity
4d
macOS 26.4 Beta breaks keyboard remapping for built-in MacBook keyboards – significant ecosystem impact
Since macOS 26.4 Beta 1, virtual HID devices created via DriverKit can no longer intercept key events from the built-in MacBook keyboard. External keyboards still work. This is confirmed and tracked here: https://github.com/pqrs-org/Karabiner-Elements/issues/4402 One possible lead (from LLM-assisted analysis of Apple's open-source IOHIDFamily code and cross-referencing community reports): macOS 26.4 Beta may have introduced or modified a security policy referred to as com.apple.iohid.protectedDeviceAccess, which could block IOHIDDeviceOpen for the Apple Internal Keyboard connected via SPI transport (AppleHIDTransportHIDDevice). This appears related to a "GamePolicy" check in IOHIDDeviceClass.m that gates whether processes can open HID devices. This has not been independently verified and may or may not be the root cause. This has far-reaching consequences. Karabiner-Elements alone has over 21,000 GitHub stars and is used by hundreds of thousands of macOS users for keyboard customization, accessibility workflows, ergonomic setups, and multilingual input. This change completely breaks its core functionality on any MacBook. Beyond Karabiner, this affects every developer building keyboard remapping, input customization, or accessibility tooling via DriverKit virtual HID devices — including commercial applications currently in development. I'd argue that the power and flexibility of keyboard customization on macOS is a genuine competitive advantage for the platform. Developers and power users choose Macs partly because tools like this exist. Restricting this capability would be detrimental to the ecosystem and to Apple's appeal among professional users. I'd like to understand: is this an intentional security change or a regression? If intentional, is there a migration path?
Replies
1
Boosts
0
Views
124
Activity
2w
Can't get USBSerialDriverKit driver loaded
I am writing a DriverKit driver for the first that uses the USBSerialDriverKit. The driver its purpose is to expose the device as serial interface (/dev/cu.tetra-pei0 or something like this). My problem: I don't see any logs from that driver in the console and I tried like 40 different approaches and checked everything. The last message I see is that the driver get successfully added to the system it is in the list of active and enabled system driver extensions but when I plug the device in none of my logs appear and it doesn't show up in ioreg. So without my driver the target device looks like this: +-o TETRA PEI interface@02120000 <class IOUSBHostDevice, id 0x10000297d, registered, matched, active, busy 0 (13 ms), retain 30> | { | "sessionID" = 268696051410 | "USBSpeed" = 3 | "UsbLinkSpeed" = 480000000 | "idProduct" = 36886 | "iManufacturer" = 1 | "bDeviceClass" = 0 | "IOPowerManagement" = {"PowerOverrideOn"=Yes,"DevicePowerState"=2,"CurrentPowerState"=2,"CapabilityFlags"=32768,"MaxPowerState"=2,"DriverPowerState"=0} | "bcdDevice" = 9238 | "bMaxPacketSize0" = 64 | "iProduct" = 2 | "iSerialNumber" = 0 | "bNumConfigurations" = 1 | "UsbDeviceSignature" = <ad0c16901624000000ff0000> | "USB Product Name" = "TETRA PEI interface" | "locationID" = 34734080 | "bDeviceSubClass" = 0 | "bcdUSB" = 512 | "USB Address" = 6 | "kUSBCurrentConfiguration" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "UsbPowerSinkAllocation" = 500 | "bDeviceProtocol" = 0 | "USBPortType" = 0 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "USB Vendor Name" = "Motorola Solutions, Inc." | "Device Speed" = 2 | "idVendor" = 3245 | "kUSBProductString" = "TETRA PEI interface" | "kUSBAddress" = 6 | "kUSBVendorString" = "Motorola Solutions, Inc." | } | +-o AppleUSBHostCompositeDevice <class AppleUSBHostCompositeDevice, id 0x100002982, !registered, !matched, active, busy 0, retain 5> | { | "IOProbeScore" = 50000 | "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOProviderClass" = "IOUSBHostDevice" | "IOClass" = "AppleUSBHostCompositeDevice" | "IOPersonalityPublisher" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "bDeviceSubClass" = 0 | "CFBundleIdentifierKernel" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOMatchedAtBoot" = Yes | "IOMatchCategory" = "IODefaultMatchCategory" | "IOPrimaryDriverTerminateOptions" = Yes | "bDeviceClass" = 0 | } | +-o lghub_agent <class AppleUSBHostDeviceUserClient, id 0x100002983, !registered, !matched, active, busy 0, retain 7> | { | "IOUserClientCreator" = "pid 1438, lghub_agent" | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@0 <class IOUSBHostInterface, id 0x100002986, registered, matched, active, busy 0 (5 ms), retain 9> | | { | | "USBPortType" = 0 | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | "USB Vendor Name" = "Motorola Solutions, Inc." | | "bcdDevice" = 9238 | | "USBSpeed" = 3 | | "idProduct" = 36886 | | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | | "bInterfaceSubClass" = 0 | | "bConfigurationValue" = 1 | | "locationID" = 34734080 | | "USB Product Name" = "TETRA PEI interface" | | "bInterfaceProtocol" = 0 | | "iInterface" = 0 | | "bAlternateSetting" = 0 | | "idVendor" = 3245 | | "bInterfaceNumber" = 0 | | "bInterfaceClass" = 255 | | "bNumEndpoints" = 2 | | } | | | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x100002988, !registered, !matched, active, busy 0, retain 6> | { | "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} | "IOUserClientCreator" = "pid 1438, lghub_agent" | "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@1 <class IOUSBHostInterface, id 0x100002987, registered, matched, active, busy 0 (5 ms), retain 9> | { | "USBPortType" = 0 | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "USB Vendor Name" = "Motorola Solutions, Inc." | "bcdDevice" = 9238 | "USBSpeed" = 3 | "idProduct" = 36886 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "bInterfaceSubClass" = 0 | "bConfigurationValue" = 1 | "locationID" = 34734080 | "USB Product Name" = "TETRA PEI interface" | "bInterfaceProtocol" = 0 | "iInterface" = 0 | "bAlternateSetting" = 0 | "idVendor" = 3245 | "bInterfaceNumber" = 1 | "bInterfaceClass" = 255 | "bNumEndpoints" = 2 | } | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x10000298a, !registered, !matched, active, busy 0, retain 6> { "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} "IOUserClientCreator" = "pid 1438, lghub_agent" "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} "IOUserClientDefaultLocking" = Yes } more details in my comment.
Replies
6
Boosts
0
Views
173
Activity
2w
How to get a IOSerialBSDClient attached?
I have a driver extending IOUserUSBSerial and I want the device to show up as /dev/tty.mycustombasename-123 and /dev/cu. respectively. How can I achieve that?
Replies
1
Boosts
0
Views
126
Activity
3w
Kernel Panic: Power state transition (0 -> 2) timeout during DriverKit (DEXT) load sequence (IOUserSCSIParallelInterfaceController)
Hi Everyone, We are currently migrating a mature legacy KEXT to DriverKit for our PCIe SCSI storage controller (connected via Thunderbolt 3). During the DEXT load sequence, we have observed that the system automatically triggers a power state transition from State 0 (Off) to State 2 (On). However, this process results in a Kernel Panic due to a timeout after approximately 21 seconds. We have verified that our implementation of Start_Impl, UserInitializeController_Impl, and SetPowerState_Impl executes extremely fast, with a total execution time of less than one second. Specifically, SetPowerState_Impl returns kIOReturnSuccess immediately upon being called. Furthermore, our current Info.plist does not contain any IOPowerManagement dictionary or related keys. Despite the fast execution and the absence of explicit power management declarations in the plist, the kernel power management state machine (IOServicePM) still generates a 21-second timeout, leading to the following panic: Panic Log: panic(cpu 7 caller 0xfffffe0020be8fec): MySCSIDriver::setPowerState(0xfffffe2fb1a65c00 : 0xfffffe0020bfed88, 0 -> 2) timed out after 21257 ms @IOServicePM.cpp:5609 com.example.driver.dext: ( id: com.example.driver.dext; path: /Library/SystemExtensions/[UUID]/com.example.driver.dext; state: loaded ) Note on Previous Discussion: I would like to express my gratitude to Kevin from Apple DTS for the helpful discussion regarding the implementation of BundleParallelTask on the forums. Since then, we have shifted our development focus toward completing the overall management ecosystem, delivering a comprehensive operational interface for users, and handling specific user environments and behaviors. Our current priority is ensuring system stability—specifically resolving these Thunderbolt-related power management issues (sleep/wake)—to prepare the product for upcoming testing. I remain very grateful for the guidance provided on batch task optimization and intend to resume those optimizations once this critical stability baseline is secured. Technical Guidance Needed for PM Migration In our legacy KEXT, we utilized PMinit(), registerPowerDriver(), and joinPMtree() to precisely control the timing of power management registration. In transitioning to the DriverKit SDK, we have not found clear guidance on several key points: Standardized Migration Path: What is the recommended way to implement equivalent power management initialization (formerly PMinit) within a DriverKit subclass? In DriverKit, how should we replicate the behavior of manually calling registerPowerDriver and joinPMtree to ensure the driver is only monitored once the hardware is ready? Implicit Power Registration: Why does the system enforce a setPowerState(0 -> 2) transition on a subclass of IOUserSCSIParallelInterfaceController even when no IOPowerManagement dictionary is defined in the Info.plist? Is this a default behavior of the SCSI or PCI transport framework? Thunderbolt Specifics: Are there specific power proxying requirements or configurations for PCIe devices over Thunderbolt to avoid conflicts with the default IOPCIFamily power policies? Best Regards, Charles
Replies
1
Boosts
0
Views
77
Activity
1w
DriverKit Entitlement Model Has No Viable Path for Open Source and Community-Maintained Drivers
While I welcome the arrival of a userspace implementation of drivers, DriverKit as it stands has some notable flaws. My main concern is the ability of open-source projects like HoRNDIS being able to access paid developer accounts and the limited entitlement scope (plus the waiting period) for what is essentially a hobbyist free project. Even if the developer is a professional company, some legacy hardware will go unsupported because of a lack of support from the vendor. Providing a way for users who need access to older hardware would be needed. Three concrete requests: A class-level or wildcard VID/PID entitlement for open source projects with a verifiable public repository A free or reduced-cost entitlement path for non-commercial volunteer-maintained drivers Published approval criteria and timelines so projects can plan accordingly Depreciating kexts without providing an accessible successor for community projects isn't security, it is gatekeeping access to hardware that is critically needed. Is this use case on the roadmap at all? Developers deserve a clear answer.
Replies
1
Boosts
0
Views
44
Activity
2d
iOS AirPrint sends print-quality=high when file-type is photo even if user selects “normal”
Hi everyone, I observed a behavior with AirPrint from an iPhone and wanted to confirm if this is expected behavior from iOS. Scenario tested: File type: Photo Print-quality selected by the user: Normal Observation (from packet capture): When checking the PCAP for the request sent from the iPhone, the print-quality attribute is always sent as high, even though the user selected Normal in the UI. Question: Is this an expected behavior in iOS/AirPrint where photos are always sent with print-quality=high regardless of the user-selected print quality? Or could this be a bug?
Replies
0
Boosts
0
Views
17
Activity
5d
DriverKit vs MFi for iPad custom hardware serial communication?
I have a custom hardware board that I want to communicate serially with from an iPad. Should I use the DriverKit route or the MFi route?
Replies
1
Boosts
0
Views
40
Activity
2d
Why don't my os_log entries show up until the second time my driver loads?
I'm in the process of writing a DriverKit USBHostInterface driver, and while I'm finally starting to get there, I've run into a bit of a frustration with logging. Naturally I have a liberal amount of os_log calls that I'm using to troubleshoot my driver. However I've noticed that they don't show up until after the first time my driver has loaded. Meaning, for example, suppose I make a new build of my driver and it's bundled user-mode app, install the bundle to /Applications, run the installer, verify it took with systemextensionsctl list, fire up Console and start streaming log entries, then plug in my device. I can see the log entries that show that my driver is loaded, etc., then a bunch of kernel -> log entries, but none of my Start method log entries. If I unplug my device and plug it in again, my log entries show up as expected. Why is this and, more importantly, how can I fix it? I'd like to see those log entries the first time the driver loads, if I could.
Replies
0
Boosts
0
Views
16
Activity
1d
Entitlements for VMWare et al access to access USB devices
How does VMWare access USB devices without have any specifics of the USB device? Does it use the same profile/entitlement process or does it take a different approach?
Replies
14
Boosts
0
Views
2.3k
Activity
May ’25
How to Symbolicate an Apple Silicon Panic?
Investigating a kernel panic, I discovered that Apple Silicon Panic traces are not working with how I know to symbolicate the panic information. I have not found proper documentation that corrects this situation. Attached file is an indentity-removed panic, received from causing an intentional panic (dereferencing nullptr), so that I know what functions to expect in the call stack. This is cut-and-pasted from the "Report To Apple" dialog that appears after the reboot: panic_1_4_21_b.txt To start, I download and install the matching KDK (in this case KDK_14.6.1_23G93.kdk), identified from this line: OS version: 23G93 Kernel version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8122 Then start lldb from Terminal, using this command: bash_prompt % lldb -arch arm64e /Library/Developer/KDKs/KDK_14.6.1_23G93.kdk/System/Library/Kernels/kernel.release.t8122 Next I load the remaining scripts per the instructions from lldb: (lldb) settings set target.load-script-from-symbol-file true I need to know what address to load my kext symbols to, which I read from this line of the panic log, after the @ symbol: com.company.product(1.4.21d119)[92BABD94-80A4-3F6D-857A-3240E4DA8009]@0xfffffe001203bfd0->0xfffffe00120533ab I am using a debug build of my kext, so the DWARF symbols are part of the binary. I use this line to load the symbols into the lldb session: (lldb) addkext -F /Library/Extensions/KextName.kext/Contents/MacOS/KextName 0xfffffe001203bfd0 And now I should be able to use lldb image lookup to identify pointers on the stack that land within my kext. For example, the current PC at the moment of the crash lands within the kext (expected, because it was intentional): (lldb) image lookup -a 0xfffffe001203fe10 Which gives the following incorrect result: Address: KextName[0x0000000000003e40] (KextName.__TEXT.__cstring + 14456) Summary: "ffer has %d retains\n" That's not even a program instruction - that's within a cstring. No, that cstring isn't involved in anything pertaining to the intentional panic I am expecting to see. Can someone please explain what I'm doing wrong and provide instructions that will give symbol information from a panic trace on an Apple Silicon Mac? Disclaimers: Yes I know IOPCIFamily is deprecated, I am in process of transitioning to DriverKit Dext from IOKit kext. Until then I must maintain the kext. Terminal command "atos" provides similar incorrect results, and seems to not work with debug-built-binaries (only dSYM files) Yes this is an intentional panic so that I can verify the symbolicate process before I move on to investigating an unexpected panic I have set nvram boot-args to include keepsyms=1 I have tried (lldb) command script import lldb.macosx but get a result of error: no images in crash log (after the nvram settings)
Replies
5
Boosts
0
Views
1.9k
Activity
Apr ’25
Peripheral Devices control on macOS
We are looking for a solution (API, Frameworks) that would allow us to block any type of external device, including storage devices, HIDs, network adapters, and Bluetooth devices according with dynamic rules that comes from management server . This feature is important for endpoint security solutions vendors, and it can be implemented on other platforms and older versions of macOS using the IOKit framework and kexts. I have found one solution that can control the usage only of "storage" devices with the EndpointSecurity framework in conjunction with the DiskArbitration framework. This involves monitoring the MOUNT and OPEN events for /dev/disk files, checking for devices as they appear, and ejecting them if they need to be blocked.. Also, I have found the ES_EVENT_TYPE_AUTH_IOKIT_OPEN event in EndpointSecurity.framework, but it doesn't seem to be useful, at least not for my purposes, because ES doesn't provide AUTH events for some system daemons, such as configd (it only provides NOTIFY events). Furthermore, there are other ways to communicate with devices and their drivers apart from IOKit. DriverKit.framework does not provide the necessary functionality either, as it requires specific entitlements that are only available to certain vendors and devices. Therefore, it cannot be used to create universal drivers for all devices, which should be blocked. Any advice would be greatly appreciated!
Replies
2
Boosts
0
Views
745
Activity
Jun ’25
DriverKit - IOUSBHostDevice::SetProperties
I am trying to add a few properties to an IOUSBHostDevice but the SetProperties is returning kIOReturnUnsupported. The reason I am trying to modify the IOUSBHostDevice's properties is so we can support a MacBook Air SuperDrive when it is attached to our docking station devices. The MacBook Air SuperDrive needs a high powered port to run and this driver will help the OS realize that our dock can support it. I see that the documentation for SetProperties says: The default implementation of this method returns kIOReturnUnsupported. You can override this method and use it to modify the set of properties and values as needed. The changes you make apply only to the current service. Do I need to override IOUSBHostDevice? This is my current Start implementation (you can also see if in the Xcode project): kern_return_t IMPL(MyUserUSBHostDriver, Start) { kern_return_t ret = kIOReturnSuccess; OSDictionary * prop = NULL; OSDictionary * mergeProperties = NULL; bool success = true; os_log(OS_LOG_DEFAULT, "&gt; %s", __FUNCTION__); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = Start(provider, SUPERDISPATCH); __Require(kIOReturnSuccess == ret, Exit); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ivars-&gt;host = OSDynamicCast(IOUSBHostDevice, provider); __Require_Action(NULL != ivars-&gt;host, Exit, ret = kIOReturnNoDevice); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = ivars-&gt;host-&gt;Open(this, 0, 0); __Require(kIOReturnSuccess == ret, Exit); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = CopyProperties(&amp;prop); __Require(kIOReturnSuccess == ret, Exit); __Require_Action(NULL != prop, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); mergeProperties = OSDynamicCast(OSDictionary, prop-&gt;getObject("IOProviderMergeProperties")); mergeProperties-&gt;retain(); __Require_Action(NULL != mergeProperties, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); OSSafeReleaseNULL(prop); ret = ivars-&gt;host-&gt;CopyProperties(&amp;prop); __Require(kIOReturnSuccess == ret, Exit); __Require_Action(NULL != prop, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); os_log(OS_LOG_DEFAULT, "%s : %s", "USB Product Name", ((OSString *) prop-&gt;getObject("USB Product Name"))-&gt;getCStringNoCopy()); os_log(OS_LOG_DEFAULT, "%s : %s", "USB Vendor Name", ((OSString *) prop-&gt;getObject("USB Vendor Name"))-&gt;getCStringNoCopy()); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); success = prop-&gt;merge(mergeProperties); __Require_Action(success, Exit, ret = kIOReturnError); os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__); ret = ivars-&gt;host-&gt;SetProperties(prop); // this is no working __Require(kIOReturnSuccess == ret, Exit); Exit: OSSafeReleaseNULL(mergeProperties); OSSafeReleaseNULL(prop); os_log(OS_LOG_DEFAULT, "err ref %d", kIOReturnUnsupported); os_log(OS_LOG_DEFAULT, "&lt; %s %d", __FUNCTION__, ret); return ret; }
Replies
2
Boosts
0
Views
1.3k
Activity
Jan ’26
How to implement mouse (pointing) acceleration function in DriverKit?
Hello every one good day :) My project uses a mouse driver handling all events from the mouse produced by our company. In the past the driver is a kext, which implement acceleration by HIDPointerAccelerationTable, we prepare data in the driver's info.plist, while our app specifies a value to IOHIDSystem with key kIOHIDPointerAccelerationKey, the driver will call copyAccelerationTable() to lookup the HIDPointerAccelerationTable and return a value. In current DriverKit area, the process above is deprecated. Now I don't know to do. I've read some document: https://developer.apple.com/documentation/hiddriverkit/iohidpointereventoptions/kiohidpointereventoptionsnoacceleration?changes=__7_8 https://developer.apple.com/documentation/hiddriverkit/kiohidmouseaccelerationtypekey?changes=__7_8 https://developer.apple.com/documentation/hiddriverkit/kiohidpointeraccelerationkey?changes=__7_8 but no any description in those articles. Please help!
Replies
6
Boosts
0
Views
553
Activity
Jun ’25
How to setup DriverKit Timer Event with OSAction Callback Binding
Hello Everyone, I'm encountering an issue while setting up a timer event in DriverKit and would appreciate any guidance. Here's my current implementation: void DRV_MAIN_CLASS_NAME::SetupEventTimer() { // 1. Create dispatch queue kern_return_t ret = IODispatchQueue::Create("TimerQueue", 0, 0, &ivars->dispatchQueue); if (ret != kIOReturnSuccess) { LogErr("Failed to create dispatch queue: 0x%x", ret); return; } // 2. Create timer source ret = IOTimerDispatchSource::Create(ivars->dispatchQueue, &ivars->dispatchSource); if (ret != kIOReturnSuccess) { LogErr("Failed to create timer: 0x%x", ret); OSSafeReleaseNULL(ivars->dispatchQueue); return; } /*! * @brief Create an instance of OSAction. * @discussion Methods to allocate an OSAction instance are generated for each method defined in a class with * a TYPE attribute, so there should not be any need to directly call OSAction::Create(). * @param target OSObject to receive the callback. This object will be retained until the OSAction is * canceled or freed. * @param targetmsgid Generated message ID for the target method. * @param msgid Generated message ID for the method invoked by the receiver of the OSAction * to generate the callback. * @param referenceSize Size of additional state structure available to the creator of the OSAction * with GetReference. * @param action Created OSAction with +1 retain count to be released by the caller. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ // 3: Create an OSAction for the TimerOccurred method // THIS IS WHERE I NEED HELP OSAction* timerAction = nullptr; ret = OSAction::Create(this, 0, 0, 0, &timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to create OSAction: 0x%x", ret); goto cleanup; } // 4. Set handler ret = ivars->dispatchSource->SetHandler(timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to set handler: 0x%x", ret); goto cleanup; } // 5. Schedule timer (1 second) uint64_t deadline = mach_absolute_time() + NSEC_PER_SEC; ivars->dispatchSource->WakeAtTime(0, deadline, 0); cleanup: if (ret != kIOReturnSuccess) { OSSafeReleaseNULL(timerAction); OSSafeReleaseNULL(ivars->dispatchSource); OSSafeReleaseNULL(ivars->dispatchQueue); } } Problem: The code runs but the OSAction callback binding seems incorrect (Step 3). According to the OSAction documentation, I need to use the TYPE macro to properly bind the callback method. But I try to use TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; TYPE(TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; kern_return_t TimerOccurred() TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) LOCALONLY; All results in Out-of-line definition of 'TimerOccurred' does not match any declaration in 'DRV_MAIN_CLASS_NAME' Questions: What is the correct way to declare a timer callback method using TYPE? How to get the values targetmsgid & msgid generated by Xcode? Any help would be greatly appreciated! Best Regards, Charles
Replies
6
Boosts
0
Views
421
Activity
Apr ’25