操作系统实验指导书
实验9设备管理实验
1.实验目的
熟加深对设备管理的理解;进一步认识设备驱动程序的实质。
2.实验设备
计算机、安装了Linux的虚拟机。
3. 实验内容及要求
(1)编写一个简单的字符设备驱动程序;
(2)再编写一个测试程序来测试用户所编写的字符设备驱动程序。
4.实验步骤
4.1字符类型设备的驱动程序
(1)字符设备驱动程序要用到的数据结构定义: struct device_struct
{
const char *name; struct file_operations *chops; }; static struct device_struct chrdevs[MAX_CHRDEV]; typedef struct Scull_Dev
{
void **data; int quantum; // 当前容量的大小。 int qset; // 当前数组的大小。 unsigned long size; unsigned int access_key;
// 由sculluid 和scullpriv 使用的存取字段。 unsigned int usage; //当字符设备正使用时加锁。
struct Scull_Dev *next; // 指向下一字符设备
} scull;
字符设备的结构device_struct即字符设备的开关表。当字符设备注册到内核后,字符设备的名字和相关操作被添加到device_struct结构类型的chrdevs全局数组中,称chrdevs为字符设备的开关表。
28
操作系统实验指导书
下面以一个简单的例子说明字符设备驱动程序中字符设备结构的定义:(假设设备名为scull)
**** file_operations结构定义如下,即定义chr设备的_fops **** static int scull_open(struct inode *inode,struct file *filp); //打开字符设备。
static int scull_release(struct inode *inode,struct file*filp); //释放字符设备。
static ssize_t scull_write(struct inode *inode,struct file *filp, const char *buffer,int count); //将数据送往字符设备。 static ssize_t scull_read(struct inode *inode,struct file *filp, char *buffer,int count); //从字符设备读出数据,写入用户空间。
static int scull_ioctl(struct inode *inode,struct file *filp,unsigned long int cmd,unsigned long arg);
//字符设备的控制操作。
struct file_operations chr_fops = {
NULL, // seek,改变字符设备的操作位置。 scull_read, // read,字符设备的读操作。 scull_write, // write,字符设备的写操作。
NULL, // readdir,读取某个子目录中的内容。
NULL, // poll,允许应用程序响应来自字符设备的事件。 scull_ioctl, // ioctl,字符设备的控制操作。 NULL,
// mmap,字符设备地址空间到用户地址空间的映射。 scull_open, // open,字符设备的打开操作。
NULL, // flush,冲掉缓冲区的数据,对字符设备无用。 scull_release, // release,字符设备的释放操作。
NULL, // fsync,同步内存与磁盘上的数据状态,把输出
缓冲区里尚未写到磁盘的数据写出去。 NULL, // fasync,改变字符设备行为。
NULL, // check media change,检查自上次操作后, 介质(软盘和CD-ROM)是否更换。 NULL, // revalidate,若更换了介质,则更新信息。 NULL // lock,锁定字符设备操作。 (2)字符设备驱动程序入口点
字符设备驱动程序入口点主要包括初始化字符设备、字符设备的I/O调用和中断。在引导系统时,每个设备驱动程序通过其内部的初始化函数init()对其控制的设备及其自身初始化。字符设备初始化函数为chr_dev_init(),包含在/linux/drivers/char/mem.c中,它的主要功能之一是在内核中登记设备驱动程序。具体调用是通过register_chrdev()函数。
register_chrdev()函数定义如下: #include
(unsigned int major,const char *name,struct file_operation *fops);
29
操作系统实验指导书
用于字符设备的I/O调用主要有:open()、release()、read()、write()和ioctl()。 open()函数
static int scull_open(struct inode *inode,struct file *filp) {
?? ??
MOD_INC_USE_COUNT; return 0; }
release()函数
static int scull_release(struct inode *inode,struct file *filp) {
?? ??
MOD_DEC_USE_COUNT; return 0; }
函数scull_write()的流程图如图9.1所示。
函数scull_read()的流程图如图9.2所示。
30
操作系统实验指导书
scull_ioctl()的流程图如图9.3所示。
31
函数 操作系统实验指导书
函数scull_release()的流程图如图9.4所示。
32