linux 内核模块文件操作

 

这里介绍内核模块中对文件的读取,这个模块实现的方式是在每次插入模块的时候实现一次对文件的读和对另外一个文件的写,其他的方式读者可以自己实现,基本的流程和框架在本例子中已经体现:

kernel_file.c

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
 
我们注意到在vfs_read和vfs_write函数中,其参数buf指向的用户空间的内存地址,如果我们直接使用内核空间的指针,则会返回-EFALUT。
所以我们需要使用set_fs()和get_fs()宏来改变内核对内存地址检查的处理方式,
所以在内核空间对文件的读写流程为:
  mm_segment_t fs = get_fs();
  set_fs(KERNEL_FS); 
  vfs_write(); 或者 vfs_read();   
  set_fs(fs);
 
/*
  * Copyright (c) 2010-~ zhouyongfei
  *
  * The source code is released for free distribution under the terms of the GNU General Public License
  *
  *
  * Author:  alen Chou<zhouyongfei1988@gmail.com>
  * Created Time: 2010年11月27日 星期六 10时56分22秒
  * File Name: kernel_file.c
  * Description:
  *
  */
  
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
  
#define FILE_PATH_READ "/home/zhou/alen/file_read_test"
#define FILE_PATH_WRITE "/home/zhou/alen/new_file_test"
  
struct file *file = NULL;
struct inode *inode = NULL;
  
int *file_buf;
loff_t fsize;
mm_segment_t old_fs;
  
/*
  * 内核文件打开函数
  * 参数为文件路径
  * 操作file类型结构变量
  *
  */
static int kernel_file_open( char *file_path)
{
     file = filp_open(file_path,O_RDWR|O_CREAT,0777);
     if (IS_ERR(file)){
         printk( "Open file %s failed..\n" ,file_path);
         return 0;
     }
  
     return 0;
}
  
/*
  * 内核文件大小获取
  * 参数为获得的文件file结构体
  * 返回文件大小
  *
  */
static loff_t kernel_file_size( struct file *file)
{
     inode = file->f_dentry->d_inode;
     fsize = inode->i_size;
     printk(KERN_ALERT "size = %d\n" ,( int )fsize);
     return fsize;
}
  
/*
  * 内核文件读函数
  * 封装了vfs_read函数
  *
  */
void *kernel_file_read( struct file *file,loff_t fsize)
{
     int *buff;
     loff_t *pos = &(file->f_pos);
     buff = ( int *)kmalloc(fsize+100,GFP_KERNEL);
     vfs_read(file,buff,fsize,pos);
     return buff;
}
  
/*
  * 内核文件写函数
  * 封装了vfs_write函数
  *
  */
static int kernel_file_write( struct file *file, int *buf,loff_t fsize)
{
     loff_t *pos = &(file->f_pos);
     vfs_write(file,buf,fsize,pos);
     return 0;
}
  
static int hello_init( void )
{
     printk(KERN_ALERT "hello alen's file-test in kernel module.\n" );
     kernel_file_open(FILE_PATH_READ);
     kernel_file_size(file);
     old_fs = get_fs();
     set_fs(KERNEL_DS); //扩展内核空间到用户空间
     file_buf = kernel_file_read(file,fsize);
     filp_close(file,NULL);
     set_fs(old_fs); //恢复内核空间
  
     kernel_file_open(FILE_PATH_WRITE);
     old_fs = get_fs();
     set_fs(KERNEL_DS);
     kernel_file_write(file,file_buf,fsize);
     filp_close(file,NULL);
     set_fs(old_fs);
  
     return 0;
}
  
static void hello_exit( void )
{
     printk(KERN_ALERT "bye bye alen's kernel space..\n" );
}
  
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE( "Dual BSD/GPL" );
 
 
 
obj-m:=kernel_file.o
  
KDIR?= /lib/modules/ $(shell uname -r) /build
  
all:
     make -C $(KDIR) M=$(PWD) modules
clean:
     make -C $(KDIR) M=$(PWD) clean
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值