教你如何学习linux内核
毫不夸张地说,Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件。基本上,Linux 内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。对于一个希望能够在Linux内核的汪洋代码里看到一丝曙光的人来说,将它们放在怎么重要的地位都不过分。
我们去香港,通过海关的时候,总会有免费的地图和各种指南拿,有了它们在手里我们才不至于无头苍蝇般迷惘的行走在陌生的街道上。即使在内地出去旅游的时候一般来说也总是会首先份地图,当然了,这时就是要去买了,拿是拿不到的,不同的地方有不同的特,只不过有的特是服务,有的特是索取。
Kconfig和Makefile就是Linux Kernel迷宫里的地图。地图引导我们去认识一个城市,而Kconfig 和Makefile则可以让我们了解一个Kernel目录下面的结构。我们每次浏览kernel寻属于自己的那一段代码时,都应该首先看看目录下的这两个文件。
利用Kconfig和Makefile寻目标代码
就像利用地图寻目的地一样,我们需要利用Kconfig和Makefile来寻所要研究的目标代码。比如我们打算研究U盘驱动的实现,因为U盘是一种storage设备,所以我们应该先进入到
drivers/usb/storage/目录。但是该目录下的文件很多,那么究竟哪些文件才是我们需要关注的?这时就有必
要先去阅读Kconfig和Makefile文件。
对于Kconfig文件,我们可以看到下面的选项。
config USB_STORAGE_DATAFAB
bool "Datafab Compact Flash Reader support (EXPERIMENTAL)"
depends on USB_STORAGE && EXPERIMENTAL
help
Support for certain Datafab CompactFlash readers.
Datafab has a web page at <www.datafabusa/>.
显然,这个选项和我们的目的没有关系。首先它专门针对Datafab公司的产品,其次虽然CompactFlash reader是一种flash设备,但显然不是U盘。因为drivers/usb/storage目录下的代码是针对usb mass storage这一类设备,而不是针对某一种特定的设备。U盘只是usb mass storage
设备中的一种。再比如:
config USB_STORAGE_SDDR55
bool "SanDisk SDDR-55 SmartMedia support (EXPERIMENTAL)"
depends on USB_STORAGE && EXPERIMENTAL
help
Say Y here to include additional code to support the Sandisk SDDR-55
SmartMedia reader in the USB Mass Storage driver.
很显然这个选项是有关SanDisk产品的,并且针对的是SM卡,同样不是U盘,所以我们也不需要去关注。
事实上,很容易确定,只有选项CONFIG_USB_STORAGE才是我们真正需要关注的。
9 config USB_STORAGE
10 tristate "USB Mass Storage support"
11 depends on USB && SCSI
12 ---help---
13 Say Y here if you want to connect USB mass storage devices to your
14 computer's USB port. This is the driver you need for USB
15 floppy drives, USB hard disks, USB tape drives, USB CD-ROMs,
16 USB flash devices, and memory sticks, along with
17 similar devices. This driver may also be used for some cameras
18 and card readers.
19
20 This option depends on 'SCSI' support being enabled, but you
21 probably also need 'SCSI device support: SCSI disk support'
22 (BLK_DEV_SD) for most USB storage devices.
23
24 To compile this driver as a module, choose M here: the
25 module will be called usb-storage.
接下来阅读Makefile文件。
0 #
1 # Makefile for the USB Mass Storage device drivers.
2 #
3 # 15 Aug 2000, Christoph Hellwig
4 # Rewritten to use lists instead of if-statements.
5 #
6
7 EXTRA_CFLAGS := -Idrivers/scsi
8
9 obj-$(CONFIG_USB_STORAGE) += usb-storage.o
10
11 usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
12 usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT) += shuttle_usbat.o
13 usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o
14 usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o
15 usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o
16 usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
17 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
18 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
19 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
20 usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
21 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
22 usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
23
24 usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
25 initializers.o $(usb-storage-obj-y)
26
27 ifneq ($(CONFIG_USB_LIBUSUAL),)
28 obj-$(CONFIG_USB) += libusual.o
29 endif
前面通过Kconfig文件的分析,我们确定了只需要去关注CONFIG_USB_STORAGE选项。在Makefile文件里查CONFIG_USB_STORAGE,从第9行得知,该选项对应的模块为usbstorage。因为Kconfig文件里的其他选项我们都不需要关注,所以Makefile的11~22行可以忽略。第24行意味着我们只需要关注scsiglue.c、protocol.c、transport.c、usb.c、initializers.c以及它们同名的.h头文件。
Kconfig和Makefile很好的帮助我们定位到了所要关注的目标,就像我们到一个陌生的地方要随身携带地图,当我们学习Linux内核时,也要谨记寻求Kconfig和Makefile的帮助。
透过现象看本质,兽兽门无非就是一些人体艺术展示。同样往本质里看过去,学习内核,就是学习内核的源代码,任何内核有关的书籍都是基于内核,而又不高于内核的。
既然要学习内核源码,就要经常对内核代码进行分析,而内核代码千千万,还前仆后继的不断往里加,这就让大部分人都有种雾里看花花不见的无助感。不过不要怕,孔老夫子早就留给我们了应对之策:敏于事而慎于言,就有道而正焉,可谓好学也已。这就是说,做事要踏实才是好学生好同志,要遵循严谨的态
度,去理解每一段代码的实现,多问多想多记。如果抱着走马观花,得过且过的态度,结果极有可能就是一边看一边丢,没有多大的收获。
假设全国房价上涨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与其他各种设备的驱动程序的代码都堆砌自学linux买什么书好
在这里,后来,怎奈世间万千的变幻,总爱把有情的人分两端。于是在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两个文件了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。