?? 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 + -