储蓄卡怎么销户:揭秘linux驱动程序----都是关于模块

来源:百度文库 编辑:中财网 时间:2024/05/12 12:16:54

揭秘linux驱动程序----都是关于模块

在这一篇文章里面,作者讲述了linux系统稳定、方便的原因是-----模块化。然后,简要介绍了对模块的相关操作Tags:编程 |   | linux驱动程序  | 模块 
Linux Device Drivers Demystified
  linux Device Drivers Demystified
All About Moduless
James Andrews
  James Andrews
Thursday, September 23, 1999 12:49:47 PM
  Thursday, September 23, 1999 12:49:47 PM
Another much-trumpeted advantage of Linux is that it does not need to be rebooted as often as other operating systems. You might think that this is due to its rock solid stability. You may think I am now going to talk about the quality of the device drivers. But you'd be wrong. The reason that Linux device drivers lead to less rebooting is that we can reconfigure, load or unload them without restarting the system.
            

Linux系统另一种广为人知的优势是-----它并不需要像其他操作系统那样,总是要重启(想一想,我们在windows下安装某些软件或驱动的时候,都是要重启系统才可以使软件完整地生效。)。你或许认为这是因为linux那岩石搬坚固的稳定性造就的。你也许认为,我准备谈论设备驱动程序的质量。如果你那样想的话,那么,你就错了。安装了linux设备驱动程序,然后并不需要重启系统的原因是,我们可以在不用重启动操作系统的基础下重新配置驱动,载入或者是卸掉它们。

To do this modular kernel drivers are used.

           

要实现上面的那种功能,就必须用到模块化的内核驱动程序。

  
How to load a module
              

如何载入一个模块

Most people configure their modules at install time and then leave them alone. All the major distributions have taken to modules because of another advantage they have: size. Distribution makers want to support all the possible cards and devices that Linux can. If we compiled all these into the kernel it would be huge. If several different static kernels for different devices were supplied then they would take up too much space, as well. With the modular system distribution makers supply a stripped down kernel plus a comprehensive set of device drivers. This typically only occupies two or three floppy disks in total.

很多人,在安装他们需要的模块的时候进行配置,完成之后,就不用再去理它们了。所有,主要的linux操作系统发行版,都采用了模块化的机制,因为,这让它们有另外的优势:系统大小(意思是说,在发行系统的时候,只发行核心的部分,其他,驱动程序方面的,你在需要的时候再自行载入。)。发行商,想让他们发行的linux操作系统,尽可能支持所有的扩展卡和设备。

如果发行商的确提供了几种支持一定数量的设备,内核定制好的linux操作系统(就是它支持的设备的驱动程序已经编译进内核了),那么这样的话操作系统的是很大的(很占磁盘空间的)。

采用模块化机制的系统,发行商可以提供一个只包含基本功能的操作系统,外加一系列linux设备驱动程序(这是不编译进内核的)。这种发行的操作系统大小只占两个或三个软盘。

modprobe, lsmod and insmod
  
if you want to load a module after system setup time, then the easiest way is as follows:
           

如果你想在系统设置好之后,再添加一个模块到系统中,那么,最简单的办法是:

modprobe hfs
  
This example loads the Apple Mac disk subsystem driver (called hfs) with the modprobe command. If the module takes parameters, like IRQ numbers, then you can specify them with modprobe too.
              

这个例子,用modprobe命令为苹果机上的系统,添加一个磁盘子系统驱动模块。如果(在添加)这一个模块时需要用到参数,比如系统中断请求号(每个系统都提供了一组中断请求,每个中断请求都有一个编号),那么你也可以通过modprobe命令来指定相应的中断请求号。

To see what modules are loaded and to see information on how they depend on each other we use lsmod. Here is some example output from lsmod.
             

我们可以使用lsmod命令来查看系统中都安装了哪些模块,还有这些模块之间的关联性,依赖性。下面是使用lsmod命令后的输出结果:

Module                  Size   Used by
gus                     45016    0
mad16                   6564     0
sb                       31416   0
ad1848                 15112     0  [mad16]
uart401                 5588     0  [mad16 sb]
sound                  54368    0  [gus mad16 sb ad1848 uart401]
In this example the mad16 kernel device driver depends on the ad1848 device driver.
            

在这个例子里面,mad16内核设备驱动程序依赖于ad1848驱动。

Yes, there really is a mad16 device driver. It is a soundcard chipset.
             

的确,存在一个mad16设备驱动程序,它是驱动一组声卡芯片的。

/etc/modules, /etc/conf.modules
  
In the normal course of events the modules we asked for when Linux was installed are loaded at boot time. To achieve this the file /etc/modules is used. This is a list of modules to be loaded.
          

在通常情况下,我们在安装linux系统的时候,会编译一部分我们需要的驱动模块到系统中,这样的模块,在每次系统启动时都会载入(我们可以选择一些驱动模块不载入,在系统启动时)。

要达到这样的功能,我们就要用到/etc目录下的modules文件,这个文件里面列出了在系统启动时要载入的模块(我在自己的fedora系统中,在/etc目录下并没有找到这个modules文件,或许是因为系统版本不同吧。)。

The options for the modules are stored in /etc/conf.modules. Recommended practice is to not edit /etc/conf.modules, however, but to use a script like update-modules; see the man pages for more details.
              

所有模块的配置信息都存在/etc目录下的conf.modules文件中。建议不要手动去编辑这个conf.modules文件,不过呢,可以通过一个脚本来修改配置conf.modules,比如更新模块的脚本(这个作者点出的脚本update-modules应该是要自己编写的,并没有现成的可以给我们修改)。

要想了解更多的细节,可以查看man手册。

如何编译linux驱动模块

首先,我们要了解一下模块是如何别被构造的。模块的构造过程与用户空间的应用程序的构造过程有显著不同;内核是一个大的、独立的程序,对于它的各个部分如何组合在一起有详细的明确的要求。Linux2.6内核的构造过程也与以前版本的内核构造过程不同;新的构造系统用起来更加简单,并且可产生更加正确的结果,但是它看起来和先前的方法有很大不同。 内核的构造系统非常复杂,我们所看到的只是它的一小部分。如果读者想了解更深入的细节,则应阅读在内核源码中的Document/kbuild目录下的文件。在构造内核模块之前,有一些先决条件首先应该得到满足。首先,读者要保证你有适合于你的内核版本的编译器、模块工具,以及其他必要工具。在内核文档目录下的文件Documentation/Changes里列出了需要的工具版本;在开始构造内核前,读者有必要查看该文件,并确保已安装了正确的工具。如果用错误的工具版本来构造一个内核(及其模块),可能导致许多奇怪的问题。另外也要注意,使用太新版本的编译器偶尔可能也会导致问题。一旦做好了上面的准备工作之后,其实给自己的模块创建一个makefile则非常简单。实际上,对于本章前面展示的" hello world"例子,下面一行就够了:obj-m := hello.o如果读者熟悉make,但是对Linux2.6内核构造系统不熟悉的话,可能奇怪这个makefile如何工作。毕竟上面的这一行不是一个传统的makefile的样子。 问题的答案当然是内核构造系统处理了余下的工作。上面的赋值语句(它利用了由GNU make提供的扩展语法)说明有一个模块要从目标文件hello.o构造, 而从该目标文件构造的模块名称为hello.ko.如果我们想由两个源文件(比如file1.c和file2.c )构造出一个名称为module.ko的模块,则正确的makefile可如下编写:obj-m := module.omodule-objs := file1.o file2.o为了让上面这种类型的makefile文件正常工作,必须在大的内核构造系统环境中调用他们。假设读者的内核源码数位于~/kernel-2.6目录,用来建立你的模块的make命令(在包含模块源代码和makefile的目录下键入)应该是:make -C ~/kernel-2.6 M=`pwd` modules这个命令首先是改变目录到用-C选项指定的位置(即内核源代码目录),其中保存有内核的顶层makefile文件。这个M=选项使makefile在构造modules目标前,返回到模块源码目录。然后,modules目标指向obj-m变量中设定的模块,在上面的例子里,我们将该变量设置成了module.o。上面这样的make命令对于多个文件的编译显得不是很方便,于是内核开发者就开发了一种makefile方式,这种方式使得内核树之外的模块构造变得更加容易。代码清单1.4展示了makefile的编写方法:代码清单1.4 makefileifeq ($(KERNELRELEASE),)KERNELDIR ?= /source/linux-2.6.13PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions.PHONY: modules modules_install cleanelseobj-m := hello.oendif我们再次看到了扩展的GNU make语法在起作用。在一个典型的构造过程中,这个makefile将被读取两次。当从命令行中调用这个makefile ,它注意到KERNELRELEASE变量尚未设置。我们可以注意到,已安装的模块目录中存在一个符号连接,它指向内核的构造树,这样这个makefile就可以定位内核的源代码目录。如果读者时间运行的内核并不是要构造的内核,则可以在命令行提供KERNELDIR=选项或者设置KERNELDIR环境变量,或者修改makefile中设置KERNELDIR的那一行。在找到内核源码树,这个makefile会调用default:目标,这个目标使用先前描述过的方法第二次运行make命令(注意,在这个makefile里make命令被参数化成$(MAKE)),以便运行内核构造系统。在第二次读取makefile时,它设置了obj-m,而内核的makefile负责真正构造模块。这种构造模块的机制看起来很繁琐,可是,一旦我们习惯了使用这种机制,则会欣赏内核构造系统带给我们的便利。需要注意的是,上面makefile并不完整,一个真正的makefile应包含通常用来清除无用文件的目标,安装模块的目标等等。一个完整的例子可以参考例子代码目录的makefile。