快速业务通道

一个简单的演示用的Linux字符设备驱动程序

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-05-06
实现如下的功能:
--字符设备驱动程序的结构及驱动程序需要实现的系统调用
--可以使用cat命令或者自编的readtest命令读出"设备"里的内容
--以8139网卡为例,演示了I/O端口和I/O内存的使用
本文中的大部分内容在Linux Device Driver这本书中都可以找到,
这本书是Linux驱动开发者的唯一圣经.
=======================================================
先来看看整个驱动程序的入口,是char8139_init()这个函数
如果不指定MODULE_LICENSE("GPL"), 在模块插入内核的
时候会出错,将非"GPL"的模块插入内核就沾污了内核的
"GPL"属性.
module_init(char8139_init);
module_exit(char8139_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ypixunil");
MODULE_DESCRIPTION("Wierd char device driver for Realtek 8139 NIC");

接着往下看char8139_init()

static int __init char8139_init(void)
{
int result;

PDBG("hello. init.n");

/* register our char device */
result=register_chrdev(char8139_major, "char8139", &char8139_fops);
if(result<0)
{
PDBG("Cannot allocate major device number!n");
return result;
}
/* register_chrdev() will assign a major device number and return if it called
* with "major" parameter set to 0 */
if(char8139_major == 0)
char8139_major=result;

/* allocate some kernel memory we need */
buffer=(unsigned char*)(kmalloc(CHAR8139_BUFFER_SIZE, GFP_KERNEL));
if(!buffer)
{
PDBG("Cannot allocate memory!n");
result= -ENOMEM;
goto init_fail;
}
memset(buffer, 0, CHAR8139_BUFFER_SIZE);
p_buf=buffer;

return 0; /* everything''s ok */

init_fail:
char8139_exit();
return result;
}

这个函数的工作就是使用register_chrdev()注册我们的设备的主设备号和系统调用.
系统调用对于字符设备驱动程序来说就是file_operations接口.

我们先来看看char8139_major的定义,
#define DEFAULT_MAJOR 145
/* data structure used by our driver */
int char8139_major=DEFAULT_MAJOR; /* major device number. if initial value is 0,
the kernel will dynamically assign a major device
number in register_chrdev() */
这里我们指定我们的设备的主设备号是145,你找到一个系统中没有用的主设备号,
可以通过"cat /proc/devices"命令来查看系统中已经使用的主设备号.

[michael@char8139]$ cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 ttyS
5 cua
7 vcs
10 misc
14 sound
116 alsa
128 ptm
136 pts
162 raw
180 usb
195 nvidia
226 drm

Block devices:
2 fd
3 ide0
22 ide1
[michael@char8139]$

可见在我的系统中,145还没有被使用.

指定主设备号值得考虑.像上面这样指定一个主设备号显然缺乏灵活性,不能保证
一个驱动程序在所有的机器上都能用.可以在调用register_chrdev()时将第一个
参数,即主设备号指定为0,这样register_chrdev()会分配一个空闲的主设备号
作为返回值. 但是这样也有问题,我们只有在将模块插入内核之后才能得到我们设备
的主设备号(使用 "cat /proc/devices"),但是要操作设备需要在系统/dev目录
下建立设备结点,而建立结点时要指定主设备号.当然,你可以写一个脚本来自动完成
这些事情.

总之,作为一个演示

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号