中南大学
字符设备驱动程序
课程设计报告
姓名:王学彬
专业班级:信安1002班
学号:0909103108
课程:操作系统安全课程设计
指导老师:张士庚
一、课程设计目的
1.了解Linux字符设备驱动程序的结构;
2.掌握Linux字符设备驱动程序常用结构体和操作函数的使用方法;
3.初步掌握Linux字符设备驱动程序的编写方法及过程;
4.掌握Linux字符设备驱动程序的加载方法及测试方法。
二、课程设计内容
5.设计Windows XP或者Linux操作系统下的设备驱动程序;
6.掌握虚拟字符设备的设计方法和测试方法;
7.编写测试应用程序,测试对该设备的读写等操作。
三、需求分析
3.1驱动程序介绍
驱动程序负责将应用程序如读、写等操作正确无误的传递给相关的硬件,并使硬件能够做出正确反应的代码。驱动程序像一个黑盒子,它隐藏了硬件的工作细节,应用程序只需要通过一组标准化的接口实现对硬件的操作。
3.2 Linux设备驱动程序分类
Linux设备驱动程序在Linux的内核源代码中占有很大的比例,源代码的长度日益增加,主要是驱动程序的增加。虽然Linux内核的不断升级,但驱动程序的结构还是相对稳定。
Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三种。字符设备是指在存取时没有缓存的设备,而块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access)。典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD-ROM等。
网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据传递。系统有支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。
3.3驱动程序的结构
驱动程序的结构如图3.1所示,应用程序经过系统调用,进入核心层,内核要控制硬件需要通过驱动程序实现,驱动程序相当于内核与硬件之间的“系统调用”。
图3.1驱动程序的结构
3.3.1 内核模块
内核模块是Linux内核的重要组成要素,内核模块能在Linux系统启动之后能够动态进行装载和卸载,因此不需对内核进行重新编译或重启系统就可将内核的一部分替换掉,Linux 内核的所有设备驱动,文件系统,网络协议等可做成模块的形式来提供。在所有的模块中需记录编译的内核版本信息,并与当前执行的内核版本一致。即,模块具有版本依赖性,如果不一样就会出错,当然可以在模块程序中的include
内核模块程序与一般应用程序之间主要不同之处是,模块程序没有main()函数,模块程序在装载时调用init_module(void)函数添加到内核中,在卸载时调用void cleanup_module( )函数从内核中卸载。另外一个应用程序从头到尾只执行一个任务,但一个模块可以把响应未来请求的事务登记到内核中,然后等待系统调用,内核模块程序结构如图3.2所示。
insmod
rmmod
图3.2内核模块程序结构
3.4主、从设备号
应用程序通过设备文件系统(devfs)的名字(或节点)访问硬件设备,所有的设备节点在/dev目录下。利用mknod命令生成设备文件系统的节点,但只有超级用户才能生成设备文。Mknod命令必须要有设备名和设备类型,主设备号(Major Number),次设备号(Minor Number)等3个参数。主设备号用于内核区分设备驱动,次设备号用于设备驱动区分设备。一个设备驱动可能控制多个设备。新的设备驱动要有新的主设备号。在内核源代码的Documentation/devices.txt中定义了所有设备的主设备号。在创建设备的时候不要与常用的设备好冲突。
3.5驱动程序基本框架
如果采用模块方式编写设备驱动程序时,通常至少要实现设备初始化模块、设备打开模块、数据读写与控制模块、中断处理模块(有的驱动程序没有)、设备释放模块和、设备卸载模块等几个部分。
3.6重要结构体
打开的设备在内核内部由file结构标识,内核使用结构访问驱动程序函数。结构是一个定义在
struct
{
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsignedint (*poll) (struct file *, structpoll_table_struct *);
int (*ioctl) (structinode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, structvm_area_struct *);
int (*open) (structinode *, struct file *);
int (*flush) (struct file *);
int (*release) (structinode *, struct file *);
int (*fsync) (struct file *, structdentry *, intdatasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct *);
ssize_t (*readv) (struct file *, conststructiovec *, unsigned long, loff_t *);
ssize_t (*writev) (struct file *, conststructiovec *, unsigned long, loff_t *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long,
unsigned long, unsigned long);
}
四、总体设计
1.在对设备驱动的有了充分的学习后,字符设备的驱动程序我们确定采用虚拟设备的驱动程序实现
2.实现平台为linux系统,借助linux内核对设备驱动程序的抽象结构体和内核函数3.要明确定义虚拟设备的的设备结构体
4.实现模块加载函数和卸载函数
5.实现open(),close(),lseek(),write(),read()函数
6.因源码包中已包含makefile,故利用make命令交叉编译memdev.c、test.c(已修改)等2个文件
7.模块的动态加载,以及/dev/memdev节点的创建
8.运行test程序测试,观察结果
五、详细设计
1.在对设备驱动的有了充分的学习后,字符设备的驱动程序我们确定采用虚拟设备的驱
动程序实现,其中确定该设备主要的结构体为:
struct mem_dev
{
char *data;
unsigned long size;
};
2.实现平台为linux系统,借助linux内核对设备驱动程序的抽象结构体和内核函数,
要调用的内核抽象体有:
struct cdev cdev; //表示一个字符设备的内核设备的抽象体
static const struct mem_fops =
{
.owner = THIS_MODULE,
.llseek = mem_llseek,
.read = mem_read,
.write = mem_write,
.open = mem_open,
.release = mem_release,
};
3.要明确定义虚拟设备的的设备结构体
struct mem_dev
{
char *data;
unsigned long size;
};
4.实现模块加载函数和卸载函数
static int memdev_init(void){}
static int memdev_exit(void){}
5.实现open(),close(),lseek(),write(),read()函数
int mem_open(struct inode *inode, struct file *filp);
int mem_release(struct inode *inode, struct file *filp);
static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos);
static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
static loff_t mem_llseek(struct file *filp, loff_t offset, int whence);
6.编译模块,模块的动态加载,以及/dev/memdev节点的创建,mknod /dev/memdev
结果如下:
模块编译完,后我们需要把内核模块动态加载到内核,用命令insmod memdev.ko加载,用命令lsmod显示加载成功,结果为:
7运行test程序测试,观察结果
我们看到我们用应用程序成功的写入了”xiaotian!”并出设备中成功的读出,证明我们的驱动程序运行完美。
六、关键源代码注解
/*设备驱动模块加载函数*/
static int memdev_init(void)
{
int result;
int i;
dev_t devno = MKDEV(mem_major, 0); /*通过主设备号得到dev_t类型的设备号*/
/* 静态申请设备号*/
if (mem_major)
result = register_chrdev_region(devno, 2, "memdev");
else/* 动态分配设备号 */
{
result = alloc_chrdev_region(&devno, 0, 2, "memdev");
mem_major = MAJOR(devno);
}
if (result < 0)
return result;
/*初始化cdev结构*/
cdev_init(&cdev, &mem_fops);//使cdev与mem_fops联系起来
cdev.owner = THIS_MODULE;//owner成员表示谁拥有这个驱动程序,使“内核引用模块计数”加1;THIS_MODULE表示现在这个模块被内核使用,这是内核定义的一个宏
cdev.ops = &mem_fops;
/* 注册字符设备 */
cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);
/* 为设备描述结构分配内存*/
mem_devp = kmalloc(MEMDEV_NR_DEVS*sizeof(struct mem_dev), GFP_KERNEL);//目前为止我们始终用GFP_KERNEL
if (!mem_devp) /*申请失败*/
{
result = - ENOMEM;
goto fail_malloc;
}
memset(mem_devp, 0, sizeof(struct mem_dev));
/*为设备分配内存*/
for (i=0; i < MEMDEV_NR_DEVS; i++)
{
mem_devp[i].size = MEMDEV_SIZE;
mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);//分配出来的地址存在此
memset(mem_devp[i].data, 0, MEMDEV_SIZE);
}
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return result;
}
/*模块卸载函数*/
static void memdev_exit(void)
{
cdev_del(&cdev); /*注销设备*/
kfree(mem_devp); /*释放设备结构体内存*/
unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*释放设备号*/
}
七、心得体会
通过本次操作系统的课程设计,我经历了从选定课题,在到查资料自学习,到写程序和测试,可以说是一个艰难又具有挑战的过程,在这半个的月的时间里,我翻阅了大概两本关于嵌入式设备驱动开发的书籍,通过了解linux内核的结构到相关的内核结构和函数,在到建立一个驱动程序的模型,可以说是个漫长的过程,这是动力,在掌握了内核相关的数据结构和函数后,我开始建立我自己的驱动程序模型,对重点函数进行详细的学习后,比较open(),read(),write()等,我开始搭建这样一个虚拟的字符设备程序,给我最大的体会就是自学习能力的重要性,在拿到一个课题后我发现我要学习的新知识很多,而且是在很短的时间内,通过参阅资料,总算完成了任务。很感谢张士庚老师的认真指导与检查,让我对知识理解的更深了一步,在这么热了天就跑新校图书馆有好多次。总算课程设计的圆满的结束了,但学无止境,一起努力吧。
八、参考文献
(1)张尧学等. 计算机操作系统教程. 清华大学出版社,2006
(2)陈向群等. Windows内核实验教程. 机械工业出版社,2004
(3)罗宇等. 操作系统课程设计. 机械工业出版社,2005
中南大学 字符设备驱动程序 课程设计报告 姓名:王学彬 专业班级:信安1002班 学号:0909103108 课程:操作系统安全课程设计 指导老师:张士庚 一、课程设计目的 1.了解Linux字符设备驱动程序的结构; 2.掌握Linux字符设备驱动程序常用结构体和操作函数的使用方法; 3.初步掌握Linux字符设备驱动程序的编写方法及过程; 4.掌握Linux字符设备驱动程序的加载方法及测试方法。 二、课程设计内容 5.设计Windows XP或者Linux操作系统下的设备驱动程序; 6.掌握虚拟字符设备的设计方法和测试方法;
7.编写测试应用程序,测试对该设备的读写等操作。 三、需求分析 3.1驱动程序介绍 驱动程序负责将应用程序如读、写等操作正确无误的传递给相关的硬件,并使硬件能够做出正确反应的代码。驱动程序像一个黑盒子,它隐藏了硬件的工作细节,应用程序只需要通过一组标准化的接口实现对硬件的操作。 3.2 Linux设备驱动程序分类 Linux设备驱动程序在Linux的内核源代码中占有很大的比例,源代码的长度日益增加,主要是驱动程序的增加。虽然Linux内核的不断升级,但驱动程序的结构还是相对稳定。 Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三种。字符设备是指在存取时没有缓存的设备,而块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access)。典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD-ROM等。 网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据传递。系统有支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。 3.3驱动程序的结构 驱动程序的结构如图3.1所示,应用程序经过系统调用,进入核心层,内核要控制硬件需要通过驱动程序实现,驱动程序相当于内核与硬件之间的“系统调用”。
网页制作课程设计报告 学院: 专业班级: 姓名: 学号: 成绩: 阅卷教师:
目录 1.设计目的 (1) 2.设计思想 (1) 2.1网站整体结构规划思想 (1) 2.2 主页设计思想 (1) 2.3子页的设计思想 (1) 3网页详细设计分析 (1) 4结论 (2)
1.设计目的 阐述该个人网站的设计意图和创意,简单介绍自己的个人网站。 2.设计思想 阐述网站的整体设计思想,包括: 2.1网站整体结构规划思想 要求阐述网站整体结构的选择、设计的思想,绘制网站结构草图。 2.2 主页设计思想 要求对主页的布局思路进行阐述和分析。 2.3子页的设计思想 要求对子页的设计以及网页对象的选取思路进行阐述和分析。 3网页详细设计分析 要求选取一张网页,对网页的设计实现过程进行阐述和分析,详细说明制作该网页的步骤,所使用的网页对象以及该网页对象的操作方法。
4结论 对整个设计报告做归纳性总结,并分析设计过程中的困难及如何解决的,最后提出展望。 一、设计目的 本课程的设计目的是通过实践使同学们经历Dreamweaver cs3开发的全过程和受到一次综合训练,以便能较全面地理解、掌握和综合运用所学的知识。结合具体的开发案例,理解并初步掌握运用Dreamweaver cs3可视化开发工具进行网页开发的方法;了解网页设计制作过程。通过设计达到掌握网页设计、制作的技巧。了解和熟悉网页设计的基础知识和实现技巧。根据题目的要求,给出网页设计方案,可以按要求,利用合适图文素材设计制作符合要求的网页设计作品。熟练掌握Photoshop cs3、Dreamweaver cs3等软件的的操作和应用。增强动手实践能力,进一步加强自身综合素
Linux字符设备驱动(转载) 来源: ChinaUnix博客日期:2008.01.01 18:52(共有0条评论) 我要评论 Linux字符设备驱动(转载) 这篇文章描述了在Linux 2.4下,如何建立一个虚拟的设备,对初学者来说很有帮助。原文地址:https://www.doczj.com/doc/bf314013.html,/186/2623186.shtml Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Windows的设备操作犹如文件一般。在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。 Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行;而块设备则以整个数据缓冲区的形式进行。字符设备的驱动相对比较简单。 下面我们来假设一个非常简单的虚拟字符设备:这个设备中只有一个4个字节的全局变量int global_var,而这个设备的名字叫做"gobalvar"。对"gobalvar"设备的读写等操作即是对其中全局变量global_var的操作。 驱动程序是内核的一部分,因此我们需要给其添加模块初始化函数,该函数用来完成对所控设备的初始化工作,并调用register_chrdev() 函数注册字符设备: static int __init gobalvar_init(void) { if (register_chrdev(MAJOR_NUM, " gobalvar ", &gobalvar_fops)) { //…注册失败 } else
Web应用开发技术 实验报告 专业:计算机科学与技术 班级: 学号: 姓名:
一、设计题目 个人网站 二、目的 1、本次设计是学生在学完ASP动态网站开发课程后的一次实践性很强的课程设计,是对ASP进行动态网站开发所学知识的综合运用。 2、掌握使用ASP技术进行网站开发设计。 3、通过本次实习,使学生加深所学知识内容的理解,并能积极地调动学生的学习兴趣,结合实际应用操作环境,真正做到理论与实际相结合。 三、功能需求描述 此网站可以对主人留言,来发表自己的心情,也可以把自己的联系方式写入其中,达到和睦相处、心灵的驿站的目的等。 四、总体设计
五、详细设计 (一)、我的主页 此页面为网站的主页,通过发布新心情,点击通讯录可以查看通讯录好友信息,点击留言板可以查看好友留言。 主要代码: