2019-2020-1 20199304《Linux内核原理与分析》第五周作业 第四章 系统调用的三层机制(上)

4.1 用户态、内核态和中断

知识点总结:

  • 与系统调用打交道的方式是通过库函数的方式。
  • 用户态与内核态的区分
    • 内核态:高的执行级别下,代码可以执行特权指令,访问任意的物理内存
    • 用户态:低级别指令
  • 系统调用也是一种中断
    • 中断处理是从用户态进入内核态的主要方式
    • 当用户态切换到内核态时,就要把用户态寄存器上下文保存起来,同时要把内核态的寄存器的值放到当前CPU中
  • 进入及内核态是有中断触发,可能是硬件中断,也可能是Trap。
  • int指令触发中断机制会保存用户态堆栈顶地址、当时的状态字、当时的CS:EIP的值。

4.2 系统调用概述

知识点总结:

  • 系统调用的意义是操作系统为用户态进程与硬件设备进行交互提供了一组接口。
  • 一个API可能只对应一个系统调用,也可能内部由多个系统调用实现,一个系统调用也可能被多个API调用。
  • libc函数库定义的一些API内部使用了系统调用的封装例程,唯一目的是发布系统调用,每个系统调用对应一个系统调用的封装例程,函数库再用这些封装例程定义出给程序员调用的API。
  • 系统调用的三层机制分别为xyz(),system_call,sys_xyz()。
  • 系统调用举例:
    2019-2020-1 20199304《Linux内核原理与分析》第五周作业
第四章 系统调用的三层机制(上)

实验

1.使用库函数API触发一个系统调用

C语言代码如下:
2019-2020-1 20199304《Linux内核原理与分析》第五周作业
第四章 系统调用的三层机制(上)

运行结果如下:
2019-2020-1 20199304《Linux内核原理与分析》第五周作业
第四章 系统调用的三层机制(上)

2.C代码中嵌入汇编代码出发一个系统调用

源代码如下:
2019-2020-1 20199304《Linux内核原理与分析》第五周作业
第四章 系统调用的三层机制(上)

运行结果如下:
2019-2020-1 20199304《Linux内核原理与分析》第五周作业
第四章 系统调用的三层机制(上)

3.代码分析


#include <stdio.h>
#include <unistd.h>
int main(void){
    int u_id;
    asm volatile(
            "movl $0x14, %%eax
	"   //将系统调用号赋给eax寄存器
            "int $0x80
	"           //执行系统调用
            "movl %%eax, %0
	"      //将系统调用执行后的返回值赋给变量tt
            :"=m"(u_id)  
            );
    printf("%u
",u_id);
    return 0;
    }

总结

对系统调用机制的理解:

   所谓系统调用,简单的说,就是内核为用户提供的功能强大的函数。比如read ,write函数等这些函数都是在内核中编辑实现的,用户只需要把这些函数拿来用到自己的程序中即可,至于这些函数是如何实现和运行的,那是内核已经做好的事,用户只需知道这些函数有啥功能,如何使用即可。
  • 系统调用是用户态进程访问硬件的一种方式,它通过中断(int 0x80)由用户态进入内核态。
  • 应用程序应该以某种方式(库函数或汇编代码)通知系统,告诉内核自己需要执行一个系统调用,希望系统切换到内核态。
  • 系统调用最多使用6个寄存器作为参数(除eax外)-ebx,ecx,edx,esi,edi,ebp,如果超过6个参数,寄存器中将会保存一个指向内核态可以操作的一块的内存,参数保存在内存上面。