linux驅動開發實戰
1. linux驅動開發1之什麼是驅動
准確來說,驅動是針對於硬體設備的,比如:
一個鍵盤,插到電腦上,那麼電腦是如何使用鍵盤的呢,它們兩者之間是如何相互交互的呢。這個過程是需要驅動程序來實現的。
鍵盤插入電腦,引發一個中斷,然後中斷程序會檢查設備,並將一個驅動程序與這個鍵盤設備進行綁定,當你按下一個按鍵,會觸發鍵盤內的電子信號的傳輸(理解為電位1和0吧),並最終轉換為數字信號(即0和1表示的),然後Linux系統中的驅動程序接收到了這個信號,根據這個信號來判斷觸發了哪個按鍵(這個中間,其實有很多工作,不過可以這樣概括的理解),最終反饋到屏幕上。
看到了嗎,驅動,就是一個可以和硬體通信(能夠正確理解硬體發出的信號)的程序。
看到這,我想你應該明白了,你也可以為一個滑鼠寫一個驅動(前提是你了解這個滑鼠的通信協議,即電位轉換情況),然後你可以把滑鼠左鍵點擊的效果,更改成正常情況下,滑鼠右鍵點擊的效果。是不是挺有意思的。
另外,因為現在系統的日益成熟,現在Linux系統工作者很少有機會再寫硬體驅動程序了,因為這些驅動,大多數硬體產商都會給做好了(因為Linux驅動介面封裝的很好)。在移植到其它平台的時候,可能只需要簡單的修改一下Linux的驅動,就可以用了。
(ps:望採納)
2. Linux驅動開發
你學了好久都不知道...我們只能一起期盼高人出現了。
我想是需要先編譯驅動到linux內核的。
3. 嵌入式Linux驅動程序開發學習路線
關於這個方向,我認為大概分3個階段:
1、嵌入式linux上層應用,包括QT的GUI開發
2、嵌入式linux系統開發
3、嵌入式linux驅動開發
嵌入式目前主要面向的幾個操作系統是,LINUX,WINCE、VxWorks等等
Linux是開源免費的,而且其源代碼是開放的,更加適合我們學習嵌入式。
所以你可以嘗試以下路線:
(1) C語言是所有編程語言中的強者,單片機、DSP、類似ARM的種種晶元的編程都可以用C語言搞定),因此必須非常熟練的掌握。
推薦書籍:《The C Programming Language》 這本經典的教材是老外寫的,也有中譯版本。
(2) 操作系統原理,是必需的,如果你是計算機專業畢業那也就無所謂了,如果是非計算機專業的就必須找一本比較淺顯的計算機原理書籍看一看,把啥叫「進程」「線程」「系統調度」等等基本問題搞清楚。
(3)Linux操作系統就是用C語言編寫的,所以你也應該先學習下Linux方面的編程,只有你會應用了,才能近一步去了解其內核的精髓。
推薦書籍:《UNIX環境高級編程》(第2版)
(4) 了解ARM的架構,原理,以及其匯編指令,我們在嵌入式開發中,一般很少去寫匯編,但是最起碼的要求是能夠看懂arm匯編。
(5) 系統移植的時候,就需要你從最下層的bootloader開始,然後內核移植,文件系統移植等。而移植這部分對硬體的依賴是非常大的,其配置步驟也相對復雜,也沒有太多詳細資料。
(6) 驅動開發
linux驅動程序設計既是個極富有挑戰性的領域,又是一個博大精深的內容。
linux驅動程序設計本質是屬於linux內核編程范疇的,因而是對linux內核和內核編程是有要求的。在學習前你要想了解linux內核的組成,因為每一部分要詳細研究的話足夠可以擴展成一本厚書。
以上只不過是大概的框架,在實際的開發中還會涉及很多東西,比如:交叉編譯、makefile、shell腳本等等,所以說學習嵌入式的周期較長,門檻較高,自學的話更是需要較強的學習能力和專業功底。只要能堅持下來一定會取得成功!
…………………………………………
嵌入式非常難,看書的話比較晦澀難懂,不容易入門,我個人比較偏向於看視頻教程,因為有老師帶著比較容易入門。給看看一篇文章是關於一位專科生怎麼自學嵌入式的。
做個自我介紹,我07年考上一所很爛專科民辦的學校,學的是生物專業,具體的學校名稱我就不說出來獻丑了。09年我就輟學了,我在那樣的學校,一年學費要1萬多,但是根本沒有人學習,我實在看不到希望,我就退學了。
退學後我也迷茫,大專都沒有畢業,我真的不知道我能幹什麼,我在糾結著我能做什麼。所以輟學後我一段時間,我想去找工作,因為我比較沉默寡言,不是很會說話,我不適合去應聘做業務。我想應聘做技術的,可是處處碰壁。
一次偶然的機會,我才聽到嵌入式這個行業。那天我去新華書店,在計算機分類那邊想找本書學習。後來有個女孩子走過來,問我是不是讀計算機的,有沒有興趣學習嵌入式,然後給我介紹了一下嵌入式現在的火熱情況,告訴我學嵌入式多麼的有前景,給我了一份傳單,嵌入式培訓的廣告。聽了她的介紹,我心裡癢癢的,確實我很想去學會一門自己的技術,靠自己的雙手吃飯。
回家後,我就上網查了下嵌入式,確實是當今比較熱門的行業,也是比較好找工作的,工資也是相對比較高。我就下決心想學嵌入式了。於是我去找嵌入式培訓的相關信息,說真的,我也很迷茫,我不知道培訓是否真的能像他們宣傳的那樣好,所以我就想了解一段時間再做打算。
後來,我在網路知道看到一篇讓我很鼓舞的文章,是一個嵌入式高手介紹沒有基礎的朋友怎麼自學入門學嵌入式,文章寫的很好,包含了如何學習,該怎麼學習。他提到一個方法就是看視頻,因為看書實在太枯燥和費解的,很多我們也看不懂。這點我真的很認同,我自己看書往往看不了幾頁。
我在想,為什麼別人都能自學成才,我也可以的!我要相信自己,所以我就想自學,如果實在學不會我再去培訓。
主意一定,我就去搜索嵌入式的視頻,雖然零星找到一些嵌入式的視頻,但是都不系統,我是想找一個能夠告訴我該怎麼學的視頻,一套從入門到精通的視頻,一個比較完整的資料,最好能有老師教,不懂可以請教的。
後來我又找到一份很好的視頻,是在IT學習聯盟網站推出的一份視頻《零基礎嵌入式就業班》(喜歡《零基礎嵌入式就業班》的可以復制 sina.lt/qKh 粘貼瀏覽器按回車鍵即打開)。裡面的教程還不錯,很完整,可以讓我從基礎的開始學起。視頻比較便宜。
下面介紹下我的學習流程,希望對和我一樣完全沒有基礎的朋友有所幫助。
收到他們寄過來的光碟後,我就開始學習了,由於我沒有什麼基礎,我就從最簡單的C語言視頻教程學起,話說簡單,其實我還是很多不懂的,我只好請教他們,他們還是很熱心的,都幫我解決了。C語言我差不多學了一個禮拜,接下來我就學了linux的基本命令,我在他們提供linux虛擬機上都有做練習,敲linux的基本命令,寫簡單的C語言代碼,差不多也就三個禮拜。我每天都在不停的寫一些簡單的代碼,這樣一月後我基本掌握了C和linux的基本操作。
接下來我就去學習了人家的視頻的培訓教程,是整套的,和去參加培訓沒有多大的區別,這一看就是兩個月,學習了ARM的基本原理,學習嵌入式系統的概念,也掌握了嵌入式的環境的一些搭建,對linux也有更深層次的理解了,明白了嵌入式應用到底是怎麼做的,但是驅動我只是有一點點的了解,這個相對難一點,我想以後再慢慢啃。
這兩個月,除了吃飯睡覺,我幾乎都在學習。因為我知道幾乎沒有基礎,比別人差勁,我只能堅持努力著,我不能放棄,我必要要靠自己來養活自己,必須學好這門技術,然後我就把不懂的問題總結記下來,這樣慢慢積累了一段時間,我發現自己真的有點入門了。
最後的一個月,我就去看關於實踐部分的內容,了解嵌入式項目具體的開發流程,需要什麼樣的知識,我就開始准備這方面的知識,也就是學習這方面的視頻,同時他們建議我去找了找一些嵌入式面試的題目,為自己以後找工作做准備。我就到網上找了很多嵌入式的題目,把他們理解的記下來,這樣差不多准備了20天左右
我覺得自己差不多入門了,會做一些簡單的東西了。我就想去找工作看看,於是我就到51job瘋狂的投簡歷,因為我學歷的問題,專科沒有畢業,說真的,大公司沒有人會要我,所以我投的都是民營的小公司,我希望自己的努力有所回報。沒有想過幾天過後,就有面試了,但是第一次面試我失敗了,雖然我自認為筆試很好,因為我之前做了准備,但是他們的要求比較嚴格,需要有一年的項目經驗,所以我沒有被選中。
後來陸續面試了幾家公司,終於功夫不負有心人。我終於面試上的,是在閔行的一家民營的企業,公司規模比較小,我的職務是嵌入式linux應用開發,做安防產品的應用的。我想我也比較幸運,經理很看重我的努力,就決定錄用我,開的工資是3500一個月,雖然我知道在上海3500隻能過溫飽的生活,但是我想我足夠了。我至少不用每天都要靠父母養,我自己也能養活自己的。我想只要我繼續努力,我工資一定會翻倍的。
把本文寫出來,希望能讓和我一樣的沒有基礎的朋友有信心,其實我們沒有必要自卑,我們不比別人笨,只要我們肯努力,我們一樣會成功。
4. Linux驅動開發入門與實戰 這書怎麼樣
真心一般。。
5. 如何系統的學習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
6. 如何自學linux驅動開發,做驅動開發需要哪些方面的知識
硬體介面標准(參閱有關匯流排,設備控制器的技術文檔)
操作系統的設備無關的部分
也就是說 驅動位於硬體和設備無關軟體之間,向下屏蔽設備的硬體細節,向上為操作系統IO管理機制提供具體的策略。
一者,你即要有系統結構的常識,又要有IO軟體層次的常識
二者,必須和參閱硬體介面標准,必須懂操作系統的IO管理的機制。
所以,驅動的編寫,即與硬體細節打交道,有和具體的操作系統打交道。
驅動的編寫模式單一,只要你啃下這些東西,就OK了,相對而言,不如應用軟體難做,只是不少人對系統沒有較為深入的理解罷了。
7. 新手學習嵌入式linux驅動開發有沒有什麼步驟
1. 學會寫簡單的makefile
2. 編一應用程序,可以用makefile跑起來
3. 學會寫驅動的makefile
4. 寫一簡單char驅動,makefile編譯通過,可以insmod, lsmod, rmmod. 在驅動的init函數里列印hello world, insmod後應該能夠通過dmesg看到輸出。
5. 寫一完整驅動, 加上read, write, ioctl, polling等各種函數的驅動實現。 在ioctl里完成從用戶空間向內核空間傳遞結構體的實現。
6. 寫一block驅動, 加上read,write,ioctl,poll等各種函數實現。
7. 簡單學習下內存管理, 這個是最難的,明白各種memory alloc的函數實現細節。這是Linux開發的基本功。
8. 學習鎖機制的應用,這個不是最難的但是最容易犯錯的,涉及到很多同步和並發的問題。
9. 看內核中實際應用的驅動代碼。 你會發現最基本的你已經知道了, 大的框架都是一樣的, 無非是read, write, ioctl等函數的實現, 但裡麵包含了很多很多細小的實現細節是之前不知道的。 這時候就要考慮到很多別的問題而不僅僅是基本功能的實現。 推薦您看2.6.20中integrated的一個驅動 kvm, 記得是在driver/lguest下,很好玩的, 就是Linux下的虛擬機驅動, 代碼不長,但功能強大。有能力的可以自己寫一操作系統按照要求做成磁碟鏡像載入到虛擬機中, 然後客戶機可以有自己的4G虛擬地址空間。
10. 看完驅動歡迎您進入Linux kernel學習中來。 最簡單的方法,跟著ldd(Linux devive driver)做一遍。
8. 怎麼學linux內核驅動
怎麼學linux內核驅動?1. 分享Linux內核學習和驅動開發的經驗。
內核學習
Linux 內核功能越來越完善,如果沒有充裕的時間,深入內核並不是很現實。所以建議先讀一本內核的書,
第一遍是讀,會讀的很迷糊;之後反省一下,然後再瀏覽一下;可以想像一個 OS 是如何運行的,這樣可以不
陷入 Linux 內核的細節;最後可以深入自己感興趣或者需要的那一子系統
推薦 《Linux Kernel Development》
即便是子系統,也是很龐大的。一個省力的方式是網上搜一些相關的文章,便於快速了解這個子系統的運作;
然後結合代碼,形成自己的認知,最後做一下總結。如果僅僅是快速了解某一子系統的運作,可以參考一些早期
代碼的註解書籍,再深入的時候看看最新的代碼實現
對內核的認知是一個反復的過程,一開始並不完善,可能需要反復糾正。不要陷入這種糾錯中;而是以後繼續
使用和學習過程中,發現了沒有弄清楚的地方再深入,畢竟 Linux 內核是不斷變化的
還有一個很好的方式是,從系統調用入手,現在這方面的數據不少,而且對系統調用的語義都有講解,這樣可以
間接了解 Linux 系統的一些概念。對系統調用熟悉了,可以根據系統調用的執行過程,來大體了解內核的一個
運作過程;但是跟蹤系統調用的時候要注意抓主線,現在內核系統很復雜,一些 code path 上可能會涉及多個
子系統,可以從名字上猜測它們是干什麼的,不需要深入,否則會發現精力完全被分散掉了
學習 Linux 內核,一個很重要的是抽象的能力,所謂的抽象這里僅僅是指分清介面和介面的實現。因為 Linux
內核子系統很多,有很多子系統相互滲透,這樣 code path 看上去很復雜。閱讀代碼的時候,為了排除干擾,
需要分清哪些是自己需要看的,哪些是其它子系統的介面,對於其它子系統的介面,先當作它們功能完善不會
出問題好了,這樣可以關注重點;打個比方,一個應用程序的代碼可能量很大,比如一個 apache 項目,它
包含很多組件,有時候閱讀代碼的時候會看到不同組件的 API,深入看相關組件實現並不現實,這時候分清主次
對於代碼的閱讀就很有幫助了,總不能看到了 malloc 就要先把它的實現弄清楚吧,系統調用多者呢