Kernel

系統呼叫:使用者程序如何向/從核心傳遞/接收數據?

  • July 7, 2020

使用者和核心虛擬地址之間的關係之前已經在幾個問題中討論過(下面的連結),但據我了解,使用者程序無法讀取或寫入核心地址。

那麼,使用者程序如何從核心共享和接收數據呢?

是通過記憶嗎?如果是這樣,記憶體佈局在哪裡?也許CPU寄存器?

相關問題:

記憶體佈局

讓我們考慮一個例子:一個用於 Linux 的簡單 x86 Hello World程序,它列印一條消息stdout並退出。它需要將幾個數據項傳遞給核心:

  • 要輸出的文本字元串,
  • 退出程式碼。

這是彙編程式碼(使用 FASM 編譯):

format ELF executable
segment readable executable

; system call numbers
SYS_EXIT=1
SYS_WRITE=4
; file descriptors
STDOUT=1

entry $
start:
   mov eax, SYS_WRITE
   mov ebx, STDOUT
   mov ecx, message
   mov edx, messageLength
   int 0x80

   mov eax, SYS_EXIT
   xor ebx, ebx ; exit code 0
   int 0x80

message:
   db "Hello, world!",0xa
messageLength=$-message

該程序為實現其主要目標(消息輸出)所做的一切是

  • 將適當的 CPU 寄存器設置為代表系統呼叫號(用於sys_write系統呼叫)、文件描述符 ( stdout)、消息地址和消息長度的值
  • 執行系統呼叫,在本例中通過軟體中斷 0x80

類似的順序是退出:將寄存器設置為系統呼叫號和退出程式碼,然後進行系統呼叫。

哪些寄存器設置為哪些值由系統呼叫呼叫約定定義。

在核心開始執行系統呼叫處理程序後,該處理程序從應用程序的上下文中讀取寄存器的值,並根據呼叫約定解釋它們。特別是,當它看到系統呼叫是sys_write時,它會獲取消息的長度和地址,並使用它們從使用者空間記憶體中讀取。然後這些數據(連同文件描述符)被傳遞給將執行實際工作的驅動程序。

引用自:https://unix.stackexchange.com/questions/597241