實驗五:分析system_call中斷處理過程

賀邦 + 原創做品轉載請註明出處 + 《Linux內核分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000linux

將上一個系統調用函數和asm版本的實現整合進入menu的內核中:函數

 

  1. int GetPid()  
  2. {  
  3.      int pid = getpid();  
  4.     printf("The Current Progress pid is : % d\n",pid);  
  5.      return 0;  
  6. }  
  7.     
  8. int GetPidAsm()  
  9. {  
  10.      int pid;  
  11.     asm  volatile(  
  12.         "mov $0,%% ebx\n\t"  
  13.         "mov $0x14,%% eax\n\t"   
  14.         "int $0x80\n\t"   
  15.         "mov %% eax,% 0\n\t"
  16.         : "=m" (pid)   
  17.     );  
  18.     printf("The Current Progress pid asm is : % d\n",pid);  
  19.      return 0;  
  20. }  
  21. int main()  
  22. {  
  23.     PrintMenuOS();  
  24.     SetPrompt("MenuOS>>");  
  25.     MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);  
  26.     MenuConfig("quit","Quit from MenuOS",Quit);  
  27.     MenuConfig("time","Show System Time",Time);  
  28.     MenuConfig("time-asm","Show System Time(asm)",TimeAsm);  
  29.     MenuConfig("getpid","Show Current Progress id",GetPid);  
  30.     MenuConfig("getpid-asm","Show Current Progress asm id",GetPidAsm);  
  31.     ExecuteMenu();  
  32. }  

 

 

上面的一段代碼,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:是系統調用結束前的進程切換模塊,其代碼以下:進程

syscall_exit_work:get

	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返回主程序,至此,系統調用實現任務並返回。回調函數

總之,系統調用做爲一種中斷處理過程,可以反映出通常的中斷處理機制,對於通常的中斷處理,一樣是由四個主要步驟完成的,首先進入中斷,保護好現場,第二步調用中斷的服務程序,第三步,完成中斷退出前的進程切換工做,第四步,返回主程序並恢復現場

相關文章
相關標籤/搜索