2009-08-07 36 views
9

靈感來自這個問題系統調用在Linux上如何實際發生?

How can I force GDB to disassemble?

和與此相關的一個

What is INT 21h?

如何實際的系統調用Linux下發生的呢?調用執行時會發生什麼,直到調用實際的內核例程?

+0

+1,有趣的問題! – 2009-08-07 17:12:48

+0

系統調用實現問題:http://stackoverflow.com/questions/499188/how-is-the-system-call-in-linux-實施 – nik 2009-08-07 17:17:05

+0

投票自己關閉。實際上是重複的(沒有出現在搜索中,因爲我使用了系統調用) – 2009-08-07 18:41:14

回答

8

假設我們正在談論86:

  1. ID of the system call被存入EAX寄存器
  2. 通過系統調用所需的任何參數都存入locations dictated by the system call。例如,一些系統調用期望它們的參數駐留在EBX寄存器中。其他人可能會認爲他們的論點是坐在頂端。
  3. 一個INT 0x80中斷被調用。
  4. Linux內核爲由EAX寄存器中的ID標識的系統調用提供服務,將任何結果存放在預定位置。
  5. 調用代碼使用任何結果。

我可能是在這個有點生疏了,它已經有幾年...

+0

如果我沒有記錯,由於內核有自己的堆棧,所以用戶空間程序不能在其上放置任何東西,所以所有參數都必須通過寄存器傳遞。 – Benno 2009-08-07 17:18:07

+0

真的嗎?我隱約記得我的教授提到Linux有一些將用戶空間地址映射到內核空間的宏...我可能是錯的。 – 2009-08-07 17:20:09

+3

INT 0x80僅用於SYSCALL/SYSENTER指令不可用的情況下,IIRC。 – 2009-08-09 23:37:34

7

給出的答案是正確的,但我想補充說有更多的機制進入內核模式。每個最近的內核都在每個進程的地址空間中映射「vsyscall」頁面。它只包含最有效的系統調用陷阱方法。

例如常規的32位系統上它可能包含:


0xffffe000: int $0x80 
0xffffe002: ret 

但在我64 bitsystem我有機會的方式來使用更有效的方法的系統調用/ SYSENTER指令


0xffffe000: push %ecx 
0xffffe001: push %edx 
0xffffe002: push %ebp 
0xffffe003:  mov %esp,%ebp 
0xffffe005:  sysenter 
0xffffe007: nop  
0xffffe008: nop  
0xffffe009: nop  
0xffffe00a: nop  
0xffffe00b: nop  
0xffffe00c: nop  
0xffffe00d: nop  
0xffffe00e:  jmp 0xffffe003 
0xffffe010: pop %ebp 
0xffffe011: pop %edx 
0xffffe012: pop %ecx 
0xffffe013: ret  

這個vsyscall頁面還映射了一些可以在沒有上下文切換的情況下完成的系統調用。我知道一定gettimeofday的時間getcpu被映射在那裏,但我想GETPID可能適合在那裏一樣好。