看代碼之前,我曾經認真地思考過這麼一個問題,需要關注的僅僅是drivers/usb/storage/目錄下面那相關的3000多行代碼嗎?就是這樣幾個檔案就能讓一個個不同的隨身碟在Linux下面工作起來嗎?像一開始那樣把這個目錄比成一個小城的話,也許,城裡的月光很漂亮,她能夠把人的夢照亮,能夠溫暖人的心房。但我們真的就能廝守在這個城裡,一生一世嗎?
很不幸,問題遠不是這樣簡單。外面的世界很精彩,作為隨身碟,她需要與USB Core、SCSI Core、記憶體管理單元,還有核心中許許多多其他模組打交道。外面的世界很大,遠比我們相像的大。
什麼是USB Core?它負責實現一些核心的功能,為別的裝置驅動程式提供服務,比如申請記憶體,比如實現一些所有裝置都會需要的公用函數。事實上,在USB的世界裡,要使一個普通的裝置正常地工作,除了要有裝置本身以外,還要有主機控制器(Host Controller),和這個控制器相串連在一起的是Root Hub。
Hub應該不會陌生乙太網路上的Hub允許多個人的電腦共用一個網口。而USB的世界裡同樣有Hub,其實原理是一樣的,任何支援USB的電腦不會說只允許只能一個時刻使用一個USB裝置,比如插入了隨身碟,同樣還可以插入USB鍵盤,還可以再插一個USB滑鼠,因為你會發現你的電腦裡並不只是一個USB介面。這些口實際上就是所謂的Hub口。而現實中經常是讓一個USB控制器和一個Hub綁定在一起,即整合,而這個Hub也被稱作Root Hub。換言之,和USB控制器綁定在一起的Hub就是系統中最根本的Hub,其他Hub可以串連到她這裡,然後可以延伸出去,外接別的裝置,當然也可以不用別的Hub,讓USB裝置直接接到Root Hub上。
那麼USB主機控制器本身是幹什麼用的呢?控制器,顧名思義,用於控制所有USB裝置的通訊。通常電腦的CPU並不是直接和USB裝置打交道,而是和控制器打交道,它要對裝置做什麼,他會告訴控制器,而不是直接把指令發給裝置,控制器再去負責處理這件事情,會去指揮裝置執行命令,而CPU就不用管剩下的事情,還是該幹嘛幹嘛去,控制器替他去完成剩下的事情,事情辦完了再通知CPU。
否則讓CPU去盯著每一個裝置做每一件事情,那是不現實的,那就好比讓一個學院的院長去盯著我們每一個本科生上課,去管理我們的出勤,只能說,不現實。所以我們就被分成了幾個系,通常院長有什麼指示直接跟各系領導說就可以了,如果他要和三個系主任說事情,他即使不把三個人都召集起來開個會,也可以給三個人各打一個電話,打完電話他就忙他自己的事情去了。
所以,Linux核心開發人員們,專門寫了一些代碼,並美其名曰USB Core。時代總在發展,當年胖楊貴妃照樣迷死唐明皇,而如今人們欣賞的則是林志玲這樣的魔鬼身材。同樣,早期的Linux核心,其結構並不是如今天這般有層次感,遠不像今天這般錯落有致,那時候drivers/usb/這個目錄下邊放了很多很多檔案,USB Core與其他各種裝置的驅動程式的代碼都堆砌在這裡,後來,怎奈世間萬千的變幻,總愛把有情的人分兩端。
於是在drivers/usb/目錄下面出來了一個core目錄,就專門放一些核心的代碼,比如初始化整個USB系統,初始化Root Hub,初始化主機控制器的代碼,再後來甚至把主機控制器相關的代碼也單獨建了一個目錄,叫host目錄,這是因為USB主機控制器隨著時代的發展,也開始有了好幾種,不再像剛開始那樣只有一種,所以呢,設計者們把一些主機控制器公用的代碼仍然留在core目錄下,而一些各主機控制器單獨的代碼則移到host目錄下面讓負責各種主機控制器的人去維護。常見的主機控制器有三種:EHCI,UHCI和OHCI。
所以這樣,出來了三個概念,USB Core,USB主機控制器和USB裝置,現實總是很無奈,然而,心若知道靈犀的方向,哪怕不能夠朝夕相伴?沒錯,USB通訊的靈魂就是USB協議。USB協議將是所有USB裝置和USB主機所必須遵循的遊戲規則。這種規則也很自然地體現在了代碼中。於是,我們需要瞭解的不僅僅是drivers/usb/storage/目錄下面的檔案,還得去瞭解那外面的世界,雖然,只需要瞭解一點點。
*****************************
摘自《Linux那些事兒之我是USB》
《Linux那些事兒之我是USB》
連結為:china-pub
、噹噹
、卓越
《Linux
核心修鍊之道》連結為: 卓越
、噹噹
、
china-pub