Linux 0.11内核之系统调用机制

Linux系统调用

注:本文代码均取自Linux 0.11版本内核源码,下载链接:http://oldlinux.org/Linux.old/kernel/0.1x/,用到时会注明源码路径。

1. 系统调用是什么?

一句话说,系统调用(syscalls)是上层应用程序与系统内核进行交互通信的唯一接口。

那么,为什么不能让用户程序直接访问内核资源?又是什么机制使得用户程序不能直接访问内核资源?若用户程序想要访问内核资源,又该怎么做?本文将依次回答这三个问题

2. 为什么不能让用户程序直接访问内核资源

对于这个问题,可以有很多合理的解释,如通过系统调用来使用硬件而不用关心具体的硬件设备可以简化用户程序的开发、系统调用可以让用户程序合规的使用硬件资源、系统调用使得用户程序有更好的可移植性、系统调用有效的分离了用户程序和内核的开发等等。下面,我们主要从安全的角度来解释为什么不能让用户程序直接访问内核资源。

假设用户程序可以直接访问内核资源,而内核中通常存储有很多重要信息,如系统root用户密码、其他应用程序在内核中的发送、接收缓冲区数据等,如下图所示:

RNR1bR.png

因此,若毫不限制对用户程序对内核资源的访问,会带来严重安全问题。因此,计算机需要提供一种机制来限制用户程序对内核资源的直接访问。下面就来探讨一下这种机制在Linux系统中是如何实现的。

3. 什么机制使得用户程序不能直接访问内核资源

首先,这种限制用户程序不能直接访问内核资源的机制是由硬件实现的。这种硬件机制将内存分为用户段和内核段(计算机对内存的使用是以段为单位的),用户段工作在用户态,而内核段工作在内核态。那么,这种硬件是通过什么来区分用户段和内核段的呢?当然是通过段寄存器。下面简要介绍段寄存器中几个很重要的概念:

  1. CPL:CPL是当前进程的特权级(Current Privilege Level),是当前正在执行的代码所在的段的特权级,存在于CS寄存器的低两位。当程序转移到不同特权级的代码段时,处理器将改变CPL。只有0和3两个值,分别表示用户态和内核态。
  2. DPL:DPL(Descriptor Privilege Level)存储在段描述符中,规定访问该段的权限级别,每个段的DPL固定。当进程访问一个段时,需要进程特权级检查,一般要求DPL >= max {CPL, RPL}。
  3. RPL:RPL(Request Privilege Level)是通过段选择子的第0和第1位表现出来的。RPL是代码中根据不同段跳转而确定,以动态刷新CS里的CPL,在代码段选择符中。而且RPL对每个段来说不是固定的,两次访问同一段时的RPL可以不同。操作系统往往用RPL来避免低特权级应用程序访问高特权级段内的数据,即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的,当RPL的值比CPL大的时候,RPL将起决定性作用。也就是说,RPL相当于附加的一个权限控制,只有当RPL>DPL的时候,才起到实际的限制作用。

在分段机制中,特权级总共有4个特权级别,于系统初始化时确定,从高到低分别是0、1、2、3,数字越小表示的特权级别越大,其中,用户段和内核段所对应的特权级分别为0和3,通过这种机制实现了用户程序和内核程序的隔离。如下图所示:

RNWPJK.png

计算机中,正在执行的指令是通过PC指针指定,而PC指针由CS:IP确定,也就是段基址+偏移,而前面已经提过,CS寄存器低两位就是CPL,所以每个正在执行的指令都有一个用于指示当前特权级的CPL标志。对于用户态,在操作系统初始化时将其置为3,而当操作系统初始化时,会对内核态代码建立GDT表,其中初始化了内核态下代

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值