
In today’s high-performance computing environments, even a small inefficiency in driver architecture can lead to major bottlenecks. For developers working with custom hardware and device drivers, Jungo’s WinDriver offers a unique approach to maximizing throughput and responsiveness via Kernel Plugins (KPs). This post walks you through what Kernel Plugins are, why you should use them, and how to get started building one using WinDriver’s tools.
🧠 What is a Kernel Plugin?
A Kernel Plugin (KP) is a block of code that runs in kernel mode, giving it direct access to hardware and low-level resources. Unlike standard user-mode drivers that must constantly switch between user and kernel mode, KPs handle time-sensitive tasks like interrupts and DMA transfers directly in the kernel, avoiding costly context switches.
This architectural shift results in major performance gains, especially in high-speed applications.
🚀 Why Use a Kernel Plugin?
Here’s why Kernel Plugins are worth your attention:
- Speed: Handle 100,000+ interrupts per second without missing a beat.
- Efficiency: Eliminates the back-and-forth between user and kernel mode.
- Portability: Same KP source code works across Windows, Linux, and macOS.
- Safety: Develop and test logic in user mode first, then port to kernel mode—reducing crash risk.
🧱 Kernel Plugin Architecture
A Kernel Plugin runs independently of the user application, though the two communicate via message passing and callback functions.
Key interactions include:
- Driver load
- Handle request
- Message call
- Interrupt handling
✅ Tip: Use the high-level WDC_* API for most KP operations to simplify development and maintain portability.
🛠️ Building Your First Kernel Plugin
Follow these steps to get started:
- Use the PCI Diag Sample
Located in the WinDriver installation folder, this is a fully working driver + KP example. - Generate Your Driver
Open the Driver Wizard GUI, scan your PCI device, and generate a new project. Enable the Kernel Plugin option during setup. - Edit the Plugin Code
The Wizard generates skeleton KP code. You’ll primarily edit kp_init, kp_call, and kp_int_handler. - Message Passing
Use WDC_CallKerPlug() in user mode to invoke your KP logic. Use shared headers to keep enums, struct names, and command codes synchronized between modes.

⚡ Interrupt Handling in Kernel Mode
Interrupts can overwhelm a user-mode driver. But in kernel mode:
- You can process interrupts immediately.
- Handle high IRQL tasks with minimal delay.
- Offload lower-priority tasks using Deferred Procedure Calls (DPCs), keeping the system responsive.
Real-World Example
On Lattice’s CPNX and Avant FPGAs, switching to Kernel Plugin interrupt handling improved DMA throughput by over 100%.

✅ Best Practices
- Develop in User Mode First
Fully test and debug before moving any logic into the kernel. - Keep IRQL Sections Short
Do the bare minimum in kpinthandler() and defer everything else. - Use Shared Headers
Maintain one source of truth for constants, enums, and IOCTL codes across both layers. - Gradual Migration
Don’t port everything at once. Move only critical functions into the KP.
Contact our team today to learn more about WinDriver.
Download WinDriver for free, and enjoy our 30-day trial.