欢迎转载,转载时需保留做者信息,谢谢。linux
邮箱:tangzhongp@163.comweb
博客园地址:http://www.cnblogs.com/embedded-tzp数据结构
Csdn博客地址:http://blog.csdn.net/xiayulewaapp
为了简化问题,上图省略了app层与driver层中间的libc层。socket
linux驱动的开发步骤:设备号→设备(struct cdev,struct input_dev等)→驱动(struct file_operations)→应用层接口(建立/dev)ide
linux应用的open最终调用驱动struct file_operations的open,依次类推。函数
设备节点:atom
即/dev目录下面的设备,当驱动层申请设备号后,经过cat /proc/devices 能够查询到申请设备的主次设备号。而后管理员能够手动去建立该设备,命令形式为:mknod -m 777 /dev/buttons c 249 0 spa
以linux下的/dev/fb0设备节点为例:.net
tang@tang-vm ~ $ cat /proc/devices
Character devices:
...
29 fb
...
可见其主设备号为29.
tang@tang-vm ~ $ ls /dev/fb0 -l
crw-rw---- 1 root video 29, 0 4月 14 00:01 /dev/fb0
设备节点/dev/fb0主设备号与cat /proc/devices获得的一致。
|
。
![]() |
|
||||
|
l 在sysfs下建立类
/sys
├── class
│ ├── input
│ │ ├── event0 -> ../../devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input0/event0
│ ├── leds → 由cls = class_create(THIS_MODULE, "leds"); //建立设备类
│ │ └── phy0-led -> ../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/phy0-led →由 device_create(cls, NULL, dev, NULL, "phy0-led"); //建立/sys/class/leds/phy0-led
l udev自动加载
加载模块insmod *.ko的时候,用户空间中的udev会自动响应 device_create(…)函数,内核产生uevent, 在kset下产生uevent文件,其文件内容为action(add, remove等), 经过netlink socket被守护进程udevd捕获后,扫描/sys下的uevent文件,在/dev下自动建立对应的设备号。 见下面例子
l e.g
cls = class_create(THIS_MODULE, "leds-atomic"); //
device_create(cls, NULL, dev, NULL, "myled");//dev/myled
当insmod 该驱动后,
cat /sys/class/leds-atomic/myled/uevent(文件在内核中数据结构为struct attribute)
→ MAJOR=250
MINOR=0
DEVNAME=myled
所以,udevd根据上述uevent文件在建立设备节点 /dev/myled, major和minor分别为250和0。