Day 10 – Platform Driver + Device Tree (Driver Model Introduction)¶
🎯 Objective¶
Understand the core concepts of the Linux driver model:
- Device Tree (DT) describes hardware
- Platform driver matching mechanism
- probe / remove lifecycle
- Creating a character device in probe()
🧠 Core Concepts¶
1️⃣ Linux Driver Model¶
@@@ Device (from Device Tree) ↓ Platform Bus ↓ Platform Driver ↓ probe() is invoked @@@
Key idea:
- Devices are defined by Device Tree
- Drivers wait for matching devices
2️⃣ Relationship Between Device and Driver¶
| Component | Description |
|---|---|
| Device Tree | Describes hardware existence |
| Platform Device | Created by kernel from DT |
| Platform Driver | Matches using compatible string |
| probe() | Called when device and driver match |
3️⃣ compatible Matching Mechanism¶
Device Tree¶
@@@ myplatdev@0 { compatible = "mycompany,myplatdev"; }; @@@
Driver¶
@@@ static const struct of_device_id myplatdev_of_match[] = { { .compatible = "mycompany,myplatdev" }, { } }; MODULE_DEVICE_TABLE(of, myplatdev_of_match); @@@
Kernel performs:
@@@ DT compatible == driver compatible → match → probe() @@@
🔥 Driver Flow¶
Traditional Flow (Day 9 mindset)¶
@@@ insmod ↓ module_init() ↓ driver creates device @@@
Platform Driver Flow (Day 10)¶
@@@ Device Tree defines device ↓ Kernel creates platform device ↓ insmod driver ↓ Match compatible ↓ probe() is called ↓ Create /dev/myplatdev @@@
Key shift:
👉 Device drives the driver (not the other way around)
🧩 Platform Driver Structure¶
@@@ static struct platform_driver myplatdev_driver = { .probe = myplatdev_probe, .remove = myplatdev_remove, .driver = { .name = "myplatdev", .of_match_table = myplatdev_of_match, }, };
module_platform_driver(myplatdev_driver); @@@
🧩 probe() and remove()¶
probe()¶
- Called when a matching device is found
- Used for initialization
@@@ static int myplatdev_probe(struct platform_device *pdev) { pr_info("myplatdev: probe called\n");
} @@@
remove()¶
- Called when device is removed or module unloaded
@@@ static int myplatdev_remove(struct platform_device *pdev) { // cleanup resources return 0; } @@@
🧩 Character Device Creation Flow¶
Inside probe():
@@@ alloc_chrdev_region cdev_init cdev_add class_create device_create @@@
Result:
@@@ /dev/myplatdev @@@
⚠️ Permission Issue¶
Common error:
@@@ echo "test" > /dev/myplatdev → Permission denied @@@
Solutions:
@@@ sudo chmod 666 /dev/myplatdev @@@
or
@@@ sudo sh -c 'echo test > /dev/myplatdev' @@@
🧪 Test Procedure¶
1️⃣ Verify Device Tree¶
@@@ ls /proc/device-tree/myplatdev@0 cat /proc/device-tree/myplatdev@0/compatible @@@
2️⃣ Load Driver¶
@@@ sudo insmod myplatdev_platform.ko @@@
3️⃣ Check Logs¶
@@@ dmesg | tail @@@
Expected:
@@@ myplatdev: probe called @@@
4️⃣ Test Device¶
@@@ echo "hello" > /dev/myplatdev cat /dev/myplatdev @@@
🧠 Difference from Day 9¶
| Item | Day 9 | Day 10 |
|---|---|---|
| Driver type | Platform driver | Platform driver |
| Device source | Driver / GPIO DT | Device Tree |
| Focus | GPIO control | Driver model |
| probe() usage | Yes | Yes |
| GPIO subsystem | Yes | No |
| Abstraction level | Real hardware | Framework / structure |
🔥 Key Takeaways¶
1️⃣ driver ≠ device¶
@@@ Driver is passive Device determines driver usage @@@
2️⃣ probe() is the real initialization¶
@@@ module_init → register driver probe → initialize device @@@
3️⃣ module_platform_driver only registers driver¶
@@@ It does NOT create device It does NOT trigger probe @@@
Required condition:
@@@ Device + Driver + match @@@
🚀 Next Step (Day 11)¶
- Use
gpiod_get() - Retrieve GPIO from Device Tree
- Control real hardware (LED / button)
- Move from framework to hardware interaction