一个简单的演示用的Linux字符设备驱动程序.
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实现如下的功能:
--字符设备驱动程序的结构及驱动程序需要实现的系统调用
--可以使用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目录
下建立设备结点,而建立结点时要指定主设备号。当然,你可以写一个脚本来自动完成
这些事情。
总之,作为一个演示,我们还是指定主设备号为145
这样我们可以在/dev/目录下建立几个设备节点。
[root@char8139]$ mknod /dev/char8139_0 c 145 0
[root@char8139]$ mknod /dev/char8139_0 c 145 17
[root@char8139]$ mknod /dev/char8139_0 c 145 36