qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          《Linux內核修煉之道》——分析內核源碼如何入手?(上)

          《Linux內核修煉之道》——分析內核源碼如何入手?(上)

          透過現象看本質,獸獸門無非就是一些人體藝術展示。同樣往本質里看過去,學習內核,就是學習內核的源代碼,任何內核有關的書籍都是基于內核,而又不高于內核的。

            既然要學習內核源碼,就要經常對內核代碼進行分析,而內核代碼千千萬,還前仆后繼的不斷往里加,這就讓大部分人都有種霧里看花花不見的無助感。不過不要怕,孔老夫子早就留給我們了應對之策:敏于事而慎于言,就有道而正焉,可謂好學也已。這就是說,做事要踏實才是好學生好同志,要遵循嚴謹的態度,去理解每一段代碼的實現,多問多想多記。如果抱著走馬觀花,得過且過的態度,結果極有可能就是一邊看一邊丟,沒有多大的收獲。

            假設全國房價上漲1.5%,假設80后局長是農民子弟,??,既然我們的人生充滿了假設,那么我在這里假設你現在就迫不及待的希望研究內核中USB子系統的實現,應該沒有意見吧?那好,下面就以USB子系統的實現分析為標本看看分析內核源碼應該如何入手。

            分析README

            內核中USB子系統的代碼位于目錄drivers/usb,這個結論并不需要假設。于是我們進入到該目錄,執行命令ls,結果顯示如下:

            atm  class  core  gadget  host  image  misc  mon  serial  storage Kconfig 
            Makefile  README usb-skeleton.c

            目錄drivers/usb共包含有10個子目錄和4個文件,usb-skeleton.c是一個簡單的USB driver的框架,感興趣的可以去看看,目前來說,它還吸引不了我們的眼球。那么首先應該關注什么?如果迎面走來一個ppmm,你會首先看臉、腳還是其它?當然答案依據每個人的癖好會有所不同。不過這里的問題應該只有一個答案,那就是Kconfig、Makefile、README。

            README里有關于這個目錄下內容的一般性描述,它不是關鍵,只是幫助你了解。再說了,面對“read我吧read我吧”這么熱情奔放的呼喚,善良的我們是不可能無動于衷的,所以先來看看里面都有些什么內容。

            23 Here is a list of what each subdirectory here is, and what is contained in
            24 them.
            25
            26 core/        - This is for the core USB host code, including the
            27             usbfs files and the hub class driver ("khubd").
            28
            29 host/        - This is for USB host controller drivers.  This
            30             includes UHCI, OHCI, EHCI, and others that might
            31             be used with more specialized "embedded" systems.
            32
            33 gadget/        - This is for USB peripheral controller drivers and
            34             the various gadget drivers which talk to them.
            35
            36
            37 Individual USB driver directories.  A new driver should be added to the
            38 first subdirectory in the list below that it fits into.
            39
            40 image/        - This is for still image drivers, like scanners or
            41             digital cameras.
            42 input/        - This is for any driver that uses the input subsystem,
            43             like keyboard, mice, touchscreens, tablets, etc.
            44 media/        - This is for multimedia drivers, like video cameras,
            45             radios, and any other drivers that talk to the v4l
            46             subsystem.
            47 net/        - This is for network drivers.
            48 serial/        - This is for USB to serial drivers.
            49 storage/    - This is for USB mass-storage drivers.
            50 class/        - This is for all USB device drivers that do not fit
            51             into any of the above categories, and work for a range
            52             of USB Class specified devices.
            53 misc/        - This is for all USB device drivers that do not fit
            54             into any of the above categories.

            這個README文件描述了前邊使用ls命令列出的那10個文件夾的用途。那么什么是USB Core?Linux內核開發者們,專門寫了一些代碼,負責實現一些核心的功能,為別的設備驅動程序提供服務,比如申請內存,比如實現一些所有的設備都會需要的公共的函數,并美其名曰USB Core。

            時代總在發展,當年胖楊貴妃照樣迷死唐明皇,而如今人們欣賞的則是林志玲這樣的魔鬼身材。同樣,早期的Linux內核,其結構并不是如今天這般有層次感,遠不像今天這般錯落有致,那時候drivers/usb/這個目錄下邊放了很多很多文件,USB Core與其他各種設備的驅動程序的代碼都堆砌在這里,后來,怎奈世間萬千的變幻,總愛把有情的人分兩端。于是在drivers/usb/目錄下面出來了一個core目錄,就專門放一些核心的代碼,比如初始化整個USB系統,初始化Root Hub,初始化主機控制器的代碼,再后來甚至把主機控制器相關的代碼也單獨建了一個目錄,叫host目錄,這是因為USB主機控制器隨著時代的發展,也開始有了好幾種,不再像剛開始那樣只有一種,所以呢,設計者們把一些主機控制器公共的代碼仍然留在core目錄下,而一些各主機控制器單獨的代碼則移到host目錄下面讓負責各種主機控制器的人去維護。

            那么USB gadget那?gadget白了說就是配件的意思,主要就是一些內部運行Linux的嵌入式設備,比如PDA,設備本身有USB設備控制器(USB Device Controller),可以將PC,也就是我們的主機作為master端,將這樣的設備作為slave端和主機通過USB進行通信。從主機的觀點來看,主機系統的USB驅動程序控制插入其中的USB設備,而USB gadget的驅動程序控制外圍設備如何作為一個USB設備和主機通信。比如,我們的嵌入式板子上支持SD卡,如果我們希望在將板子通過USB連接到PC之后,這個SD卡被模擬成U盤,那么就要通過USB gadget架構的驅動。

            剩下的幾個目錄分門別類的放了各種USB設備的驅動,比如U盤的驅動在storage目錄下,觸摸屏和USB鍵盤鼠標的驅動在input目錄下,等等。

            我們響應了README的熱情呼喚,它便給予了我們想要的,通過它我們了解了USB目錄里的那些文件夾都有著什么樣的角色。到現在為止,就只剩下內核的地圖——Kconfig與Makefile兩個文件了。有地圖在手,對于在內核中游蕩的我們來說,是件很愉悅的事情,不過,因為我們的目的是研究內核對USB子系統的實現,而不是特定設備或host controller的驅動,所以這里的定位很明顯,USB Core就是我們需要關注的對象,那么接下來就是要對core目錄中的內容進行定位了。

            分析Kconfig和Makefile

            進入到drivers/usb/core目錄,執行命令ls,結果顯示如下:

            Kconfig  Makefile  buffer.c  config.c  devices.c  devio.c  driver.c  
            endpoint.c  file.c  generic.c  hcd-pci.c  hcd.c  hcd.h  hub.c  hub.h  
            inode.c  message.c  notify.c  otg_whitelist.h  quirks.c  sysfs.c  urb.c  
            usb.c  usb.h

            然后執行wc命令,如下所示。

            # wc –l ./*
               148 buffer.c
               607 config.c
               706 devices.c
              1677 devio.c
              1569 driver.c
               357 endpoint.c
               248 file.c
               238 generic.c
              1759 hcd.c
               458 hcd.h
               433 hcd-pci.c
              3046 hub.c
               195 hub.h
               758 inode.c
               144 Kconfig
                21 Makefile
              1732 message.c
                68 notify.c
               112 otg_whitelist.h
               161 quirks.c
               710 sysfs.c
               589 urb.c
               984 usb.c
               160 usb.h
             16880 total

           drivers/usb/core目錄共包括24個文件,16880行代碼。core不愧是core,為大家默默的做這么多事。不過這么多文件里不一定都是我們所需要關注的,先拿咱們的地圖來看看接下來該怎么走。先看看Kconfig文件,可以看到下面的選項。

            15 config USB_DEVICEFS
            16         bool "USB device filesystem"
            17         depends on USB
            18         ---help---
            19           If you say Y here (and to "/proc file system support" in the "File
            20           systems" section, above), you will get a file /proc/bus/usb/devices
            21           which lists the devices currently connected to your USB bus or
            22           busses, and for every connected device a file named
            23           "/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the
            24           device number; the latter files can be used by user space programs
            25           to talk directly to the device. These files are "virtual", meaning
            26           they are generated on the fly and not stored on the hard drive.
            27
            28           You may need to mount the usbfs file system to see the files, use
            29           mount -t usbfs none /proc/bus/usb
            30
            31           For the format of the various /proc/bus/usb/ files, please read
            32           <file:Documentation/usb/proc_usb_info.txt>.
            33
            34           Usbfs files can't handle Access Control Lists (ACL), which are the
            35           default way to grant access to USB devices for untrusted users of a
            36           desktop system. The usbfs functionality is replaced by real
            37           device-nodes managed by udev. These nodes live in /dev/bus/usb and
            38           are used by libusb.

            選項USB_DEVICEFS與usbfs文件系統有關。usbfs文件系統掛載在/proc/bus/usb目錄,顯示了當前連接的所有USB設備及總線的各種信息,每個連接的USB設備在其中都會有一個對應的文件進行描述。比如文件/proc/bus/usb/xxx/yyy,xxx表示總線的序號,yyy表示設備所在總線的地址。不過不能夠依賴它們來穩定地訪問設備,因為同一設備兩次連接對應的描述文件可能會不同,比如,第一次連接一個設備時,它可能是002/027,一段時間后再次連接,它可能就已經改變為002/048。

            就好比好不容易你暗戀的mm今天見你的時候對你拋了個媚眼,你心花怒放,趕快去買了100塊彩票慶祝,到第二天再見到她的時候,她對你說你是誰啊,你悲痛欲絕的刮開那100塊彩票,上面清一色的謝謝你。

            因為usbfs文件系統并不屬于USB子系統實現的核心部分,與之相關的代碼我們可以不必關注。

            74 config USB_SUSPEND
            75       bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
            76       depends on USB && PM && EXPERIMENTAL
            77       help
            78         If you say Y here, you can use driver calls or the sysfs
            79         "power/state" file to suspend or resume individual USB
            80         peripherals.
            81
            82         Also, USB "remote wakeup" signaling is supported, whereby some
            83         USB devices (like keyboards and network adapters) can wake up
            84         their parent hub.  That wakeup cascades up the USB tree, and
            85         could wake the system from states like suspend-to-RAM.
            86
            87         If you are unsure about this, say N here.

          這一項是有關USB設備的掛起和恢復。開發USB的人都是節電節能的好孩子,所以協議里就規定了,所有的設備都必須支持掛起狀態,就是說為了達到節電的目的,當設備在指定的時間內,如果沒有發生總線傳輸,就要進入掛起狀態。當它收到一個non-idle的信號時,就會被喚醒。節約用電從USB做起。不過這個與主題也沒太大關系,相關代碼也可以不用關注了。

            剩下的還有幾項,不過似乎與咱們關系也不大,還是去看看Makefile。

            5 usbcore-objs    := usb.o hub.o hcd.o urb.o message.o driver.o /
            6                         config.o file.o buffer.o sysfs.o endpoint.o /
            7                         devio.o notify.o generic.o quirks.o
            8
            9 ifeq ($(CONFIG_PCI),y)
            10         usbcore-objs    += hcd-pci.o
            11 endif
            12
            13 ifeq ($(CONFIG_USB_DEVICEFS),y)
            14         usbcore-objs    += inode.o devices.o
            15 endif
            16
            17 obj-$(CONFIG_USB)       += usbcore.o
            18
            19 ifeq ($(CONFIG_USB_DEBUG),y)
            20 EXTRA_CFLAGS += -DDEBUG
            21 endif

            Makefile可比Kconfig簡略多了,所以看起來也更親切點,咱們總是拿的money越多越好,看的代碼越少越好。這里之所以會出現CONFIG_PCI,是因為通常USB的Root Hub包含在一個PCI設備中。hcd-pci和hcd顧名而思義就知道是說主機控制器的,它們實現了主機控制器公共部分,按協議里的說法它們就是HCDI(HCD的公共接口),host目錄下則實現了各種不同的主機控制器。

            CONFIG_USB_DEVICEFS前面的Kconfig文件里也見到了,關于usbfs的,與咱們的主題無關,inode.c和devices.c兩個文件也可以不用管了。

            那么我們可以得出結論,為了理解內核對USB子系統的實現,我們需要研究buffer.c、config.c、driver.c、endpoint.c、file.c、generic.c、hcd.c  hcd.h、hub.c、message.c、notify.c、otg_whitelist.h、quirks.c、sysfs.c、urb.c 和usb.c文件。這么看來,好像大都需要關注的樣子,沒有減輕多少壓力,不過這里本身就是USB Core部分,是要做很多的事為咱們分憂的,所以多點也是可以理解的

          posted on 2011-11-09 16:38 順其自然EVO 閱讀(264) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2011年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 抚顺市| 电白县| 阿坝| 固原市| 隆子县| 辽宁省| 衡山县| 普洱| 太谷县| 佛山市| 大厂| 甘泉县| 庆城县| 嘉祥县| 三亚市| 怀集县| 中山市| 竹山县| 江陵县| 景德镇市| 利津县| 鄂托克旗| 西青区| 富民县| 凤阳县| 永和县| 内江市| 沂水县| 高雄县| 潜山县| 米脂县| 伊春市| 平利县| 塔河县| 盐池县| 墨玉县| 昌黎县| 鄂托克前旗| 富裕县| 咸丰县| 屯昌县|