作业信息
这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第六周作业> |
这个作业的目标 | <给MenuOS增加命令,使用gdb跟踪系统调用内核函数sys_time,分析system_call流程示意图,分析系统调用在内核代码中的处理过程> |
作业正文 | ... 本博客链接 |
系统调用的三层机制(下)
1.给MenuOS增加命令
输入以下命令:
rm -rf menu 删除menu文件
git clone https://github.com/mengning/menu.git 克隆一个新版本的menu
cd menu 进入menu目录
make rootfs
查看test.c文件,发现增加了2个命令,一个是time,功能是显示系统时间,另一个命令是time-asm,功能是使用汇编方式显示系统时间。
2.使用gdb跟踪系统调用内核函数sys_time
启动内核,输入以下命令:
cd ../ #返回到LinuxKernel目录中
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
启动gdb,把3.18.6的内核加载进来,之后连接到target remote 1234,操作完成后,就连接到了需要调试的MenuOS,输入以下命令:
file linux-3.18.6/vmlinux
target remote:1234
在sys_time处设置断点
在sys_time断点处停下来后用list查看这段代码
用gdb的finish命令把这个函数全部执行完,再单步执行,一直到return i,获得的就是当前系统时间time的数值。
3.system_call流程示意图
4.系统调用在内核代码中的处理过程
在用户态有一个系统调用xyz(),xyz()系统调用库函数里面用了sys_call来触发系统调用,即CPU一旦执行到int 0x80指令就会立即跳转到system_call的位置,system_call这一段代码就是系统调用的处理过程,系统调用是一个特殊一点的中断,中断过程都有保护现场(save_all)和恢复现场(restore_all)。代码中的sys_call_table是一个系统调用的表,EAX寄存器传递系统调用号,使用者在调用它时会根据EAX寄存器来调用对应的系统调用内核处理函数,比如EAX寄存器是13,即在调用完sys_time之后需要先保存它的返回值,在退出之前根据需要有一个syscall_exit_work,如果没有,则恢复现场并iret返回用户态。