MOOC-Linux内核lab5 分析system_call中断处理过程

首先,把上周用汇编实现的getpid加入menuOS。

可见getpid工作正常。 



接着开始调试内核。

qemu -kernel arch/x86/boot/bzImage -initrd rootfs/rootfs.img -s -S
新建一个终端,用gdb链接到端口1234

gdb -q -ex 'file vmlinux' -ex 'target remote:1234'
gdb 的 -ex 可以让gdb直接执行某命令。 非常建议把这两行指令放在两个bash file里,方便调试。


查得getpid对应sys_getpid, 在sys_getpid处设置断点后,使用next命令。

Breakpoint 1, sys_getpid () at kernel/sys.c:817
817	{
(gdb) n
818		return task_tgid_vnr(current);
(gdb) 
817	{
(gdb) 
818		return task_tgid_vnr(current);
(gdb) 
819	}
(gdb) 
schedule () at kernel/sched/core.c:2866
2866	{
(gdb) 
2867		struct task_struct *tsk = current;
(gdb) 
2869		sched_submit_work(tsk);
(gdb) 
2866	{
(gdb) 
2869		sched_submit_work(tsk);
(gdb) 
2870		__schedule();
(gdb) 
2871	}
0x0804a13b in ?? ()
(gdb) 
Cannot find bounds of current function

可以发现getpid调用了kernel/sys.c模块,得到当前pid,最后恢复现场。

接着使用单步调试, 发现在kernel/pid.c中有以下关键代码。

pid_nr_ns (ns=<optimized out>, pid=<optimized out>) at kernel/pid.c:502
502		if (pid && ns->level <= pid->level) {
(gdb) 
503			upid = &pid->numbers[ns->level];
(gdb) l
498	{
499		struct upid *upid;
500		pid_t nr = 0;
501	
502		if (pid && ns->level <= pid->level) {
503			upid = &pid->numbers[ns->level];
504			if (upid->ns == ns)
505				nr = upid->nr;
506		}
507		return nr;
(gdb) 

系统调用流程(ubuntu上找不到合适的软件画图。。只能用文字箭头表示)

用户态 内核态

getpid() ->  int 0x80 利用中断向量匹配system_call  保存现场->  

内核态 用户态

sys_getpid()   利用系统调用号匹配 -> syscall_after_call 保存返回值 -> restore all 恢复现场 ->iret 返回用户态


以下摘录一些kernel/entry_32.S 关键代码。

ENTRY(system_call)
	SAVE_ALL
	GET_THREAD_INFO(%ebp)
syscall_call:
        call *sys_call_table(,%eax,4)
syscall_after_call:
        movl %eax,PT_EAX(%esp)          # store the return value
restore_all:
        TRACE_IRQS_IRET
irq_return:
        INTERRUPT_RETURN





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值