get_ds, set_fs, get_fs函数的使用

在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()); fp->f_op->read(fp, buf, 2, &fp->f_pos); //调用真正的read set_fs(old_fs); //恢复环境 printk(KERN_ALERT "ftyjl:read[%s]\n", buf); printk(KERN_ALERT "end of Hello ,ftyjl.\n"); return 0;}void cleanup_module(void){ printk(KERN_ALERT "Good bye, ftyjl\n");}MODULE_LICENSE("Proprietary");一个人的天地是冷得连呼吸都会寂寞的颤栗,而麻烦,

get_ds, set_fs, get_fs函数的使用

相关文章:

你感兴趣的文章:

标签云: