朱国庆+原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
扒开系统调用的三层皮
用户态,内核态和中断
1,内核态:在高执行级别下,代码可以执行特权指令,访问任意的物理地址。
2,用户态
-Intel x86 CPU有四种不同的执行级别0~3,Linux只用其中的0和3来表示内核态和用户态
-区分内核态和用户态:CPU每条指令的读取都是通过cs:eip,cs寄存器最低两位表明了当前代码的特权级。
-内核态下可访问所有地址空间
-0xc0000000(逻辑地址)以上的空间只能在内核态下访问
-0x00000000 ~ 0xbfffffff 内核态和用户态均可访问
用户态转换为内核态的主要方式:中断
3,用户态到内核态的切换:必须保存用户态的寄存器上下文,包括用户态栈顶地址、当时的状态字、cs:eip的值,以及内核态的栈顶地址、当时的状态字、中断处理程序入口。
-中断发生后的第一件事:保存现场(SAVE_ALL:保存需要用到的寄存器数据)。
-中断处理结束前的最后一件事:恢复现场(RESTORE_ALL:退出中断程序,恢复保存寄存器的数据)。
系统调用概述
意义:操作系统为用户态进程与硬件设备进行交互提供了一组接口。
API:应用程序编程接口,是一个函数定义。
系统调用:通过软中断向内核发出一个明确的请求。
API与系统调用不是一一对应的
系统调用“三层皮:(1)API(2)中断向量(3)中断服务程序。
系统调用的参数传递:
-函数调用——压栈
-用户态到内核态——寄存器传递。
每个参数长度不能超过32位,个数不能超过6个。
超过的话?
使某个寄存器中存储指针,指向内存,内存中存储参数。
使用库函数API和C代码中嵌入汇编代码触发同一系统调用
使用库函数API获取系统当前的时间
结果:
使用C代码中嵌入汇编代码触发系统调用获取系统当前时间
执行结果:
实践
24号getuid
总结
通过本周学习,我们简单了解了系统调用,并将其“扒皮”老师视频中所讲解的三层皮:API,中断向量以及中断服务程序,分别所对应视频中的XYZ,system_call和sys_xyz.系统调用返回的值长度不能超过32位而且个数不能超过6个。在实验中关于汇编代码的理解还不是很透彻,在以后学习中还需多学习。