• 2020-2021-1 20209326 《Linux内核原理与分析》第六周作业


    作业信息

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)>
    这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第六周作业>
    这个作业的目标 <使用gdb跟踪分析一个系统调用内核函数>
    作业正文 <本博客链接>

    一、实验内容

    1. 给MenuOS增加命令

    修改test.c文件,新增creat功能。

    rm -rf menu
    git clone https://github.com/mengning/menu.git
    cd menu
    


    make rootfs

    2. 用GDB来跟踪系统调用内核的函数sys_time

    //启动内核
    qemu -kernel linux-3.18.6/arch/x86/boot/bzImage/ -initrd rootfs.img -S -s     
    //新打开一个shell窗口,启动gdb
    file linux-3.18.6/vmlinux
    target remote:1234
    //加入断点
    b start_kernel//代码会在start_kernel()处停下来
    b sys_time    //调试time系统调用
    b sys_creat   //调试creat系统调用
    



    查看了linux-3.18.6/fs/open.c和linux-3.18.6/kernel/time/time.c文件。因为系统调用是用宏来定义的,所以无法直接调试。

    3.在linux-3.18.6/arch/x86/kernel/entry_32.S查看system_call源码

    一旦执行int 0x80,CPU就直接跳转到system_call这个位置来执行,即系统调用的工作机制在start_kernel这里初始化之后,CPU一遇到int 0x80就会立即跳转到sys_call的位置,system_call中断服务程序的入口这段会变代码的处理过程是非常重要的,它是系统调用的处理过程,而系统调用是一个特殊的中断,在中断过程中有保护现场和恢复现场,这段代码里面同样也有保护现场SAVE_ALL和恢复现场restore_all的过程。

    	# system call handler stub
    ENTRY(system_call)
    	RING0_INT_FRAME			# can't unwind into user space anyway
    	ASM_CLAC
    	pushl_cfi %eax			# save orig_eax//保存系统调用号
    	SAVE_ALL                        //保存现场,将用到的所有CPU寄存器保存到栈中
    	GET_THREAD_INFO(%ebp)           //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        //检查系统调用号(系统调用号应小于NR_syscalls)
    	jae syscall_badsys               //不合法,跳入异常处理
    syscall_call:
    	call *sys_call_table(,%eax,4)    //合法,对照系统调用号在系统调用表中寻找相应的系统调用的内核处理函数
    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	# current->work//检查是否需要处理信号
    	jne syscall_exit_work            //需要,进入 syscall_exit_work
    
    restore_all:
    	TRACE_IRQS_IRET                  //不需要,执行restore_all恢复,返回用户态
    restore_nocheck:
    	RESTORE_REGS 4			# skip orig_eax/error_code
    irq_return:
    	INTERRUPT_RETURN                  //相当于iret
    

    二、总结

    1.系统调用过程

    2.系统调用处理过程的理解
    通过本实验的学习,知道了:系统调用时,首先通过save_all来保存现场,然后进行系统调用,并将返回值放入寄存器eax中,然后确认有没有其他的中断进入,以便设置返回信号。如果没有就从系统调用返回,并通过函数restore_all恢复现场;如果有就进入函数syscall_exit_work,查看有没有挂起的任务,有就转入函数work_pending进行任务调度,没有就返回,并恢复现场。

  • 相关阅读:
    BNU 沙漠之旅
    手把手教你在Windows端搭建Redmine项目管理软件
    [置顶] mybatis批量新增系列之有主键的表的批量新增
    linux 命令之sar——监视系统状态
    简单的串行通信程序
    Hibernate_12_HQL句子
    初次使用glog
    2014辛星在读CSS第八节 使用背景图片
    poj 2763 Housewife Wind(树链拆分)
    堆,队列,单一列表,双向链表
  • 原文地址:https://www.cnblogs.com/gann/p/13966886.html
Copyright © 2020-2023  润新知