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