第 7 章 块设备驱动程序
7.2 块设备驱动开发实例
7.2.6 S3C2410 SDI 接口驱动分析
7.2.6.2 SDI 接口驱动方法
return driver_register(&s3c2410sdi_driver);
}
其调用 driver_register 函数来注册 SDI 接口驱动,其中传递参数 s3c2410sdi_driver 被定 义为 SDI 接口驱动,它的定义如下:
static struct device_driver s3c2410sdi_driver = {
.name = "s3c2410-sdi", .bus = &platform_bus_type, .probe = s3c2410sdi_probe, .remove = s3c2410sdi_remove, };
通过上面代码可以看出,它定义了 SDI 接口驱动的两个方法,分别是 probe 和 remove。
这两个函数的作用类似于 MMC 设备驱动中的 probe 和 remove 方法。这里 probe 方法是由 s3c2410sdi_probe 函数来实现,主要完成 SDI 接口的初始化工作,包括 MMC host 的初始化,
中断的初始等。由于篇幅的关系,这里不再列举它的实现代码,读者可以参考附件光盘中的 参 考 代 码 。 此 外 , remove 方 法 是 由 s3c2410sdi_remove 函 数 来 完 成 , 用 它 来 实 现 与 s3c2410sdi_probe 函数相反功能的操作。
最后再看一下 SDI 接口驱动的卸载程序,它的实现也非常简单,调用 driver_unregister 函数来实现 SDI 接口驱动的卸载功能,具体代码如下:
static void __exit s3c2410sdi_exit(void) {
driver_unregister(&s3c2410sdi_driver);
}
7.2.6.2 SDI 接口驱动方法
在分析 SDI 接口驱动方法的实现之前,首先看一下 SDI 接口驱动方法的定义,它是由 s3c2410sdi_ops 变量定义的,该变量的定义如下:
static struct mmc_host_ops s3c2410sdi_ops = { .request = s3c2410sdi_request,
.set_ios = s3c2410sdi_set_ios, };
其中 mmc_host_ops 结构定义在<include/linux/mmc/host.h>文件中,用于定义 MMC host 驱 动 的方 法 ,该 结构 中 只定 义了 request 和 set_ios 两 个 方 法 。其 中 request 方 法 由 s3c2410sdi_request 函数实现,主要完成 MMC 所有请求命令相关的处理功能,包括数据的 读/写等实现。另外 set_ios 方法由 s3c2410sdi_set_ios 函数实现,主要用于设置 MMC 电源的
开/关,以及开启 MMC 时钟等功能。由于 SDI 接口驱动方法实现代码较长,并且也不是我 们研究的重点,所以这里只是做一个简单的介绍,有兴趣的读者可以分析附件光盘中的提供 的参考代码。
7.2.7 配置和编译驱动程序
与第 6 章中介绍的触摸屏设备驱动类似,需要相应的配置才能进行正确的编译。由于 MMC 设备驱动内核中已经提供,只不过内核中提供的驱动是应用于 X86 平台的,而我们这 里开发的目标平台是 ARM,所以需要一定的修改。本实例将源程序放在了 driver/mmc 目录 下。同时需要修改该目录下 Kconfig 配置文件,添加以下内容到该文件:
config MMC_S3C2410
tristate "Samsung S3C2410 Multimedia Card Interface support"
depends on ARCH_S3C2410 && MMC help
This selects the Samsung S3C2410 Multimedia Card Interface support.
If unsure, say N.
添加以上内容后,在用 make menuconfig 配置内核时会增加关于 S3C2410 的 MMC 选项,
此外,还需要修改 driver/mmc/Makefile 文件,添加下面一行内容:
obj-$(CONFIG_MMC_S3C2410) += s3c2410mci.o
修改完配置文件和 Makefile 文件,最后重新配置内核选项,将触摸屏选项以模块形式 添加或直接添加到内核,然后就可以编译该驱动程序了。
7.3 本章小结
本章讲述了另一类常见的 Linux 设备驱动程序——块设备驱动,首先讲述了块设备相关 的重要数据结构,包括 block_device_operations,gendisk,request 结构,并且讲述了块设备 中非常重要的请求处理函数;然后重点讲述了一个块设备驱动的典型实例——MMC 驱动开 发,读者通过学习该设备驱动程序将对块设备驱动开发有深入的了解,此外对 MMC/SD 的 工作原理有一定的了解。下一章将介绍另一类常见的 Linux 设备驱动程序——网络设备。
7.4 常见问题
1.字符设备与块设备之间的主要区别?
参考答案:字符设备与快设备的最大不同就是:字符设备传输数据是按字节的大小传输,而 块设备是以块为单位传输,通常块的大小是 1024 字节。其次字符设备通常是直接作用于 I/O 端口的,而块设备是间接作用的,因为它与内核之间是有缓冲区的。
2.块设备中请求处理函数的作用?
参考答案:请求函数是块设备驱动程序的核心,实际的工作中,设备的启动,以及对设备的 读取都是在 request 函数中实现的。使用请求函数的原因是块设备利用一块系统内存作缓冲 区,当用户进程对设备请求能满足用户的要求时就返回请求的数据,如果不能,就调用请求 函数来进行实际的 I/O 操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的