為自己編寫的模組配置並構造好核心樹
1.應用程式和核心模組的區別
應用程式:
1).應用程式從頭到尾執行單個任務
2).應用程式在退出時,可以不管資源的釋放或者其他的清除工作
3).應用程式可以呼叫它並未定義的函式,這是因為在鏈結過程能夠解析外部引用從而使用適當的函式庫.
4).應用程式開發過程中的段錯誤是無害的,並且總是可以使用偵錯程式跟蹤到源**中的問題所在
5).應用程式執行在使用者空間中
核心模組:
1).模組只是預先註冊自己以便服務於將來的某個請求,然後它的初始化函式就立即結束.換句話說,模組初始化函式的任務就是為以後呼叫模組函式預先做好準備.這就像模組再說,「我在這兒,並且我能做這些工作,儘管呼叫我吧」
2).模組的退出函式:將在模組被解除安裝之前呼叫.它告訴核心:"我要離開了,不要再讓我做任何事情了"
3).模組的退出函式必須仔細撤銷初始化函式所做的一切,否則,在系統重啟之前某些東西會殘留在系統中.
4).模組化驅動程式設計有助於模組的開發周期.(當測試新驅動的一系列版本的時候不需要總是來開關機重新啟動系統了)
5).模組僅僅被連線到核心,因此它只能呼叫由核心匯出的函式,不存在任何可連線的函式庫.
6).核心錯誤即使不影響整個系統,也至少會殺死當前程序.
7).模組執行在核心空間中
2.模組的makefile的編寫(編譯模組)
1). 對於單個原始檔來說
obj-m := hello.o#------>意思是:有乙個模組要從目標檔案hello.o中構造,這個模組的名稱是hello.ko
2). 對於多個原始檔來說
obj-m := module.o
module-objs := file1.o file2.o
# 指定核心原始碼所在路徑,將核心編譯進模組
make -c /lib/modules/2.6.38-8-generic/build m='pwd' modules
-c改變目錄到指定核心原始碼路徑 返回到當前模組源**目錄 生成指向obj-m變數所設定的模組
3.insmod,modeprobe將模組插入正在執行的核心中
1). insmod
a. 將模組的**和資料裝入核心,然後使用核心的符號表解析模組中任何未解析的符號
b. insmod可以接受一些命令列選項,並且可以在模組鏈結到核心之前給模組的整型和字串變數賦值.
c. # insmod hello.ko
2). modprobe
a. 和insmod一樣將模組載入到核心中
b. 和insmod的區別在於modprobe可以同時插入多個模組,也就是說如果有乙個模組a要依賴於另一模組b的話,那麼在插入a的時候b將自動的插入到核心
4.rmmod從核心中刪除插入的模組.
a. 如果模組正在使用狀態是移除不掉的,最好重啟系統.
b. # rmmod hello ------------>注意刪除的時候不用加字尾.ko
5.lsmod列出當前裝載在核心中的所有模組
a. lsmod其實是通過讀取/proc/modules虛擬檔案來獲得這些資訊的
b. 執行 cat /proc/modules一樣可以獲取這些資訊
6.核心符號表
a. 公共的核心符號表中包含了所有的全域性核心項的位址,所謂核心專案,其實也就是函式和變數
b. 當模組被裝入核心後,它所匯出的任何符號都會變成核心符號表的一部分.
c. 在其他模組上層疊新的模組,即新的模組會呼叫該模組匯出的函式,變數等
d.乙個模組向其他模組匯出符號的方法
export_symbol(name);
export_symbol_gpl(name);#--------->匯出的模組只能被gpl許可證下的模組使用.
1). 符號必須在模組檔案的全域性部分匯出,不能在函式中匯出
2). 匯出的變數必須是全域性的
7.專門用於模組的標頭檔案,所有的模組**必須包含
# include --------------------->包含大量有可裝載模組需要的大量符號和函式的定義
# include ---------------------->指定初始化,和清除函式
8.有關對模組描述的巨集
module_license("gpl");-------------->指定**所使用的許可證,可以不指定,但建議最好指定
module_author(「bruce」);--------------->指定模組的作者
module_description(「」):--------------->用來說明模組用途的簡短說明
module_version(「」);---------------->模組的版本設定
module_alias("");---------------->模組的別名
module_device_table("");---------------->用來告訴使用者空間模組所支援的裝置
說明:這些巨集可以放在模組源**函式外的任何地方.
9.模組初始化函式
static int __init func_init(void)------------------>函式名可以自定義
module_init(func_init);------------------>註冊初始化函式
幾點說明:
1).初始化函式應該被宣告為static,因為這種函式在特定檔案之外沒有其他意義.如果乙個模組函式要對核心其他部分可見,必須被顯示匯出.也就是說static可以不加
2). __init,(是可選的),它對核心來說是一種暗示,用來表明該函式僅僅在初始化期間使用,在模組被裝載之後,模組裝載器就會將初始化函式扔掉,這樣可將該函式占用的記憶體釋放出來.
3). module_init():這個巨集函式是必須要使用的,這個巨集會在模組的目標**中增減乙個特殊段,用於說明核心初始化函式所在的位置.說白了也就是註冊初始化函式,如果不註冊初始化函式,那麼初始化函式將永遠不會被呼叫.
10.模組清除函式
static void __exit func_exit(void)------------------->函式名自定義
module_exit(func_exit);------------------->註冊模組退出函式
說明:1). __exit標示的函式只有在模組被解除安裝或者系統停止時呼叫
2). 如果模組沒有定義清理函式,核心不會允許模組被解除安裝.
Linux裝置驅動程式(第三版) 忙等待
include include include include include include include include include include jiffies include include u64 include file operations,file include inclu...
linux裝置驅動程式(第三版)閱讀筆記(三)
第三章 字元裝置驅動程式 1 裝置編號的內部表示 在核心中,dev t 型別 在 中定義 用來持有裝置編號 主次 部分都包括.對於 2.6.0 核心,dev t 是 32 位的量,前12 位用作主編號,後 20 位 用作次編號.當然,對於裝置編號的內部組織從不做任何假設 相反,應當利用在中的一套巨集...
編譯apue 第三版
想要直接使用作者提供的源 就需要編譯下,這個檔名是src.3e.tar.gz 很簡單的幾步就搞定了.解壓src.3e.tar.gz 進入apue.3e make 進入apue.3e lib目錄,複製libapue.a到 usr local lib目錄 進入 apue.3e include目錄,複製 ...