使用gdb跟蹤系統(tǒng)調(diào)用內(nèi)核函數(shù)sys_time
查看? linux-3.18.6/arch/x86/syscalls/syscall_32.tbl
13 i386 time sys_time compat_sys_time
可以得知久信,13號(hào)系統(tǒng)調(diào)用time對應(yīng)的內(nèi)核處理函數(shù)是sys_time
1. 設(shè)置斷點(diǎn) b sys_time
2. 設(shè)置斷點(diǎn) b system_call
可以看到伟端,在system_call的地方,并沒有停下,因?yàn)閟ystem_call不是一個(gè)正常的函數(shù)货矮,它是一段匯編代碼补箍,怎么讓系統(tǒng)停在system_call的位置進(jìn)行調(diào)試?
查看? linux-3.18.6/arch/x86/kernel/entry_32.S
gdb應(yīng)該可以發(fā)現(xiàn)system_call它聲明了一個(gè)函數(shù)原型赦邻,但它實(shí)際上不是一個(gè)函數(shù)侵蒙,而只是一段匯編代碼的起點(diǎn)
系統(tǒng)調(diào)用的機(jī)制的初始化
\init\main.c
????? start_kernel
\arch\x86\kernel\traps.c
????? #ifdef
CONFIG_X86_32
??????????? set_system_trap_gate(SYSCALL_VECTOR, &system_call);
??????????? set_bit(SYSCALL_VECTOR, used_vectors);
????? #endif
系統(tǒng)調(diào)用的工作機(jī)制一旦在start_kernel()初始化好之后霎迫,在代碼中一旦出現(xiàn)int 0x80的指令,它就會(huì)立即跳轉(zhuǎn)到system_call這個(gè)位置
490ENTRY(system_call)
這個(gè)位置是執(zhí)行完int 0x80這條指令的下一條指令
490ENTRY(system_call) # system_call的位置 491 RING0_INT_FRAME # can't unwind into user space anyway 492 ASM_CLAC 493 pushl_cfi %eax # save orig_eax 494 SAVE_ALL # 保護(hù)現(xiàn)場 495 GET_THREAD_INFO(%ebp) 496 # system call tracing in operation / emulation 497 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) 498 jnz syscall_trace_entry 499 cmpl $(NR_syscalls), %eax 500 jae syscall_badsys 501syscall_call: 502 call *sys_call_table(,%eax,4) # 系統(tǒng)調(diào)用表,eax存放系統(tǒng)調(diào)用號(hào)署鸡,相當(dāng)于調(diào)用sys_time 503syscall_after_call: 504 movl %eax,PT_EAX(%esp) # store the return value 保存返回值 505syscall_exit: 506 LOCKDEP_SYS_EXIT 507 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt 508 # setting need_resched or sigpending 509 # between sampling and the iret 510 TRACE_IRQS_OFF 511 movl TI_flags(%ebp), %ecx 512 testl $_TIF_ALLWORK_MASK, %ecx # current->work 513 jne syscall_exit_work # 一旦進(jìn)入到syscall_exit_work里面,會(huì)有進(jìn)程調(diào)度時(shí)機(jī) 514 515restore_all: 516 TRACE_IRQS_IRET 517restore_all_notrace: # 返回到用戶態(tài) 518#ifdef CONFIG_X86_ESPFIX32 519 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS 520 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we 521 # are returning to the kernel. 522 # See comments in process.c:copy_thread() for details. 523 movb PT_OLDSS(%esp), %ah 524 movb PT_CS(%esp), %al 525 andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax 526 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax 527 CFI_REMEMBER_STATE 528 je ldt_ss # returning to user-space with LDT SS 529#endif 530restore_nocheck: 531 RESTORE_REGS 4 # skip orig_eax/error_code 532irq_return: 533 INTERRUPT_RETURN # 這個(gè)地方就是iret铃在,系統(tǒng)調(diào)用的處理過程到此結(jié)束
系統(tǒng)調(diào)用處理過程的匯編偽代碼
當(dāng)一個(gè)系統(tǒng)調(diào)用發(fā)生的時(shí)候遥诉,它進(jìn)入內(nèi)核處理系統(tǒng)調(diào)用,內(nèi)核提供了一些服務(wù)铐料,在這個(gè)服務(wù)結(jié)束返回到用戶態(tài)之前渐裂,可能會(huì)發(fā)生進(jìn)程調(diào)度,在進(jìn)程調(diào)度里面钠惩,就會(huì)發(fā)生進(jìn)程上下文的切換
可以把內(nèi)核抽象成很多中不同的中斷處理過程的集合
(完)