举例跟踪分析Linux内核5.0系统调用处理过程
学号后三位:072
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
一:实验要求
(1) 编译内核5.0
(2) 选择系统调用号后两位与您的学号后两位相同的系统调用进行跟踪分析
(3)撰写一篇博客, 给出相关关键源代码及实验截图,
二:实验环境
本次实验主要使用自己的个人电脑和电脑上安装的ubuntu来完成。
三:实验过程
1. 编译Linux内核5.0
第一步:下载Linux内核源码
连接:https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz
第二步:解压并编译Linux内核
第三步:安装QEMU虚拟机
第四步:构造并启动MenuOS
2. 选择学号后两位进行系统调用
第一步:根据72号找到对应的系统调用函数
第二步:编写代码,进行系统调用
第三步:代码运行结果如下:
四:实验总结
linux的系统调用过程的层次例如以下:
用户程序------>C库(即API):INT 0x80 ----->system_call------->系统调用服务例程-------->内核程序
系统调用是通过软中断指令 INT 0x80 实现的,而这条INT 0x80指令就被封装在C库的函数中。
过程:通过系统调用号查找系统调用表sys_call_table,软中断指令0x80执行时,系统调用号会被放入eax寄存器当中(由于系统调用服务例程只会从堆栈中获取参数),system_call函数可以读取eax寄存器获取(system_call函数执行时会首先将这些寄存器压入堆栈中),然后将其乘以4,生成偏移地址,然后以sys_call_table为基址,基址加上偏移地址,就可以得到具体的系统调用服务例程的地址,然后就可以得到系统服务例程(是对一个具体的系统调用的内核实现函数,系统调用处理程序是在执行系统调用服务例程之前的一个引导过程,是针对INT 0x80这条指令的,面向所有系统调用)了。
系统调用通过软中断INT 0x80陷入内核,跳转到系统调用处理程序system_call函数,然后处理相应的服务例程。但是由于是代表用户进程,所以这个执行过程并不属于中断上下文,而是进程上下文。因此,在系统调用的过程中,可以访问用户进程的许多信息,可以被其它进程抢占,可以休眠。当系统调用完成后,把控制权交回到发起调用的用户进程,内核会有一次调度。如果发现有优先级更高的进程或当前进程的时间片用完,那么会选择优先级更高的进程或重新选择进程执行。
在本次实验中我初步体会了Linux系统内核的编译过程和系统调用的过程,但是对Linux系统的理解还不够深入,需要进一步加强,期待下一次的实验。