金钟国宋智孝粉红:linux驱动入门(转)
来源:百度文库 编辑:偶看新闻 时间:2024/04/28 20:28:30
linux驱动入门(转)
用来防止用户程序直接访问内核中关键性数据结构和硬件设备是驱动程序的主要目的之一,所以,一个设计精良的驱动通常应该隐藏了硬件的复杂性和多变性。例如,一个程序写数据到磁盘时,只需要打开一个文件并执行写命令即可,而不必了解磁盘中的每个扇区的大小是512字节或者是1024字节,细节性的问题则交由驱动程序处理。此外,驱动程序还可以隐藏硬件的多变性(可能来自于不同厂家,甚至同一厂家不同型号)并给用户提供一个统一的访问接口。这也是Unix/Linux信条之一“一切皆文件”的赖以存在的基础。1、可加载模块(loadable module)Linux采取了“宏内核”的结构,并附带一个设计精良的接口以实现在系统运行时动态的加载或移除驱动模块。这种富有弹性的设计,为最终用户,甚至也为程序的开发过程带来了极大的便利。基于此功能,在开发驱动的过程中,开发人员不用在每一次驱动程序的修改后重启系统就能对其进行测试。当然,驱动程序也可以以静态方式编译进内核,而且,许多关键性的驱动也需要这样编译。比如,对于无盘工作站而言,由于系统启动最初就需要通过网卡从其它共享文件系统中加载所需的资源,此时必须将网卡驱动静态编译进内核,因为可加载模块都是系统启动后才进行动态加载。通常使用启动脚本装载动态驱动模块,当然,也可以使用相关命令在需要时再进行加载。此外,内核也可以在某个服务需要某个特殊模块时自动请求加载所需的模块。虽然前文中一直称驱动程序为可加载模块,但内核模块并没有确定的术语,硬件驱动(device drivers)、可加载内核模块(LKM,loadable kernel modules)、内核模块(kernel modules)、可加载模块(loadable modules)、驱动模块(driver modules)和模块(modules)等都常用来表示可动态加载进内核的硬件驱动,后文中则不加区别的使用它们。2、硬件驱动结构尽管Linux/Unix驱动程序模块的开发一直处于不断地演进中,但其基本结构并没有太大改变。硬件设备大体上可分为两大类:字符设备和块设备。- 字符设备是以串行流式数据序列进行数据存取的设备,字符设备驱动负责实现这种行为;通常字符设备驱动至少需要实现 open、 close、read和 write等系统调用。常见的字符设备如控制台( /dev/console )和串口( /dev/ttyS0 )。
- 块设备通常是可编址的,其数据存取也通常以固定大小的数据块进行,但数据块的存入位置则可能是随机的。在大部分Unix系统中, 一个块设备传送一个或多个长度经常是512字节(或者其2次幂倍)的整块数据,但Linux允许一次传递任意字节的数据,其跟字符设备的区别仅在于内核内部对数据的管理方式上和驱动程序的接口实现上有所不同。磁盘是常见的块设备。
/* Example Minimal Character Device Driver */
#include
static int __init hello_init(void)
{
printk("Hello Device Driver World!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk("Goodbye, Cruel World!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Marion");
MODULE_DESCRIPTION("An example of device driver!");
MODULE_LICENSE("GPL");
/* End the hello*/
(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/
# 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()宏来实现。其工作方式类似前面的加载过程。
linux的 入门
linux 入门问题
linux入门的书籍
怎么才能更容易入门LINUX系统?
学习UNIX/LINUX怎样入门
linux入门电子书到哪里能下载
Linux怎么样才可以入门啊~~
能否推荐linux入门的教程?
linux下网卡驱动
linux 的网卡驱动
linux 安装显卡驱动
关于linux网卡驱动
D101GGC 装 linux驱动
安装Redhat linux 9.0遇到的新问题(驱动)
Linux用装驱动吗?
linux下的硬件驱动
ati x800gto驱动 for linux
富士施乐linux驱动
驱动For linux 哪里有?
大家给介绍一个入门级的linux版本
LINUX内核入门用那本书比较好
有人愿意学习LINUX入门吗?加QQ379576382
红旗LINUX的驱动能用到LINUX里吗?
linux下串口驱动如何实现?