圖解Linux系統呼叫
在Linux下面,我們經常呼叫系統API來完成核心的操作,例如呼叫open開啟一個檔案。
這個過程看似簡單,其實已經包括了一次從使用者態到核心態,然後由核心態返回使用者態的過程。
當然使用者不會直接呼叫系統呼叫,而是呼叫glibc中的函式open開啟檔案。
在glibc中維護了一張表格,在syscalls.list裡面,是c函式到系統呼叫的對映。
編譯的過程會將這個對映表格變成程式碼。
真正呼叫系統呼叫的時候,會將引數放入CPU暫存器中,然後通過trap陷入核心,這裡呼叫的是syscall。
ENTRY (syscall)
movq %rdi, %rax /* Syscall number -> rax. */
movq %rsi, %rdi /* shift arg1 - arg5. */
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp),%r9 /* arg6 is on the stack. */
syscall /* Do the system call. */
cmpq $-4095, %rax /* Check %rax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
ret /* Return to caller. */
在核心中,也是有一個sys_call_table陣列的。
陣列中的內容來自與syscall_64.tbl,這是一個文字,編譯的時候會將裡面的系統呼叫名稱放入程式碼中。
在核心中首先從CPU暫存器中拿到系統呼叫號,然後在這個表中查詢open系統呼叫對應的核心函式,經過查抄對應的是sys_open,於是開始呼叫sys_open真正的開啟一個檔案。