filp_open与filp_close和get_fs 与set_fs
来源:互联网 发布:sql count用法 慢 编辑:程序博客网 时间:2024/06/04 17:58
在linux内核编程时,进行系统调用(如文件操作)时如果要访问用户空间的参数,可以用set_fs,get_ds等函数实现访问。get_ds获得kernel的内存访问地址范围(IA32是4GB),set_fs是设置当前的地址访问限制值,get_fs是取得当前的地址访问限制值。进程由用户态进入核态,linux进程的task_struct结构中的成员addr_limit也应该由0xBFFFFFFF变为0xFFFFFFFF(addr_limit规定了进程有用户态核内核态情况下的虚拟地址空间访问范围,在用户态,addr_limit成员值是0xBFFFFFFF也就是有3GB的虚拟内存空间,在核心态,是0xFFFFFFFF,范围扩展了1GB)。使用这三个函数是为了安全性。为了保证用户态的地址所指向空间有效,函数会做一些检查工作。
如果set_fs(KERNEL_DS),函数将跳过这些检查。
下面是典型用法:
//#define __NO_VERSION__
//#define __KERNEL__
//#define MODULE
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>;
#include <linux/init.h>;
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/file.h>;
#include <linux/fs.h>;
#include <linux/sched.h>;
#include <asm/uaccess.h>;
#include <asm/processor.h>;
int init_module(void)
{
struct file *fp = NULL;
char buf[100];
int i;
for(i=0;i<100;i++)
buf[i] = 0;
printk(KERN_ALERT "Hello ,ftyjl.\n");
fp = filp_open("/tmp/8899", 3, 0); //内核的open函数,返回struct file *
if (fp == NULL)
printk(KERN_ALERT "filp_open error ,ftyjl.\n");
mm_segment_t old_fs=get_fs(); //下面两步,设置当前执行环境为kernel_ds,否则会出错
set_fs(get_ds()); //set_fs(KERNEL_DS)
fp->f_op->read(fp, buf, 2, &fp->f_pos); //调用真正的read
如果set_fs(KERNEL_DS),函数将跳过这些检查。
下面是典型用法:
//#define __NO_VERSION__
//#define __KERNEL__
//#define MODULE
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>;
#include <linux/init.h>;
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/file.h>;
#include <linux/fs.h>;
#include <linux/sched.h>;
#include <asm/uaccess.h>;
#include <asm/processor.h>;
int init_module(void)
{
struct file *fp = NULL;
char buf[100];
int i;
for(i=0;i<100;i++)
buf[i] = 0;
printk(KERN_ALERT "Hello ,ftyjl.\n");
fp = filp_open("/tmp/8899", 3, 0); //内核的open函数,返回struct file *
if (fp == NULL)
printk(KERN_ALERT "filp_open error ,ftyjl.\n");
mm_segment_t old_fs=get_fs(); //下面两步,设置当前执行环境为kernel_ds,否则会出错
set_fs(get_ds()); //set_fs(KERNEL_DS)
fp->f_op->read(fp, buf, 2, &fp->f_pos); //调用真正的read
//vfs_read() 也可以调VFS的读接口
set_fs(old_fs); //恢复环境
printk(KERN_ALERT "ftyjl:read[%s]\n", buf);
filp_close(fp,NULL); //关闭文件
printk(KERN_ALERT "end of Hello ,ftyjl.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Good bye, ftyjl\n");
}
MODULE_LICENSE("Proprietary");
set_fs(old_fs); //恢复环境
printk(KERN_ALERT "ftyjl:read[%s]\n", buf);
filp_close(fp,NULL); //关闭文件
printk(KERN_ALERT "end of Hello ,ftyjl.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Good bye, ftyjl\n");
}
MODULE_LICENSE("Proprietary");
- filp_open与filp_close和get_fs 与set_fs
- get_fs()和set_fs()解析
- set_fs get_fs
- get_fs,set_fs使用原理
- get_fs,set_fs使用原理
- Usage of get_fs and set_fs
- 在linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- 在linux内核中操作文件的方法--使用get_fs()和set_fs(get_ds())
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
- 关于get_ds, set_fs, get_fs函数的使用
- get_ds, set_fs, get_fs函数的使用
- get_ds, set_fs, get_fs函数的使用
- C/C++中的变量存储类别以及内存分配
- MyEclipse8.6注册码
- 趣味算式
- 跟我一起写 Makefile(四)
- 移动字母
- filp_open与filp_close和get_fs 与set_fs
- 《c和指针》笔记--让rand更随机一点
- 锁的位置和效率
- 密码截获
- LINUX-C成长之路(三):基本IO函数操作
- 数字游戏
- 一个最简单的MFC应用程序
- uva 11168 Airport(训练指南)
- 带分数