2019-2020-1 20199312《Linux内核原理与分析》第六周作业

删除旧版menu克隆新版menu并运行

    rm -rf menu
    git clone http://github.com/mengning/menu.git
    make rootfs

查看新增功能,及其具体代码实现

增加显示id功能

启动后进行gdb调试

file命令用于加载linux内核代码的符号表,target用于将gdb调试工具连接到已经启动的程序上。完成之后,执行continue继续程序的执行。为什么是1234呢?因为-s是在1234端口上创建了一个gdb-server。

    (gdb)file linux-3.18.6/vmlinux
    (gdb)target remote:1234
    

在sys_time处设置断点,继续执行,观察time函数的返回值,

system_call

system_call这一段代码就是系统调用的处理过程,系统调用是一个特殊一点的中断(或称之为软中断),这一段代码中也有保存现场SAVE_ALL和恢复现场restore_all的过程。同时,system_call_table是一个系统调用的表,EAX寄存器传递的系统调用号,使用者在调用它时会根据EAX寄存器来调用对应的系统调用内核处理函数。


ENTRY(system_call)
           RING0_INT_FRAME
           ASM_CLAC
           pushl_cfi %eax                    #保存系统调用号
           SAVE_ALL                          #保存现场,将用到的所有CPU寄存器保存在栈中
           GET_THREAD_INFO(%ebp)             #ebp用于存放当前进程thread_info的结构地址
           testl $_TIE_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
           jnz syscall_trace_entry
  cmpl $(nr_syscalls),%eax                   #检查系统调用号
           jae syscall_badsys                #不合法,跳入异常处理
  syscall_call:
           call *sys_call_table(,%eax,4)     #通过系统调用号在系统调用表中找到相应的系统调用内核处理函数
           movl %eax,PT_EAX(%esp)
  syscall_exit:
           testl $_TIF_ALLWORK_MASK, %ecx    #检查是否有任务需要处理
           jne   syscall_exit_work           #需要,进入syscall_exit_work
  restore_all:
          TRACE_IEQS_IRET                    #恢复现场
  irq_return:
          INTERRUPT_RETURE                   #iret

流程图

感想:

  • 32位x86 Linux系统中系统调用处理过程的最后一条汇编指令是iret。
  • Linux内核中,系统调用处理过程中保护现场使用的宏是SAVE_ALL。
  • 中断都有保护现场SAVE_ALL和恢复现场restore_all的过程。
posted @ 2019-10-27 22:21  刚刚吃饭来着呢  阅读(186)  评论(0编辑  收藏  举报