1. 程式人生 > >Exynos 4412 Cortex-A9嵌入式Linux驅動開發學習筆記-第一期

Exynos 4412 Cortex-A9嵌入式Linux驅動開發學習筆記-第一期

一、Linux 體系結構

如下圖所示,Linux 體系結構,從大的方面可以分為使用者空間(User Space)和核心空間 (Kernel Space)。


使用者空間中包含了 C 庫,使用者的應用程式。在某些體系結構圖中還包含了 shell,當然 shell指令碼也是 Linux 體系中不可缺少的一部分。
核心空間包括硬體平臺、平臺依賴程式碼、核心、系統呼叫介面。
另外,使用者空間和核心空間是程式執行的兩種不同狀態,我們可以通過“系統呼叫”和“硬體中斷”來完成使用者空間到核心空間的轉移。

二、瞭解 Linux 核心結構

如下圖所示,是 Linux 核心結構圖。


SCI 層(System Call Interface),這一層是給應用使用者空間提供一套標準的系統呼叫函式來訪問 Linux。前面分析 Linux 體系結構的時候,介紹過任何一類現代作業系統都不會允許上層應用直接訪問底層,在 Linux 中,核心提供了一套標準介面,上層應用就可以通過這一套標準介面來訪問底層。

PM(Procees Management),這一部分包括具體建立建立程序(fork、exec),停止程序(kill、exit),並控制他們之間的通訊(signal 等)。還包括程序排程,控制活動程序如何共享 CPU。這一部分是 Linux 已經做好的,在寫驅動的時候,只需要呼叫對應的函式即可實現這些功能,例如建立程序、程序通訊等等。

MM(Memory Management),記憶體管理的主要作用是控制多個程序安全的共享記憶體區域。

VFS(Virtual File Systems),虛擬檔案系統,隱藏各種檔案系統的具體細節,為檔案操作提供統一的介面。在 Linux 中“一切皆檔案”,這些檔案就是通過 VFS 來實現的。Linux 提供了一個大的通用模型,使這個模型包含了所有檔案系統功能的集合。如下圖所示,是一個虛擬檔案系統的結構圖。


Device Drivers 裝置驅動,這一部分就是需要學習和掌握的。Linux 核心中有大量的程式碼在裝置驅動程式部分,用於控制特定的硬體裝置。

Linux 驅動一般分為網路裝置、塊裝置、字元裝置、雜項裝置,需要我們編寫的只有字元裝置,雜項裝置是不容易歸類的一種驅動,雜項裝置和字元裝置有很多重合的地方。

網路協議棧,Linux 核心中提供了豐富的網路協議實現。

 三、瞭解 Linux 核心原始碼目錄結構

 

Linux核心目錄結構(2.6版本以上的kernel)
1、documentation:

沒有核心程式碼,提供文件幫助。

2、arch:

arch是architecture的縮寫。所有與體系結構相關的程式碼都在這個目錄以

include/asm-*/目錄中。Linux支援的每種體系結構在arch目錄下都有對應的目錄,又進一

步分解為boot,mm,kernel等子目錄:

| kernel: 存放支援體系結構特有的諸如訊號量處理和SMP之類特徵的實現。

| lib: 存放體系結構特有的對諸如strlen和memcpy之類的通用函式的實現。

| mm: 存放體系結構特有的記憶體管理程式的實現。

除了這3個子目錄以外,大多數體系結構在必要的情況下還有一個boot子目錄,包括了在這種硬體平臺上啟動核心所使用的記憶體管理程式的實現。

3、drivers:

驅動程式碼,驅動是一個控制硬體的軟體。這個目錄是核心中最龐大的一個目錄,顯示卡、網絡卡、SCSI介面卡、PCI匯流排、USB匯流排和其他任何Linux支援的外圍裝置或匯流排的驅動程式都可以在這兒找到。

4、fs:

虛擬檔案系統(VFS)的程式碼,和各個不同檔案系統的程式碼都在這個目錄中。Linux支援的所有檔案系統在fs目錄下面都有一個對應的子目錄。比如ext2檔案系統對應的是fs/ext2目錄。

一個檔案系統是儲存裝置和需要訪問儲存裝置的程序之間的媒介。儲存裝置可能是本地的物理上可以訪問的,比如硬碟或者CD-ROM驅動器,他們分別使用而系統ext2/ext3和isofs檔案系統。

還有一些虛擬檔案系統(proc),它是一個標準檔案系統出現。然而,他其中的檔案只存在於記憶體中,並不佔磁碟空間。

5、include:

這個目錄包含了核心中大部分的標頭檔案,它按照下面的子目錄進行分組。要修改處理器結構則只需編輯核心的makefile並重新執行Linux核心配置程式。

| include/asm-*/ 每一個對應著一個arch的子目錄,比如include/asm-alpha、

Include/asm-arm等。每個子目錄中的檔案都定義了支援給定體系結構所必要的預處理函式和行內函數,這些行內函數多數都是全部或者部分的組合語言實現。

| include/linux 與平臺無關的標頭檔案都在這個目錄下,它通常會被連結到目錄 /usr/include/linux(或者它裡面的所有檔案都會被複制到

/usrinclude/linux目錄下邊)

6、init:

核心的初始化程式碼。包括main.c、建立早起使用者空間的程式碼及其他初始化程式碼。

7、ipc:

IPC(程序間通訊)。它包含了共享記憶體、訊號量及其他形式的IPC程式碼。

8、kernel:

核心中最核心的部分,包括程序的排程(sched.c),以及程序的建立和撤銷(fork.c和exit.c)和平臺相關的另外一部分核心程式碼在arch/*/kernel目錄下。

9、mm

此目錄包含了與體系無關的部分記憶體管理程式碼。與體系結構相關的記憶體管理程式碼位於arch/*/mm下。
10、net
核心的網路部分程式碼,實現了各種常見的網路協議,入TCP/IP、IPX等。
11、lib
此目錄包含了核心的庫程式碼。實現了一個標準C庫的通用子集,包括字串和記憶體操作的函式(strlen、mmcpy等)以及有關sprintf和atoi系列函式。與arch/lib下的程式碼不同,這裡的庫程式碼都是C編寫的,在核心新的移植版本中可以直接使用。與處理器結構相關庫程式碼被放在arch/mm中。
12、block:
塊裝置驅動包括IDE(在ide.c中)驅動。塊裝置是以資料塊方式接收和傳送的資料的裝置。最初block層程式碼一部分位於drivers目錄,一部分位於fs目錄。從2.6.15開始,block層的核心程式碼就被提取出來放在頂層的block目錄中。如果你想尋找這些可包含檔案系統的裝置的初始化過程則應該在drivers/block/genhd.c中的device_setup()。當安裝一個nfs檔案系統時不但要初始化硬碟還需初始化網路。塊裝置包括IDE與SCSI裝置。

13、firmware

fireware中包含了讓計算機讀取和理解從裝置發來的訊號的程式碼。舉例來說,一個攝像頭管理它自己的硬體,但計算機必須瞭解攝像頭給計算機發送的訊號。Linux系統會使用vicam韌體(firmware)來理解攝像頭的通訊。否則,沒有了韌體,Linux系統將不知道如何處理攝像頭髮來的資訊。另外,韌體同樣有助於將Linux系統傳送訊息給該裝置。這樣Linux系統可以告訴攝像頭重新調整或關閉攝像頭。

13、usr:

實現用於打包和壓縮的cpio等。這個資料夾中的程式碼在核心編譯完成後建立這些檔案。

14、securtity:

這個目錄下包含了不同的Linux安全模型的程式碼。它對計算機免於受到病毒和黑客的侵害很重要。否則,Linux系統可能會遭到損壞。

15、crypto:

核心本身所用的加密API,實現了常用的加密和雜湊演算法,還有一些壓縮和CRC校驗演算法。例:“sha1_generic.c”這個檔案包含了SHA1加密演算法的程式碼。

16、scripts:

該目錄下沒有核心程式碼,只是包含了用來配置核心的指令碼檔案。當執行make menuconfig或者make xconfig之類的命令配置核心時,使用者就是和位於這個目錄下的指令碼進行互動的。
17、sound:

音效卡驅動以及其他聲音相關的原始碼。

18、samples
一些核心程式設計的範例

19、virt

此資料夾包含了虛擬化程式碼,它允許使用者一次執行多個作業系統。通過虛擬化,客戶機作業系統就像任何其他執行在Linux主機的應用程式一樣執行。

20、tools

這個資料夾中包含了和核心互動的工具。

COPYING:許可和授權資訊。Linux核心在GPLv2許可證下授權。該許可證授予任何人有權免費去使用、修改、分發和共享原始碼和編譯程式碼。然而,沒有人可以出售原始碼。

CREDITS : 貢獻者列表

Kbuild : 這是一個設定一些核心設定的指令碼。打個比方,這個指令碼設定一個ARCH變數,這是開發者想要生成的核心支援的處理器型別。

Kconfig: 這個指令碼會在開發人員配置核心的時候用到

MAINTAINERS : 這是一個目前維護者列表,他們的電子郵件地址,主頁,和他們負責開發和維護的核心的特定部分或檔案。當一個開發者在核心中發現一個問題,並希望能夠報告給能夠處理這個問題的維護者時,這是是很有用的。

Makefile :這個指令碼是編譯核心的主要檔案。這個檔案將編譯引數和編譯所需的檔案和必要的資訊傳給編譯器。

README : 這個文件提供給開發者想要知道的如何編譯核心的資訊。

REPORTING-BUGS : 這個文件提供如何報告問題的資訊。

核心的程式碼是以“.c”或“.h”為副檔名的檔案。 “.c”的擴充套件名錶明核心是用眾多的程式語言之一的C語言寫的, “h”的檔案是標頭檔案,而他們也是用C寫成。標頭檔案包含了許多“.c”檔案需要使用的程式碼,因為他們可以引入已有的程式碼而不是重新編寫程式碼,這節省了程式設計師的時間。否則,一組執行相同的動作的程式碼,將存在許多或全部都是“c”檔案。這也會消耗和浪費硬碟空間。(譯註:標頭檔案不僅僅可節省重複編碼,而且程式碼複用也會降低程式碼錯誤的機率)