2019-2020-1 20199308《Linux内核原理与分析》第五周作业

《Linux内核分析》

第四章 系统调用的三层机制(上)

4.1 用户态、内核态和中断

  • 与系统调用打交道的方式是通过库函数的方式
  • 用户态与内核态的区分
    • 内核态:高的执行级别下,代码可以执行特权指令,访问任意的物理内存
    • 用户态:低级别指令
  • 系统调用也是一种中断
    • 中断处理是从用户态进入内核态的主要方式
    • 当用户态切换到内核态时,就要把用户态寄存器上下文保存起来,同时要把内核态的寄存器的值放到当前CPU中

      4.2 系统调用概述

  • 系统调用的意义:
    错做系统为用户态进程与硬件设备进行交互提供了一组接口
  • 系统调用的功能和特性:
    • 把用户从底层的硬件编程中解放出来
    • 极大地提高系统安全新
    • 使用户程序具有可移植性

      4.2.1 操作系统提供的API和系统调用的关系

  • API:应用程序编程接口
    • 只是函数定义
    • 系统调用时通过软中断向内核发出了中断请求
  • libc函数库定义的一些API内部使用了系统调用的封装例程,唯一目的是发布系统调用
    • 每个系统调用对应一个系统调用的封装例程
    • 函数库再用这些封装例程定义出给程序员调用的API
  • 不是每个API都对应一个特定的系统调用(一对一,一对多,多对一)
  • 返回值
    • 大多数系统调用的封装例程返回一个整数,其值的含义依赖于对应的系统调用
    • 返回值-1在多数情况下表示内核不能满足进程的请求
    • libc中进一步定义的errno变量包含特定的出错码

4.2.2 出发系统调用及参数传递方式

  • 当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个system_call和系统调用内核函数
  • 传参
    • 内核实现了很多不同的系统调用
    • 使用EAX寄存器传递一个名为系统调用号的参数

4.3 使用库函数API和C代码中嵌入汇编代码触发同一个系统调用

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

  • 代码
#include<stdio.h>
#include<sys/types.h>
int main(void)
{
    int u_id;
    printf("%u\n",u_id);
    return 0;
}
  • 运行截图

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

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

猜你喜欢

转载自www.cnblogs.com/hsj910/p/11677494.html