linux中设备驱动和设备文件

3 篇文章 0 订阅
可能是以前的驱动太多简单,也可能是我看书的时候不够仔细,一直以为ko写好以后,insmod成功以后就能在/dev下直接引用。其实不然。
对于misc类型的驱动,可能确实如此(没有系统的考证过)。但是对于字符设备和块设备,insmod驱动以后,只是单纯的加载了驱动。可以使用cat对/proc/devices进行查看。如下:
________________________________________________________________________________________________
[root@FriendlyARM /irr2013]# 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
 13 input
 14 sound
 21 sg
 29 fb
 81 video4linux
 89 i2c
 90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyUSB
189 usb_device
204 s3c2410_serial
253 IRR_GPF0
254 rtc
Block devices:
259 blkext
  7 loop
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
____________________________________________________________________________________
众所周知,/proc不是一个真实存在的文件夹。 而是对内存情况的一个反映,提供一个接口而已。这个cat出的信息中,前面的数字是注册设备时获得的主设备号。如果想获得对设备的引用,可以使用mknod指令:
在文件系统上创建一个设备节点的命令是mknod,而且你必须是 超级用户才能操作。除了要创建的节点名字外,该命令还带三个参数。例如,命令:
mknod /dev/scull0 c 254 0
创建一个字符设备(c),主设备号是254,次设备号是0。由于历史原因,次设备号应该在0-255范围内,有时它们存储在一个字节中。存在很多原因扩展可使用的次设备号的范围,但就现在而言,仍然有8位限制。
请注意:如果一旦用mknod生成了一个特别的设备文件,它就永远存在了硬盘上,除非你明白的删除了它。你可以通过执行命令"rm"命令来删除例子中的设备。
rm /dev/scull0
——————————————————————————————————————————————————
 
当没有使用devfs时,向系统增加一个 驱动程序意味着要赋值它一个主设备号。这一赋值过程应该在 驱动程序(模块)的初始化过程中完成,它调用如下函数,这个函数定义在<linux/fs.h>:
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
返回值提示成功或者失败。返回一个负值,表示出错;返回零或正值,表示成功。参数major是所请求的主设备号,name是你的设备的名字,它将在/proc/devices中出现,fops是一个指向函数队列的 指针,利用它完成对设备函数的调用。
主设备号是一个用来索引静态 字符设备组的整数,“动态分配主设备号”将在本章的稍后部分中介绍怎样选择一个主设备号。2.0 内核支持128个 设备驱动,而2.2和2.4内核支持256个(保留数值0和255为将来使用)。而次版本号(8位字节的数)并没有传递给 register_chrdev函数,因为次版本号是 驱动程序自己使用的。开发团队为了增加 内核可能支持的设备数量而带来了很大的压力,在开发树2.5版本内核的目标中,设备号至少是16位的。
一旦设备驱动程序注册到 内核表中,它的操作都与分配的主设备号匹配,何时在 字符设备文件上操作都与它的主设备号相关联,内核都会通过 file_operations 结构体查找并调用相应的驱动程序中的函数。为了这个原因,传递给 register_chrdev指针应该是指向 驱动程序中的全局 结构体,而不是一个局部的一个模块初始化函数。
接下来的问题就是如何给程序一个名字以被它们用来请求你的设备驱动程序。这个名字必须插入到/dev目录中,并与你的驱动程序的主设备号和次设备号相连。
____________________________________________________________________
 
某些主设备号已经静态地指派给了大部分常见设备。在 内核源代码树的Documentation/device.txt文件中可以找到这些设备的列表。由于许多编号已经分配了,为新设备选择一个唯一的编号是很困难的——可配置的设备要比主设备号多得多。
所幸,可以对主设备号进行动态分配。如果调用register_chrdev时将major设为0,则该函数会自动选择一个空闲的号码并返回作为该设备的主设备号。返回的主设备号总是正值,而返回负值时表明出错。注意如下两种情况的细微差别:若调用者请求一个动态的主设备号时函数register_chrdev返回值为所分配的主设备号,而当成功地注册到一个预先定义的主设备号时(即不采用动态分配而采用 静态指派方式),函数返回值为0而非主设备号。
对于private dirvers,强烈建议使用动态分配的方法来得到主设备号。相反,如果你的设备普遍应用在大多数场合甚至要被包含在官方的内核树中,你就需要指派一个主设备号作为专用。
动态分配的缺点是:由于分配给你的主设备号不能保证总是一样的,因而你无法用mknod命令事先创建设备节点(即设备文件)(可在加载模块时用脚本自动创建)。这意味着你将不能使用Chapter 11中介绍的关于“按需载入模块(loading-on-demandof your driver)”的先进特性。对于用于一般用途的 驱动程序,这不是什么问题,因为一旦分配了设备号,你就可以从/proc/devices读取相关的设备号信息。
为了加载一个用动态分配来得到主设备号的驱动程序,对 insmod的调用需要被替换为一个简单的 脚本,这个脚本先调用insmod,再读/proc/devices以得到主设备号,并创建设备文件。
 更多相关内容,请关注我的个人微信公众号:hearwithlisten
微信 扫描以下二维码可以关注我的公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值