好文档 - 专业文书写作范文服务资料分享网站

块设备驱动课程设计 可编辑

天下 分享 时间: 加入收藏 我要投稿 点赞

Word可编辑

一、 课程设计目的

通过操作系统设计可以学习操作系统的原理和设计技巧。本次课程设计所选的是设备驱动程序,通过此次课程设计可以掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法。

具体为:掌握设备驱动程序的编写、编译和装载、卸载方法,了解设备文件的创建,并知道如何编写测试程序测试自己的驱动程序是否能够正常工作。

二、 课程设计内容与要求

1、 编写一个简单的块设备驱动程序,该块设备包括打开、IO控制与释放三个基本操作。 2、 编写一个测试程序,测试字符设备驱动程序的正确性。

3、 要求在实验报告中列出Linux内核的版本与内核模块加载过程

三、 系统分析与设计

1、 系统分析

所有设备控制操作都是由与被控制设备相关的代码来完成的,这段代码就叫做驱动程序;而一个块驱动程序主要通过传输固定大小的随机数据来访问设备。

这次的驱动程序只是编写一个虚拟程序,并不需要去驱动硬件,通过一系列的注册函数,使内核知道设备的存在。

内核模块的编写,首先是进行编写函数入口,对函数进行加载,module_init(),然后到加载函数中编写操作。

块设备的操作主要包括:设备的打开、IO控制与释放;

最后,对模块进行卸载,调用module_exit(),在卸载模块中对一些内存进行释放。

2、 系统设计

2.1 概要设计:

2.1.1 函数加载模块:

在函数加载模块中,实现对块设备的注册、对sbull_dev数据结构的初始化;对请求队列的分配;以及设置扇区大小和分配、初始化及安装相应的gendisk结构。

函数声明:static int __init sbull_init(void);

2.1.2 函数操作模块: 设备打开模块:

函数声明:static int sbull_open(struct inode *inode,struct file *filp);

IO控制模块:

函数声明:static int sbull_release(struct inode *inode,struct file *filp);

设备释放模块:

函数声明:static int sbull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);

2.1.3 函数卸载模块:

在函数卸载模块中实现对申请内存的释放和对请求队列的删除。 函数声明:static void __exit sbull_exit(void);

Word可编辑

2.2 详细设计:

2.2.1 函数加载模块具体功能实现:

首先,对块设备驱动程序进行注册, int register_blkdev(unsigned int major,const char *name);,获得主设备号。

然后,对sbull_dev数据结构进行内存的分配和初始化工作: Devices = kmalloc(sizeof(struct sbull_dev),GFP_KERNEL); memset(Devices,0,sizeof(struct sbull_dev)); Devices->size = nsectors * hardsect_size; Devices->data = vmalloc(Devices->size); memset(Devices->data,0,Devices->size);

对自旋锁进行分配和初始化: spin_lock_init(&Devices->lock);

分配请求队列:

Devices->queue = blk_init_queue(sbull_request,&Devices->lock);

设置扇区大小:

blk_queue_logical_block_size(Devices->queue, hardsect_size);

分配、初始化及安装相应的gendisk结构 Devices->gd = alloc_disk(1);

Devices->gd->major = sbull_major; Devices->gd->first_minor = 0; Devices->gd->fops = &sbull_ops;

Devices->gd->queue = Devices->queue; Devices->gd->private_data = Devices; strcpy(Devices->gd->disk_name,\

set_capacity(Devices->gd,nsectors * (hardsect_size / KERN_SECTOR_SIZE)); 最后,调用add_disk()结束设置过程。 add_disk(Devices->gd);

2.2.2 函数操作模块的具体实现:

在块设备驱动程序中,主要有设备的打开、IO控制与释放三个基本操作。而这三个操作是通过block_device_operations结构中的sbull_open、sbull_release、sbull_ioctl实现的。

其中,因为此次的块设备驱动程序只是虚拟内存,而没有操作实际的硬件,在打开和、释放操作中并没有具体的功能。

而在IO控制中,主要实现了得到主设备号、得到扇区总数、得到块设备大小的操作功能。

在IO控制中,首先对参数进行了检测: //检测命令的有效性

if(_IOC_TYPE(cmd) != SBULL_IOC_MAGIC) { return -EINVAL; }

if(_IOC_NR(cmd) > SBULL_IOC_MAXNR) {

Word可编辑

return -EINVAL; }

//根据命令类型,检测用户空间是否可以访问 if(_IOC_DIR(cmd) & _IOC_READ) { err = !access_ok(VERIFY_WRITE,(void*)arg,_IOC_SIZE(cmd)); }

else if(_IOC_DIR(cmd) & _IOC_WRITE) { err = !access_ok(VERIFY_READ,(void*)arg,_IOC_SIZE(cmd)); } if(err) { return -EFAULT; }

然后,根据传递参数cmd的命令来实现具体功能: switch(cmd) { case SBULL_IOCGETMAJOR: //得到主设备号 ret = __put_user(sbull_major,(int __user*)arg); break; case SBULL_IOCGETSECTORS: //得到扇区总数 ret = __put_user(nsectors,(int __user*)arg); break; case SBULL_IOCGETSIZE: //得到块设备大小 ret = __put_user(nsectors * hardsect_size,(int __user*)arg); break; default: return -EFAULT; }

2.2.3 函数卸载模块具体实现: 对gendisk进行释放: if(dev->gd) { del_gendisk(dev->gd); put_disk(dev->gd); }

对队列进行清除: if(dev->queue) { blk_cleanup_queue(dev->queue); printk(\}

清除设备信息:

Word可编辑

if(dev->data) { vfree(dev->data); printk(\}

对块设备进行注销:

unregister_blkdev(sbull_major,\对设备内存进行释放: kfree(Devices);

3、 模块设计

3.1 装载模块

3.2 设备操作模块:打开、释放、IO控制 3.3 卸载模块

3.4程序模块之间的层次关系:

模块装载 打开 释放 IO控制 模块卸载

4、 数据结构说明

4.1 块设备操作接口结构

static struct block_device_operations sbull_ops = { .owner = THIS_MODULE, .open = sbull_open, .release= sbull_release, .ioctl = sbull_ioctl, };

4.2 块设备结构描述 struct sbull_dev { int size; //以扇区为单位设备的大小 u8 *data; //数据数组(存储磁盘数据队列) struct request_queue *queue; //请求队列(用于互斥) struct gendisk *gd; //gendisk结构 spinlock_t lock; //设备自旋锁 };

Word可编辑

四、 系统测试与调试分析

4.1 系统测试: 测试方法:黑盒测试 测试技术:功能测试 测试用例表:

测试名称 块设备驱动程序 测试块设备驱动程序能否正常工作 功能测试 黑盒测试 块设备的IO控制操作 将块设备驱动程序加载,然后执行test程序测试 块设备驱动程序加载后,将在/proc/devices中sbull的主设备号与test测试终端输出的主设备号进行对比,判断IO控制的正确性。 251 与预期相符 测测试目的 试说明 测试技术 测试方法 测试内容 测测试步骤 试用测试数据 例 预期结果 测试结果 4.2 调试分析: 4.2.1 最初始,对块驱动程序设计并不了解,不知该从何下手。 解决方法:通过上网查资料和向接触过Linux的同学请教,大致了解了使用Linux编程的基础,然后,通过学习《Linux驱动程序》这本书,学习到驱动程序并不像应用程序那样,从主函数开始进行的,而是一种模块化的设计方法。通过模块入口函数进行加载,然后通过各自的结构调用所需要的模块,完成相应的操作后,通过卸载模块来结束程序。

4.2.2 在编写程序过程中,因为内核版本的问题,许多参考书中的函数不能正常工作。 解决方法:通过上网查资料,对因版本变动而不能用的几个函数,有的找到了最新版本的代替者,有的是通过定义相应的宏来解决的。

五、 用户手册

5.1 使用平台:Linux系统 版本为ubantu10.10 5.2 内核版本:2.6.35 5.3 操作步骤: 5.3.1 编译:make

5.3.2 文件加载:insmod sbull.ko 5.3.3 用lsmod查看:lsmod

块设备驱动课程设计 可编辑

Word可编辑一、课程设计目的通过操作系统设计可以学习操作系统的原理和设计技巧。本次课程设计所选的是设备驱动程序,通过此次课程设计可以掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法。具体为:掌握设备驱动程序的编写、编译和装载、卸载方法,了解设备文件的创建,并知道如何编写测试程序测试
推荐度:
点击下载文档文档为doc格式
6kuhm48bni5nrap1rg1l036aw5tvqk00xpx
领取福利

微信扫码领取福利

微信扫码分享