文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>linux驱动入门(转)

linux驱动入门(转)

时间:2011-02-22  来源:Mingxx

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("Marion");
MODULE_DESCRIPTION("An example of device driver!");
MODULE_LICENSE("GPL");
/* End the hello*/

上面这个例子虽然短小,但却充分具备了让内核加载或卸载以及初始化或退出的程序结构。 不同于标准的二进制可执行程序,设备驱动是一种特殊的二进制模块,它不能简单的通过shell执行。2.6系列内核的模块通常是内核对象 (kernel object)格式,这些模块在完成编译后通常以.ko为后缀。创建内核对象步骤和编译选项非常复杂,本文仅描述其大体过程,以帮助读者简单了解内核对象 的构建步骤。 4、模块构建基础 驱动程序的编译必须针对于特定的内核进行。尽管在另一个不同的内核上编译的驱动模块也可以运行,但如果不确定此模块是否依赖于编译时的内核的某 些特性时,将会给后来运行过程来带来很大风险。因此,最稳妥的办法还是基于某内核自身的代码树(Source tree)构建内核对象,这也可以保证在开发人员改变了内核的配置后,驱动也会在新配置的内核的基础上进行重建。如果需要在不同的内核上构建内核对象,则 必须确保驱动程序构建时的配置所使用的编译选项、引用内核头文件的位置和内核配置选项在驱动实际运行的内核上做了同样的配置。 为了基于前文中的例子构建驱动程序,大致要经过以下几个步骤: (1)在内核源码目录中的.../driver/char目录中创建一个名为examples的子目录;
(2)在内核配置文件中添加一个菜单项,以允许在编译内核时可以选择编译examples(编译进内核或编译成模块);
(3)在.../driver/char/Makefile文件中添加一个子目录项examples以对应于前述第二步骤的菜单项;
(4)为.../driver/char/examples目录创建一个makefile文件,在其中为前述第二个步骤中创建的菜单项添加hello.o模块对象以进行编译;
(5)添加驱动程序源码; 下面详细描述前面的几个步骤: 首先,在内核源码目录的.../driver/char目录中创建examples子目录,而后再创建两个文件:一个是前面例子中的驱动源码,一个是为其创建的makefile文件。makefile文件非常简单,其内容只有如下一行即可:
obj-$(CONFIG_EXAMPLES) += hello.o
添加菜单项至内核配置工具的过程可能稍有些绕。首先需要在.../driver/char/Kconfig文件中添加一个"config"项以启用前文中的examples配置项。添加位置是menu "Character devices"一行的后面,添加内容如下: config EXAMPLES
tristate "Enable Examples"
default m
---help---
   Enable compilation option for driver examples
而后回到内核目录中,运行内核编译命令make gconfig(需要xwindow的支持)后,可以Device Drivers->Character drivers找到我们添加的“Enable Examples”项,默认为“-”(通过default项指定),即编译为内核模块。如果指定为“对号”则表示以静态方式编译进内核;如果为空,则表示 不编译此项。如下图所示: 接下来还需要在.../drivers/char/Makefile文件中添加一个选项,以指示内核编译程序在我们选择了 CONFIG_EXAMPLES时会到examples子目录中编译hello1模块。这需要在 “obj-$(CONFIG_IPMI_HANDLER)      += ipmi/”一行附近添加如下行: obj-$(CONFIG_EXAMPLES)          += examples/ 至此,此示例驱动构建基础结构已经完成,而且会在内核编译过程中自动选择此项进行编译了。在执行完前面的"make gconfig"命令后,此时再执行如下命令即可完成驱动模块的编译。 # make modules

CHK     include/linux/version.h
CHK     include/linux/utsrelease.h
CC [M] drivers/char/examples/hello.o
Building modules, stage 2.
MODPOST
CC      drivers/char/examples/hello.mod.o
LD [M] drivers/char/examples/hello.ko
如果您的编译过程显示有如上信息,则表示内核模块编译完成。接下来就可以使用如下命令安装刚刚编译完成的内核模块:
# make modules_install
使用此种方式安装时,安装过程会重新安装所有已编译的内核模块,包括此前编译的其它模块,而这并非是必须的。 在一个通过标准方式安装的Linux系统上,内核模块通常位于/lib/modules/<kernel-version>/…之 中,其中的<kernel-version>即当前系统运行中的内核版本号,并且此目录的结构组织方式跟内核源代码树的结构是类似的。通常使 用“make modules_install”命令安装的模块就位于此目录中。因此,在单独安装某个或某些内核模块时,可以通过在此目录中创建跟编译时内核源码树中一 样的内核模块驱动相关的目录,并把编译完成的*.ko文件复制到新建的对应目录中来实现。 5、加载/卸载内核模块 安装完成后,便可以手动加载或卸载这些模块了,这可以使用modprobe实现。我们首先去加载hello模块。 # modprobe hello
# tail -1 /var/log/messages
Sep 14 22:06:23 localhost kernel: Hello Device Driver World!
此模块在加载时会调用模块初始化函数,程序中使用module_init()宏(macro)来指定的模块初始化函数,如 module_init(hello_init)。在此模块中,初始化函数仅用来打印一行信息至系统日志,信息内容是在hello_init()中定义好 的。在实际驱动程序编写中,初始化函数常用来执行资源分配及硬件设备初始化。 接下来可以使用lsmod命令以格式化列表的形式显示系统中加载的所有模块。如果其中有hello模块出现则表示前面的加载是成功的。例如: # lsmod
Module                  Size Used by
hello                   5632 0
ipv6                  274208 18
autofs4                25092 2
i2c_core               25344 1 i2c_piix4
…………
其中Used by一列表示当前模块正在被使用的信息,以及依赖于当前模块的其它模块。如最后一行表示i2c_piix4模块依赖于i2c_core模块。 内核模块的卸载可以通过使用modprobe的-r选项来实现。 # modprobe -r hello
# tail -1 /var/log/messages
Sep 14 22:14:33 localhost kernel: Goodbye, Cruel World!
hello模块退出时会调用exit例行函数,这使用module_exit()宏来实现。其工作方式类似前面的加载过程。 
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载