内核态下的设备文件操作(filp_open)
时间:2009-07-31 来源:red_eyed_hare
Linux驱动编程书籍大多数都是介绍怎样用户态下怎么访问硬件设备,由于项目的需要,本人做了内核态下访问设备文件的方法,现在把程序拿出来和大家分享一下,希望对刚入门的朋友有所帮助。
在我的《内核模块调用驱动》中给出了简单的字符设备文件程序,可以作为本文的驱动对象,在此,我就不多介绍了。调用驱动程序的模块如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include "chardev.h" MODULE_LICENSE("GPL"); //#define __KERNEL_SYSCALLS__
#define bao "/dev/baovar"
static char buf1[20];
static char buf2[20];
static int __init testmod_init(void)
{
mm_segment_t old_fs;
ssize_t result;
ssize_t ret;
sprintf(buf1,"%s","baoqunmin");
struct file *file=NULL;
file=filp_open(bao,O_RDWR,0);
if(IS_ERR(file)) goto fail0;
old_fs=get_fs();
set_fs(get_ds());
ret=file->f_op->write(file,buf1,sizeof(buf1),&file->f_pos);
result=file->f_op->read(file,buf2,sizeof(buf2),&file->f_pos);
if(result>=0){buf2[20]='\n';printk("buf2-->%s\n",buf2);}
else printk("failed\n");
result=file->f_op->ioctl(file,buf2,sizeof(buf2),&file->f_pos);
result=file->f_op->read(file,buf2,sizeof(buf2),&file->f_pos);
set_fs(old_fs);
filp_close(file,NULL);
printk("file loaded\n");
return 0;
fail0:{filp_close(file,NULL);printk("load failed\n");}
return 1;
} static void __exit testmod_cleanup(void)
{
printk("module exit......................................................\n");
} module_init(testmod_init);
module_exit(testmod_cleanup); 以上是完整的程序,直接可以编译运行。 #include "chardev.h"头文件定义如下,此头文件也必须在驱动中包含! #include <linux/ioctl.h> #define BAO_IOCTL 't'
#define IOCTL_READ _IOR(BAO_IOCTL, 0, int)
#define IOCTL_WRITE _IOW(BAO_IOCTL, 1, int)
#define BAO_IOCTL_MAXNR 1 以下给出了我的Makefile文件: CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include
test.o :test.c
$(CC) $(MODCFLAGS) -c test.c
echo insmod test.o to turn it on
echo rmmod test to turn it off
echo 1.先加载设备驱动,我的设备文件为bao, 2.再make以上文件 3./sbin/insmod test.o加载模块 4.dmesg 查看运行结果 5./sbin/rmmod test 6.卸载加载的驱动 我在Linux red hat 9.0下成功运行 我实现的只是在模块间对驱动程序的调用,可以说是这是一个最简单的例子。 希望大家能有所收获!
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include "chardev.h" MODULE_LICENSE("GPL"); //#define __KERNEL_SYSCALLS__
#define bao "/dev/baovar"
static char buf1[20];
static char buf2[20];
static int __init testmod_init(void)
{
mm_segment_t old_fs;
ssize_t result;
ssize_t ret;
sprintf(buf1,"%s","baoqunmin");
struct file *file=NULL;
file=filp_open(bao,O_RDWR,0);
if(IS_ERR(file)) goto fail0;
old_fs=get_fs();
set_fs(get_ds());
ret=file->f_op->write(file,buf1,sizeof(buf1),&file->f_pos);
result=file->f_op->read(file,buf2,sizeof(buf2),&file->f_pos);
if(result>=0){buf2[20]='\n';printk("buf2-->%s\n",buf2);}
else printk("failed\n");
result=file->f_op->ioctl(file,buf2,sizeof(buf2),&file->f_pos);
result=file->f_op->read(file,buf2,sizeof(buf2),&file->f_pos);
set_fs(old_fs);
filp_close(file,NULL);
printk("file loaded\n");
return 0;
fail0:{filp_close(file,NULL);printk("load failed\n");}
return 1;
} static void __exit testmod_cleanup(void)
{
printk("module exit......................................................\n");
} module_init(testmod_init);
module_exit(testmod_cleanup); 以上是完整的程序,直接可以编译运行。 #include "chardev.h"头文件定义如下,此头文件也必须在驱动中包含! #include <linux/ioctl.h> #define BAO_IOCTL 't'
#define IOCTL_READ _IOR(BAO_IOCTL, 0, int)
#define IOCTL_WRITE _IOW(BAO_IOCTL, 1, int)
#define BAO_IOCTL_MAXNR 1 以下给出了我的Makefile文件: CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include
test.o :test.c
$(CC) $(MODCFLAGS) -c test.c
echo insmod test.o to turn it on
echo rmmod test to turn it off
echo 1.先加载设备驱动,我的设备文件为bao, 2.再make以上文件 3./sbin/insmod test.o加载模块 4.dmesg 查看运行结果 5./sbin/rmmod test 6.卸载加载的驱动 我在Linux red hat 9.0下成功运行 我实现的只是在模块间对驱动程序的调用,可以说是这是一个最简单的例子。 希望大家能有所收获!
相关阅读 更多 +