这里介绍内核模块中对文件的读取,这个模块实现的方式是在每次插入模块的时候实现一次对文件的读和对另外一个文件的写,其他的方式读者可以自己实现,基本的流程和框架在本例子中已经体现:
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()宏来改变内核对内存地址检查的处理方式,
所以在内核空间对文件的读写流程为:
/*
* 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"
);
|