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

《庖丁解牛》 第4章——系统调用的三层机制(上)

一、学习内容及实践过程整理

4.1用户态、内核态和中断

库函数封装系统调用,使得程序员不直接接触到系统调用,保持整个系统的稳定,避免崩溃。

1.用户态与内核态的区分

内核只能被系统调用操作,系统调用可以被API、Shell、应用程序操作,API和SHELL可以被应用程序操作

2.Intel x86 CPU的执行级别——0~3,数字越小,级别越高

OS----Ring0
驱动程序----Ring1、Ring2
应用程序----Ring3
在Linux系统中只采用了其中的0和3两个特权级别,分别对应内核态和用户态。
用户态只能访问0x00000000~0xbfffffff的地址空间,0xc0000000以上的地址空间只能在内核态下访问。这里说的地址空间是进程的逻辑地址而不是物理地址,逻辑地址是进程的地址空间里面的,现在的CPU都可以通过MMU(内存管理单元)把逻辑地址转换为物力地址。

3.中断(系统调用是一种特殊的中断)

从用户态进入内核态的方式有两种
(1)中断(进入内核态的主要方式),用户态进程执行时,硬件中断信号到来,进入内核态
(2)Trap(系统调用只是特殊的中断)

4.中断过程

从用户态切换到内核态,就要把用户态寄存器上下文保存起来,同时要把内核态的寄存器的值放到当前CPU中。
中断/init指令保存用户态栈顶地址、当时的状态字、当时的CS:EIP的值,同时会将内核态的栈顶地址、内核态的状态字放入CPU对应的寄存器。

4.2系统调用概述

系统调用有一下的功能和特性:

  • 把用户从底层的硬件编程中解放出来
  • 极大地提高系统的安全性
  • 使用户程序具有可移植性

4.2.1 OS提供的API和系统调用间关系

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

用户态进程调用系统调用时,需要传递两类参数,一类是系统调用号(即指明需要哪个系统调用,EAX寄存器传递),一类是该系统调用所需要传递的参数(按顺序赋值给EBX、ECX、EDX、ESI、EDI、EBP)。若超过6个参数,,则把某一个寄存器作为指针指向内存,这样就可以通过内存来传递更多参数。

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

请求一个系统调用,一般有两种方法可以实现,一是使用Libc提供的API,二是直接在C中内嵌汇编代码触发0x80中断来完成。
这里调用20号系统调用

在实验楼环境下在C代码中嵌入汇编代码触发同一个系统调用

二、学习中遇到的问题

1.用户态进程指明需要哪个系统调用是在什么时候?即什么时候传递系统调用的编号(系统调用号)的? 是发生在xyz()的SYSCALL中传递系统调用的编号吗?
2.在C代码中嵌入汇编代码触发同一个系统调用的时候,在自己的虚拟机上无法运行代码,但是复制到实验楼上却可以运行。推测是版本问题,但不知道具体问题在哪里。情况如图

posted @ 2018-11-11 22:53  天青Cris  阅读(195)  评论(0编辑  收藏  举报