學習Linux驅動開發(fā),先知道這些!
Linux驅動開發(fā)前奏
一、驅動開發(fā)概述
1.驅動分類,常規(guī)分類
字符設備:一種以字節(jié)為最小訪問單位的設備,通常支持open,close,read,write系統(tǒng)調用。
塊設備:大部分Unix系統(tǒng)中,以塊(通常是512字節(jié))為最小傳輸單位的設備,塊設備不能按字節(jié)處理數據。
網絡設備:可以是一個硬件設備,如網卡;也可以是一個純粹的軟件設備,比如回環(huán)接口(lo)。一個網絡接口負責發(fā)送和接受數據報文。
2.總線分類法
USB設備
PCI設備
平臺總線設備
二、驅動學習方法
1.驅動模型
分析范例程序、制作思維導圖、自己編寫代碼、驅動程序框架
2.硬件操作
復習裸機驅動
將裸機中的硬件操作移植到Linux驅動中
三、硬件訪問技術
1.1 硬件訪問實質
驅動程序控制設備,主要是通過訪問設備內的寄存器來達到控制目的,因此我們討論如何訪問硬件,就成了如何訪問這些寄存器了。
2. 地址映射
在Linux系統(tǒng)中,無論是內核程序還是應用程序,都只能使用虛擬地址,而芯片手冊中給出的硬件寄存器地址或者RAM地址則是物理地址,無法直接使用,因此,我們讀寫寄存器的第1步就是將將它的物理地址映射為虛擬地址。
2.1 動態(tài)映射
所謂動態(tài)映射,是指在驅動程序中采用ioremap函數將物理地址映射為虛擬地址。
原型:void * ioremap(physaddr, size)
參數:
Physaddr:待映射的物理地址
Size: 映射的區(qū)域長度
返回值:映射后的虛擬地址
2.2 靜態(tài)映射
所謂靜態(tài)映射,是指Linux系統(tǒng)根據用戶事先指定的映射關系,在內核啟動時,自動地將物理地址映射為虛擬地址。
1. 如何事先指定映射關系?????填充結構,告訴內核map_desc數組中
2. 內核啟動時,在什么地方完成自動映射? lotable_init();
2.3 映射關系
在靜態(tài)映射中,用戶是通過map_desc結構來指明物理地址與虛擬地址的映射關系。
struct map_desc {
????unsigned long virtual; /* 映射后的虛擬地址 */
????unsigned long pfn; /* 物理地址所在的頁幀號 */
????unsigned long length; /* 映射長度 */
????unsigned int type; /* 映射的設備類型 */
};
pfn: 利用__phys_to_pfn(物理地址)可以計算出物理地址所在的物理頁幀號。
3.寄存器讀寫
在完成地址映射后,就可以讀寫寄存器了,Linux內核提供了一系列函數,來讀寫寄存器。
unsigned ioread8(void *addr)
unsigned ioread16(void *addr)
unsigned ioread32(void *addr)
unsigned readb(address)
unsigned readw(address)
unsigned readl(address)
void iowrite8(u8 value, void *addr)
void iowrite16(u16 value, void *addr)
void iowrite32(u32 value, void *addr)
void writeb(unsigned value, address)
void writew(unsigned value, address)
void writel(unsigned value, address)
? ? ? ? ?