賀邦 + 原創做品轉載請註明出處 + 《Linux內核分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000linux
將上一個系統調用函數和asm版本的實現整合進入menu的內核中:函數
上面的一段代碼,MenuConfig這個函數是菜單(也就是製做出來的內核)的初始化配置函數,第一個參數是命令,第二個參數是該命令的描述,第三個參數是這個命令相對應的handler,也就是回調函數,是經過一個函數指針進行實現的。ExecuteMenu這個函數是爲了啓動這個menu引擎,實際上是一個循環等待用戶輸入命令的過程。ui
將上週寫的兩個函數分別命名爲int getuidc() int getuid_asm,將這兩個函數寫入test.c文件中:spa
而後,修改main()函數中的配置命令,加入兩個命令usrid和userid_asm,分別有函數getuidc和函數getuid_asm實現:操作系統
經過make rootfs腳本命令運行一下,能夠看出經過userid命令和userid_asm命令均可以獲取程序的用戶id:指針
下面,詳細分析一下menu操做系統經過user命令和user_asm命令對系統內核服務的調用。在操做系統啓動過程當中,首先對系統調用進行初始化,系統調用實質上是一種中斷,是經過\int\main.c \start_kernel文件中的trap_int()函數聲明的,trap_int()函數指向\arch\x86\kernel\traps.c文件中的set_system_trap_gate(SYSCALL_VECTOR,&system_call)函數,在這一過程當中,經過參數SYS_CALL傳遞系統調用中斷向量,&system_call是彙編代碼入口。在本例的menu操做系統中,中斷向量int 0x80指向系統調用system_call:code
在如上流程中,system_exit:是系統調用結束前的進程切換模塊,其代碼以下:進程
testl $_TIF_WORK_SYSCALL_EXIT, %ecx jz work_pending TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call # schedule() instead movl %esp, %eax call syscall_trace_leave jmp resume_userspace END(syscall_exit_work)
系統調用完成後,經過彙編命令iret返回主程序,至此,系統調用實現任務並返回。回調函數
總之,系統調用做爲一種中斷處理過程,可以反映出通常的中斷處理機制,對於通常的中斷處理,一樣是由四個主要步驟完成的,首先進入中斷,保護好現場,第二步調用中斷的服務程序,第三步,完成中斷退出前的進程切換工做,第四步,返回主程序並恢復現場