Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1351662
  • 博文数量: 244
  • 博客积分: 10311
  • 博客等级: 上将
  • 技术积分: 3341
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-14 21:50
文章分类

全部博文(244)

文章存档

2013年(6)

2012年(5)

2011年(16)

2010年(11)

2009年(172)

2008年(34)

分类: LINUX

2009-03-02 14:58:33


这是一个字符驱动的框架,使用固定分配主设备号和次设备号,功能只是读取内核
中的一段字符串“hello world!”但是麻雀随小无脏俱全!
模块代码
/*chardev.c*/
#include
#include /*for file-f_op*/
#include
#include /*for copy_to_user()*/
#include /*for cdev ,cdev_init,cdev_add....*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Helight");

#define DP_MAJOR 250 /*the major number of the chardev*/
#define DP_MINOR 0 /*the minor number of the chardev*/
static int char_read(struct file *filp,char __user *buffer,size_t,loff_t
*); /*the read operation of the chardev----read the data from kernel*/
static int char_open(struct inode *,struct file *); /*open the chardev*/
static int char_write(struct file *filp,const char __user *buffer,size_t
,loff_t*); /*write data to kernel*/
static int char_release(struct inode *,struct file *); /*release the
chardev*/
static char *arr,*p;
static int chropen; /*the chardev open or not*/
struct cdev *chardev; /*define a char device*/
static int len;

struct file_operations char_ops = {
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release,

};

static int __init char_init(void)
{
dev_t dev;
printk(KERN_ALERT"Initing......\n");
dev=MKDEV(DP_MAJOR,DP_MINOR);
chardev = cdev_alloc( );

if(chardev==NULL){
return -1;
}

if(register_chrdev_region(dev,10,"chardev")<0){
printk(KERN_ALERT"Register char dev error\n");
return -1;
}

chropen=0;
len=0;
//chardev->ops = &char_ops;
cdev_init(chardev,&char_ops);
if(cdev_add(chardev,dev,1)<0)
{
printk(KERN_ALERT"Add char dev error\n");

}

return 0;

}

static int char_open(struct inode *inode,struct file *file)
{
if(chropen==0)
chropen++;
else{
printk(KERN_ALERT"Another process open the char device\n");
return -1;
}

try_module_get(THIS_MODULE);
return 0;

}

static int char_release(struct inode *inode,struct file *file)
{
chropen--;
module_put(THIS_MODULE);
return 0;

}

static int char_read(struct file *filp,char __user *buffer,size_t
length,loff_t *offset)
{
int i=0;
if(length     if(copy_to_user(buffer,"hello world!",length))
     {
            return 0;
      }
}else{
     if(copy_to_user(buffer,"hello world!",12))
     {
            return 0;
      }
}

return i;

}

static int char_write(struct file *filp,const char __user *buffer,size_t
length,loff_t *offset)
{

int i=0;
return i;

}

static void __exit module_close(void)
{
len=0;
printk(KERN_ALERT"Unloading..........\n");
kfree(arr);
unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10);
cdev_del(chardev);

}

module_init(char_init);
module_exit(module_close);

用户程序
/*main.c*/
#include
#include
#include
#include
#include
#include
#include

int main(void)
{
int testdev;
int i;
char buf[15];

testdev = open("/dev/chardev0",O_RDWR);
if ( testdev == -1 )
{
printf("Cann't open file \n");
exit(0);
}

memset(buf, 0, sizeof(buf));
if(i=read(testdev,buf,12)<0)
perror("read error\n");


printf("Re:%d %s\n",i,buf);
close(testdev);

return 0;

}

Makefile文件:

obj-m:=chardev.o
KERNELDIR=/usr/src/linux-headers-2.6.22-14-generic/
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
gcc -o main main.c

使用步骤:
1。make模块
2。insmod模块
3。mknod结点,具体命令如下:
mknod /dev/chardev0 c 250 0
命令解释:
mknod是建立节点的命令;
/dev/chardev0:在/dev/目录下建立chardev0这样一个节点,
c:这个节点是指向一个字符设备的节点
250:这个设备的主设备号;
0:次设备号
4。chmod 666 /dev/chardev0 使其他用户也可以对这个设备进行读写操作,否则
只有root用户可以对他进行读写
5。编译用户程序
6,运行用户程序./main
7.如果没有什么问题的话应该要输出
Re:12 hello world!
这几个字符。
阅读(757) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~