Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1517295
  • 博文数量: 338
  • 博客积分: 2695
  • 博客等级: 少校
  • 技术积分: 3556
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-05 11:37
个人简介

小鱼儿游啊游啊。。。。

文章分类

全部博文(338)

文章存档

2019年(4)

2018年(8)

2017年(6)

2016年(10)

2015年(49)

2014年(48)

2013年(98)

2012年(115)

分类: LINUX

2012-10-23 19:17:06

在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 ;
#include ;
#include ;
#include ;
#include ;
#include ;
#include ;
#include ;
#include ;


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");
阅读(1636) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~