DirectHW is an advanced hardware access library and kernel extension for macOS, providing comprehensive low-level hardware control interfaces. This enhanced fork extends the standard DirectHW with advanced physical memory management, DMA buffer allocation, and sophisticated hardware control capabilities.
This fork provides significantly more control interfaces than standard DirectHW:
🚀 Advanced Memory Management
- Physical Memory Allocation - Allocate physically contiguous memory buffers
- DMA Buffer Management - Create DMA-capable buffers with specific constraints
- Memory Mapping Control - Fine-grained control over memory mapping options
- 32-bit Address Space - Support for legacy hardware requiring 32-bit addresses
- Cache Control - Inhibit, write-through, or copyback caching per mapping
🔧 Enhanced Hardware Control
- MSR Operations - Read/write Model Specific Registers on specific CPU cores (Intel only)
- CPUID Instructions - Execute CPUID with full control over input registers (Intel only)
- Multi-Core Support - Target specific CPU cores for operations (Intel only)
- Cross-Endian Compatibility - Rosetta translation layer support
- Physical Address Translation - Direct physical memory access with virtual mapping
⚡ Advanced I/O Capabilities
- Port I/O (8/16/32/64-bit) - Enhanced port access with 64-bit support (Intel only)
- Memory-Mapped I/O - Sophisticated MMIO with configurable caching policies
- PCI Configuration Space - Complete PCI config access with bus/device/function addressing
- Physical Memory Reading - Direct physical memory access with safety controls
Kernel Extension Methods
The kernel component implements 11 distinct hardware control methods:
| Method | Function | Enhanced Capabilities |
|---|---|---|
| kReadIO/kWriteIO | Port I/O operations | 64-bit port support, multi-width access |
| kPrepareMap | Memory mapping setup | Advanced caching control, alignment options |
| kReadMSR/kWriteMSR | MSR operations | Per-core targeting, validation checks |
| kReadCpuId | CPUID instruction | Full register control, core selection |
| kReadMem | Physical memory access | Safe direct physical memory reading |
| kRead/kWrite | Generic hardware access | Unified interface for all address spaces |
| kAllocatePhysicalMemory | Memory allocation | DMA buffers, contiguous allocation, constraints |
| kUnallocatePhysicalMemory | Memory cleanup | Automatic resource tracking and cleanup |
Memory Allocation Types & Options
enum {
kMemoryTypeUser=10000000, // User-space accessiblekMemoryTypeKernel=20000000, // Kernel-space only kMemoryTypeKernelMalloc=30000000, // Kernel malloc'dkMemoryTypeSegments=40000000, // Segmented allocationkMemoryTypeSegmentsKernel=50000000// Kernel segmented
};enum {
kPhysContig=0, // Physically contiguous allocationkUseVirt=1, // Use existing virtual address kUsePhys=2, // Use existing physical addresskMapKernel=16// Create kernel mapping
};Hardware Driver Development
// Allocate DMA buffer for hardware communicationuint32_tphysAddr;
void*userAddr; uint32_tbufferType;
// Create 32-bit physically contiguous DMA bufferallocate_physically_contiguous_32(65536, &physAddr, &userAddr, &bufferType);
// Hardware can now use physAddr for DMA operations// User code can access buffer via userAddrLow-Level System Analysis
// Read MSR on specific CPU corelogical_cpu_select(2); // Select CPU core 2msr_tmsr=rdmsr(0x1A0); // Read IA32_MISC_ENABLEprintf("MSR 0x1A0 = 0x%08x%08x\n", msr.hi, msr.lo);
// Execute CPUID with full controluint32_tcpudata[4];
rdcpuid(0x80000008, 0, cpudata); // Get physical address size infoMemory-Mapped Hardware Access
// Map hardware registers with inhibited cachevoid*hwRegs=map_physical(0xFED00000, 4096); // Map hardware regionif (hwRegs!=MAP_FAILED) {
// Direct hardware register accessuint32_tstatus=*(volatileuint32_t*)(hwRegs+0x100);
*(volatileuint32_t*)(hwRegs+0x104) =0x12345678;
unmap_physical(hwRegs, 4096);
}Memory Management APIs
// Advanced memory allocation with constraintsintallocate_physically_contiguous_32(size_tlen, uint32_t*phys, void**user, uint32_t*type);
intunallocate_mem(uint32_ttype);
void*map_physical(uint64_tphys_addr, size_tlen);
voidunmap_physical(void*virt_addr, size_tlen);CPU Control APIs
// MSR operations with core selection intlogical_cpu_select(intcpu);
msr_trdmsr(intaddr);
intwrmsr(intaddr, msr_tmsr);
// Enhanced CPUID with input controlintrdcpuid(uint32_teax, uint32_tecx, uint32_tcpudata[4]);Memory Access APIs
// Direct physical memory readingintreadmem32(uint64_taddr, uint32_t*data);
// Enhanced port I/O (including 64-bit on supported systems)unsigned charinb(unsigned shortaddr);
unsigned shortinw(unsigned shortaddr);
unsigned intinl(unsigned shortaddr);
#ifdef__EA64__unsigned longinq(unsigned shortaddr);
#endifdmidecode Integration
This fork includes patches for dmidecode integration, allowing:
# Standard dmidecode with DirectHW backend
dmidecode -t memory # Memory information via DirectHW
biosdecode # BIOS analysis via DirectHW
vpddecode # VPD decoding via DirectHWFramework Integration (Objective-C/Swift)
#import<DirectHW/DirectHW.h>@implementationHardwareController
- (void)readHardwareInfo {
if (iopl(3) == 0) {
// Hardware access availableuint32_t data;
if (readmem32(0xE0000, &data) == 0) {
NSLog(@"BIOS signature: 0x%08x", data);
}
}
}
@end| Platform | Kernel Extension | Memory Management | MSR Support | Multi-Core | Port I/O | Notes |
|---|---|---|---|---|---|---|
| macOS 13+ (Ventura+) Intel | ✅ Universal | ✅ Full DMA | ✅ All MSRs | ✅ Per-Core | ✅ Full | Complete x86_64 support |
| macOS 13+ (Ventura+) Apple Silicon | ✅ Universal | ✅ Full DMA | ❌ No MSRs | ❌ No Port I/O | ARM64 limitations | |
| macOS 10.15-12 Intel | ✅ Intel/Universal | ✅ Full DMA | ✅ All MSRs | ✅ Per-Core | ✅ Full | Complete Intel support |
| macOS 10.15-12 Apple Silicon | ✅ Universal | ✅ Full DMA | ❌ No MSRs | ❌ No Port I/O | ARM64 limitations | |
| macOS 10.9-14 Intel | ✅ Intel 64-bit | ✅ Full DMA | ✅ All MSRs | ✅ Per-Core | ✅ Full | Complete Intel support |
| Mac OS X 10.4-10.8 | ✅ Intel/PPC | ✅ Basic DMA | ✅ Limited | ✅ Legacy | Vintage system support |
⚠️ Apple Silicon Limitations
- ✅ Memory Management - Full DMA buffer allocation and physical memory mapping
- ✅ Memory-Mapped I/O - Direct hardware register access via memory mapping
- ✅ Physical Memory Access - Direct physical memory reading with
readmem32() - ✅ Universal Binary Support - Native ARM64 execution
- ❌ Port I/O Operations -
inb(),inw(),inl(),outb(),outw(),outl()are x86-specific - ❌ MSR Access - Model Specific Registers don't exist on ARM architecture
- ❌ CPUID Instructions - x86-specific instruction not available on ARM
- ❌ Multi-Core CPU Targeting - Limited to single-core operations
// On Apple Silicon, these operations return zero/no-op:msr_tmsr=rdmsr(0x1A0); // Returns { .hi = 0, .lo = 0 }rdcpuid(0x80000008, 0, cpudata); // Returns cpudata[0-3] = 0outb(0x80, 0xFF); // No operation performed// Focus on memory management and MMIO operationsvoid*hwRegs=map_physical(0x100000000ULL, 4096); // Works on ARM64if (hwRegs!=MAP_FAILED) {
uint32_tvalue=*(volatileuint32_t*)hwRegs;
*(volatileuint32_t*)(hwRegs+4) =0x12345678;
unmap_physical(hwRegs, 4096);
}
// DMA buffer allocation works fully on ARM64uint32_tphysAddr;
void*userAddr;
uint32_tbufferType;
if (allocate_physically_contiguous_32(65536, &physAddr, &userAddr, &bufferType) ==0) {
// Use DMA buffer...unallocate_mem(bufferType);
}Installation Options
DirectHW requires loading a kernel extension, which requires SIP modification on modern macOS:
- Boot into Recovery Mode (⌘+R during startup)
- Open Terminal from Utilities menu
- Configure SIP for kernel extension loading:
# Allow kernel extension loading while keeping other SIP protections csrutil enable --without kext # Or disable SIP entirely (less secure) csrutil disable
- Reboot into normal macOS
- Download the latest DMG from Releases
- Mount the DMG and run
Install DirectHW.pkg - Approve kernel extension in System Preferences → Security & Privacy
- Restart your system to load the kernel extension
- Verify installation:
kextstat | grep DirectHW
# Install kernel extension
sudo cp -R DirectHW.kext /Library/Extensions/
sudo chmod -R 755 /Library/Extensions/DirectHW.kext
sudo chown -R root:wheel /Library/Extensions/DirectHW.kext
# Install framework
sudo cp -R DirectHW.framework /Library/Frameworks/
# Install libraries
sudo cp libDirectHW.* /usr/local/lib/
# Load kernel extension (may require approval in System Preferences)
sudo kextload /Library/Extensions/DirectHW.kext# Check if DirectHW kernel extension loaded successfully
kextstat | grep DirectHW
# Check SIP status
csrutil status
# Test DirectHW functionality (requires root)
sudo -s
cd /path/to/directhw/examples
./simple_testFor kernel extension development and debugging:
# Check current boot args first
nvram boot-args
# Add kernel debugging to existing boot args (preserves other settings)
CURRENT_ARGS=$(nvram boot-args 2>/dev/null | cut -d$'\t' -f2)
sudo nvram boot-args="$CURRENT_ARGS debug=0x144"# Alternative: Add multiple debug flags to existing args
CURRENT_ARGS=$(nvram boot-args 2>/dev/null | cut -d$'\t' -f2)
sudo nvram boot-args="$CURRENT_ARGS debug=0x14e kext-dev-mode=1"# View kernel messages in real-time
sudo dmesg -w | grep DirectHW
# Remove only debug flags (preserves other boot args)
CURRENT_ARGS=$(nvram boot-args 2>/dev/null | cut -d$'\t' -f2)
CLEAN_ARGS=$(echo "$CURRENT_ARGS"| sed -E 's/debug=[^ ]*//g; s/kext-dev-mode=[^ ]*//g; s/ +/ /g; s/^ //; s/ $//')
sudo nvram boot-args="$CLEAN_ARGS"Debug Flag Meanings:
debug=0x144= Basic kernel debugging + panic debuggingdebug=0x14e= Enhanced debugging with detailed kernel messageskext-dev-mode=1= Enable development mode for unsigned kernel extensions
Building from Source
- Xcode Command Line Tools
- macOS SDK (10.9 or later recommended)
- Valid code signing certificate (for kernel extensions)
# Clone the repository
git clone https://github.com/startergo/directhw.git
cd directhw
# Build all components
xcodebuild -project DirectHW.xcodeproj -configuration Release
# Build artifacts will be in:# - build/Release/DirectHW.kext# - build/Release/DirectHW.framework # - build/Release/libDirectHW.a# - build/Release/libDirectHW.dylib# Build universal AppleScript runner (for multi-architecture support)cd create-dmg/support
make clean && make
# Create DMG with proper layout
./create-dmg/create-dmg \
--volname "DirectHW v1.5.1" \
--window-size 700 400 \
--icon-size 96 \
--icon "Install DirectHW.pkg" 200 200 \
--icon "DirectHW.framework" 350 200 \
--icon "DirectHW.kext" 500 200 \
DirectHW-v1.5.1.dmg \
/path/to/distribution/contents# Build with enhanced features
xcodebuild -project DirectHW.xcodeproj \
-configuration Release \
-arch x86_64 -arch arm64
# Integration with external projects
gcc -framework DirectHW -framework IOKit myapp.c -o myapp# Enhanced DirectHW supportOS_ARCH = $(shell uname)ifeq ($(OS_ARCH), Darwin)
LDFLAGS += -framework IOKit -framework DirectHW
CFLAGS += -DUSE_DIRECTHW
endifBuilt-in Protections & Safe Usage
- Root Privilege Enforcement - All operations require administrator access
- Memory Validation - Kernel validates all memory operations for safety
- Resource Tracking - Automatic cleanup prevents resource leaks
- Cross-Endian Safety - Proper byte ordering for Rosetta compatibility
DirectHW requires loading a third-party kernel extension, which has significant restrictions under SIP:
macOS 10.13+ (High Sierra and later):
- SIP must be partially disabled for kernel extension loading
- Requires
csrutil enable --without kextorcsrutil disable - User must approve kernel extension in System Preferences → Security & Privacy
- May require reboot into Recovery Mode to modify SIP settings
macOS 10.15+ (Catalina and later):
- Additional notarization requirements for kernel extensions
- Apple is phasing out third-party kernel extensions
- May require developer-signed kernel extensions
- SystemExtensions framework is preferred for new development
Recommended SIP Configuration:
# Check current SIP status
csrutil status
# Disable only kernel extension protection (requires Recovery Mode)
csrutil enable --without kext
# Or disable SIP entirely (NOT recommended for production)
csrutil disable// Always check return values and initializationif (darwin_init() !=0) {
fprintf(stderr, "DirectHW initialization failed\n");
fprintf(stderr, "Check that DirectHW.kext is loaded and SIP allows kernel extensions\n");
return-1;
}
// Clean up allocated resourcesuint32_tbufferType;
if (allocate_physically_contiguous_32(size, &phys, &user, &bufferType) ==0) {
// Use the buffer...unallocate_mem(bufferType); // Always clean up
}Troubleshooting
Kernel Extension Won't Load
# Check system logs for errors
sudo dmesg | grep DirectHW
# Enable detailed kernel debugging (requires reboot)
CURRENT_ARGS=$(nvram boot-args 2>/dev/null | cut -d$'\t' -f2)
sudo nvram boot-args="$CURRENT_ARGS debug=0x144"# Check SIP status (most common issue)
csrutil status
# If SIP blocks kernel extensions:# 1. Reboot into Recovery Mode (⌘+R)# 2. csrutil enable --without kext# 3. Reboot normally# Verify permissions
ls -la /Library/Extensions/DirectHW.kext
# Force reload with verbose output
sudo kextload -v /Library/Extensions/DirectHW.kext
# Watch kernel messages in real-time during load
sudo dmesg -w | grep -E "(DirectHW|kext)""Operation not permitted" Errors
- Most likely caused by SIP blocking kernel extension loading
- Check
csrutil status- should show "Kernel Extension Signing: disabled" - Modify SIP in Recovery Mode as described in installation section
"DirectHW.kext not loaded" Error
# Check if kext is present but not loaded
ls -la /Library/Extensions/DirectHW.kext
# Try manual load with verbose output
sudo kextload -v /Library/Extensions/DirectHW.kext
# Enable kernel debugging for detailed load information
sudo nvram boot-args="debug=0x144 kext-dev-mode=1"# Reboot, then try loading again# Check system preferences for kernel extension approval
open "/System/Library/PreferencePanes/Security.prefPane"# Monitor kernel messages during load attempt
sudo dmesg -w &
sudo kextload /Library/Extensions/DirectHW.kextPermission Denied in User Code
- Ensure application runs with root privileges:
sudo ./your_app - Check that DirectHW.kext is properly loaded:
kextstat | grep DirectHW - Verify SIP allows kernel extension communication
Framework Not Found
# Verify framework installation
ls -la /Library/Frameworks/DirectHW.framework
# Check search paths in Xcode project settings# Add /Library/Frameworks to Framework Search PathsApple Silicon Specific Issues
- Port I/O operations fail silently (expected - not supported on ARM64)
- MSR operations return zero (expected - no MSRs on ARM architecture)
- Focus on memory management features which work fully on Apple Silicon
Contributing & Support
- Fork the repository
- Create a feature branch
- Make your changes with appropriate tests
- Submit a pull request with detailed description
For issues, questions, or contributions:
- GitHub Issues: Report bugs or request features
- Discussions: Community support and questions
- Wiki: Additional documentation and guides
DirectHW is released under the BSD 3-Clause License. See LICENSE.txt for details.
| Version | Date | Changes |
|---|---|---|
| 1.5.1 | 2025-08-26 | Universal binary support, Apple Silicon compatibility, Enhanced CI/CD |
| 1.5.0 | 2024-xx-xx | macOS Ventura support, Security improvements |
| 1.4.x | 2023-xx-xx | Big Sur/Monterey compatibility |