由于Linux驅動編程的本質屬于Linux內核編程,因此我們非常有必要熟悉Linux內核以及Linux內核的特點。 這篇文章將會幫助讀者打下Linux驅動編程的基礎知識。
本篇文章分為如下三個小節進行講解:
1、Linux內核的組成(進程調度、內存管理、虛擬文件系統、網絡接口和進程間通信);
2、Linux的用戶空間和內核空間;
3、Linux內核的引導過程。
1、Linux內核的組成
1.1、Linux內核源代碼的目錄結構
讀者朋友千萬不要覺得了解目錄結構對我們進行Linux開發沒什么幫助,實際上目錄體現了Linux的整體架構和思想,對于我們理解Linux是大有裨益的。Linux內核源代碼包含如下目錄:
arch:包含和硬件體系結構相關的代碼,每種平臺占一個相應的目錄,如:ARM、PowerPC、MIPS等,在arch目錄下,存放了各個不同的平臺芯片對Linux內核進程調度、內存管理和中斷等的支持;
block:塊設備驅動程序調度(塊設備不是我們學習的重點,前期學習中可忽略);
crypto:常用加密算法、一些壓縮算法和CRC校驗算法;
documentation:內核各部分的注釋;
drivers:設備驅動程序,每個不同的驅動占用一個子目錄,如char、net、i2c、spi等(重點來了,劃重點了:高工資,設備驅動程序就是我們學習的重點,而開發過單片機程序的讀者對驅動程序應該有更深刻的理解);
fs:所支持的各種文件系統,如EXT、FAT、NTFS等;
include:頭文件,與系統相關的頭文件放在include/linux的目錄下;
init:內核初始化代碼;
ipc:進程間通信的代碼;
kernel:內核最核心的部分,包括進程調度和定時器等;
lib:庫文件代碼;
mm:內存管理代碼:
net:網絡相關代碼,實現常見的網絡協議;
scripts:用于配置內核的文件;
security:主要是一個SELinux模塊;
sound:音頻設備的驅動核心代碼;
usr:實現用于打包和壓縮等。
Linux的目錄結構
1.2、進程調度
進程調度控制系統中的多個進程對CPU的訪問,使得多個進程能夠在CPU中“宏觀并行、微觀串行”地執行。進程調度處于系統的中心位置,內核其他的功能都依賴于它,因為每個子系統都需要掛起或者恢復進程。Linux進程會在幾個狀態之間進行切換,在設備驅動編程中,當請求的資源不能得到滿足時,驅動一般或調度其他進程執行并使本進程進入睡眠狀態,直到它請求的資源被釋放,才會被系統喚醒從而進入就緒狀態等待調度。絕大多數的進程是由我們的應用程序創建的,當它們存在硬件訪問的需求時,會通過系統調用進入內核空間(文章的后面會講到用戶空間和內核空間的區別)。
1.3、內存管理
內存管理的主要作用是控制多個進程安全的共享內存區域。當CPU提供內存管理單元MMU時,Linux內存管理對于每個進程完成從虛擬內存到物理內存的轉換。現在常用的處理器都是32位的,那么每個進程也就享有4GB(2的32次方)的內存空間,0~3GB屬于用戶空間,3~4GB屬于內核空間。當然,這個界限是可以調整的,但是我們一般使用這個默認配置即可。
1.4、虛擬文件系統
Linux虛擬文件系統隱藏了各種硬件的具體細節,為所有設備提供了統一的接口。而且,虛擬文件系統獨立于各個具體的文件系統,是對各種文件系統的一個抽象。它為上層的應用程序提供了統一的vfs_read()、vfs_write()等接口,然后它在調用具體的底層文件系統或者設備驅動中實現的file_operations結構體的成員函數(這個結構體將是我們后面學習Linux設備驅動的關鍵數據結構)。
1.5、網絡接口
網絡接口提供了對各種網絡標準的存取和網絡硬件的支持。在Linux中網絡接口可分為網絡協議和網絡驅動程序,網絡協議負責實現每一種可能的網絡傳輸協議,網絡設備驅動程序負責與硬件設備通信。Linux內核支持的協議棧很多,例如:Internet、NFC、Bluetooth等,在上層的應用程序中統一使用接口。看到這里,我想你也大概明白了吧,都是套路,我們需要學會這些調用API的套路。
1.6、進程間通信
Linux支持進程間的多種通信機制,包含信號量、共享內存、消息隊列、管道等,這些機制可以協調多個進程、多個資源的互斥訪問,進程間的同步和消息傳遞。這一部分也是我們后續學習的重點。
2、Linux內核的用戶空間和內核空間
在Linux中分為用戶空間和內核空間,我們開發時寫的程序就是運行在用戶空間,那我在這一節為什么又要說驅動的編程實質上就是內核的編程呢?這是因為我們完成驅動程序的開發之后,它是被編譯進內核的,那它也就屬于內核空間。在這種情況下,上層的程序是不能直接訪問底層功能的,這就意味著應用程序是被禁止直接訪問硬件和內存的,在應用程序中操作硬件的時候,其實發生了這樣一個轉換的過程:應用程序(用戶空間)--->系統調用(文件系統)--->內核空間(驅動程序)。這樣做有很多優點,最重要的一點是保證了系統的安全運行。
內核空間和用戶空間這兩個名詞還用來區別程序執行的兩種不同狀態,也就是用戶態和內核態,他們使用的是不同的地址空間。看到這里的讀者還記不記得他們分別使用的地址空間呢?上文已經說過了哦。
用戶和內核使用的地址空間
3、Linux內核的引導過程
SoC上電時,CPU0會先引導bootloader,而其他的CPU則判斷自己是不是CPU0,進入等待狀態等待CPU0來喚醒它。CPU0引導bootloader,bootloader引導Linux內核,在內核啟動階段,CPU0會發中斷喚醒CPU1,之后CPU0和CPU1都投入運行。CPU0導致了用戶空間的init初始化程序被調用,init程序再派生出其他進程,然后這些進程再派生出其他的進程 (看到這里你有沒有想起單片機開發時的啟動文件stm32f10x_startup.s,正因為有它幫我們把代碼運行的環境都準備好了,所以我們才直接從main函數進入)
Linux系統的啟動流程(大概看一下)
關于內核啟動,與我們關系比較大的部分是每個平臺的設備回調函數和屬性信息,這些回調函數會在內核啟動過程中被調用,后續的文章會進一步介紹。
相信讀者已經對Linux的內核有了一個初步的了解,當然這只是初步的而已,更多更難的還在后面等著你呢!我們一步一步來,循序漸進的學習才能達到最好的效果。下一篇文章將介紹在Linux中 C語言編程的特點。
-
cpu
+關注
關注
68文章
11049瀏覽量
216156 -
接口
+關注
關注
33文章
8961瀏覽量
153294 -
Linux
+關注
關注
87文章
11469瀏覽量
212921
發布評論請先 登錄
功率器件熱設計基礎知識
玩轉FPGA必備的基礎知識
全新的半導體基礎知識

評論