📄 testdriver.c
字号:
/*TestDriver.c*/
/*一个简单的字符设备驱动实例*/
#define __NO_VERSION__
#include <linux/modules.h>
#include <linux/version.h>
char kernel_version [] = UTS_RELEASE;
#define KERNEL
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/segment.h>
#define SUCCESS 0
static int device _read(struct inode *, struct file *, char *, int);
static int device_open(struct inode *inode, struct file *file)
static void device _release(struct inode *, struct file *);
/*在fs.h中定义有与入口相关的数据结构*/
struct file_operations tdd_fops =
{
NULL,
device _read,
NULL,
NULL,
NULL,
NULL,
NULL,
device _open,
device _release,
NULL,
NULL,
NULL,
NULL
};
/*设备声明 ******************************** */
/*将出现在 /proc/devices 中设备名*/
#define DEVICE_NAME "char_dev"
/*设备正打开?防止对同一设备的同时访问*/
static int Device_Open = 0;
unsigned int test_major = 0;
/*当被询问时设备将给出的消息*/
static char Message[BUF_LEN];
/*这个函数在进程试图打开设备文件时被调用*/
static int device_open(struct inode *inode, struct file *file){
#ifdef DEBUG
printk ("device_open(%p)\n", file);
#endif
/*不想同时和两个进程对话*/
if (Device_Open)
return -EBUSY;
Device_Open++;
MOD_INC_USE_COUNT;
return SUCCESS;
}
/*这个函数在关闭设备时调用*/
static void device_release(struct inode *inode, struct file *file){
#ifdef DEBUG
printk ("device_release(%p,%p)\n", inode, file);
#endif
/*为下个调用者做准备*/
Device_Open --;
MOD_DEC_USE_COUNT;
}
/*read()入口,这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的
缓冲区全部写1*/
static int device_read (struct inode *node,struct file *file,char *buf,int count){
int left;
if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )
return -EFAULT;
for(left = count ; left > 0 ; left--){
/*在device_read被调用时,系统进入核心态,所以不能使用buf这个地址,而必须用_put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数,请参考<linux/mm.h>*/
_put_user(1,buf,1);
buf++;
}
return count;
}
/*init_module向系统的字符设备表登记一个字符设备*/
int init_module(void)
{
int result;
/*注册字符设备*/
result = register_chrdev(0, " char_dev", & tdd_fops);
if (result < 0) {
printk(KERN_INFO "char_dev: can't get major number\n");
return result;
}
/*如果登记成功,则返回0,得到设备的主设备号,如不成功,则返回一个负值*/
if (test_major == 0) test_major = result;
/*安装进入内核时打印提示信息*/
printk("Hello,I'm in kenel mode\n");
return 0;
}
void cleanup_module(void)
{
printk("Hello,I'm going to out \n");
unregister_chrdev(test_major, "test");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -