一個完整的test字元裝置驅動程式,以下給出模組載入卸載方法以及簡單的測試程式。
首先編寫一個test.h,定義各個介面函數以及包含的標頭檔:
#define __NO_VERSION__
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/page.h>
static ssize_t read_test(struct file *file,char *buf,size_t count,loff_t *ppos);
static ssize_t write_test(struct file *file,const char *buf,size_t count,loff_t *ppos);
static int open_test(struct inode *inode,struct file *file);
static int release_test(struct inode *inode,struct file *file);
struct file_operations test_fops={
owner: THIS_MODULE,
read: read_test,
write: write_test,
open: open_test,
release: release_test,
};
char kernel_version[]=UTS_RELEASE;
原始碼test.c如下:
#include "test.h"
unsigned int test_major = 0;
MODULE_LICENSE("GPL");
static ssize_t read_test(struct file *file,char *buf,size_t count,loff_t *ppos)
{
size_t left;
/* int x=sizeof(buf);*/
if(verify_area(VERIFY_WRITE,buf,count)==-EFAULT)
return EFAULT;
for(left=count;left>0;left--)
{
__put_user(1,buf); //將1從核心空間拷到使用者空間
buf++;
}
return count;
}
static ssize_t write_test(struct file *file,const char *buf,size_t count,loff_t *ppos)
{
return count;
}
static int open_test(struct inode *inode,struct file *file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int release_test(struct inode *inode,struct file *file)
{
MOD_DEC_USE_COUNT;
return 0;
}
int init_module(void)
{
int result;
result=register_chrdev(0,"test",&test_fops); //註冊字元裝置模組,動態分配主裝置號
if(result<0)
{
printk(KERN_INFO"test:cant get major number/n");
return result;
}
if(test_major==0)
test_major=result;
return 0;
}
void cleanup_module(void)
{
unregister_chrdev(test_major,"test");
}
原始碼編譯載入方法如下:首先還是要確保linux核心原始碼放在/usr/src裡面,編譯原始碼:gcc -O2 -DMODULE -D__KERNEL__ -I/usr/src/linux/include -c test.c
編譯結果為test.o,載入模組:insmod test.o,載入成功可以在/proc/drivers下面看到test模組,其中主裝置號動態分配為253,接下來建立節點:mknod /dev/test c 253 0,在/dev下建立test節點,c表示test模組為字元裝置,253為主裝置號,在/proc/driver裡面可以找到,0為從裝置號。建立節點成功後可以尋找一下test模組,在/dev 下面 find -name test。
編寫一個簡單的測試程式:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
int testdev;
int i;
char buf[10];
testdev=open("/dev/test",O_RDWR);
if(testdev==-1)
{
printf("cant open file/n");
exit(0);
}
read(testdev,buf,10);
for(i=0;i<9;i++)
{printf("%d",buf[i]);}
printf("%d/n",buf[9]);
close(testdev);
}
編譯gcc -o test_app test_app.c,運行./test_app,列印出來的一概是十個1。
卸載test模組:rmmod test,打完收工 :-)