linux 字符设备的demo

linux 的版本中字符设备的操作有升级,demo的中使用的版本是 

Linux localhost.localdomain 2.6.27.5-117.fc10.i686 #1 SMP Tue Nov 18 12:19:59 EST 2008 i686 i686 i386 GNU/Linux

编译完就可以操作试试了。什么都不用改,直接就可以用了。

CODE

/*
字符设备注册的方法:
*/

#include "linux/string.h"
#include "linux/fs.h"
#include "linux/module.h"
#include "linux/types.h"
#include "linux/compiler.h"

#include 
   
   
    
     
#include 
    
    
     
      


static int hello_major;
#define HELLONAME	"hello"
#define HELLOCDEV	"hellodev"

static int hello_open(struct inode *inode, struct file *file)
{
	printk(KERN_ALERT "open hello\n");
	return 0;
}

static int hello_release (struct inode *inode, struct file *file)
{
	printk(KERN_ALERT "release hello\n");
	return 0;
}

static long hello_unlock_ioctl (struct file *file, unsigned int op, unsigned long param)
{
	printk(KERN_ALERT "hello_unlock_ioctl \n");
	return 0;
}


ssize_t hello_read(struct file *file, char __user *buf, size_t buf_len, loff_t *offset)
{
	printk(KERN_ALERT "hello_read \n");
	return 0;
}

ssize_t hello_write(struct file *file, const char __user *buf, size_t buf_len, loff_t *offset)
{
	printk(KERN_ALERT "hello_write \n");
	return 0;
}

#if 0
static struct file_operations hello_fops = {
	owner: THIS_MODULE,
	write: hello_write,
	read: hello_read,
	unlocked_ioctl :hello_unlock_ioctl,
	open: hello_open,
	release: hello_release,
};
#endif
// 标准C的标记化结构初始化语法
static struct file_operations hello_fops = {
	.owner = THIS_MODULE,
	.write = hello_write,
	.read = hello_read,
	.unlocked_ioctl = hello_unlock_ioctl,
	.open = hello_open,
	.release = hello_release,
};


static dev_t devnum;
struct cdev *cdev_hello;
struct class *cls_hello;

static int helloModule_init(void)
{
	int ret;
	
	printk("KERN_ALERT helloModule_init\n");

#if 0
	hello_major = register_chrdev(0, HELLONAME, &hello_fops);
	if (hello_major < 0) {
		printk("KERN_ALERT register hello fail\n");
		return hello_major;
	}
#endif
	ret = alloc_chrdev_region(&devnum, 0, 1, HELLOCDEV);
	if (ret) {
		printk("error\n");
	}

	// cdev_init(cdev_hello, &hello_fops);	

	/*
	 * cdev_alloc 和cdev_init 有些工作是重复的,
	 * 如果已经有cdev结构了,就用 cdev_init 来初始化
	 * cdev_init(cdev_hello, &hello_fops);	
	 * cdev_hello.ower = THIS_MODULE;
	 * 这样就可以了,cdev_hello.ops = &hello_fops; 就是多余
	 */
	cdev_hello = cdev_alloc();
	cdev_hello->owner = THIS_MODULE;
	cdev_hello->ops = &hello_fops;
	cdev_add(cdev_hello, devnum, 1);		
	// 到这里通过cat /proc/devices 可以看到我们添加的设备了
	// 但是要操作的还是要建文件,最好是在 /dev/ 目录下
	// 方法有好几种
	// 1 通过devfs 系统API    
	//     好用,但是由于技术问题被linux移除
	// 2 mknod 工具
	//     在代码里就不好用了
	// 3 udev
	//     目前用的就是这种,通过 device_create 来建立文件

	// 在/sys/class 下建立hello目录
	cls_hello = class_create(THIS_MODULE, "hello"); 

	// 在/dev/下创建文件
	device_create(cls_hello, NULL, devnum, NULL, "helloCCT");	
	
	return 0;
}

static void helloModule_exit(void)
{
	printk("KERN_ALERT helloModule exit\n");

	device_destroy(cls_hello, devnum);	
	class_destroy(cls_hello);  
	cdev_del(cdev_hello);
	unregister_chrdev_region(devnum, 1); 
}

module_init(helloModule_init);
module_exit(helloModule_exit);

MODULE_AUTHOR("CHENCHENGTIAN");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("created by cct, just for test");


    
    
   
   

Makefile

obj-m := helloworld.o  

#KDIR 要根据运行的kernel的源码目录修改
KDIR := /lib/modules/2.6.27.5-117.fc10.i686/build  

MAKE := make  
PWD  := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD)

clean:  
    $(MAKE) -C $(KDIR) M=$(PWD) clean  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值