免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1973 | 回复: 1
打印 上一主题 下一主题

[SCO UNIX] Unix 驱动程序开发过程及分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-02-08 10:29 |只看该作者 |倒序浏览
序言:
  对于unix的动态驱动程序,我们称之为逻辑上的驱动程序,因为它不和任何的硬件设备相连接。这种驱动程序能够生成数据文件、监测打印机、或者产生大量不挤占磁盘空间的随机数据。
目标:
1.设计一个简单的设备驱动程序
2.研究用户程序如何与设备进行交互数据
3.知道动态装入

正文:
  我们用一个长字符串"How are you?"作为输出结果。当用户程序调用设备程序时,设备程序将会把字符串放到一个缓冲区中,而这个缓冲区也能为用户程序所访问。如:
bytes_read = read(fileDescr, buffer, sizeof(buffer));
其中,fileDescr是系统调用的文件描述符;
buffer 是字符串的缓冲区;
当我们调用此函数,核心进程就会执行设备驱动程序,设备驱动程序就会通过这一接口把字符串数据写入buffer缓冲区中,接着用户程序就能得到此字符串的内容、属性。
下面,我将介绍一下unix驱动程序的安装过程、入口。首先,系统监测驱动设备是否存在;接着,设备初始化;分配内存并且和一定数据结构对应;初始化着一数据结构并赋值;最后,赋以指针指向此结构。这样我们就能够着手设计了。
首先,定义数据结构,其包含字符串长度、内存区间:
/*drv1info.h*/
#define STRLEN 45
struct drv1info {
char foxmessage[STRLEN];
};

我们对字符串进行初始化:
/* drv1info.c*/
#include "drv1info.h"

struct drv1info drv1info0 = {
"How are you?.\n"
};

我们再定义一个数据静态类型,通过它调用字符串信息,调用之后要求释放其内存:
struct drv1statics {
char *foxmessage;
};
  数据结构定义之后,我们就要设计驱动程序的入口了。我们知道,系统打开设备驱动程序时,系统首先确定此文件类型,同时系统使用主设备号与设备驱动程序接口绑定,如果不成功,则使用此设备号。如果都不成功,那末就无法打开此设备驱动程序了。
  设备驱动程序入口的建立,主要通过数据结构进行,系统能够提供服务即使用此数据区,用户程序能够读取此数据区接收服务,相当于客户。这种方式是应用unix的系统设备服务调用(sysbrk driver service call):
struct drv1statics *sp; /* allocate a (s)tatics (p)ointer */

/* allocate memory for the statics structure */
if (!(sp = (struct drv1statics *) sysbrk((long) sizeof *sp) ))
return (char *) SYSERR;
指向此数据结构的指针sp->;foxmessage,其内容是:How are you?。对此字符串的引用为:
if (!(sp->;foxmessage = sysbrk((long) STRLEN)))
sysfree(sp, (long)sizeof *sp);
return (char *) SYSERR;
}
  由上可见,如果条件成立,那末静态数据的内存区将被释放。但是,其返回的数据为字符指针,给出结果情况。如果分配到缓冲区了,则有:
strcpy(sp->;foxmessage, info->;foxmessage);
它把info->;foxmessage("How are you?"通过字符串函数拷贝给sp->;foxmessage。
如果设备驱动程序不能成功初始化,许多已分空间要释放:
void drv1uninstall(sp)
struct drv1statics *sp;
{
sysfree(sp->;foxmessage,(long)STRLEN);
sysfree(sp, (long)sizeof *sp);
}
读接口数据,即驱动程序把数据写到数据缓冲区的过程:
int drv1read(sp, fp, buf, count)
struct drv1statics *sp;
struct file *fp;
char *buf;
int count;
{
int index=0;
static long offset=0;

if (wbounds(buf) < count) {
pseterr(EFAULT);
return(SYSERR);
}
while (count) {
*(buf+index) = sp->;foxmessage[offset%(STRLEN-1)];
index++;
offset++;
count--;
}
return index;
}
设备驱动程序被初始化之后,如何动态装载,只需在入口点结构前加上dldd
编译动态属性即可:
#include <dldd.h>;
/* Add this statement to the end of drv1drvr.c */
static struct dldd entry_points = {
ionull, /* open */
ionull, /* close */
drv1read, /* read */
ionull, /* write */
ionull, /* select */
ionull, /* ioctl */
drv1install, /* install */
drv1uninstall, /* uninstall */
(char *) 0
};
此设备驱动程序编译步骤:
1,#cc -c drv1drvr.c
编译成为目标文件drv1drvr.o
2, #drinstall -c drv1drvr.o
drv1drvr.o xid
安装测试设备程序,若成功返回设备号(xid)
3. # devinstall -c -d xid drv1drvr.o
若生成设备文件名:Un_driver
4. # mknod /dev/Un_driver c xid 0 0444
给此设备分配节点,用户程序能够通过节点访问设备驱动程序。
至此,设备驱动程序设计过程结束。下面我们如何调用它略举一例:
/* drv1test.c */

#include <io.h>;
#include <fcntl.h>;
#include <stdio.h>;

main() {
int fildes;
char buffer[100];

fildes = open ("/dev/Un_driver",O_RDONLY);
if (sizeof(buffer) == read (fildes, buffer, sizeof(buffer)))
write(1,buffer,sizeof (buffer));
else
printf("操作失败!";
}
附整个程序:
/* drv1info.h */
#define STRLEN 45
struct drv1info {
char foxmessage[STRLEN];
};

--------------------------------------------------------------------------------

/* drv1info.c */
#include "drv1info.h"

struct drv1info drv1info0 = {
"How are you?.\n";
};

main() {
write (1,&amp;drv1info0,sizeof (struct drv1info));
}

--------------------------------------------------------------------------------

/* drv1drvr.c */
#include <io.h>;
#include <conf.h>;
#include <kernel.h>;
#include <mem.h>;
#include <file.h>;
#include <errno.h>;
#include <dldd.h>;
#include "drv1info.h"

struct drv1statics {
char *foxmessage;
};

extern int ionull();

char *drv1install(info)
struct drv1info *info;
{
struct drv1statics *sp;
int i;

if (!(sp = (struct drv1statics *) sysbrk((long) sizeof *sp) ))
return (char *) SYSERR;

if (!(sp->;foxmessage = sysbrk((long) STRLEN))) {
sysfree(sp, (long)sizeof *sp);
return (char *) SYSERR;
}

strcpy(sp->;foxmessage, info->;foxmessage);
return (char *) sp;
}

void drv1uninstall(sp)
struct drv1statics *sp;
{
sysfree(sp->;foxmessage,(long)STRLEN);
sysfree(sp, (long)sizeof *sp);
}

int drv1read(sp, f, buf, count)
struct drv1statics *sp;
struct file *f;
char *buf;
int count;
{
int index=0;
static long offset=0;

if (wbounds(buf) < count) {
pseterr(EFAULT);
return(SYSERR);
}
while (count) {
*(buf+index) = sp->;foxmessage[offset%(STRLEN-1)];
index++;
offset++;
count--;
}
return index;
}

static struct dldd entry_points = {
ionull, /* open */
ionull, /* close */
drv1read, /* read */
ionull, /* write */
ionull, /* select */
ionull, /* ioctl */
drv1install, /* install */
drv1uninstall, /* uninstall */
(char *) 0
};

论坛徽章:
0
2 [报告]
发表于 2003-02-08 20:59 |只看该作者

Unix 驱动程序开发过程及分析

好,好东西
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP