linux驅動開發詳解
① 求教怎麼學習linux內核驅動
1.首先要了解為什麼要學習內核?下圖已表明,如果要從事驅動開發或系統研究,就要學習內核。
2.內核的知識就像下面的繩結一樣,一環扣一環,我們要解開它們,就必須要先找到線頭也就是內核中的函數介面。初學階段,我們一般不深入的研究內核代碼,會使用內核的介面函數就不錯了。
3.下面提供了如何學習這些內核函數的方法,就像解繩子一樣
4.學習內核的四步法則,思維導圖的設計尤為重要,這也是能否學習好內核的關鍵
5.語言基礎也需要扎實,所以需要把C語言鞏固鞏固
② 什麼是linux 平台驅動開發
在學習之前一直對驅動開發非常的陌生,感覺有點神秘。不知道驅動開發和普通的程序開發究竟有什麼不同;它的基本框架又是什麼樣的;他的開發環境有什麼特殊的地方;以及怎麼寫編寫一個簡單的字元設備驅動前編譯載入,下面我就對這些問題一個一個的介紹。
一、驅動的基本框架
1. 那麼究竟什麼是驅動程序,它有什麼用呢:
l 驅動是硬體設備與應用程序之間的一個中間軟體層
l 它使得某個特定硬體能夠響應一個定義良好的內部編程介面,同時完全隱蔽了設備的工作細節
l 用戶通過一組與具體設備無關的標准化的調用來完成相應的操作
l 驅動程序的任務就是把這些標准化的系統調用映射到具體設備對於實際硬體的特定操作上
l 驅動程序是內核的一部分,可以使用中斷、DMA等操作
l 驅動程序在用戶態和內核態之間傳遞數據
2. Linux驅動的基本框架
3. Linux下設備驅動程序的一般可以分為以下三類
1) 字元設備
a) 所有能夠象位元組流一樣訪問的設備都通過字元設備來實現
b) 它們被映射為文件系統中的節點,通常在/dev/目錄下面
c) 一般要包含open read write close等系統調用的實現
2) 塊設備
d) 通常是指諸如磁碟、內存、Flash等可以容納文件系統的存儲設備。
e) 塊設備也是通過文件系統來訪問,與字元設備的區別是:內核管理數據的方式不同
f) 它允許象字元設備一樣以位元組流的方式來訪問,也可一次傳遞任意多的位元組。
3) 網路介面設備
g) 通常它指的是硬體設備,但有時也可能是一個軟體設備(如回環介面loopback),它們由內核中網路子系統驅動,負責發送和接收數據包。
h) 它們的數據傳送往往不是面向流的,因此很難將它們映射到一個文件系統的節點上。
二、怎麼搭建一個驅動的開發環境
因為驅動是要編譯進內核,在啟動內核時就會驅動此硬體設備;或者編譯生成一個.o文件, 當應用程序需要時再動態載入進內核空間運行。因此編譯任何一個驅動程序都要鏈接到內核的源碼樹。所以搭建環境的第一步當然是建內核源碼樹
1. 怎麼建內核源碼樹
a) 首先看你的系統有沒有源碼樹,在你的/lib/ moles目錄下會有內核信息,比如我當前的系統里有兩個版本:
#ls /lib/ moles
2.6.15-rc7 2.6.21-1.3194.fc7
查看其源碼位置:
## ll /lib/moles/2.6.15-rc7/build
lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/moles/2.6.15-rc7/build -> /root/xkli/linux-2.6.15-rc7
發現build是一個鏈接文件,其所對應的目錄就是源碼樹的目錄。但現在這里目標目錄已經是無效的了。所以得自己重新下載
b)下載並編譯源碼樹
有很多網站上可以下載,但官方網址是:
http://www.kernel.org/pub/linux/kernel/v2.6/
下載完後當然就是解壓編譯了
# tar –xzvf linux-2.6.16.54.tar.gz
#cd linux-2.6.16.54
## make menuconfig (配置內核各選項,如果沒有配置就無法下一步編譯,這里可以不要改任何東西)
#make
…
如果編譯沒有出錯。那麼恭喜你。你的開發環境已經搭建好了
三、了解驅動的基本知識
1. 設備號
1) 什麼是設備號呢?我們進系統根據現有的設備來講解就清楚了:
#ls -l /dev/
crwxrwxrwx 1 root root 1, 3 2009-05-11 16:36 null
crw------- 1 root root 4, 0 2009-05-11 16:35 systty
crw-rw-rw- 1 root tty 5, 0 2009-05-11 16:36 tty
crw-rw---- 1 root tty 4, 0 2009-05-11 16:35 tty0
在日期前面的兩個數(如第一列就是1,3)就是表示的設備號,第一個是主設備號,第二個是從設備號
2) 設備號有什麼用呢?
l 傳統上, 主編號標識設備相連的驅動. 例如, /dev/null 和 /dev/zero 都由驅動 1 來管理, 而虛擬控制台和串口終端都由驅動 4 管理
l 次編號被內核用來決定引用哪個設備. 依據你的驅動是如何編寫的自己區別
3) 設備號結構類型以及申請方式
l 在內核中, dev_t 類型(在 中定義)用來持有設備編號, 對於 2.6.0 內核, dev_t 是 32 位的量, 12 位用作主編號, 20 位用作次編號.
l 能獲得一個 dev_t 的主或者次編號方式:
MAJOR(dev_t dev); //主要
MINOR(dev_t dev);//次要
l 但是如果你有主次編號, 需要將其轉換為一個 dev_t, 使用: MKDEV(int major, int minor);
4) 怎麼在程序中分配和釋放設備號
在建立一個字元驅動時需要做的第一件事是獲取一個或多個設備編號來使用. 可以達到此功能的函數有兩個:
l 一個是你自己事先知道設備號的
register_chrdev_region, 在 中聲明:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
first 是你要分配的起始設備編號. first 的次編號部分常常是 0,count 是你請求的連續設備編號的總數. name 是應當連接到這個編號范圍的設備的名子; 它會出現在 /proc/devices 和 sysfs 中.
l 第二個是動態動態分配設備編號
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
使用這個函數, dev 是一個只輸出的參數, 它在函數成功完成時持有你的分配范圍的第一個數. fisetminor 應當是請求的第一個要用的次編號; 它常常是 0. count 和 name 參數如同給 request_chrdev_region 的一樣.
5) 設備編號的釋放使用
不管你是採用哪些方式分配的設備號。使用之後肯定是要釋放的,其方式如下:
void unregister_chrdev_region(dev_t first, unsigned int count);
6)
2. 驅動程序的二個最重要數據結構
1) file_operation
倒如字元設備scull的一般定義如下:
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
file_operation也稱為設備驅動程序介面
定義在 , 是一個函數指針的集合. 每個打開文件(內部用一個 file 結構來代表)與它自身的函數集合相關連( 通過包含一個稱為 f_op 的成員, 它指向一個 file_operations 結構). 這些操作大部分負責實現系統調用, 因此, 命名為 open, read, 等等
2) File
定義位於include/fs.h
struct file結構與驅動相關的成員
l mode_t f_mode 標識文件的讀寫許可權
l loff_t f_pos 當前讀寫位置
l unsigned int_f_flag 文件標志,主要進行阻塞/非阻塞型操作時檢查
l struct file_operation * f_op 文件操作的結構指針
l void * private_data 驅動程序一般將它指向已經分配的數據
l struct dentry* f_dentry 文件對應的目錄項結構
3. 字元設備注冊
1) 內核在內部使用類型 struct cdev 的結構來代表字元設備. 在內核調用你的設備操作前, 必須編寫分配並注冊一個或幾個這些結構. 有 2 種方法來分配和初始化一個這些結構.
l 如果你想在運行時獲得一個獨立的 cdev 結構,可以這樣使用:
struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;
l 如果想將 cdev 結構嵌入一個你自己的設備特定的結構; 你應當初始化你已經分配的結構, 使用:
void cdev_init(struct cdev *cdev, struct file_operations *fops);
2) 一旦 cdev 結構建立, 最後的步驟是把它告訴內核, 調用:
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
說明:dev 是 cdev 結構, num 是這個設備響應的第一個設備號, count 是應當關聯到設備的設備號的數目. 常常 count 是 1, 但是有多個設備號對應於一個特定的設備的情形.
3) 為從系統去除一個字元設備, 調用:
void cdev_del(struct cdev *dev);
4. open 和 release
③ 《Linux設備驅動開發詳解基於最新的Linux4.0內核》pdf下載在線閱讀,求百度網盤雲資源
《Linux設備驅動開發詳解》(宋寶華)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:https://pan..com/s/1ddjTHycqTk3yYQDr-raoKw
書名:Linux設備驅動開發詳解
作者:宋寶華
豆瓣評分:6.5
出版社:機械工業出版社
出版年份:2015-8
頁數:618
內容簡介:
對於嵌入式工程師來說,進入更高階段後,學習Linux設備驅動開發無疑就是職業生涯的一次「重生」。這是因為Linux設備驅動開發不僅僅涉及操作系統的轉換,開發方式的轉換,更重要的是思維上的轉變。對於Linux這樣一個復雜系統,如何從復雜的代碼中抓住設備驅動開發的關鍵是任何一個Linux設備驅動開發者入門時需要面對的挑戰。除了知識、工具之外,往往還需要思路上的指導。本書不但幫助Linux設備驅動開發的初學者釐清必要的概念,還從具體的實例、設備驅動開發的指導原則循序漸進地引導讀者漸入學習佳境。為了讓讀者能夠達到Linux設備驅動開發的至臻境界,作者更是從軟體工程的角度抽象出設備驅動開發的一般思想。毫無疑問,本書將成為讀者學習Linux設備驅動開發過程中的一座「燈塔」。
作者簡介:
宋寶華,
Linux佈道者,知名嵌入式系統專家,《Essential Linux Device Drivers》譯者。作為最早從事Linux內核與設備驅動研究的專家之一,他在眾多國內外知名企業開展Linux技術培訓。他也是一位活躍的Linux開發者和深度實踐者,為Linux官方內核貢獻了大量的Linux源碼並承擔代碼審核工作。至今已向Linux官方內核提交逾數萬行代碼和幾百個補丁。他的《Linux設備驅動開發詳解》系列書在嵌入式Linux開發者中有口皆碑,是眾多Linux書籍中為數不多的暢銷書。
④ 驅動開發必須使用開發板廠家提供的Linux源碼嗎
驅動開發環境
要進行linux驅動開發我們首先要有linux內核的源碼樹,並且這個linux內核的源碼樹要和開發板中的內核源碼樹要一直;
比如說我們開發板中用的是linux kernel內核版本為2.6.35.7,在我們ubuntu虛擬機上必須要有同樣版本的源碼樹,
我們再編譯好驅動的的時候,使用modinfo XXX命令會列印出一個版本號,這個版本號是與使用的源碼樹版本有關,如果開發板中源碼樹中版本與
modinfo的版本信息不一致使無法安裝驅動的;
我們開發板必須設置好nfs掛載;這些在根文件系統一章有詳細的介紹;
⑤ 《Linux設備驅動開發詳解4.0》pdf下載在線閱讀全文,求百度網盤雲資源
《Linux設備驅動開發詳解4.0》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1wxaYK87l11FDur15aS6FTQ
簡介:Linux設備驅動開發詳解介紹了Linux設備驅動開發理論、框架與實例,詳細說明了自旋鎖、信號量、完成量、中斷頂/底半部、定時器、內存和I/O映射以及非同步通知、阻塞I/O、非阻塞I/O等Linux設備驅動理論,以及字元設備、塊設備、tty設備、I2c設備、LCD設備、音頻設備、USB設備、網路設備、PCI設備等Linux設備驅動架構中各個復雜數據結構和函數的關系,並講解了Linux驅動開發的大量實例,使讀者能夠獨立開發各類Linux設備驅動。
⑥ 嵌入式Linux設備驅動開發詳解的目錄
第1章嵌入式系統與驅動程序1
本章目標1
1.1嵌入式系統概述1
1.1.1嵌入式系統的概念1
1.1.2嵌入式系統的特點2
1.1.3嵌入式系統的體系結構2
1.2嵌入式處理器介紹4
1.2.1嵌入式處理器分類4
1.2.2ARM概述5
1.2.3ARM系列晶元簡介5
1.3嵌入式操作系統介紹7
1.3.1主流嵌入式操作系統7
1.3.2嵌入式系統的發展狀況8
1.3.3嵌入式Linux介紹8
1.3.4嵌入式系統開發環境的建立9
1.3.5嵌入式軟體開發10
1.4嵌入式Linux驅動程序12
1.4.1嵌入式Linux的內核空間和用戶空間12
1.4.2嵌入式Linux的文件系統12
1.4.3嵌入式Linux的設備管理14
1.4.4嵌入式Linux的驅動程序16
1.5知識索引20
1.6思考與練習21
第2章簡單的字元設備驅動程序23
本章目標23
2.1嵌入式Linux字元設備的驅動程序結構23
2.1.1嵌入式Linux驅動程序常用的頭文件24
2.1.2File_operations結構體24
2.1.3字元設備驅動程序的入口25
2.1.4驅動程序的設備注冊26
2.2設備驅動程序中的具體問題27
2.2.1I/O埠28
2.2.2內存操作29
2.2.3中斷處理29
2.3LED的驅動程序實例及測試30
2.3.1LED I/O埠設置30
2.3.2LED硬體電路設計32
2.3.3LED驅動程序設計33
2.3.4LED測試程序設計36
2.4嵌入式Linux中斷處理驅動程序及測試37
2.4.1中斷處理過程37
2.4.2中斷向量表39
2.4.3中斷的處理模式39
2.4.4中斷的優先順序40
2.4.5中斷的嵌套40
2.4.6中斷源的擴展40
2.4.7中斷控制寄存器的設置41
2.5按鍵中斷的驅動程序實例45
2.5.1按鍵中斷的電路設計45
2.5.2按鍵中斷的驅動程序設計45
2.6知識索引48
2.7思考與練習49
第3章數字顯示驅動程序50
本章目標50
3.1數字顯示器50
3.1.1數碼管簡介50
3.1.2數碼管的分類51
3.1.3數碼管顯示原理51
3.2數碼管顯示電路的硬體設計52
3.2.1解碼器的使用52
3.2.2數碼管的驅動方式53
3.2.3串/並變換的解碼設計55
3.3數碼管驅動程序實例56
3.3.1驅動程序的初始化和卸載模塊56
3.3.2文件操作結構模塊57
3.3.3數碼管的打開模塊57
3.3.4數碼管的讀寫模塊58
3.3.5數碼管的I/O控制模塊58
3.3.6數碼管的退出模塊58
3.3.7驅動程序的模塊載入和卸載59
3.4數碼管顯示電路測試程序設計60
3.4.1數碼管測試設計60
3.4.2數碼管測試程序60
3.4.3數碼管測試效果61
3.5知識索引61
3.6思考與練習62
第4章鍵盤驅動程序63
本章目標63
4.1鍵盤介面概述63
4.1.1鍵盤的分類63
4.1.2鍵盤的防抖65
4.1.3鍵盤的掃描65
4.1.4鍵盤的緩沖演算法67
4.2鍵盤的驅動設計實例67
4.2.1鎖存器和緩沖器擴展鍵盤67
4.2.2鎖存器和緩沖器的介面68
4.2.3鎖存器和緩沖器擴展鍵盤驅動程序設計69
4.2.4鎖存器和緩沖器擴展鍵盤測試程序設計71
4.3智能控制晶元HD7279擴展鍵盤72
4.3.1HD7279的電路設計72
4.3.2HD7279的指令介紹73
4.3.3HD7279的串列介面74
4.3.4HD7279的驅動程序設計75
4.3.5HD7279的測試程序設計84
4.4知識索引85
4.5思考與練習85
第5章A/D驅動程序86
本章目標86
5.1A/D轉換的過程86
5.1.1采樣和保持86
5.1.2量化和編碼88
5.1.3ADC的分類89
5.2A/D轉換器的基本原理89
5.2.1逐次逼近型A/D轉換器89
5.2.2雙積分型A/D轉換器90
5.2.3V/F和F/V型轉換器93
5.2.4其他A/D轉換器95
5.3A/D轉換器介面技術97
5.3.1ADC的主要參數及意義97
5.3.2ADC的電路選擇方法98
5.3.3ADC實際應用中的問題99
5.4S3C2410 A/D轉換驅動設計實例99
5.4.1S3C2410的A/D轉換電路99
5.4.2S3C2410X的A/D轉換控制寄存器100
5.4.3S3C2410X的A/D轉換數據寄存器101
5.4.4S3C2410X中A/D轉換驅動程序的設計102
5.4.5S3C2410X中A/D轉換測試程序的設計105
5.5知識索引106
5.6思考與練習107
第6章D/A驅動程序108
本章目標108
6.1D/A的原理介紹108
6.1.1D/A轉換的概念及基本原理108
6.1.2電子模擬開關109
6.1.3D/A轉換器的基本結構110
6.1.4D/A轉換的靜態參數114
6.1.5D/A轉換的動態參數115
6.2D/A轉換的硬體電路設計116
6.2.1D/A轉換的介面技術116
6.2.2D/A轉換晶元介紹117
6.2.3D/A轉換的電路設計118
6.3D/A轉換器的驅動程序實例118
6.3.1D/A驅動程序中的宏定義118
6.3.2D/A的模塊載入118
6.3.3D/A轉換器的文件操作模塊119
6.3.4D/A轉換器的讀寫控制模塊120
6.3.5D/A轉換器的打開、退出模塊120
6.4測試程序的設計120
6.4.1D/A測試程序中的宏定義121
6.4.2D/A測試程序的主函數121
6.4.3D/A測試程序中的功能函數122
6.4.4D/A測試程序中的功能列印函數123
6.4.5D/A測試程序中的波形生成函數123
6.4.6D/A測試程序的效果124
6.5知識索引125
6.6思考與練習125
第7章LCD驅動程序126
本章目標126
7.1LCD顯示器概述126
7.1.1液晶126
7.1.2LCD顯示屏的背光127
7.1.3LCD顯示器的分類127
7.1.4LCD的顯示原理127
7.1.5LCD的驅動方式130
7.1.6LCD的常用指標131
7.2LCD的顯示介面131
7.2.1灰度STN的時序132
7.2.2彩色STN的時序133
7.2.3TFT的時序134
7.3嵌入式處理器的LCD控制器136
7.3.1LCD控制器136
7.3.2LCD控制器的設置137
7.3.3LCD的字元顯示緩存139
7.4LCD的驅動程序設計140
7.4.1LCD驅動程序相關的宏定義140
7.4.2LCD驅動程序的底層操作函數142
7.4.3LCD驅動程序提供的API145
7.4.4LCD驅動程序的模塊化載入151
7.4.5LCD的測試程序152
7.5基於Framebuffer的LCD驅動程序實例155
7.5.1Framebuffer概述155
7.5.2LCD的電路連接155
7.5.3Framebuffer設備驅動程序的結構156
7.5.4Framebuffer設備驅動程序的設計159
7.5.5Framebuffer設備測試程序的設計164
7.5.6嵌入式Linux常用的GUI166
7.6知識索引166
7.7思考與練習167
第8章觸摸屏驅動程序168
本章目標168
8.1觸摸屏概述168
8.2觸摸屏的分類168
8.2.1電阻技術觸摸屏168
8.2.2表面聲波技術觸摸屏169
8.2.3電容電感技術觸摸屏170
8.2.4紅外線技術觸摸屏170
8.3觸摸屏的特性171
8.3.1透明度和色彩失真171
8.3.2反光性171
8.3.3清晰度171
8.3.4漂移172
8.3.5檢測和定位172
8.4觸摸屏的硬體電路設計172
8.4.1電阻式觸摸屏的電路原理172
8.4.2電阻式觸摸屏原點的定位173
8.4.3電阻式觸摸屏的電路連接174
8.5觸摸屏的驅動程序實例176
8.5.1觸摸屏介面的模式176
8.5.2A/D轉換和觸摸屏寄存器的設置177
8.5.3觸摸屏的坐標179
8.5.4觸摸屏的電路連接180
8.5.5觸摸屏的驅動程序介面181
8.6測試程序的設計182
8.6.1觸摸屏的數據定義183
8.6.2觸摸屏的數據處理183
8.6.3觸摸屏的運行測試185
8.7知識索引186
8.8思考與練習187
第9章CAN匯流排驅動程序188
本章目標188
9.1CAN匯流排介面設計188
9.1.1CAN匯流排概述188
9.1.2CAN的工作特點及主要優點189
9.1.3CAN匯流排的電氣特徵和MAC幀結構189
9.2嵌入式處理器上CAN匯流排介面的擴展190
9.2.1SJA1000簡介190
9.2.2SJA1000擴展191
9.3SJA1000擴展CAN匯流排介面的設計192
9.3.1CAN 控制器SJA1000的操作模式192
9.3.2CAN控制器SJA1000的特徵功能193
9.3.3CAN 控制器SJA1000的Basic CAN模式設置194
9.4SJA1000擴展CAN匯流排介面的通信196
9.4.1通過CAN匯流排建立通信的步驟196
9.4.2SJA1000的初始化196
9.4.3驅動程序的結構設計198
9.4.4驅動程序init、exit、open、close函數的實現200
9.4.5驅動程序read、write函數的實現201
9.4.6驅動程序interrupt、ioctl函數實現202
9.4.7測試程序的編寫202
9.5驅動程序的載入204
9.6知識索引204
9.7思考與練習205
第10章IIC匯流排驅動程序206
本章目標206
10.1IIC匯流排概述206
10.1.1IIC匯流排介紹206
10.1.2IIC匯流排引入的原因206
10.1.3IIC匯流排的特點206
10.1.4IIC匯流排的基本結構207
10.1.5IIC匯流排的術語207
10.1.6IIC匯流排的工作208
10.1.7IIC匯流排的競爭仲裁209
10.1.8IIC匯流排的工作流程210
10.2嵌入式處理器的IIC介面211
10.2.1IIC匯流排控制寄存器212
10.2.2IIC匯流排控制/狀態寄存器213
10.2.3IIC匯流排地址寄存器214
10.2.4IIC匯流排移位數據寄存器214
10.2.5S3C2410中與IIC對應的I/O埠215
10.3基於IIC的鍵盤晶元應用216
10.3.1ZLG7290的功能217
10.3.2ZLG7290的控制方式218
10.3.3ZLG7290的寄存器218
10.3.4ZLG7290的通信介面219
10.3.5ZLG7290的指令介紹219
10.4IIC匯流排驅動程序實例221
10.4.1ZLG7290的電路連接221
10.4.2ZLG7290的通信流程223
10.4.3ZLG7290驅動中變數的定義225
10.4.4ZLG7290驅動中實時時鍾的改變226
10.4.5ZLG7290和IIC寄存器的初始化227
10.4.6ZLG7290驅動程序的模塊化228
10.4.7ZLG7290的文件操作結構228
10.5IIC匯流排的測試程序230
10.6知識索引231
10.7思考與練習231
第11章音頻匯流排驅動程序232
本章目標232
11.1音頻匯流排介面概述232
11.1.1音頻的采樣精度233
11.1.2音頻編碼233
11.2IIS音頻匯流排介面233
11.2.1IIS匯流排的物理連接233
11.2.2IIS的匯流排協議234
11.2.3IIS匯流排的硬體設計235
11.2.4IIS匯流排的寄存器236
11.3AC97音頻匯流排介面239
11.4IIS匯流排的驅動程序設計240
11.4.1音頻設備基礎知識240
11.4.2音頻設備文件241
11.4.3WAV聲音文件243
11.4.4音頻設備和驅動程序的通信243
11.4.5設備的初始化和載入244
11.4.6DMA的操作和宏定義246
11.4.7audio設備文件的操作248
11.4.8mixer設備文件的操作260
11.5音頻驅動程序的測試262
11.6知識索引262
11.7思考與練習263
第12章IDE介面驅動程序264
本章目標264
12.1IDE介面概述264
12.1.1硬碟知識介紹264
12.1.2IDE介面標准267
12.1.3IDE介面的傳輸模式269
12.1.4IDE介面寄存器269
12.2IDE介面驅動程序的移植271
12.2.1嵌入式Linux下IDE驅動程序介面271
12.2.2嵌入式Linux下IDE驅動程序272
12.2.3IDE硬碟的讀/寫操作274
12.3IDE驅動程序測試282
12.3.1磁碟文件系統簡介283
12.3.2IDE分區測試283
12.4知識索引285
12.5思考與練習285
第13章快閃記憶體晶元的驅動程序286
本章目標286
13.1快閃記憶體晶元概述286
13.1.1快閃記憶體晶元的物理特性286
13.1.2嵌入式文件系統概述289
13.1.3MTD體系介紹289
13.1.4Flash專有名詞291
13.2NAND Flash291
13.2.1NAND Flash的結構291
13.2.2NAND Flash的操作292
13.2.3NAND Flash控制器294
13.2.4NAND Flash的時序296
13.2.5NAND Flash的驅動程序實例297
13.3NOR Flash301
13.3.1NOR Flash的結構301
13.3.2NOR Flash的操作302
13.3.3NOR Flash的驅動程序實例303
13.4基於快閃記憶體的文件系統307
13.5知識索引309
13.6思考與練習310
第14章USB 設備驅動程序311
本章目標311
14.1USB介面概述311
14.1.1USB系統311
14.1.2USB的電氣特性312
14.1.3USB匯流排的拓撲結構313
14.1.4USB的通信協議313
14.2嵌入式系統中USB的使用315
14.2.1OHCI概述315
14.2.2Host介面硬體設計316
14.3嵌入式系統中USB設備的驅動程序設計316
14.3.1
⑦ linux驅動開發insmod hello.ko失敗
你好,記得當初也被這個問題困惑了,kernel mole 的insmod 的時候是需要版本驗證的(也可以使用方法繞過版本驗證)。你可以看看他到底是怎麼個版本驗證法,加深你的學習。
現在看看你的問題,你下載的kerne 是2.30.4的,在make的時候kernel_dir 指定也是這個。那編譯出來的mole 肯定也是也是2.30.4的版本了,然後你想把這個mole insmod 到的你pc linux 系統,那就肯定不行了。
1. 你可以用的linux系統內核來編譯你的hello 模塊。
2. 先寫個makefile:
obj-m:= hello.o
3. 然後 make -C /lib/moles/$(shell uname -r )/build M=`pwd` moles
4.編譯好了再insmode. 就能成功了。但是還要看的printk 的等級了,可能你還需要dmesg才能看道你的模塊的操作
5. 然後你可以把上面的過程集成道一個makefile里,直接在當前目錄make 就好了。
提醒下,假如你是用自己的系統作這些實驗,要當心點,有的mole可能會讓你的系統出現oops。
所以建議你安裝個虛擬機玩,或者真正要學的話,直接買個板子最好了。
最後看你下載了linux 2.30.4?是不是應該是2.6.30.4? 然後你的開發板是也是這個kernel?假如你是用板子,你現在可以把剛編好的模塊,push 到板子,在insmod就好了。
⑧ 如何系統的學習Linux驅動開發
在學習之前一直對驅動開發非常的陌生,感覺有點神秘。不知道驅動開發和普通的程序開發究竟有什麼不同;它的基本框架又是什麼樣的;他的開發環境有什麼特殊的地方;以及怎麼寫編寫一個簡單的字元設備驅動前編譯載入,下面我就對這些問題一個一個的介紹。
一、驅動的基本框架
1.那麼究竟什麼是驅動程序,它有什麼用呢:
l驅動是硬體設備與應用程序之間的一個中間軟體層
l它使得某個特定硬體能夠響應一個定義良好的內部編程介面,同時完全隱蔽了設備的工作細節
l用戶通過一組與具體設備無關的標准化的調用來完成相應的操作
l驅動程序的任務就是把這些標准化的系統調用映射到具體設備對於實際硬體的特定操作上
l驅動程序是內核的一部分,可以使用中斷、DMA等操作
l驅動程序在用戶態和內核態之間傳遞數據
2.Linux驅動的基本框架
3.Linux下設備驅動程序的一般可以分為以下三類
1)字元設備
a)所有能夠象位元組流一樣訪問的設備都通過字元設備來實現
b)它們被映射為文件系統中的節點,通常在/dev/目錄下面
c)一般要包含open read write close等系統調用的實現
2)塊設備
d)通常是指諸如磁碟、內存、Flash等可以容納文件系統的存儲設備。
e)塊設備也是通過文件系統來訪問,與字元設備的區別是:內核管理數據的方式不同
f)它允許象字元設備一樣以位元組流的方式來訪問,也可一次傳遞任意多的位元組。
3)網路介面設備
g)通常它指的是硬體設備,但有時也可能是一個軟體設備(如回環介面loopback),它們由內核中網路子系統驅動,負責發送和接收數據包。
h)它們的數據傳送往往不是面向流的,因此很難將它們映射到一個文件系統的節點上。
二、怎麼搭建一個驅動的開發環境
因為驅動是要編譯進內核,在啟動內核時就會驅動此硬體設備;或者編譯生成一個.o文件,當應用程序需要時再動態載入進內核空間運行。因此編譯任何一個驅動程序都要鏈接到內核的源碼樹。所以搭建環境的第一步當然是建內核源碼樹
1.怎麼建內核源碼樹
a)首先看你的系統有沒有源碼樹,在你的/lib/ moles目錄下會有內核信息,比如我當前的系統里有兩個版本:
#ls /lib/ moles
2.6.15-rc72.6.21-1.3194.fc7
查看其源碼位置:
## ll /lib/moles/2.6.15-rc7/build
lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/moles/2.6.15-rc7/build -> /root/xkli/linux-2.6.15-rc7
發現build是一個鏈接文件,其所對應的目錄就是源碼樹的目錄。但現在這里目標目錄已經是無效的了。所以得自己重新下載
b)下載並編譯源碼樹
有很多網站上可以下載,但官方網址是:
http://www.kernel.org/pub/linux/kernel/v2.6/
下載完後當然就是解壓編譯了
# tar –xzvf linux-2.6.16.54.tar.gz
#cd linux-2.6.16.54
## make menuconfig (配置內核各選項,如果沒有配置就無法下一步編譯,這里可以不要改任何東西)
#make
…
如果編譯沒有出錯。那麼恭喜你。你的開發環境已經搭建好了
三、了解驅動的基本知識
1.設備號
1)什麼是設備號呢?我們進系統根據現有的設備來講解就清楚了:
#ls -l /dev/
crwxrwxrwx 1 root root1,3 2009-05-11 16:36 null
crw------- 1 root root4,0 2009-05-11 16:35 systty
crw-rw-rw- 1 root tty5,0 2009-05-11 16:36 tty
crw-rw---- 1 root tty4,0 2009-05-11 16:35 tty0
在日期前面的兩個數(如第一列就是1,3)就是表示的設備號,第一個是主設備號,第二個是從設備號
2)設備號有什麼用呢?
l傳統上,主編號標識設備相連的驅動.例如, /dev/null和/dev/zero都由驅動1來管理,而虛擬控制台和串口終端都由驅動4管理
l次編號被內核用來決定引用哪個設備.依據你的驅動是如何編寫的自己區別
3)設備號結構類型以及申請方式
l在內核中, dev_t類型(在中定義)用來持有設備編號,對於2.6.0內核, dev_t是32位的量, 12位用作主編號, 20位用作次編號.
l能獲得一個dev_t的主或者次編號方式:
MAJOR(dev_t dev); //主要
MINOR(dev_t dev);//次要
l但是如果你有主次編號,需要將其轉換為一個dev_t,使用: MKDEV(int major, int minor);
4)怎麼在程序中分配和釋放設備號
在建立一個字元驅動時需要做的第一件事是獲取一個或多個設備編號來使用.可以達到此功能的函數有兩個:
l一個是你自己事先知道設備號的
register_chrdev_region,在中聲明:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
first是你要分配的起始設備編號. first的次編號部分常常是0,count是你請求的連續設備編號的總數. name是應當連接到這個編號范圍的設備的名子;它會出現在/proc/devices和sysfs中.
l第二個是動態動態分配設備編號
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
使用這個函數, dev是一個只輸出的參數,它在函數成功完成時持有你的分配范圍的第一個數. fisetminor應當是請求的第一個要用的次編號;它常常是0. count和name參數如同給request_chrdev_region的一樣.
5)設備編號的釋放使用
不管你是採用哪些方式分配的設備號。使用之後肯定是要釋放的,其方式如下:
void unregister_chrdev_region(dev_t first, unsigned int count);
6)
2.驅動程序的二個最重要數據結構
1)file_operation
倒如字元設備scull的一般定義如下:
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
file_operation也稱為設備驅動程序介面
定義在,是一個函數指針的集合.每個打開文件(內部用一個file結構來代表)與它自身的函數集合相關連(通過包含一個稱為f_op的成員,它指向一個file_operations結構).這些操作大部分負責實現系統調用,因此,命名為open, read,等等
2)File
定義位於include/fs.h
struct file結構與驅動相關的成員
lmode_t f_mode標識文件的讀寫許可權
lloff_t f_pos當前讀寫位置
lunsigned int_f_flag文件標志,主要進行阻塞/非阻塞型操作時檢查
lstruct file_operation * f_op文件操作的結構指針
lvoid * private_data驅動程序一般將它指向已經分配的數據
lstruct dentry* f_dentry文件對應的目錄項結構
3.字元設備注冊
1)內核在內部使用類型struct cdev的結構來代表字元設備.在內核調用你的設備操作前,必須編寫分配並注冊一個或幾個這些結構.有2種方法來分配和初始化一個這些結構.
l如果你想在運行時獲得一個獨立的cdev結構,可以這樣使用:
struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;
l如果想將cdev結構嵌入一個你自己的設備特定的結構;你應當初始化你已經分配的結構,使用:
void cdev_init(struct cdev *cdev, struct file_operations *fops);
2)一旦cdev結構建立,最後的步驟是把它告訴內核,調用:
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
說明:dev是cdev結構, num是這個設備響應的第一個設備號, count是應當關聯到設備的設備號的數目.常常count是1,但是有多個設備號對應於一個特定的設備的情形.
3)為從系統去除一個字元設備,調用:
void cdev_del(struct cdev *dev);
4.open和release
⑨ linux驅動開發 主要要開發哪些驅動
您好:做嵌入式應用的話一般的編程就可以了。那麼嵌入式驅動開發與內核開發的話就需要學習多個方面的知識。我就把這方面的要求給你交流一下:
(一家之言啊,自己多年從事嵌入式開發的一點感悟)
嵌入式驅動開發需要了解的知識大概有以下幾類:
1 嵌入式操作系統驅動框架。每一個操作系統都有自己的構架,應該了解驅動在整個系統中的具體位置與構建驅動程序的主要事項
2 匯流排知識,比如PCI、USB匯流排。
3 晶元知識。驅動其實就是對設備上一些寄存器的配置、CPU與設備本身的通訊以及對不同命令的處理
4 要做好驅動,必須對所使用的CPU體系結構有一個比較深刻的認識
5 C++基本用不上,主要是C和匯編。
6 做驅動最好要懂內核調試(比如說linux)
⑩ 怎麼學linux內核驅動
怎麼學linux內核驅動?1. 分享Linux內核學習和驅動開發的經驗。
內核學習
Linux 內核功能越來越完善,如果沒有充裕的時間,深入內核並不是很現實。所以建議先讀一本內核的書,
第一遍是讀,會讀的很迷糊;之後反省一下,然後再瀏覽一下;可以想像一個 OS 是如何運行的,這樣可以不
陷入 Linux 內核的細節;最後可以深入自己感興趣或者需要的那一子系統
推薦 《Linux Kernel Development》
即便是子系統,也是很龐大的。一個省力的方式是網上搜一些相關的文章,便於快速了解這個子系統的運作;
然後結合代碼,形成自己的認知,最後做一下總結。如果僅僅是快速了解某一子系統的運作,可以參考一些早期
代碼的註解書籍,再深入的時候看看最新的代碼實現
對內核的認知是一個反復的過程,一開始並不完善,可能需要反復糾正。不要陷入這種糾錯中;而是以後繼續
使用和學習過程中,發現了沒有弄清楚的地方再深入,畢竟 Linux 內核是不斷變化的
還有一個很好的方式是,從系統調用入手,現在這方面的數據不少,而且對系統調用的語義都有講解,這樣可以
間接了解 Linux 系統的一些概念。對系統調用熟悉了,可以根據系統調用的執行過程,來大體了解內核的一個
運作過程;但是跟蹤系統調用的時候要注意抓主線,現在內核系統很復雜,一些 code path 上可能會涉及多個
子系統,可以從名字上猜測它們是干什麼的,不需要深入,否則會發現精力完全被分散掉了
學習 Linux 內核,一個很重要的是抽象的能力,所謂的抽象這里僅僅是指分清介面和介面的實現。因為 Linux
內核子系統很多,有很多子系統相互滲透,這樣 code path 看上去很復雜。閱讀代碼的時候,為了排除干擾,
需要分清哪些是自己需要看的,哪些是其它子系統的介面,對於其它子系統的介面,先當作它們功能完善不會
出問題好了,這樣可以關注重點;打個比方,一個應用程序的代碼可能量很大,比如一個 apache 項目,它
包含很多組件,有時候閱讀代碼的時候會看到不同組件的 API,深入看相關組件實現並不現實,這時候分清主次
對於代碼的閱讀就很有幫助了,總不能看到了 malloc 就要先把它的實現弄清楚吧,系統調用多者呢