- Linux設備驅動開發詳解:基于最新的Linux4.0內核
- 宋寶華
- 2885字
- 2018-12-31 20:25:11
前言
Linux從未停歇前進的腳步。Linus Torvalds,世界上最偉大的程序員之一,Linux內核的創始人,Git的締造者,現在仍然在沒日沒夜地合并補丁、升級內核。做技術的人,從來沒有終南捷徑,拼得就是坐冷板凳的傻勁。
這是一個連閱讀都被碎片化的時代,在這樣一個時代,人們趨向于激進、浮躁,內心的不安寧使我們極難靜下心來研究什么。我見過許多Linux工程師,他們的簡歷上寫著“精通”Linux內核,有多年的工作經驗,而他們的“精通”卻只是把某個寄存器從0改成1,從1改成0的不斷重復;我也見過許多Linux工程師,他們終日埋頭苦干,敲打著自己的機器和電路板,卻從未冷靜下來思考,并不斷重構和升華自己的知識體系。
這是要把“牢底”坐穿的程序員,這樣“忙忙碌碌”的程序員,從來都不算是好程序員。
對于優秀的程序員,其最優秀的品質是能夠心平氣和地學習與思考問題,透析代碼背后的架構、原理和設計思想。沒有思想的代碼是垃圾代碼,沒有思想的程序員,只是在完成低水平重復建設的體力活。很多程序員從不過問自己寫的代碼最后在機器里面是怎么跑的,很多事情莫名其妙地發生了,很多bug莫名其妙地消失了……他們永遠都在得過且過。
由此,衍生出了本書的第一個出發點,那就是帶給讀者更多關于Linux開發思想的講解,幫助讀者奠定根基。本書呈現給讀者的更多的是一種思考方法,而不是知識點的簡單羅列。
本書除對基礎理論部分進行了詳細的講解外,還加強了對驅動編程所涉及的Linux內核最底層機理的講解,內容包括中斷、定時器、進程生命周期、uevent、并發、編譯亂序、執行亂序、等待隊列、I/O模型、內存管理等。這些知識點非常重要,是真正證明程序員理解了Linux的部分內容,程序員只有打好根基,才能游刃有余。
本書沒有大量描述各種具體驅動類型的章節,如Sound、PCI、MTD、tty等,而將更多的焦點轉移到了驅動編程背后的內核原理,并試圖從Linux內核的上百個驅動子系統中尋找出內部規律,以培養讀者舉一反三的能力。
Linux內核有上百個驅動子系統,這一點從內核的drivers子目錄中就可以看出來:

好吧,傻子才會一個目錄一個目錄地去看,一個目錄一個目錄地從頭學起。我們勢必要尋找各種驅動子系統的共性,摸索規律。在本書中,我們將更多地看到各驅動子系統的類比,以及驅動子系統的層次化設計。
技術工作從來都不能一勞永逸。世界變化得太快,當前技術革新的速度數倍于我們父輩、祖輩、祖祖輩經歷過的任何時代。證明你是“真球迷”還是“偽球迷”的時候到了,這個時代是偽程序員的地獄,也是真程序員的天堂。
從浩如煙海的知識體系、不斷更新的軟件版本中終生學習,不斷攻克一個個挑戰,獲取新養分,尋找新靈感,這實在是黑暗的碼農生涯中不斷閃現的璀璨光芒。
Linux的內核版本不斷更新,出現了Linux 3.0、Linux 3.1、Linux 3.2、…、Linux 3.19、Linux 4.0、Linux 4.1,變化的是軟件的架構,不變的是Linus的熱情。
這無疑也是本書的第二個出發點,更新Linux驅動編程的知識體系以迎合最新的時代需求。因此,本書有大量關于設備樹、ARM Linux移植、Linux電源管理、GPIO、時鐘、定時器、pinmux、DMA等內容。我們的操作平臺也轉移到了QEMU模擬的4核Cortex-A9電路板上,書中的實例基本都轉移到了市面流行的新芯片上。
最近兩三年,老是聽許多程序員抱怨,市面上缺乏講解新內核的資料、缺乏從頭到尾講解設備樹的資料,但是我想說,這實在不是什么難點。難點仍然是本書基于第一個出發點要解決的問題,如果有好的基礎,以優秀程序員極強的學習能力,應該很快就可以掌握這些新知識。機制沒有變,變化的只是策略。
因此學習能力也是優秀程序員的又一個重要品質。沒有人生下來就是天才,良好的學習能力也是通過后天的不斷學習培養的。可以說,學得越多的人,學新東西的速度一定越快,學習能力也變得越強。因為,知識的共通性實在太多。
讀者在閱讀本書時,不應該企圖把它當成一本工具書和查API的書,而是應該把它當作一本梳理理論體系、開發思想、軟件架構的書。唯如此,我們才能適應未來新的變化。
時代的滾滾車輪推動著Linux內核的版本不斷向前,也推動著每個人的人生。紅塵滾滾,
我不去想是否能夠成功,
既然選擇了遠方,
便只顧風雨兼程。
最后,本書能得以出版,要感謝帶領我向前的人生導師和我的眾多小伙伴,他們或者在我人生的關鍵時刻改變了我,或者給我黑暗的程序生涯帶來了無盡的快樂和動力。我的小伙伴,他們力挺我、鼓勵我,也辱罵我、奚落我,這些都是真摯的友情。
謹以此書,致以對楊平先生、何昭然、方毅偉、李華毅、宋志武、杜向龍、葉祥振、劉昊、王榕、何曄、王立賽、曾過、劉永生、段丙華、章君義、王文琪、盧鵬、劉濤、徐西寧、吳赫、任橋偉、秦龍廷、胡良兵、張家旺、王雷、Bryan Wu、Eric Miao、Cliff Cai、Qipan Li、Guoying Zhang、陳健松、Haoyu Zhong、劉洪濤、季久峰、邴杰、孫志忠、吳國舉、Bob Liu、趙小吾、EJ Zhao、賀亞鋒、劉仕杰、Hao Yin等老師和小伙伴的深深感激;謹以此書,致以對我的父母大人、老婆大人、兄長和姐姐、偉大丈母娘的深深感激,本書的寫作時間超過一年,其過程是一種巨大的肉體和精神折磨,沒有他們的默默支持和不斷鞭策,本書是不可能完成的;謹以此書,對為本書做出巨大貢獻的編輯、策劃老師,尤其是張國強老師致以深深的感激!
由于篇幅的關系,我沒有辦法一一列舉我要感激的所有人,但是,這些年從你們那里獲得的,遠遠大于我付出的,所以,在內心深處,唯有懷著對你們的深深感恩,不斷前行。歲月如歌,吾歌狂行。
全書結構
本書首先介紹Linux設備驅動的基礎。第1章簡要地介紹了設備驅動,并從無操作系統的設備驅動引出了Linux操作系統下的設備驅動,介紹了本書所基于的開發環境。第2章系統地講解了Linux驅動工程師應該掌握的硬件知識,為工程師打下Linux驅動編程的硬件基礎,詳細介紹了各種類型的CPU、存儲器和常見的外設,并闡述了硬件時序分析方法和數據手冊閱讀方法。第3章將Linux設備驅動放在Linux 2.6內核背景中進行講解,說明Linux內核的編程方法。由于驅動編程也在內核編程的范疇,因此,這一章實質是為編寫Linux設備驅動打下軟件基礎。
其次,講解Linux設備驅動編程的基礎理論、字符設備驅動及設備驅動設計中涉及的并發控制、同步等問題。第4、5章分別講解Linux內核模塊和Linux設備文件系統;第6~9章以虛擬設備globalmem和globalfifo為主線,逐步給其添加高級控制功能;第10、11章分別闡述Linux驅動編程中所涉及的中斷和定時器、內核和I/O操作處理方法。
接著,剖析復雜設備驅動的體系結構以及塊設備、網絡設備驅動。該篇講解了設備與驅動的分離、主機控制器驅動與外設驅動的分離,并以大量實例(如input、tty、LCD、platform、I2C、SPI、USB等)來佐證。其中第12章和第17章遙相呼應,力圖全面地展示驅動的架構。Linux有100多個驅動子系統,逐個講解和學習都是不現實的,授人以魚不如授人以漁,因此我們將更多的焦點放在了架構講解方面,以便讀者可以舉一反三。
本書最后4章分析了Linux的設備樹、Linux移植到新的SoC上的具體工作以及Linux內核和驅動的一些調試方法。這些內容,對于理解如何從頭開始搭建一個Linux,以及整個Linux板級支持包上上下下的關系尤為重要。
另外,本書的主要代碼都引用自Linux源代碼,為保留原汁原味,均延用了代碼的英文注釋,而其他非引用的代碼則使用了中文注釋或無注釋,特此說明。
本書配套的相關素材和代碼,讀者均可從與本書相關的微信公眾號中獲得,相關公眾號是:Linuxer,歡迎掃描二維碼。
宋寶華
2015年4月于上海浦東