
當我閱讀有關係統呼叫的內容時,我搜尋了「syscalls.h」以找到 LXR 中的頭檔。搜尋結果讓我很困惑。有十幾個「syscalls.h」檔案來自「arch/_arch_name_/include/asm」下的目錄。這些都可以,它們是架構特定的定義或其他需要的東西。問題是為什麼我們在 /include/linux 和 /include/asm-generic 下有兩個不同的「syscalls.h」頭檔?
另外,我想找出 /include/linux 標頭的用途以及 /include/asm-generic 標頭的用途。他們如何區分彼此?擁有兩個單獨的標頭資料夾背後的邏輯是什麼?他們之間的關係如何?
謝謝
答案1
以下的標題asm/generic
主要是作為權宜之計,在編寫特定於體系結構的版本之前,C 語言的可移植版本。您還會發現,在某些情況下,/usr/include/foobar.h
包含大量「內部實作」標頭,最後依靠來自核心的部分(通常稱為相同的部分)。範例是math.h
和 (更多依賴 Linux)syscall.h
。
答案2
該軟體必須是可移植的。如果您編譯 C/C++ 原始程式碼,那麼您不需要知道您是否執行 i386/x86_64/arm/mips 或其他什麼。標頭以軟體編譯的方式連結。
所有其他頭檔的存在是因為它們實現了許多不同的標準,有來自 BSD 的移植等等。其中許多都是有歷史根據的。每個人從哪裡來,為何存在,都有許多不同的原因,並且肯定會給出令人震驚的答案。
以及 asm-generic 的答案:堆疊溢位
答案3
arch/x86/entry/
有兩個特殊的系統呼叫檔:
syscalls/syscall_32.tbl
和迪托“64”
系統呼叫很特殊,因為核心必須將 ABI 和 API 結合在一起。
一般來說,包含目錄和其他頭檔(獨立的文件,如 kernel/sched/sched.h)遵循分層邏輯。我認為 make 和 gcc 都發揮了作用。
有系統地使用這些符號來確保每個標頭「單元」僅被讀取一次。 (“保護性包裝紙”,因為可能有太多的縱橫交錯)。這裡來自include/linux/mm.h
:
#ifndef _LINUX_MM_H
#define _LINUX_MM_H
#include <linux/errno.h>
#ifdef __KERNEL__
... (#includes)
... (ext. decl. etc., the whole mm.h)
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
tbl 檔有:
# 32-bit system call numbers and entry vectors
該列表開頭為:
0 i386 restart_syscall sys_restart_syscall __ia32_sys_restart_syscall
1 i386 exit sys_exit __ia32_sys_exit
2 i386 fork sys_fork __ia32_sys_fork
3 i386 read sys_read __ia32_sys_read
#
# 64-bit system call numbers and entry vectors
#
# The format is:
# <number> <abi> <name> <entry point>
#
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
#
# The abi is "common", "64" or "x32" for this file.
我稍後會做佈局...