在Kernel 中,照理說能存取至 0 ~ 4GB。但是實作層面卻是只能讓我們使用到3GB ~ 4GB

這會導致我們無法使用open(),write()這些在user space下的function。

而這樣的限制,實作在current->addr_limit 中

在Kernel中若真的想要能存取 0 ~ 4GB ,就要利用set_fs()與get_fs()來達成。

因為有這樣的限制存在,所以當我們在Linux撰寫程式碼時,如果也叫用了這些系統呼叫的函式,由於這些函式

(像是open(),write())被限定只能存取0—3GB的記憶體空間,可是因為我們目前是在核心程式碼使用這些系統函式,

所以說我們所配置的記憶體空間會是在3GB—4GB之間,

所以如果沒有把系統函式所能存取的記憶體空間重新設定為0—4GB的話,

那我們在核心使用的系統函式將會發生無法存取3GB以上記憶體空間的錯誤.

所以,我們可以在許多的Linux核心函式中看到以下的程式碼區段

oldfs=get_fs(); 

set_fs(KERNEL_DS); 設定為可以存取 0—4GB,包括Linux核心所屬的記憶體空間 執行核心所提供的系統呼叫

filp->f_op->write(filp,buf,size,&filp->f_pos);   

set_fs(oldfs); 執行完系統呼叫後,重新把記憶體空間設定回0—3GB

只有使用上面的方法,才能在内核中使用open,write等的系统调用。其实这样做的主要原因是open,write的参数在用户空间,在这些系统调用的实现里需要对参数进行检查,就是检查它的参数指针地址是不是用户空间的。

系统调用本来是提供给用户空间的程序访问的,所以,对传递给它的参数(比如上面的buf),它默认会认为来自用户空间,在->write()函数中,为了保护内核空间,一般会用get_fs()得到的值来和USER_DS进行比较,从而防止用户空间程序“蓄意”破坏内核空间。 为了解决这个问题; set_fs(KERNEL_DS)将其能访问的空间限制扩大到KERNEL_DS,这样就可以在内核顺利使用系统调用了!

我们这里以open系统调用为例子,它最终会调用下面所示的函数:

satic

int do_getname(const char __user *filename, char *page) {

int retval;  unsigned long len = PATH_MAX;

if (!segment_eq(get_fs(), KERNEL_DS)) {

if ((unsigned long) filename >= TASK_SIZE)

return -EFAULT;

}

其中就会对char __user *filename这个用户指针进行判断,如果它不是segment_eq(get_fs(), KERNEL_DS)就需要如上面描述的检查它的指针是不是用户空间指针。内核使用系统调用参数肯定是内核空间,为了不让这些系统调用检查参数所以必须设置  set_fs(KERNEL_DS)才能使用该系统调用.

file->f_op->write的流程可能会调用access_ok->__range_ok,而__range_ok会判断访问的buf是否在0~addr_limit之间,如何是就ok,否则invalid,这显然是为用户准备的检查。addr_limit一般设为__PAGE_OFFSET,在内核空间,buf肯定>__PAGE_OFFSET,必须修改addr_limit,这就是set_fs的由来。

ps: 在 x86 linux 系統上 ,
KERNEL_DS 為 0xFFFFFFFF ,
USER_DS 可為 0x2000000 , 0x4000000 or 0x80000000 , 所以 , 很容易知道目前 IP 在哪個 space 上
 
 
所以 linux 提供了 :
get_fs() : 取得 process(thread) 的 limited address ( 即 USER_DS )
get_ds() : 取得 Kernel Space limited address ( KERNEL_DS )
set_fs( KERNEL_DS or USER_DS ) : 設定 task limit addr

如何在LinuxKernel中操作file(set_fs與get_fs)的更多相关文章

  1. 如何在MFC中操作资源句柄

    如何获取动态库中对话框相关资源,避免因资源问题报错? AfxGetResourceHandle用于获取当前资源模块句柄AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄. ...

  2. WPF MVVM 如何在ViewModel中操作View中的控件事件

    (在学习Wpf的时候,做一个小例子,想在TextBox改变后,检验合法性,并弹出提示.在找了很多贴后,发现这个小例子,抄袭过来,仅供参考. 最后也找到了适合自己例子的办法:在出发TextChanged ...

  3. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  4. 如何在mybatis 中使用In操作

    如何在mybatis 中使用In操作 假如我们想使用这样一个sql 语句,但是这样的sql语句有IN这样的操作.在我们的mybatis中有相对应的操作 SELECT * FROM product_db ...

  5. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  6. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  7. java学习(九) —— java中的File文件操作及IO流概述

    前言 流是干什么的:为了永久性的保存数据. IO流用来处理设备之间的数据传输(上传和下载文件) java对数据的操作是通过流的方式. java用于操作流的对象都在IO包中. java IO系统的学习, ...

  8. 如何在js或者jquery中操作EL表达式的一个List集合

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先说明此篇博客看明白了可以干嘛: 就是在js或者jquery中操作一个EL表达式的一个list集合或者复杂类型 ...

  9. 如何在VC++ 中调试MEX文件

    MEX文件对应的是将C/C++文件语言的编写之后 得到的相关文件加载到Matlab中运行的一种方式, 现对于Matlab 中的某些程序运行效率而言, C/C++ 代码某些算法的领域上面执行效率很高,若 ...

随机推荐

  1. gRPC-Web正式发布

    前言: gRPC-Web是一个JavaScript客户端库,可以使Web应用程序直接与后端gRPC服务进行通信,而无需HTTP服务器充当中介. 这意味着可以通过使用.proto文件定义客户端和服务器端 ...

  2. CodeForces 707D Persistent Bookcase ——(巧妙的dfs)

    一个n*m的矩阵,有四种操作: 1.(i,j)处变1: 2.(i,j)处变0: 3.第i行的所有位置1,0反转: 4.回到第k次操作以后的状态: 问每次操作以后整个矩阵里面有多少个1. 其实不好处理的 ...

  3. C#获取实体类属性名和值

    遍历获得一个实体类的所有属性名,以及该类的所有属性的值 //先定义一个类: public class User { public string name { get; set; } public st ...

  4. sklearn4_混合分类器

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003&u ...

  5. 求平面上N点最远两点和最近两点距离

    最近两点,二分法 最远两点,凸包+找对踵点

  6. LC 652. Find Duplicate Subtrees

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...

  7. Maven 默认 SpringMVC-servlet.xml 基本配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  8. zabbix客户端监控

    1.安装zabbix客户端软件: yum install -y zabbix20-agent2.修改配置文件vim /etc/zabbix_agentd.conf修改如下: (1)更改Server,S ...

  9. C#中的datatable类型作为参数传入SQL的存储空间

    SQL中首先建立一个结构一样的自定义类型的表格,在存储空间中申明一个此类型的变量,此处注意此时后面必须有readonly,如: @paravalue_insert MaterialStruct rea ...

  10. debian系统安装vsftpd服务端和ftp客户端

    一.服务器安装和配置 1.安装vsftpd.(此处切换到su权限下了.其它用户请使用sudo权限,没有sudo权限的看前面的教程进行安装) apt-get install vsftpd 2.配置vsf ...