操作系统笔记(三)——系统调用的实现(System Call)

世界杯足彩 8917

系统调用的实现

前言

系统调用的直观实现

内核(用户)态,内核(用户)段

处理器保护环将其分为了四部分

对于内核段代码的处理用段寄存器来进行解决

硬件提供了“主动进入内核的方法”

系统调用的核心 int 0x80

拿Write函数举例

函数内部发生了什么

int 0x80中断的处理

中断处理程序

小结

前言

前面的文章说了什么是系统调用,就是系统提供给上层用户的一些函数,如open,read,write…,表面上是一些函数,背后是如何实现的呢? 这一篇文章就会记录系统调用是如何实现的。

系统调用的直观实现

反正所想要打印的代码与系统代码都在内存里,直接跳转,直接调用不可以吗? 答:肯定是不能的。 不能随意的调用内核的数据;不能随意的jmp。 如果能的话,操作系统内的很多重要的东西,比如root用户的密码,就不安全了。 所以系统调用就提供了一种可以进入内核的一种手段。

内核(用户)态,内核(用户)段

将内核程序和用户程序隔离!! 区分内核态和用户态:一种处理器“硬件设计”

处理器保护环将其分为了四部分

最内层0,为核心态。 中间两层1、2,为OS服务。 最外层3,为用户态。 当前程序执行在什么态(哪层环?)由于CS:IP是当前指令。所以用CS的最低两位来表示:0是内核态,3是用户态。 内核态可以访问任何数据,用户态不能访问内核数据。 对于指令跳转也一样,实现了隔离。

对于内核段代码的处理用段寄存器来进行解决

1. CPL(CS) 当前的特权级 current 取决于当前执行的什么指令

2. RPL(DS) 访问的数据段DS的最低两位

3. DPL 用来描述目标内存段的特权级 D目标 P特权 L级别 (DPL在GDT表中 可以找到)

4. DPL在GDT表中的级别都为0 意为内核段

5. 数字越大 特权级越低!! 只有当前的特权级>=要访问的mov的特权级,指令才可以jmp

硬件提供了“主动进入内核的方法”

对于Intel x86,那就是中断指令int int指令将使CS中的CPL改成0,“进入内核”

这是用户程序发起的调用内核代码的唯一方式。此时,CPL=3,而DPL=0。

系统调用的核心 int 0x80

(1)用户程序中包含一段包含int指令的代码 由谁做?库函数 (2)操作系统写中断处理函数,获取想调程序的编号 (3)操作系统根据编号执行相应代码

拿Write函数举例

函数内部发生了什么

在linux/include/unistd.h中

#define _syscall3(type,name,atype