这个作业属于哪个课程 | 2020-2021-1 Linux内核原理与分析 |
这个作业要求在哪里 | 2020-2021-1Linux内核原理与分析第六周作业 |
这个作业的目标 | 给MenuOS添加上周实现的系统调用、使用gdb分析sys_time执行过程、了解系统调用执行过程 |
作业正文 | 本博客链接 |
给MenuOS增加命令
1)强制删除LinuxKernel/目录下的menu文件夹;
2)用git clone重新克隆一个新版本的menu;
3)进入menu文件夹,运行此文件夹下的make rootfs脚本,自动编译并自动生成根文件系统,同时,自动运行MenuOS系统,如下图所示。
命令如下:
rm -rf menu git clone https://github.com/mengning/menu.git cd menu make rootfs
查看menu文件夹下的test.c,发现,除了上一章提及的内容外,还增加了两条命令:
- time,功能:显示系统时间
- time-asm,功能:使用汇编方式显示系统时间
从上述截图中,可以看出在test.c文件中增加系统调用,并将系统调用增加到改进后的MenuOS中,在main()函数中增加了两行代码就可以实现, MenuConfig("time") 和 MenuConfig("time-asm") 。
用 make rootfs 打开menu镜像,操作完成后可以看到MenuOS菜单中新增了两条命令,如下图所示。
使用gdb跟踪系统调用内核函数sys_time
用qemu命令启动内核
cd ../ #返回到LinuxKernel目录中 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
打开一个新的shell窗口,启动gdb,把3.18.6的内核加载进来,之后连接到 target_remote:1234。这样,就连接到了需要调试的MenuOS。
file linux-3.18.6/vmlinux target remote:1234
接下来,设置断点, b start_kernel ,按c执行代码,代码会在start_kernel()处停下来。
time系统调用是13号系统调用对应的内核处理函数,即sys_time,在此函数处设置一个断点 b sys_time ,执行代码。
在QEMU终端中执行time指令,QEMU显示当前时间,但我们发现进程并没有终止,又输入了time-asm指令后,进程终止。可能是因为我们安装的虚拟机中缺少一些包,导致执行time指令时,函数执行到time处便卡在那。
随后,我查看了linux-3.18.6/kernel/time/time.c文件。因为sys_time是用宏来定义的,所以我们无法直接看见sys_time。
系统调用的内核处理过程
system_call流程示意图如下:
总结
本周主要学习了Linux内核系统调用的过程,并通过gdb和代码分析了调用过程。一般情况下,在用户态调用time()函数时,实际上调用了系统函数sys_time(),而用户态中有一个系统调用库函数xyz(),里面通过中断向量0x80触发system_call中断服务程序入口这段汇编代码,由用户态切换到内核态。首先通过SAVE_ALL保护现场,然后通过system_call函数中调用分配表找到系统调用内核处理函数指针,调用函数后通过restore_all和INTERRUPT_RETURN(iret)恢复现场并返回系统调用到用户态结束。以上system_call调用为软中断,和其他所有中断类似,可以推广到一般的中断处理过程。