zoukankan      html  css  js  c++  java
  • LINUX内核分析第五周学习总结——扒开系统调用的“三层皮”(下)

    LINUX内核分析第五周学习总结——扒开系统调用的“三层皮”(下)

    标签(空格分隔): 20135321余佳源


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


    一、给MenuOS增加time和time-asm命令

    1.克隆并自动编译MenuOS

        rm menu -rf //强制删除原menu文件
        git clone https://github.com/mengning/menu.git //从github中克隆
        cd menu
        make rootfs //运行自动编译脚本,生成根文件系统,启动MenuOS
    

    PS:实验楼环境太恶劣而且有时候会git失败,所以我选择用自己的虚拟机来实现。make rootfs的最后一步会出错,因为qemu指令不被支持,正确使用的使用qemu-system-x86_64

    2.给MenuOS增加time和time-asm命令

    • 更新menu代码到最新版
    • test.c中main函数里,增加MenuConfig
    • 增加对应的两个函数:Time和TimeAsm
    • make rootfs


    二、调试内核

    1. 使用gdb跟踪调试内核
      --

      qemu-system-x86_64 -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

                   ------------另开一个终端------------
      

      gdb
      (gdb)file linux-3.18.6/vmlinux //加载符号表
      (gdb)target remote:1234 //连接

    • b sys_time:在系统调用time的位置设置断点
    • c:让MENUOS运行
    • 在MENUOS输入time就可以看到断点位置


    三、系统调用在内核代码中的处理过程

    1. 系统调用在内核代码中的工作机制和初始化
      --
    • main.c中start_kernel函数:trap_init()
    • set_system_trap_gate(SYSCALL_VECTOR,&system_call)
      • SYSCALL_VECTOR:系统调用的中断向量
      • &system_call:汇编代码入口
    • 一执行int 0x80,系统直接跳转到system_call。

    int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys[函数]是通过系统调用号联系起来的

    trapgate函数中,涉及到了系统调用的中断向量和systemcall的汇编代码入口;一旦执行int 0x80,CPU直接跳转到system_call

    1. 系统调用——一个特殊的中断
      --
    ENTRY(system_call)-->执行 0x80后的下一条指令
    RING0_INT_FRAME			# can't unwind into user space anyway
    ASM_CLAC
    pushl_cfi %eax			# save orig_eax
    SAVE_ALL------------------>保护现场包括系统寄存器信息
    GET_THREAD_INFO(%ebp)------------->获取thread_info结构的信息
    				# system call tracing in operation / emulation
    testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)---->测试是否有系统跟踪
    jnz syscall_trace_entry---->如果有系统跟踪,先执行,然后再回来
    cmpl $(NR_syscalls), %eax------>比较eax中的系统调用号和最大syscall,超过则无效
    jae syscall_badsys------>无效的系统调用 直接返回
    syscall_call:
    call *sys_call_table(,%eax,4)-------->eax传递系统调用号查找系统调用表sys_call_table中定义好的相应的系统调用
    syscall_after_call:----------↓
    movl %eax,PT_EAX(%esp)----->保存返回值		# store the return value
    syscall_exit:
    LOCKDEP_SYS_EXIT
    DISABLE_INTERRUPTS(CLBR_ANY)	# make sure we don't miss an interrupt
    			# setting need_resched or sigpending
    			# between sampling and the iret
    TRACE_IRQS_OFF
    movl TI_flags(%ebp), %ecx
    testl $_TIF_ALLWORK_MASK, %ecx------>判断当前的任务是否需要进程调度
    jne syscall_exit_work------->未完成,则去执行这些任务
    restore_all:---------->回复现场,回归用户态
    TRACE_IRQS_IRET---->iret 从系统调用返回
    
    • 若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。
      • work_pending -> work_notifysig,用来处理信号
        • 可能call_schedule:进程调度代码
        • 可能跳转到restore_all,恢复现场。
    • 若无sys_exit_work,就执行restore_all恢复,返回用户态。
    • INTERRUPT_RETURN <=> iret,结束。

    在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换。
    进程间通信可能有信号需要处理。
    可以将内核视为一系列中断指令的集合。


    四、实验部分

    1. 使用gdb跟踪分析第20号系统调用内核函数:getpid
      --

    先执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。

    在test.c中增加我编写的两个函数:Getpid()和asm_Getpid()

    在main函数中增加两个函数的MenuConfig命令项:

    make rootfs编译成功,qemu失败:改成 qemu-system-x86_64

    编译运行,在MenuOS中输入help,可以查看当前所有的系统调用,分别执行Getpid asm_Getpid进行系统调用:

    1. 从system_call到iret
      --
    • system_call到iret之间的主要代码

    • 流程图


    五、总结

    系统调用就是特殊的一种中断

    • 保存现场

      • 在系统调用时,我们需要SAVE_ALL,用于保存系统调用时的上下文。
      • 同样,中断处理的第一步应该也要保存中断程序现场。
      • 目的:在中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。
    • 确定中断信息

      • 在系统调用时,我们需要将系统调用号通过eax传入,通过sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。
      • 同样,中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。
    • 处理中断

      • 跳转到相应的中断处理程序后,对中断进行处理。
    • 返回

      • 系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。
      • 同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。
  • 相关阅读:
    在java中怎样获得当前日期时间
    java 常见异常
    线程中的current thread not owner异常错误
    hibernate 关于hbm.xml编写的总结
    java web 常见异常及解决办法
    初用Ajax
    JavaScript动态修改html组件form的action属性
    Ajax中文乱码的解决
    No repository found error in Installing ADT
    eclipse 安装 CDT
  • 原文地址:https://www.cnblogs.com/brotherlittlefish/p/5325545.html
Copyright © 2011-2022 走看看