?? (ldd) ch01-linux內核簡介(轉載).txt
字號:
”,其中并沒有確定某種設備與信息組織的方式有關;由于文件系統將原始數據組織為
高層信息,它實際上是軟件驅動程序。
如果你考慮到Unix系統對底層文件系統的依賴程度,你就可以意識到軟件概念對系統操
作的重要性。文件系統信息解碼的能力位于內核分層的最底層,而且是最重要的;甚至
如果給自己的CD-ROM寫一個新的塊設備驅動程序時,要是不能對其上數據上運行ls或cp
,那個驅動程序就根本沒有什么用處。Linux支持文件系統模塊,它的軟件接口聲明了可
以操作在文件系統節點,目錄,文件和超級塊上的操作。因此,接口與實際數據傳出傳
以操作在文件系統節點,目錄,文件和超級塊上的操作。因此,接口與實際數據傳出傳
入磁盤是完全獨立的,這是由塊設備驅動程序完成的。對程序員來講,由于正式內核中
已經包含大部分重要文件系統類型的代碼,編寫一個文件系統模塊是很不尋常的要求。
安全問題
最近討論安全問題很是時髦,而大多數程序員都考慮過系統的安全問題,所以,為防止
產生誤解,一開始我就要談論這個問題。
安全性有兩方面。一個問題是由于用戶對程序的誤操作或發掘出錯誤造成的;另一個問
題是由程序員實現的(錯誤)功能造成的。顯然,程序員比普通用戶擁有更多的權利。
換句話說就是,以root權限運行從朋友那拿來的程序比給他/她一個root外殼要危險得多
。盡管訪問編譯器本質上不是安全性漏洞,但當所編譯的代碼執行時,還是會出現漏洞
;要小心處理模塊,因為內核模塊可以做任何事。模塊比超級用戶的外殼的威力還要強
大,它的特權是由CPU確認的。
所有系統中的安全性檢查都是內核代碼完成的。如果內核有安全性漏洞,系統就有漏洞
。在內核正式發布版本中,只有root可以加載模塊;系統調用create_module檢查調用進
程的用戶ID。因此在正式內核中,只有超級用戶,或是成功地稱為root的闖入者可以利
用特權代碼的威力。
幸虧在編寫設備驅動程序或別的模塊時,很少需要考慮安全性問題,因為訪問塊設備的
進程已經受到更通用的塊設備技術的嚴格控制了。例如,對于塊設備來說,安全是由文
件系統節點的權限和mount命令處理的,因此,在實際的塊設備驅動程序中通常沒有什么
件系統節點的權限和mount命令處理的,因此,在實際的塊設備驅動程序中通常沒有什么
好檢查的。
盡管如此,從收到第三方軟件開始,尤其是當軟件涉及到內核時,要格外小心;由于每
個人都可以訪問源代碼,都可以改寫和重新編譯這些東西。如果可以信任發布版中已經
編譯好的內核,就要避免編譯來源不可靠的內核——如果你不能以root身份運行編譯好
的二進制代碼,那最好不要運行編譯好的內核。例如,有敵意改動過的內核可能允許任
何人加載模塊,因此通過create_module就可以打開一個不希望出現的后門。
如果確實在模塊相關部分考慮到安全性問題,我敦促你看一看securelevel內核變量是怎
樣使用的。當我寫這些的時候,Linux社團里正在討論控制securelevel變量來防止模塊
加載和卸載。很有趣,你可以注意到最近的內核支持在內核編譯時可以刪除對模塊的支
持,這樣就關閉了所有安全性有關的漏洞。
版本編號
做為開始研究編程前的最后一點,我很愿意就Linux非同尋常的版本編號這個問題加以說
明,同時說明本書使用哪個版本的內核。
首先要注意,Linux系統使用的每個軟件包都有它自己的發行號,它們之間有一些內部的
依賴關系:你需要在特定版本的軟件包上使用特定版本的另一個軟件包。Linux發布版的
開發者通常要處理大量軟件包的匹配問題,而使用者從預先打包的發布版本上安裝軟件
,無需考慮版本問題。而另一方面,那些更換和升級系統軟件的人都要自己處理版本問
題。所幸的是,一些最新發布的版本允許單個軟件包的升級,它是通過檢查軟件包間的
題。所幸的是,一些最新發布的版本允許單個軟件包的升級,它是通過檢查軟件包間的
依賴性實現的,這可大大簡化了使用者為維護系統軟件一致所要做的事情。
在本書中,我假定你有2.6.3版或更新的gcc編譯器,1.3.57版或更新版本的模塊工具,
以及最新的程序開發用GNU工具(最重要的是gmake)。這些要求不是那么嚴格,由于幾
乎所有的Linux安裝版上都配有GNU工具,這些版本都相對較舊(此外,內核2.0版及其后
繼版本不能用比版本2.6還舊的gcc編譯)。注意,最近的內核包含一個稱為Documentati
on/Changes的文件,它羅列了所有編譯和運行這個內核版本所需要的軟件。1.2的源碼中
沒有這個文件。
只要涉及到內核部分,我將集中介紹2.0.X和1.2.13版本,編寫適用于這兩個版本的代碼
。
偶數內核版本(如1.2.x和2.0.x)是穩定版本,專門用于發布的版本。而相反,奇數版
本是開發中的一個快照,相當短暫;最新的版本代表最新的發展狀況,但可能過幾天就
過時了。
這里沒有別的通用原因來解釋為什么要運行1.3和2.1核心,除非他們是最新的版本。不
過有時你會選擇運行一個開發用內核,或時由于它有一些在穩定版本中沒有的特性,而
你正好需要這些特性,或者很簡單,你就是自己改動了這些版本的一些特性,并且你沒
有時間更新你的補丁。不過還是要注意,實驗用內核沒有什么保證,如果由于在非當前
奇數版本的內核中的臭蟲導致你丟失數據,沒人幫得了你。不過,本書支持直到2.1.43
版的開發用內核,最后一章介紹如何編寫可以區分2.0和2.1.x之間不同之處的驅動程序
版的開發用內核,最后一章介紹如何編寫可以區分2.0和2.1.x之間不同之處的驅動程序
。
至于1.2.13,盡管相當舊,我仍覺得這是一個很重要的版本。盡管在某些平臺上2.0.x比
1.2.13要快得多,但1.2.13非常小,對想使用舊硬件的人來說是個很好的選擇。基于386
處理器,帶小RAM的低價系統非常適合于做嵌入式系統或自動化控制器,用1.2.13比2.0.
x也許會更快,由于1.2.13是以前1.2.x版本的錯誤修訂版,我不想考慮更早的1.2內核。
無論什么時候,只要1.2.13和2.0或最新的2.1版不兼容,我都會告訴你。
不管怎樣,我的主要目標版本是Linux 2.0,本書介紹的一些特征在舊版本中是沒有的。
大多數樣例模塊在很多內核版本中都是可以編譯和運行的;特別是它們都已經在2.0.30
版本上測試過了,而且大多數也都經過了1.2.13版本的測試。有時,我的例子不支持1.2
,但只在本書的第二部分中出現這樣的情況,這部分對設計來講更深入,并且可以不用
考慮舊版本。
由于Linux已不再只是“PC兼容機的Unix變體”了,它的另一個特點是,它是平臺獨立的
操作系統。事實上,除了x86以外,它也成功地用于Axp-Alpha,Sparc處理器,Mips
Rx000和其他一些平臺。本書也盡力達到平臺無關性,而且所有的例子代碼都在PC,Alph
a平臺和Sparc機器上測試過。由于代碼在32位和64位處理機(Alpha)上測試過,它們應
該可以在其他平臺上編譯和運行。正如你所預料的,依賴特殊硬件的編碼不能適用于所
有的平臺,但在源代碼中都有所說明。
許可證術語
Linux是按GNU“General Public License”(GPL)分布許可證的。這是由自由軟件基金會
為GNU計劃設計的文檔。GPL允許任何人重新發布,出售GPL的產品,只要允許接收者從源
碼重新建立二進制文件的精確副本。另外,任何從GPL產生的軟件產品也必須按GPL發布
。
這種許可的主要目的是通過允許每個人隨意修改程序來推廣知識;同時,向公眾出售軟
件的人仍可以做他們的工作。盡管這是個很簡單的目標,還是有一些正在進行的有關GPL
及其使用的討論。如果你想讀到這些許可證,你可以在你系統的若干個地方找到它們,
包括目錄/usr/src/linux,有一個稱為COPING文件。
當涉及到第三方和定制的模塊時,它們不屬于內核,因此你無需限制它們使用GPL許可證
。模塊通過明確的接口使用內核,它不是內核的一部分,這種關系和用戶程序通過系統
調用使用內核很相似。
簡而言之,如果你的代碼深入內核內部而你又想發布代碼,你必須使用GPL。盡管自己修
改自己使用不是非要使用GPL,如果你要發布代碼,就必須在發布中包含源代碼——人們
獲得你的軟件包,并且可以隨意修改它,重建二進制文件。換句話說,如果你寫了一個
模塊,你就可以按照二進制格式發布你的模塊。然而,由于模塊通常要針對要連接的內
核重新編譯(在第2章“編寫和運行模塊”中的“版本相關性”一節中,第11章“Kernel
d和高級模塊化”的“模塊中的版本控制”一節中都有所介紹),這也不總是可行的。對
發布模塊的二進制代碼一般障礙是,模塊包含了定義或聲明在內核頭文件中的代碼;不
發布模塊的二進制代碼一般障礙是,模塊包含了定義或聲明在內核頭文件中的代碼;不
過這個障礙并不能成立,因為頭文件是內核公共接口的一部分,因此它不受許可證制約
。
至于談到本書,大部分源碼都是可以重新發布的,或者以源碼形式,或者以二進制代碼
形式,不論O’Reilly還是我都不對任何基于此的工作有任何許可證權。所有程序都可以
通過FTP從ftp://ftp.ora.com/pub/examples/linux/drivers/下載,而且同一個目錄下
的LICENCE文件有具體的許可證說明。
當例子中包含了部分內核代碼時,GPL就適用了:與源碼一同發行的文本很清楚地說明了
這一點。這僅對某些源文件是有效的,對本書主題而言,這是次要的。
全書概貌
從此開始,我們進入內核編程的世界。第2章介紹模塊化,解釋了這門技藝的秘密,并給
出了運行模塊的代碼。第3章,字符設備驅動程序,討論字符設備驅動程序并且給出了基
于內存的設備驅動程序的完整代碼,可以按你的喜好進行讀寫。使用內存做為設備的硬
件基礎,可以使任何人運行例子代碼,而無需增加特殊硬件。
調式技術對程序員來講是至關重要的,這些內容在第4章“調試技術”中介紹。這樣,運
用我們新的調試技巧,我們將面對字符設備驅動程序高級功能,如阻塞型操作,select
的使用以及非常常用的ioctl調用;這是都是第5章“字符設備驅動程序的擴展操作”的
主題。
在涉及硬件管理之前,我們先解剖幾個內核軟件接口:第6章“時間流”,講解內核是如
何管理時間的,第7章“獲取內存”,講解內存分配。
接下來我們著重于硬件:第8章“硬件管理”,介紹I/O端口的管理和設備中的內存緩沖
區管理;之后在第9章“中斷處理”介紹中斷處理。遺憾的是,由于需要某些硬件支持來
測試中斷的軟件接口,不是每個人能運行本章給出的樣例代碼。我已經盡我全力保持所
需的硬件支持減少到最小,但你還得親自動手用烙鐵做你的硬件“設備”。這個設備僅
僅是一個加到并口上的跳線,所以我希望這不是問題。
第10章“合理使用數據類型”又提供一些有關編寫內核軟件和一致性問題的建議。
在本書的第二部分,我們更加雄心勃勃;因此從第11章開始,我們重新討論模塊化,更
加深入討論這個問題。
第12章“加載塊設備驅動程序”介紹了如何實現塊設備驅動程序,強調和字符設備驅動
程序的區別。接下來,第13章“Mmap和DMA”講解了我們原先在內存管理中留下來的問題
:mmap和DMA。到此為止,關于字符設備和塊設備驅動程序的所有問題我們都介紹過了。
接下來介紹第三類設備驅動程序:第14章“網絡設備驅動程序”討論一些關于網絡接口
的細節,剖析了樣例網絡設備驅動程序的代碼。
有些設備驅動程序的功能直接依賴于外設所在的接口總線,所以第15章“外設總線概貌
”介紹了現在經常用到的總線實現的主要功能,著重介紹內核支持的PCI總線。
最后,第16章是內核源代碼的一次檢閱:對那些想理解全部設計的人來講,這是一個起
點,但他們可能會被Linux浩如煙海的代碼嚇倒。
在Linux2.0版發布后不久,2.1開發樹開始引入不兼容性;這是在第一個月中引入的最重
要的內容。第17章“近期發展”,它幾乎可以看作是附錄,它收集所有在2.1.43版本發
布之前不兼容的東西,并且提供了解決這些兼容性問題的方法。在這章的最后,你可以
編寫出一個設備驅動程序,它能夠在1.2.13版本上編譯,運行,也可以在所有2.0和2.1.
43版本之間的內核上編譯,運行。2.2很有希望會和2.1.43非常相似,你的軟件需要為此
做好準備。
-----------------------------------------------------------------------------
* SCSI時Small Computer System Interface(小型計算機系統接口)的縮寫;它時工作
站市場上形成的標準,也廣泛應用在PC領域。
--
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -