程序在使用一個函數之前,應該首先聲明該函數。為了便于使用,通常的做法是把同一類函數或數據結構以及常數的聲明放在一個頭文件(header file)中。頭文件中也可以包括任何相關的類型定義和宏(macros)。在程序源代碼文件中則使用預處理指令“#include”來引用相關的頭文件。
程序中如下形式的一條控制行語句將會使得該行被文件filename的內容替換掉:
# include
當然,文件名filename中不能包含 > 和換行字符以及 "、'、、或 /* 字符。編譯系統會在定義的一系列地方搜索這個文件。類似地,下面形式的控制行會讓編譯器首先在源程序所在目錄中搜索filename文件:
# include "filename"
如果沒有找到,編譯器再執行同上面一樣的搜索過程。在這種形式中,文件名filename中不能包含換行字符和 "、'、、或 /* 字符,但允許使用 > 字符。
在一般應用程序源代碼中,頭文件與開發環境中的庫文件有著不可分割的緊密聯系,庫中的每個函數都需要在頭文件中加以聲明。應用程序開發環境中的頭文件(通常放置在系統/usr/include/目錄中)可以看作是其所提供函數庫(例如libc.a)中函數的一個組成部分,是庫函數的使用說明或接口聲明。在編譯器把源代碼程序轉換成目標模塊后,鏈接程序(linker)會把程序所有的目標模塊組合在一起,包括用到的任何庫文件中的模塊。從而構成一個可執行的程序。
對于標準C函數庫來講,其最基本的頭文件有15個。每個頭文件都表示出一類特定函數的功能說明或結構定義,例如I/O操作函數、字符處理函數等。有關標準函數庫的詳細說明及其實現可參照Plauger編著的《The Standard C Library》一書。
而對于本書所描述的內核源代碼,其中涉及的頭文件則可以看作是對內核及其函數庫所提供服務的一個概要說明,是內核及其相關程序專用的頭文件。在這些頭文件中主要描述了內核所用到的所有數據結構、初始化數據、常數和宏定義,也包括少量的程序代碼。除了幾個專用的頭文件以外(例如塊設備頭文件blk.h),Linux 0.12內核中所用到的頭文件都放在內核代碼樹的include/目錄中。因此編譯Linux 0.12內核無需使用開發環境提供的位于/usr/include/目錄下的任何頭文件。當然,tools/build.c程序除外。因為這個程序雖然被包含在內核源代碼樹中,但它只是一個用于組合創建內核映像文件的工具程序或應用程序,不會被鏈接到內核代碼中。
從0.95版開始,內核代碼樹中的頭文件需要復制到/usr/include/linux目錄下才能順利地編譯內核。即從該版內核開始頭文件已經與開發環境使用的頭文件合二為一。
14.1 include/目錄下的文件
內核所用到的頭文件都保存在include/目錄下。該目錄下的文件如表11-1所示。這里需要說明一點:為了方便使用和兼容性,Linus在編制內核程序頭文件時所使用的命名方式與標準C庫頭文件的命名方式相似,許多頭文件的名稱甚至其中的一些內容都與標準C庫的頭文件基本相同,但這些內核頭文件仍然是內核源代碼或與內核有緊密聯系的程序專用的。在一個Linux系統中,它們與標準庫的頭文件并存。通常的做法是將這些頭文件放置在標準庫頭文件目錄中的子目錄下,以讓需要用到內核數據結構或常數的程序使用。
另外,也由于版權問題,Linus試圖重新編制一些頭文件以取代具有版權限制的標準C庫的頭文件。因此這些內核源代碼中的頭文件與開發環境中的頭文件有一些重疊的地方。在Linux系統中,列表14-1中的asm/、linux/和sys/三個子目錄下的內核頭文件通常需要復制到標準C庫頭文件所在的目錄(/usr/include)中,而其他一些文件若與標準庫的頭文件沒有沖突則可以直接放到標準庫頭文件目錄下,或者改放到這里的三個子目錄中。
asm/目錄下主要用于存放與計算機體系結構密切相關的函數聲明或數據結構的頭文件。例如Intel CPU 端口IO匯編宏文件io.h、中斷描述符設置匯編宏頭文件system.h等。linux/目錄下是Linux內核程序使用的一些頭文件。其中包括調度程序使用的頭文件sched.h、內存管理頭文件mm.h和終端管理數據結構文件tty.h等。而sys/目錄下存放著幾個與內核資源相關頭文件。不過從0.98版開始,內核目錄樹下sys/目錄中的頭文件被全部移到了linux/目錄下。
Linux 0.12版內核中共有32個頭文件(*.h),其中asm/子目錄中含有4個,linux/子目錄中含有10個,sys/子目錄中含有5個。從下一節開始我們首先描述include/目錄下的13個頭文件,然后依次說明每個子目錄中的文件。說明順序按照文件名稱排序進行。
新聞熱點
疑難解答