一个完整的Linux测试模块驱动程序

来源:互联网 发布:虚拟机安装ubuntu教程 编辑:程序博客网 时间:2024/05/21 10:23
一个完整的Linux测试模块驱动程序

一个完整的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,打完收工 :-)

原创粉丝点击