回覆列表
-
1 # 路佚Joshua
-
2 # 江蘇優就業
Linux裝置驅動需要使用核心API來實現,被包含在Linux核心原始碼樹中。驅
動可以編譯到核心,隨著核心一起在系統啟動的時候被載入,可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動程式碼的除錯。
但並不是只有裝置驅動才能編譯成模組,有些核心功能的實現也可以,以便在需要的時候再載入,比如核心中檔案系統的實現、加密及校驗的實現、網路協議棧的實現等等。
Linux裝置驅動屬於核心的一部分,Linux核心的一個模組可以以兩種方式被編譯和載入:
(1)直接編譯進Linux核心,隨同Linux啟動時載入。
驅動程式向核心添加了一些函式,是核心的一部分。例如Open(), Release(), Read(), Write()。這些函式由核心在適當的時候來呼叫,可以用來完成硬體訪問等操作。驅動程式佔kernel原始碼超過50%。
核心中printk()函式的設計目的並不是為了和使用者交流,它實際上是核心的一種日誌機制,用來記錄下日誌資訊或者給出警告提示。如果syslogd 和klogd 守護程序在執行的話,則不管是否向控制檯輸出,訊息都會被追加進/var/log/messages 檔案。klogd只處理核心訊息,syslogd 處理其他系統訊息,比如應用程式。
裝置驅動的併發控制
自旋鎖不會引起呼叫者睡眠,如果自旋鎖已經被別的執行單元保持,呼叫者就一直迴圈檢視是否該自旋鎖的保持者已經釋放了鎖,“自旋”就是“在原地打轉”。自旋鎖適合於保持時間非常短的情況,它可以在任何上下文使用。
訊號量則引起呼叫者睡眠,它把程序從執行佇列上拖出去,除非獲得鎖。訊號量適合於保持時間較長的情況,會只能在程序上下文使用。
如果被保護的共享資源需要在中斷上下文訪問(包括底半部即中斷處理控制代碼和頂半部即軟中斷),就必須使用自旋鎖。
裝置驅動的記憶體與IO訪問
核心虛擬記憶體對映到連續的物理記憶體。
CPU 通常並沒有為這些已知的外設I/O記憶體資源的物理地址預定義虛擬地址範圍,驅動程式並不能直接透過物理地址訪問I/O 記憶體資源,而必須將它們對映到核心虛地址空間內(透過頁表),然後才能根據對映所得到的核心虛地址範圍,透過訪內指令訪問這些I/O記憶體資源。Linux 在io.h 標頭檔案中聲明瞭函式ioremap(),用來將I/O 記憶體資源的物理地址對映到核心虛地址空間(3GB-4GB)。
驅動中使用的地址是虛擬地址。外設的IO地址需要對映到虛擬地址。