Introduction – When printk Stops Being Enough
You start debugging your driver with printk().
At first, it works well.
You print values, trace execution, and fix bugs.
But then things get messy…
- You want to inspect a variable without rebooting
- You need to read internal driver state on demand
- You want to modify behavior at runtime
- You don’t want to flood logs with debug prints
And suddenly, printk() starts feeling… limited.
💭 What if you could directly interact with your driver from user space?
💭 What if you could read/write kernel variables like files?
That’s exactly where debugfs comes into the picture.
🔍 What is debugfs in Linux Kernel?
debugfs is a virtual filesystem in Linux that allows kernel developers to:
👉 Expose internal kernel data
👉 Interact with driver variables
👉 Debug without modifying logs
It is specifically designed for debugging purposes.
⚠️ Important Note
debugfsis not meant for production use- It does not enforce strict ABI rules
- It is mainly for development and debugging
📂 Mounting debugfs
Before using debugfs, you need to mount it:
mount -t debugfs none /sys/kernel/debug
Or check if already mounted:
mount | grep debugfs
🧪 Scenario – Why debugfs is Powerful
Let’s say you are writing a driver.
You want to:
- Check current buffer values
- Monitor hardware registers
- Toggle debug mode
- Inject test inputs
With printk():
❌ You must recompile or reboot
❌ Logs get cluttered
❌ No control from user space
With debugfs:
✔ Read values anytime
✔ Modify behavior dynamically
✔ No recompilation needed
Creating debugfs Entries
Kernel provides APIs to create debugfs files.
📝 Step 1: Create Directory
struct dentry *dir;
dir = debugfs_create_dir("my_driver", NULL);
📝 Step 2: Create File
debugfs_create_u32("value", 0644, dir, &my_variable);
This creates a file:
/sys/kernel/debug/my_driver/value
🧪 Access from User Space
cat /sys/kernel/debug/my_driver/value
echo 10 > /sys/kernel/debug/my_driver/value
What Just Happened?
You exposed a kernel variable as a file!
✔ Read → cat
✔ Write → echo
No recompilation. No reboot.
Advanced debugfs Usage
You can create custom file operations:
debugfs_create_file("status", 0644, dir, NULL, &fops);
Where fops defines:
- read()
- write()
- open()
This allows:
✔ Complex debugging logic
✔ Structured output
✔ Interactive control
Benefits of debugfs
✔ Real-time debugging
✔ No kernel rebuild required
✔ Clean alternative to excessive printk
✔ Easy integration with drivers
✔ User-space interaction
⚠️ Limitations of debugfs
❌ Not secure for production
❌ No stable interface guarantee
❌ Should not expose sensitive data
debugfs vs printk vs Dynamic Debug
| Feature | printk | Dynamic Debug | debugfs |
|---|---|---|---|
| Runtime control | ❌ | ✔ | ✔ |
| Data interaction | ❌ | ❌ | ✔ |
| User-space access | ❌ | ❌ | ✔ |
| Structured output | ❌ | ❌ | ✔ |
| Use case | Logging | Log control | State inspection |
Best Practices
- Use
debugfsfor state inspection - Use
pr_debugfor temporary logs - Avoid debugfs in production builds
- Combine with dynamic debug for powerful debugging
Summary
When debugging gets complex:
👉 printk shows what happened
👉 dynamic debug controls when to log
👉 debugfs lets you interact with the system
That’s why debugfs is a game changer in driver development.
Build Strong Debugging Skills
Debugging is not just about tools.
It’s about understanding the system deeply.
If you want to master:
✔ Embedded Linux fundamentals
✔ Kernel internals
✔ Device driver development
✔ Real debugging workflows
Check out:
👉 https://embitude.in/embedded-linux-bundle/
🎥 Learn more on YouTube:
👉 https://www.youtube.com/@PradeepTewani
🤝 Join the community of like-minded professionals:
👉 https://embitudeinfotech.graphy.com/s/community