5.分析system_call中断处理过程

请注意:>原作者:张澍> 原创作品转载请注明出处> 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1.实验步骤

1.1 GDB代码中调试menu_os

Linux中编辑运行:

$ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S #运行menu_os
$gdb                               #启动GDB
(gdb) file linux-3.18.6/vmlinux     #加载内核
(gdb) target remote :1234           #链接到menu_os
(gdb) b start_kernel                #在start_kernel处设置断点
(gdb) c                             #运行到断点:start_kernel处
(gdb) list                          #查看此处代码 
(gdb) b sys_time                    #在start_kernel处设置断点
(gdb) c
(gdb) s                             #但步执行
(gdb) finish                        #执行完此函数“get_seconds()”

#注意:sys_time返回后进入汇编代码处理GDB无法继续跟踪

(gdb) b system_call
(gdb) c                             #此时menu_os界面显示time命令返回

运行显示

这里写图片描述

犹豫sys_time返回后进入汇编代码处理GDB无法继续跟踪,故接下来在Linux源码中直接查看

1.2 Linux源码中跟踪

#文件位置:linux-3.18.6/init/main.c
    start_kernel() -> trap_init() ->

#文件位置:linux-3.18.6/arch/x86/kernel/traps.c
    trap_init() ->
    #ifdefCONFIG_X86_32
    set_system_trap_gate(SYSCALL_VECTOR, &system_call); 
    set_bit(SYSCALL_VECTOR, used_vectors); 
    #endif
    $0x80 -> system_call -> 

#文件位置:linux-3.18.6/arch/x86/kernel/entry_32.S
    ENTRY(system_call)  #系统调用终端处理函数
        SAVE_ALL  //保存现场
        syscall_call:
            *sys_call_table(,%eax,4)  #根据系统调用号调用相应的系统内核函数
        syscall_exit:
            testl $_TIF_ALLWORK_MASK, %ecx   #检查当前的任务是否需要处理syscall_exit_work (如传入某信号)
            jne syscall_exit_work
        #如果不需要处理
        restore_all:
            TRACE_IRQS_IRET
        irq_return:
            INTERRUPT_RETURN  #系统调用处理结束
        #如果需要处理
        syscall_exit_work:
            testl $_TIF_WORK_SYSCALL_EXIT, %ecx
            jz work_pending  #跳转到 work_pending
        END(syscall_exit_work)
        work_pending:
            testb $_TIF_NEED_RESCHED, %cl
            jz work_notifysig    #处理信号
        work_resched:
            call schedule    #进程调度
            jz restore_all
        work_notifysig:
            ...        #处理信号
        END(work_pending)  #返回系统调用
    ENDPROC(system_call)

2.总结

系统调用处理过程:

  1. 用户态调用系统API,触发“int 0x80中断”
  2. 内核收到“int 0x80中断”后进入内核态
  3. 内核态中根据系统调用号调用相应的系统内核函数
  4. 进行相应的进程调度与信号处理
  5. 返回系统调用重新回到用户态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值