在实验楼中,首先
更新menu代码到最新版
test.c中main函数里,增加MenuConfig()
增加对应的两个函数,Time和TimeAsm函数
make rootfs
自动编译脚本
下图为在虚拟机中的设置
该过程在第三周已经详细讲解过,这里不做赘述,过程如下:
整个系统调用过程中,时间很重要。
以system_call为例,int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys是通过系统调用号联系起来的
用户态时,系统调用xyz()使用int 0x80,它对应调用system_call
右边的处理过程(汇编代码)非常重要,通过系统调用号匹配起来
trap_init函数里面有一个set_system_trap_gate函数,其中涉及到了系统调用的中断向量SYSCALL_VECTOR和汇编代码入口system_call,一旦执行int 0x80,CPU直接跳转到system_call来执行。
SAVE_ALL:保存现场
syscall_after_all:保存返回值
若无sys_exit_work,就执行restore_all恢复,返回用户态。
INTERRUPT_RETURN <=> iret,结束。
这段代码有几百行,老师用伪代码简化了下
SAVE_ALL与sys_call_table系统调用分派表,对应的处理函数分别是:
sys_call_table(,%eax,4)
JMP(EAX*4 + system_xxx)
1.在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换 2.进程间通信可能有信号需要处理
1.先执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。
2.在test.c中添加C函数、汇编函数
3.make rootfs,输入help,可以看到qemu中增加了我们先前添加的命令:
4.可以看到,getuid和getud_asm已经加进去了,分别执行这两个系统调用:
1.进入gdb调试
2.给start_kernel处设置断点
3.结果如下
4.查看所选用的系统调用函数,可知断点要设置在这里
5.执行命令getuid时没有停下
6.c运行之后,在MenuOs里使用getuid_asm,可以看到它在执行时停下了
7.结束若干次单步执行,然后继续往下单步执行,发现出现了进程调度函数,返回进程调度中的一个当前进程任务的值
8.list可以查看内部的函数,直到system_call返回后进入汇编代码处理,gdb无法继续进行追踪
sys_call_table
查询到调用的系统调用,然后跳转到相应的程序进行处理。qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb
(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置,注意寻找对应的系统调用函数名字,例如time命令对应sys_time
芦畅 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
原文:http://www.cnblogs.com/bonjourvivi/p/5314902.html