/*Linux字符設備驅動源代碼scdd.c*/
#include <linux/init.h> /*模塊頭文件*/
#include <linux/module.h>
#include <linux/types.h> /*dev_t頭文件*/
#include <linux/kdev_t.h> /*MAJOR和MINOR宏頭文件*/
#include <linux/fs.h> /*register_chrdev_region等函數
file_operations結構體*/
#include <linux/cdev.h> /*struct cdev結構體*/
#include <asm/uaccess.h> /*copy_to_user函數*/
#define DEVICE_NAME "scdd" /*定義設備名*/
#define DEVICE_MAJOR 250
struct cdev my_cdev;
int scdd_open(struct inode *inode,structfile *filp)
{
return0;
}
int scdd_close(struct inode *inode,structfile *filp)
{
return0;
}
ssize_t scdd_read(struct file *filp,char__user *buff,size_t size,loff_t *offp)
{
intleft;
chardata=1;
for(left=size;left>0;left--)
{
/*拷貝數據到用戶空間*/
copy_to_user(buff,&data,1);
buff++;
}
returnsize;
}
ssize_t scdd_write(struct file *filp,char__user *buff,size_t size,loff_t *offp)
{
return0;
}
/*file_operations結構體*/
struct file_operations scdd_fops={
.owner=THIS_MODULE,
.read=scdd_read,
.write=scdd_write,
.open=scdd_open,
.release=scdd_close,
};
static int __init scdd_init(void)
{ /*模塊初始化函數*/
intsmajor;
smajor=DEVICE_MAJOR;
dev_tdev_n=MKDEV(smajor,0);
/*申請設備號*/
if(!register_chrdev_region(dev_n,1,DEVICE_NAME))
{ /*靜態申請*/
printk("registersuccess\n");
}else
{
gotoregister_error;
}
/*else
{ /*動態申請*/
/*alloc_chrdev_region(&dev_n,0,1,DEVICE_NAME);
smajor=MAJOR(dev_n);
}*/
/*初始化cdev結構體*/
cdev_init(&my_cdev,&scdd_fops);
my_cdev.owner=THIS_MODULE;
my_cdev.ops=&scdd_fops;
/*注冊字符設備*/
cdev_add(&my_cdev,dev_n,1);
return0;
register_error:
unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);
return0;
}
static void __exit scdd_exit(void)
{ /*模塊卸載函數*/
cdev_del(&my_cdev);
unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);
}
module_init(scdd_init);
module_exit(scdd_exit);
MODULE_LICENSE("Dual BSD/GPL");
這個程序只是簡單演示字符注冊的一個完整過程,並不帶有復雜的操作,調用read時向用戶空間寫全1