轉載於:
http://blog.csdn.net/jshazk1989/article/details/6908472
驅動程序的作用:
簡單來說 驅動程序就是使計算機與設備通信的特殊的代碼,在作單片機時候(無OS)我們自己定義接口及自定義的結構來操作相關硬件,而在有OS的模式下我們操作的硬件是去實現對應的接口(這些接口是已定義好的,我們需要實現這些接口)而無需自己定義接口,這樣既能正確的控制設備。又能很好的維護(如果需要升級驅動,上邊的應用程序不需要改變)
編寫驅動考慮的因素
- 提供給用戶更多的選項
- 保持用戶操作的簡單性
- 編寫驅動的時間
驅動分類:
- 字符設備:能夠像字節流(類似文件)一樣被訪問的設備(至少實現open, close, read ,write等功能)
- 快設備: 用戶空間接口與字符設備相同, 內部實與字符設備完全不同(可以被隨即訪問,一般在類UNIX系統中快設備的讀取每次只能讀一整塊在linux可以操作任意字節)
- 網絡設備:網絡通路通過網絡設備形成,能夠與主機交換數據的設備
內核功能劃分:
- 進程管理(PM):進程的創建與撤銷,在單個或者多個CPU上實現多進程的抽象
- 內存管理(MM):管理內存分配及回收的策略
- 文件系統(FS/VFS): Linux 非常依賴於文件系統,內核在沒有結構的硬件系統上構造結文件系統,而文件抽象在整個系統中會廣泛使用,Linux支持多種文件系統類型
- 設備控制:驅動程序,操控硬件以及相應總線設備
- 網絡(NET): 在網絡接口於應用程序之間傳輸數據。
好了 理論行得東西介紹的差不多了,下邊說點有用的,內核的驅動可以做成模塊在需要的時候裝載,在不需要的時候卸載
我們在編寫用戶程序的時候總喜歡從編寫hello world 寫起 , 在內核驅動模塊也是一樣,下邊是一個hello_world的一個模塊
以及對應的Makefile
有幾點與用戶空間程序不同的地方
- 模塊程序沒有main函數(那麼程序入口在哪裏?)
- 打印函數使用的printk 而不是用戶空間的printf 而且使用方式不一樣
- 模塊的編譯不是通常的方式
- 頭文件不是常見的那些頭文件
- 以及編譯之後不會產生可執行文件,而是 .ko 文件
...
模塊沒有main函數,在裝載模塊 insmod 時會調用module_init註冊的函數 此處爲hello_init
在模塊卸載remod時 會調用module_exit註冊的函數 此處爲hello_exit
在module_init 註冊的函數主要是進行初始化,分配內存, 註冊設備等
而module_exit中註冊的函數與之相反, 設備註銷, 釋放內存等
具體的編譯模塊的Makefile我在另一篇文章中有說到 此處不再贅述
內核的打印函數使用printk去打印信息, printk不支持浮點類型, 在printk中可以加入信息級別有7中
對應與不同的錯誤等級 選擇不懂的option, 並做不同的處理, 小於一定等級的信息會直接打印到終端(非X-window下的終端),可以使用dmesg來查看全部的打印信息
編譯內核的頭文件是在/lib/modules/$(shell uname -r)/build/include下得,而不是用戶模式下得/usr/include
編譯後不會生產可執行文件,會生成一個.ko的文件
使用insmod xxx.ko去裝載模塊
使用lsmod去查看已裝載的模塊
使用rmmod xxx 去卸載相應模塊(卸載是不帶.ko)