linux设备驱动归纳总结(十):1.udev&misc【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-111839.html

linux设备驱动归纳总结(十):1.udev&misc

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

不知不觉我的总结已经写得七七八八了,这一章节只是补充一下两个知识点:动态创建设备节点和杂设备类的注册。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

一、动态创建设备节点——udev

之前加载字符型设备后是通过命令mknod来创建设备节点的。在2.6内核中,有一个名叫udev的后台程序,它通过读取/sys/class的信息,一旦添加的新的设备,该后台程序就会自动创建设备节点。

一、要使用动态创建设备节点,首先要运行udev后台程序。

在嵌入式下有两种方法:

1、移植udev到嵌入式系统中。

2、在编译busybox时加入mdev。

mdev可以理解是udev的精简版,在这里我就不介绍如何加入mdev,仅仅介绍udev的移植。

首先:进入到udev的目录,我在附件中提供了udev的源文件:

[email protected]:/nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096# pwd

/nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096

接着修改Makefile的两处:

line 96 prefix = /nfsroot //指定udev安装路径,安装到我们的跟文件系统中

linr 114 CROSS_COMPILE = arm-linux- //指定编译工具

然后编译并安装:

make

make install

最后在跟文件系统的/nfsroot/etc/init.d/rcS加上三句话,让系统启动后运行udev后台程序:

mount -t tmpfs tmpfs /dev

/sbin/udevd -d

/sbin/udevstart

移植udev后,系统启动是就会自己启动udev程序。

二、接着就是在代码中使用动态创建函数了。

udev的动态创建是通过读取/sys/class的信息来实现的。所以,首先是要创建一个类:

struct class *class_create(struct module *owner, const char *name)

owner用于指定该类的所属,一般填写THIS_MODULE。

name是指定该类该/sys/class/目录下的目录名字。

同样的,该操作有可能出错,需要检验返回值。

类创建成功后会在/sys/class创建一个以name命名的目录。

类的注销使用以下函数:

void class_destroy(struct class *cls)

创建类后,就可以调用以下函数注册类设备,将设备加入到指定的类中,这样udev就可以才class目录下读取信息后动态创建设备节点了:

/*drivers/base/core.c*/

1386 struct device *device_create(struct class *class, struct device *parent,

1387 dev_t devt, void *drvdata, const char *fmt, ...)

class是用于指定所属的class。

parent用于指定设备的父设备,一般填NULL就可以了。

Devt用于指定该设备的设备号。

drvdata用于指定class下的数据,一般也不用传。

fmt就是动态创建的设备文件的名字,一般格式:"%s", "test_led"。

设个函数成功调用会在/sys/devices/virtual的对应总线下创建一个test_led的目录,并且软连接到/sys/class对应的总线目录下。

使用以下函数注销类设备:

void device_destroy(struct class *class, dev_t devt)

注意:上面的两步并没有真正创建设备文件,只有在udev读取/sys/class信息后发现tesl_led,才会真正创建设备文件。

先来来个代码,这是我之前写的简洁版led驱动,添加了动态创建设备文件功能:

/*10th_udev_misc/udev/1st_udev/test.c*/

7 #include //需要包含该头文件

10 struct class *my_class;

。。。。。

62 int test_init(void)

63 {

64      //devmodel class create

65      my_class = class_create(THIS_MODULE, "test_class"); //创建class

66      if(IS_ERR(my_class)){

67           printk("create cleaa wrong!\n");

68           return -1;

69      }

70      device_create(my_class, NULL, MKDEV(253, 0), NULL, "%s", "test_led"); //根据class和设备号创建设备

71

72      register_chrdev(253, "udev led", &led_fops);

73      led_init(); //ioremap的地址映射

74      led_config(); //gpio_led的配置

75

76      return 0;

77 }

78 void test_exit(void)

79 {

80      iounmap((void *)virt); //注销虚拟地址的映射

81      unregister_chrdev(253, "udev led"); //注销设备节点

82      device_destroy(my_class, MKDEV(253, 0)); //注销类设备

83      class_destroy(my_class); //注销类

84      printk("bye\n");

85 }

接下来验证一下:

[root: 1st_udev]# insmod test.ko //加载驱动

[root: 1st_udev]# ./app on //灯亮

[root: 1st_udev]# ./app off //灯灭

[root: 1st_udev]# cat /proc/devices //查看一下

Character devices:

1 mem

。。。。。

136 pts

204 s3c2410_serial

253 udev led //设备被注册了

254 rtc

[root: 1st_udev]# cd /

[root: /]# find -name "*test_led*" //查找test_led相关文件

./sys/devices/virtual/test class/test_led ///device/virtule目录下有test_led目录

./sys/class/test class/test_led //并且有类test_class

./dev/test_led //动态创建了test_led设备文件

[root: 1st_udev]# ls -l /sys/class/test\ class/test_led

lrwxrwxrwx 1 root root 0 Jan 1 08:29 /sys/class/test class/test_led -> ../../devices/virtual/test class/test_led

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

二、杂设备——misc

简单的说,杂设备就是内核自动帮你分配设备号并且自动创建设备文件。

1、自动分配设备号,是指所有注册为杂设备的设备的主设备号为10,而次设备号内核自动分配。

2、自动创建设备文件是指,内核会使用udev(前提是你已经移植udev),动态创建设备节点。

方法很简单:需要包含头文件:linux/miscdevice.h
1、定义杂设备结构体:

36 struct miscdevice {

37      int minor;

38      const char *name; //设备文件的名字

39      const struct file_operations *fops; //指定该设备的fops结构体

40      struct list_head list;

41      struct device *parent;

42      struct device *this_device;

43 };

红色标记的内容是我们必须要自己填写的,其他部分可以由内核自己分配。

2、定义结构体后使用使用一下函数注册和注销:

int misc_register(struct miscdevice * misc); //注册

int misc_deregister(struct miscdevice *misc); //注销

注册操作会失败,建议检查返回值。

看代码:

/*10th_udev_misc/misc/1st_misc/test.c*/

58 static struct file_operations led_fops = {

59      .ioctl = led_ioctl,

60 };

61

62 static struct miscdevice misc_led = { //杂设备

63      .name = "test_led",

64      .fops = &led_fops,

65 };

66

67 int test_init(void)

68 {

69      misc_register(&misc_led); //注册杂设备

70

71      led_init(); //ioremap的地址映射

72      led_config(); //gpio_led的配置

73

74      return 0;

75 }

76 void test_exit(void)

77 {

78      misc_deregister(&misc_led); //注销杂设备

79      iounmap((void *)virt); //注销虚拟地址的映射

80      printk("bye\n");

81 }

再看效果

[root: 1st_misc]# insmod test.ko

[root: 1st_misc]# cat /proc/devices

Character devices:

1 mem

4 /dev/vc/0

4 tty

5 /dev/tty

5 /dev/console

5 /dev/ptmx

7 vcs

10 misc //创建的设备在misc中

[root: 1st_misc]# lsmod

test 2212 0 - Live 0xbf000000

[root: 1st_misc]# ls -l /dev/test_led

crw-rw---- 1 root root 10, 0 Jan 1 08:05 /dev/test_led //自动创建的设备节点主设备号为10

[root: 1st_misc]# ./app on //亮灯

[root: 1st_misc]# ./app off //灭灯

[root: 1st_misc]# cd / //查看test_led相关文件

[root: /]# find -name "*test_led*"

./sys/devices/virtual/misc/test_led

./sys/class/misc/test_led //发现注册到misc类中

./dev/test_led

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

三、总结

这节介绍了如何动态创建设备文件和如果创建杂设备类驱动。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

时间: 2024-08-08 13:55:10

linux设备驱动归纳总结(十):1.udev&misc【转】的相关文章

linux设备驱动归纳总结

前言: (总结已经基本写完,这段时间我会从新排版和修正.错误总会有的,望能指正!) 前段时间学习了嵌入式驱动,趁着没开始找工作,这段时间我会每天抽出时间来复习. 我的总结是根据学习时的笔记(李杨老师授课).<linux内核设计与实现>第三版.<linux设备驱动程序>第三版和<linux设备驱动开发详解>第一版来归纳的.文章中涉及一些自己的想法,并不能保证所说的一定正确. 我也是一位linux初学者,在这里发博也是想跟大家分享技术,同时也希望别人能够指正错误. 我把一些

linux设备驱动归纳总结(三):5.阻塞型IO实现【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-60025.html linux设备驱动归纳总结(三):5.阻塞型IO实现 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 一.休眠简介: 进程休眠,简单的说就是正在运行的进程让出CPU.休眠的进程会被内核搁置在在一边,只有当内核再次把休眠的进程唤醒,进程才会会重新在CPU运行

linux设备驱动归纳总结(三):6.poll和sellct【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-61749.html linux设备驱动归纳总结(三):6.poll和sellct xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 接下来会讲系统调用select在驱动中的实现,如果对系统调用select不太懂的话,建议先看书补习一下. xxxxxxxxxxxxxxxxxxxx

linux设备驱动归纳总结(三):7.异步通知fasync【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-62725.html linux设备驱动归纳总结(三):7.异步通知fasync xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 异步通知fasync是应用于系统调用signal和sigaction函数,下面我会使用signal函数.简单的说,signal函数就是让一个信号与与

linux设备驱动归纳总结(七):1.时间管理与内核延时【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-100005.html linux设备驱动归纳总结(七):1.时间管理与内核延时 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 这节将介绍一些很枯燥的内核,大体是内核中时间的概念和内核延时的使用,并没有源代码. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现【转】

本文转自自:http://blog.chinaunix.net/uid-25014876-id-59418.html linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现 一.结构体struct file和struct inode 在之前写的函数,全部是定义了一些零散的全局变量.有没有办法整合成到一个结构体当中?这样的话,看起来和用起来都比较方便.接下来就要说这方面的问题. 不过先要介绍一下除了fops以外的两个比较重要的结构体: 1)struct file 在内核中,f

linux设备驱动归纳总结(四):5.SMP下的竞态和并发

linux设备驱动归纳总结(四):5.多处理器下的竞态和并发 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 这节将在上一节的基础上介绍支持多处理器和内核抢占的内核如何避免并发.除了内核抢占和中断外,由于多处理起的缘故,它可以做到多个程序同时执行.所以,进程除了要防自己的处理器外,还要防别的处理器,这个就是这节要介绍的内容. xxxxxxxxxxxxxxxxxxxxxxx

linux设备驱动归纳总结(三):6.poll和sellct

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 接下来会讲系统调用select在驱动中的实现,如果对系统调用select不太懂的话,建议先看书补习一下. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 一.系统调用select的简介 简单来说,se

linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】

本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 这一节可以理解是第八章的延伸,从这节开始介绍platform设备驱动. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx