zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209309《Linux内核原理与分析》第六周作业

    作业信息

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

    实验过程

    向MenuOS中添加命令

    删除并重新git新版本的menu文件夹

    修改相应的test.c文件,添加相应的getPid命令

    使用make rootfs重新编译生成镜像

    打开系统进行测试

    使用gdb进行调试


    源码分析

    在linux-3.18.6/arch/x86/kernel/entry_32.S中可以查看到system_call的汇编源码:

    ENTRY(system_call)
    	RING0_INT_FRAME	
    	ASM_CLAC
    	pushl_cfi %eax			
    	SAVE_ALL
    	GET_THREAD_INFO(%ebp)
    	testl $_TIF_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)
    syscall_after_call:
    	movl %eax,PT_EAX(%esp)	
    syscall_exit:
    	LOCKDEP_SYS_EXIT
    	DISABLE_INTERRUPTS(CLBR_ANY)
    	TRACE_IRQS_OFF
    	movl TI_flags(%ebp), %ecx
    	testl $_TIF_ALLWORK_MASK, %ecx
    	jne syscall_exit_work
    restore_all:
    	TRACE_IRQS_IRET
    restore_all_notrace:
    	movl PT_EFLAGS(%esp), %eax	# mix EFLAGS, SS and CS
    	movb PT_OLDSS(%esp), %ah
    	movb PT_CS(%esp), %al
    	andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
    	cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
    	CFI_REMEMBER_STATE
    	je ldt_ss
    #endif
    restore_nocheck:
    	RESTORE_REGS 4
    irq_return:
    	INTERRUPT_RETURN
    

    系统进入系统调用时(system_call),会首先保存现场,执行save_all宏,然后进行调用中断服务程序syscall_call,接着执行syscall_exit,当执行到这里准备退出时,会进行判断需不需要响应其他中断或者信号,如果不需要则直接进行restore_all恢复现场并且irq_return,正式返回到系统调用的地方;如果需要响应其他中断,则需要执行syscall_exit_work,看看有没有work_resched或者work_notifysig,看看当前进程需不需要调度,如果需要就执行call_schedule,如果需要响应某个信号,则进行work_notifysig,接着再跳转至restore_all接着执行并退出。这个就是系统调用时汇编代码级别的大致执行过程。具体可以按流程图:

  • 相关阅读:
    《UIP在NIOS上的移植》
    切勿使用:指向局部变量的指针作为函数的返回指针!
    Oeacle创建表空间
    Oracle SQL 语言分类
    线程整理
    输入输出
    异常处理
    哈希算法
    java链表
    课上重点整理
  • 原文地址:https://www.cnblogs.com/yanzs/p/13977065.html
Copyright © 2011-2022 走看看