linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘建议留言网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > article > Linux开发区 > 内核研究 >
栏目导栏
资料搜索
热门文章
·linux-2.6内核升级文档
·Linux源代码的注释
·linux2.6内核编译方法详述
·Linux操作系统内核编译详解
·Linux内核结构详解
·Linux配置与编译内核
·定时器
·Linux内核升级全攻略
·FC5(Fedora Core5)下编译内核总
·Ubuntu 6.06 dapper 内核编译初
·Linux 内核编译详解
·Linux内核管理基础知识概述
·Linux2.4升级到2.6内核升级指南
·第八章 设备驱动
·如何编译linux内核
最新文章
·Linux Kernel 最新稳定版2.6.2
·Kernel硬件中断的初始化流程
·Linux内核bootsplash功能的实现
·Linux内核2.6.25全新发布加入众
·Debian Linux系统编译内核标准
·Linux2.4内核和2.6内核对Initr
·2.6.24内核编译 initrd-2.6.24
·Qtopia应用程序与Linux内核数据
·Linux 2.6内核中sysfs文件系统
·Linux2.6内核驱动移植参考
·Andrew Morton:Linux内核的执法
·Fedora 8 Linux系统的内核配置
·Kernel中的irq.c函数
·Linux核心出现权限扩张及记忆体
·Linux 2.6本地权限提升漏洞
Google
 
内核入门:较为基础的Linux系统设备驱动
[ 作者:  加入时间:2007-12-12 11:54:02  来自:Linux联盟收集整理 ]
 

驱动程序为:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static unsigned int major = 0;
static unsigned int minor = 0;
static unsigned int devno;
static char *filename = "mydevice";
static struct cdev *mycdev = NULL;
static int mycdevflg = 0;
static int devnoflg = 0;
static int adddevflg = 0;
MODULE_LICENSE("Dual BSD/GPL");
static int myopen(struct inode *inodep, struct file *flipl)
{ 
printk("my open is run\n");
return 0;
}
static ssize_t myread(struct file *flip, char __user *buf,PnvLinux联盟
size_t size, loff_t offset) { printk("myread is ok!\n"); static int i = 0; ///copy_to_user(buf,from,size); *buf = i++; return 0; } static int myrelease(struct inode *myindoe, struct file *flip) { printk("myrelease is run.\n"); return 0; } static struct file_operations myfops = { .owner = THIS_MODULE, .open = myopen, .read = myread, .release= myrelease, }; /* 初始化设备的过程主要是三步:1,生成设备号;2初始化设备;3,添加到内核。 */ static int __init myinit(void) { int result = -1; if(major) { devno = MKDEV(major,minor); //生成设备号 result = register_chrdev_region(devno,1,filename);PnvLinux联盟
//注册设备号devno,1为设备的个数 devnoflg = 1; } else { result = alloc_chrdev_region(&devno,minor,1,filename);//生成设备号兵注册, mior为次设备号,这里注意的是指针devno? major = MAJOR(devno); devnoflg = 1; } if(result < 0) { printk("can't register the major num!\n"); devnoflg = 0; return -1; } //mycdev = kmalloc(sizeof(struct cdev),GFP_KERNEL); //如果采用cdev_init(struct cdev*,struct file *)方式的话,这个才需要。 mycdev = cdev_alloc();//申请cdev内存兵初始化设备cdev,不能在这之前申请内存, 否则要释放两次! if(NULL == mycdev) { printk("can't request the memory!\n"); } mycdevflg = 1; //memset(mycdev,0,sizeof(mycdev)); mycdev->owner = THIS_MODULE;PnvLinux联盟
//如果采用cdev_init(struct cdev*,struct file *)方式的话, 这两项可以去掉 mycdev->ops = &myfops;//如果采用cdev_init(struct cdev*,struct file *)方式的话, 这两项可以去掉 result = cdev_add(mycdev,devno,1);//设备和设备号联系起来, 即通常说的添加设备到内核 if(result < 0) { printk("can't add cdev.2\n"); adddevflg = 0; } else { adddevflg = 1; } return 0; } /* 以和设备注册的次序"卸载",注意有的时候,当出错的时候,要注意是否用到这些操作, 所以要加上判断,否则比如对空指针free会导致系统崩溃! */ static void myexit(void) { printk("myexit begin.\n"); if(adddevflg) { cdev_del(mycdev); adddevflg = 0; } if(mycdev) { kfree(mycdev); mycdev = NULL; } if(devnoflg) { unregister_chrdev_region(devno,1); devno = 0; devnoflg = 0; } printk("exit over.\n"); } module_init(myinit); module_exit(myexit);

应用程序为:

#include 
#include 
#include 
#include 
#include 
int main() 
{ 
int fd; 
int i=0; 
fd = open("/dev/mydevice", O_RDONLY); 
if (fd < 0) 
{ 
printf("error1\n"); 
return -1; 
} 
int j = 0;
while(j++<10000)
{
if (read(fd, &i, sizeof(int)) < 0) 
{ 
printf("read error2\n"); 
return -1; 
} 
printf("i = %d\n",i);
}
close("/dev/mydevice");
return 0; 
}

一定要注意register_chrdev_region(),alloc_chrdev_region(),cdev_init(),cdev_alloc(),cdev_add()这些函数的参数类型,不要把指针当成非指针,把int类型当作指针(或者&)来使用!

Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·Linux系统内核有待提高的七个领域  (2007-12-09 19:23:05)
 ·Linux内核isdn_net.c文件 本地溢出漏洞  (2007-12-07 13:48:23)
 ·一种解读Linux操作系统内核源码的好方法  (2007-12-06 18:03:07)
 ·Linux内核有待提高的七个领域  (2007-11-29 11:11:54)
 ·我的FreeBSD6.2内核配置文件  (2007-11-26 11:47:09)
 ·FreeBSD系统优化部分内核参数调整中文注释  (2007-11-26 10:58:50)
 ·关于Linux内核源码使用的心得  (2007-11-23 10:09:35)
 ·linux内核模块管理命令  (2007-11-21 11:51:46)
 ·linux 内核升级失败处理方法  (2007-11-21 11:45:00)
 ·开源社区在挑战Linux内核开发的极限速度  (2007-11-21 10:42:46)