2020-2021-1 20209322《Linux内核原理与分析》第六周作业
#作业信息
作业课程 | 2020-2021-1Linux内核原理与分析 |
---|---|
作业要求 | 2020-2021-1Linux内核原理与分析第六周作业 |
作业目标 | 分析system_call中断处理过程 |
作业正文 | 2020-2021-1 20209322《Linux内核原理与分析》第六周作业 |
分析system_call中断处理过程
本周学习了《系统调用的三层机制(下)》,了解了system_call中断处理过程 [toc]
#一、给MenuOS增加time和time-asm命令
1.更新menu代码到最新版
2.在main函数中增加MenuConfig
3.增加对应的Time和TimeAsm函数
4.make rootfs
#二、跟踪系统调用内核函数sys_time
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage/ -initrd rootfs.img -S -s
启动gdb
file linux-3.18.6/vmlinux
target remote:1234
先设置断点b start_kernel
运行,
设置断点b sys_time
运行
查看附近代码
单步执行
使用finish结束当前函数
继续单步执行,直到return i,获取到当前系统时间,给system_call设置断点,
在menuOS中输入time-asm命令,运行
继续运行,但是并不可以停在system_call的位置
gdb不能追踪entry_32.S中的汇编代码
#三、系统调用在内核代码中的处理过程
##3.1系统调用过程
系统调用过程如下图:
##3.2中断向量X80和system_call中断服务程序入口关系
在/linux-3.18.6/arch/x86/kernel/traps.c
中trap_init()
函数中,
#ifdef CONFIG_X86_32
set_system_trap_gate(SYSCALL_VECTOR,&system_call);
set_bit(SYSCALL_VECTOR,used_vectors);
#endif
这里,通过set_system_trap_gate
函数绑定了中断向量0x80,和system_call中断服务程序入口,cpu执行到int0x80指令就会跳转到system_call执行
##3.3在system_call汇编代码中的系统调用内核处理函数
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) #保存进程thread_info结构的地址
# system call tracing in operation / emulation
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) # 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_notrace:
#ifdef CONFIG_X86_ESPFIX32
movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
# are returning to the kernel.
# See comments in process.c:copy_thread() for details.
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 # returning to user-space with LDT SS
#endif
restore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
irq_return:
INTERRUPT_RETURN
##3.4整体理解系统调用的内核处理过程