系统调用的三层机制(下)
给MenuOS增加命令
-
删除当前menu,克隆新的menu
-
利用脚本自动编译生成启动menuos
-
menuos新增加功能一览
-
如何给MenuOS增加time和time-asm命令
(1)更新menu代码到最新版
(2)在test.c中的main函数里增加MenuConfig
(3)增加对应的Time函数和TimeAsm函数
(4)make rootfs 自动编译脚本
使用gdb跟踪系统调用内核函数sys_time
- 使用gdb跟踪系统
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
# 关于-s和-S选项的说明:
# -S freeze CPU at startup (use ’c’ to start execution)
# -s shorthand for -gdb tcp::1234
- 跟踪系统调用内核函数sys_time
gdb
(gdb)file linux-3.18.6/vmlinux //在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 //建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)b sys_time
(gdb)c //启动到MenuOs,在MenuOs中使用time,会停在time函数处
(gdb)list //对应代码
(gdb)s //单步执行
(gdb)finish //将这个函数执行完
(gdb)b system_call
总结
通过学习课程我们知道了,linux的系统调用过程:用户程序→C库(即API):INT 0x80 →system_call→系统调用服务例程→内核程序。我们常说的用户API其实就是系统提供的C库。
系统调用是通过软中断指令 INT 0x80 实现的,而这条INT 0x80指令就被封装在C库的函数中。软中断和我们常说的硬中断不同之处在于,软中断是由指令触发的,而不是由硬件外设引起的。INT 0x80 这条指令的执行会让系统跳转到一个预设的内核空间地址,它指向系统调用处理程序,即system_call函数。系统调用处理程序system_call 并不是系统调用服务例程,系统调用服务例程是对一个具体的系统调用的内核实现函数,而系统调用处理程序是在执行系统调用服务例程之前的一个引导过程,是针对INT 0x80这条指令,面向所有的系统调用的。简单来讲,执行任何系统调用,都是先通过调用C库中的函数,这个函数里面就会有软中断 INT 0x80 语句,然后转到执行系统调用处理程序 system_call ,system_call 再根据具体的系统调用号转到执行具体的系统调用服务例程。
而本次实验中我成功的将这个新的函数功能加入了原本的内核菜单中,并且学会了如何清除原来的菜单,下载并更新成为一个新的菜单,可以说学到了Linux内核菜单的修改与覆盖,但是我还是没有实现在自己的虚拟机上实现这些,qemu,git这些指令在虚拟机上都无法使用,导致编译内核这些部分都无法实现,通过今后老师的帮助,希望我的虚拟机可以实现实验楼的全部功能。
从system_call开始到iret结束的过程: