《Linux内核分析》 第四节 扒开系统调用的三层皮(上)


张嘉琪 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

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

1.用户态、内核态和中断的处理过程

  • 一般现代CPU都有几种不同的指令执行级别。

  • 在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态。 而在相应的低级别执行状态下,代码的掌控范围会受到限制。只能在对应级别允许的范围内活动。

  • 举例:Intel x86CPU有四种不同的执行级别0-3,Linux只使用了其中的0 3级分别表示内核态和用户态

  • 为什么有权限级别的划分?

    是为了让操作系统本身更稳定的一种机制

  • cs寄存器的最低两位表明了当前代码的特权级。

  • CPU每条指令的读取都是通过cs:eip这两个寄存器:其中cs是代码段选择寄存器,eip是偏移量寄存器。

  • 上述判断由硬件完成。

  • 一般来说在Linux中,地址空间是一个显著地标志:0xc0000000以上的地址空间只能在内核态下访问,都可以访问0x00000000-0xbfffffff的地址空间在两种状态下。

    注意:这里说的地址空间是逻辑地址而不是物理地址。

  • 中断处理是是从用户态进入内核态的主要方式。

  • 系统调用只是一种特殊的中断。

  • 寄存器上下文

    • 从用户态切换到内核态时

      • 必须要保存用户态的寄存器上下文。
  • 中断/int指令会在堆栈上保存一些寄存器的值

    • 如:用户态栈顶地址、当时的状态字、当时的cs:eip的值。
  • 中断发生后的第一件事就是保存现场,结束前最后一件事是恢复现场

    • 保护现场就是进入中断程序 保存需要用到的寄存器的数据。

    • 恢复现场就是推出中断程序 恢复保存寄存器的数据。

  • 中断处理的完整过程

    • interrupt(ex:int 0x80)-save

      cs:eip/ss:esp/eflag(curret) to kernel stack,then load cs:eip(entry of a specific ISR)and ss:esp(point to kernel stack)

    • SAVE_ALL

      • ...//内核代码,完成中断服务,发生进程调度
    • RESTORE_ALL

    • iret-pop cs:eip/ss:esp/eflags from kernel stack

二、系统调用概述

  • 应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系

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

  • 实验报告

  • 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl 参考视频中的方式使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

  • 博客内容的具体要求如下:

    1. 题目自拟,内容围绕系统调用的工作机制进行,博客中需要使用实验截图

    2. 博客内容中需要仔细分析汇编代码调用系统调用的工作过程,特别是参数的传递的方式等。

    3. 总结部分需要阐明自己对“系统调用的工作机制”的理解。
  • 本次实验选择了2号调用fork调用来做实验:fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID

用实验楼的虚拟机打开shell

Cd Code
Vi forktest.c
Gcc forktest.c -o forktest.o -m32
./forktest.o

fork.c代码如下

#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid;
int count = ;
fpid = fork();
if (fpid < )
printf("error in fork!");
else if (fpid == ) {
printf("i am the child process, my process id is %d\n",getpid());
count++;
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
count++;
}
printf("count: %d\n",count);
return ;
}

 运行结果见截图 

  • 嵌入式汇编代码的执行,fork-asm.c源代码如下(参数的传递方式见注释):
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid;
int count = ;
asm volatile (
"mov $0, %%ebx\n\t"
"mov $0x2, %%eax\n\t" // 将fork的系统调用号0x2赋值给eax
"int $0x80\n\t" // 通过0x80中断向量,执行系统调用
"mov %%eax, %0\n\t" // 系统返回的pid号默认储存在eax中
: "=m" (fpid) // 输出操作数0为内存中的fpid。
);
if (fpid < ) printf("error in fork!"); else if (fpid == ) { printf("i am the child process, my process id is %d\n",getpid()); count++; } else { printf("i am the parent process, my process id is %d\n",getpid()); count++; } printf("count: %d\n",count); return ; }

运行结果见截图

总结

调用一个系统调用经历了系统调用的三层皮。分别是系统调用函数api,中断向量systemcall,系统调用服务sysxyz。通过C嵌入汇编代码的实验可以比较清晰的了解系统调用过程。

 // 系统调用号默认通过eax传递,因此将fork的系统调用号0x2赋值给eax

《Linux内核分析》 第四节 扒开系统调用的三层皮(上)的更多相关文章

  1. 20135327郭皓--Linux内核分析第五周 扒开系统调用的三层皮(下)

    Linux内核分析第五周 扒开系统调用的三层皮(下) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/U ...

  2. Linux内核分析第五周——扒开系统调用的“三层皮”(下)

    Linux内核分析第五周--扒开系统调用的"三层皮"(下) 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.1 ...

  3. 《Linux内核分析》第四周 扒开系统调用的“三层皮”

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR( ...

  4. Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)

    作者:刘世鹏20135304  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuOS增加t ...

  5. linux内核分析 第五周 扒开系统调用的三层皮(下)

    rm menu -rf 强制删除原menu文件 git clone http://github.com/mengning/menu.git 从github中克隆 cd menu 在test.c中增加上 ...

  6. LINUX内核设计第五周——扒开系统调用的三层皮(下)

  7. 《Linux内核分析》 第五节 扒开系统调用的三层皮(下)

    <Linux内核分析> 第五节 扒开系统调用的三层皮(下) 20135307 一.给MenusOS增加time和time-asm命令 给MenuOS增加time和time-asm命令需要 ...

  8. Linux第五周学习总结——扒开系统调用的三层皮(下

    Linux第五周学习总结--扒开系统调用的三层皮(下) 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...

  9. linux 内核 第四周 扒开系统调用的三层皮 上

    姬梦馨 原创作品 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断处理过程 用户通过库函数与系统调用联系起来:库函数帮我们把系 ...

随机推荐

  1. HTML5中的Canvas详解

    什么是Canvas HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.<canvas> 标签只是图形容器,您必须使用脚本来绘制图 ...

  2. android studio 错误: InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClass annotations are ignored

    android studio 错误: InnerClass annotations are missing corresponding EnclosingMember annotations. Suc ...

  3. 【转】android Toast大全(五种情形)建立属于你自己的Toast

    Toast用于向用户显示一些帮助/提示.下面我做了5中效果,来说明Toast的强大,定义一个属于你自己的Toast. 1.默认效果 代码 Toast.makeText(getApplicationCo ...

  4. CSS 文本

    CSS 文本属性可定义文本的外观. 通过文本属性,您可以改变文本的颜色.字符间距,对齐文本,装饰文本,对文本进行缩进,等等. 缩进文本 把 Web 页面上的段落的第一行缩进,这是一种最常用的文本格式化 ...

  5. ubuntu 中安装 ZED SDK 及结合ROS 的使用

    双目视觉(stereo vision),由于估计深度相对容易且稠密,在姿态估计和建图时容易初始化和估计尺度,所以在三维重建,SLAM等的应用中有这广泛的应用. ZED 作为近几年出现的商业化双目传感器 ...

  6. 11.C++和C的区别,什么是面向对象

    c++封装更好,调用接口,c调用子函数 1.首先C和C++在基础语句上没有太大区别,c++在c基础上改进,兼容大部分c的语法结构.c++面向对象,c面向过程. 2.新增new和delete的语法,引用 ...

  7. JS五星级评分效果(类似与淘宝打分效果)

    今天晚上研究下 五星级评分效果,类似于淘宝后台评分效果,如下图所示: 思路: 当鼠标移到一颗星的时候 判断当前的索引 当前及当前的索引前面的星星亮起来 每当移到任何一颗星星时候 下面跟随提示 mous ...

  8. PAT B1042 字符统计 (20 分)

    请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母, ...

  9. CentOS7服务器添加新用户

    添加新用户[root@localhost etc]# adduser jiangshan[root@localhost etc]# passwd jiangshan[root@localhost et ...

  10. tomcat-在eclispe中配置远程调试

    在eclispe中新建web应用,名字叫webtest.里面只有一个HelloServlet.Web.xml配置如下. 修改tomcat的启动脚本startup.bat.复制startup.bat为s ...