Skip to content

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");

// register char device
// create /dev/myplatdev

return 0;

} @@@


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