Linux-Kernel

什麼是可以在使用者空間中使用的核心標頭檔?它們的簽名或介面是否與不同目錄中的標頭不同?

  • March 30, 2020

這可能是關於核心標頭檔的一個不連貫的問題,因為我對它以及它的使用位置和方式沒有清楚的了解。我認為它可能會被標記。我的問題有 3 個部分:

  1. 我認為核心標頭檔提供了一個介面,以便核心的其他部分(如模組)可以使用它們。這就是我的書本知識。我還沒有看到或找到任何使用核心標頭檔的程式碼(如果有人能指出我將不勝感激)。它也可以在使用者空間中使用嗎?任何程式碼範例將不勝感激。
  2. 我發現使用make headers_install核心標頭檔是由使用者空間公開的,但同時不鼓勵在使用者空間中使用核心標頭檔。如果不鼓勵,那麼將其暴露給使用者空間有什麼用?
  3. 根據thisthis,核心標頭檔(.h 文件)應位於 3 個位置:/usr/include/linux/kernel.h用於使用者空間 b。/lib/modules/$(uname -r)/build/include/linux/sched.h這是外部模組 c. /usr/src/...哪個用於核心模組這是否意味著不同目錄中的標頭檔具有不同的用途或不同的介面或簽名?換句話說,#include <linux/xyz.h> 使用者空間程式碼中的含義與#include <linux/xyz.h>核心模組中的含義不同嗎?外部模組也與核心模組相同嗎?

謝謝。

歡迎來到 Unix 和 Linux StackExchange!

是的,核心標頭檔為核心的其他部分提供了一個介面——在這方面你是完全正確的。它們還包括核心和使用者空間之間介面的定義——但通常不直接使用“原始”核心介面,而是通過 C 庫(通常glibc)使用。

出於向後兼容的原因,使用者空間-核心介面可能包括特定係統呼叫的多個版本。通過 C 庫進行系統呼叫,所有應用程序都獲得了相同版本的實際系統呼叫,從而保證了一致的行為。此外,當核心介面的相關部分更新時,您只需更新 C 庫即可利用新功能。

(例如,當 time_t 在 32 位架構中擴展為 64 位以避免 Y2K38 問題時,C 庫可能會轉移到始終使用 64 位版本的核心介面,但具有使用者空間可配置的應用程序映射仍然使用 32 位版本。到那時,使用 32 位 time_t 的函式可以被淘汰並從核心中刪除,C 庫可以為仍然使用 32 位類型的遺留應用程序提供更好的解決方法。)

因此,除非您還編譯自己的版本或 C 庫,否則您通常應該更喜歡 C 庫的開發標頭檔,而不是直接使用核心標頭檔。

標頭檔中/usr/include/linux/通常帶有 C 庫的開發頭包,並描述了 C 庫編譯的核心版本。這是使用者空間應用程序開發人員通常需要的。

/lib/modules/$(uname -r)/build通常是一個符號連結,指向/usr/src/...儲存實際執行核心版本的標頭或完整原始碼的位置。它在編譯外部(也稱為第三方)核心模組時使用,即來自未集成到主核心原始碼的源的核心模組。這些標頭包含必要的核心 API 版本簽名,以便模組可以使用特定於版本的核心內部 API。

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