標籤:
通過第十章的學習,我學到了如下知識點:
1、儘管linux驅動直接與硬體打交道,但並不是linux驅動直接向硬體中的記憶體寫資料,而是原生I/O記憶體進行互動。
linux驅動 I/O記憶體 硬體
2、linux核心的記憶體管理模組負責同步I/O記憶體和硬體中的資料。每一個串連linux的硬體在linux記憶體中都有映射首地址,在使用ioread、iowrite等函數讀寫I/O記憶體時,指定這些首地址。
3、硬體在被檢查到只說明在核心空間中建立了I/O記憶體,要想在使用者空間程式訪問硬體,還必須安裝可與I/O記憶體相互互動的驅動程式。
4、LED驅動提供了兩種互動方式:命令和讀寫裝置檔案。
5、linux裝置檔案的裝置號分為主裝置號和次裝置號,其中,前12位表示主裝置號,後20位表示次裝置號;裝置號有兩種指定方法:直接在代碼中指定和動態分配;
6、儘管在代碼中指定裝置號比較直觀,但如果主裝置號和次裝置號已經存在,建立裝置檔案就會失敗;
7、多個linux裝置檔案可以擁有同一個主裝置號,但兩個裝置的主裝置號和次裝置號不能設定的都一樣,使用alloc_chrder_region函數自動分配裝置時,baseminor和count參數不要設定太大,否則裝置號就會溢出,並且主裝置號會進位,從而變成下一個主裝置號。int register_chrdev_regionl (dev_t from , unsigned count , const char *name)其中from表示裝置號,count表示次裝置號範圍,name參數表示裝置檔案名稱。
int dev_dev_number=MKDEV(major,minor)
int major =MAJOR(dev_number);
int minor=MAJOR(dev_number);
使用cdev_add函數將字元裝置添加到核心中的字元裝置檔案中。
int cdev_add(struct cdev *p ,dev_t dev, unsigned count){
return kobj_map(cdev _map,dev,count,NULL,exact_match ,exact
_lock,p);
調用cdev_add函數要指定裝置檔案指標P,裝置號(dev)和裝置檔案數量count,kobj_map負責將裝置檔案的相關資訊添加到儲存已建好的裝置檔案的probes數組中。
8、使用struct class包含了一些與裝置檔案有關的變數以及一些回呼函數的指標變數;
9、卸載linux驅動的裝置檔案需要依次調用device_destroy,class _destroy和unregister_chrdev_region;
10、LED驅動可以使用兩種方式控制LED:通過字串控制LED;通過I/O命令控制LED;
11、指定一個模板參數需要使用module_param(name,type,perm)宏,
name表示參數名,type表參數類型,perm表示讀/寫入權限。指定模板參數時參數名,參數值,括弧間不能有空格;
12、移植linux驅動時,修改linux驅動的原始碼應盡量不修改linux的驅動介面。
13、修改模組參數時注意:
a、通過module_param_array宏的第三個參數指定數組長度時要使用指標類型的資料;
b、如果linux驅動包含有多個模組參數,需要將這些參數用單引號或雙引號括起來;
c、指定參數類型的參數值時,逗號前後不能有空格。
10.1列印核心調試資訊:printk
10.2防止printk函數降低Linux驅動效能
最好的方法是利用C語言中的編譯指令
10.3通過虛擬檔案系統進行資料互動
10.4調試工具
1.用gdb調試使用者空間程式
gdb可以跟蹤調試使用者空間程式
2.用gdbservice遠端偵錯使用者空間程式
3.用kgdb遠端偵錯核心程式
Kgdb包含了兩個部分:kgdb的核心和一套串連介面
Kgdb支援多種處理器架構
Kgdb想調試Linux驅動,需要配置Linux核心,使用make menuconfig命令進入linux核心的配置菜單
第十章心得體會