Linux内核分析(第四周)

时间:2023-03-09 07:30:20
Linux内核分析(第四周)

扒开系统调用的三层皮(上)

一、用户态.内核态.中断

(上周课件有学习到)

1、地址空间是一个显著的标志(是逻辑地址,不是物理地址)

2、CPU每条指令的读取都是通过cs:eip这两个寄存器;0xc00000000以上的地址空间只能用内核态访问

3、中断处理是从用户态进入内核态的主要方式(系统调用是特殊的中断)

4、保护用户态的寄存器上下文(用户栈顶地址、当时的状态字、当时cs:eip的值)

5、中断第一步:保存现场(push) 最后一步:恢复现场(pop)

二、系统调用概述

1、系统调用的意义

  1.操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用:把用户从底层的硬件编程中释放出来;极大的提高了系统的安全性;使用户程序具有可移植性

  2.API和系统调用

    应用编程接口(API)和系统调用是不同的:API只是一个函数定义,而系统调用会通过软中断向内核发出一个明确的请求

  3.Libc库定义的一些API引用了封装例程,唯一的目的就是发布系统

    一般每个系统调用对应一个封装例程

    库再用这些封装例程定义出用户的API

    *不是每个API都对应一个特定的系统调用(API可能直接提供用户态的服务);也可能调用几个系统调用;不同的API可能调用同一个系统调用

    *返回值:大部分封装例程返回一个整数(其含义依赖于相应的系统调用);-1在多数情况下表示内核不能满足进程的请求;Libc定义的errno变量包含特定的出错码

2、系统调用程序及服务例程

  1.在linux中通过执行int $0x80来执行系统调用

  2.传参:进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数(使用eax寄存器)

3、参数传递

  1.系统调用也需要输入输出参数;

  2.system_call是linux中所有系统的调用的入口点,每个系统调用至少有一个参数,即为用eax传递的系统调用号

4、系统调用的内核代码

  1.系统调用分派表(dispatch table)存放在sys_call_table数组

5、系统调用的机制初始化

(了解代码)

6.系统调用的三层皮

  xyz()

  system_call()

  sys_xyz()

7.中断向量0x80与system_call绑定起来;系统调用号将xyz和system_xyz()关联起来

三、使用库函数API和C代码嵌入汇编

实验: 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

要用到getuid()和getgid()需要用到《unistd》头文件

1.C语言汇编

Linux内核分析(第四周)

 嵌入汇编

Linux内核分析(第四周)

Linux内核分析(第四周)

调用了24号和47号;

系统调用的进入办法只有两种 一种是int $0x80,一种是sysenter;