操作系统课设_第1页
操作系统课设_第2页
操作系统课设_第3页
操作系统课设_第4页
操作系统课设_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

课课 程程 设设 计计 报报 告告 课程名称课程名称: 计算机操作系统 专业班级:专业班级: 学学 号:号: 姓姓 名:名: 指导教师:指导教师: 报告日期:报告日期: 计算机科学与技术学院计算机科学与技术学院 I 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 目 录 1实验目的实验目的 .2 2实验环境实验环境 .2 3实验内容实验内容 .2 3.1实验一.2 3.2实验二.2 3.3实验三.2 3.4实验四(选做).3 3.5实验五(选做).3 4设计与实现设计与实现.3 4.1实验一.3 4.2实验二.10 4.3实验三.14 4.4实验四.20 5心得体会心得体会 .43 2 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 1实验目的 掌握 Linux 操作系统的使用方法; 了解 Linux 系统内核代码结构; 掌握实例操作系统的实现方法; 2实验环境 本次课程设计采用的操作系统环境是 windows8、Ubuntu 双系统,Ubuntu 系统版 本号为 14.04,内核版本号为 linux 3.13.0;采用的编程环境为 CodeBlocks IDE 和 QtCreator。 3实验内容 3.1实验一 掌握 Linux 操作系统的使用方法,包括键盘命令、系统调用;掌握在 Linux 下的 编程环境。 (1)编写一个 C 程序,其内容为实现文件拷贝的功能。 (2)编写一个 C 程序,其内容为分窗口同时显示三个并发进程的运行结果。要 求用到 Linux 下的图形库(GTK/Qt) 。 3.2实验二 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编 写一个应用程序,调用新增加的系统调用。实现的功能是:文件拷贝。 3.3实验三 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序, 其功能可以简单。 (实现字符设备的驱动) 3 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 3.4实验四(选做) 了解和掌握/proc 文件系统的特点和使用方法 (1)了解/proc 文件的特点和使用方法; (2)监控系统状态,显示系统中若干部件使用状态; (3)用图形界面实现系统监控状态; 3.5实验五(选做) 设计并实现一个模拟的文件系统。 多用户的多级目录的文件系统设计。多用户、多级目录、login(用户登录) 、系 统初始化(建文件卷,提供登录模块) 、文件的创建、文件的打开、文件的读写、文 件关闭、删除文件、创建目录(建立子目录) 、改变当前目录、列出文件目录、退出。 4设计与实现 4.1实验一 4.1.1 实验要求 掌握 Linux 操作系统的使用方法,包括键盘命令、系统调用;掌握在 Linux 下 的编程环境。 4.1.2 具体实现 本实验内容是用 CodeBlocks IDE 实现的,该软件整合了函数库和编译器,因此 使用起来非常方便。 (1)编写一个 C 程序,其内容为实现文件拷贝的功能。 在 windows 操作系统上实现的文件拷贝功能一般使用 fopen、fread、fwrite 三 个来自标准 C 函数库的函数执行对文件的打开、读、写操作,而本次实验要求使用 Linux 系统的系统调用 open、read、write 实现上述三个操作。 用到的主要头文件如下: 4 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 stdio.h标准输入输出头文件 string.h字符串处理相关头文件 unistd.hLinux 系统调用头文件,比如 read、write fcntl.h包含 open 系统调用 errno.h包含一些调试错误时用到的变量 具体实现思路: 打开两个文件(分别是源文件和目标文件,可以是任意字符流形式存储的文件, 包括文本文件、照片等) ,调用 read 函数读取源文件的内容,将 read 的返回值作为 while 循环的判断条件,当返回值大于 0(即还未读取完毕源文件中的内容)时,调 用 write 执行向目标文件写的操作,否则跳出循环,表示源文件已经被拷贝到目标 文件,然后调用 close 关闭源文件和目标文件。 代码编写完成后,在 CodeBlocks 上编译运行即可。程序运行之前,桌面上只有 “教程.docx” ,运行之后,桌面上新建了“教程副本.docx” ,并且“教程.docx”中 的内容被复制到了“教程副本.docx” ,程序运行结果如下所示: 详细代码见 Error! Reference source not found.。 (2)编写一个 C 程序,其内容为分窗口同时显示三个并发进程的运行结果。要 求用到 Linux 下的图形库(GTK/Qt) 。 5 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 本次实验使用的图形库是跨平台的开发工具 Qt。首先下载 Qt 的安装包并安装。 Qt 安装完之后,先新建一个 Qt 控制台应用 MAIN 作为主进程,用于调用三个并发 的子进程。在主进程的 main 函数中,使用 fork 创建三个子进程,若进程创建成功 (即 fork 函数返回值等于 0) ,则使用 execv 函数进入对应的子进程 (get、copy、put) 。 主进程程序编写完成后,再新建三个 Qt Widgets Application,分别作为三个子进程 get、copy、put(所实现的功能并不是拷贝) 。由于三个子进程窗口显示的内容形式 一模一样,所以以子进程 get 为例。get 进程的窗口显示了一下四个内容:当前时间、 子进程名称、子进程的 pid 和父进程 MAIN 的 pid。用 Qt 的对象 QDateTime 获取系 统当前时间,然后将时间转换成一个字符串写在一个 QLabel 类的实例中,然后将该 实例添加至窗口;直接把当前进程名称写在一个标签上然后添加至窗口;使用 getpid 和 getppid 函数分别获取当前进程号和父进程号,然后调用 sprintf 把进程号转换成字 符串类型之后写在标签上并添加至窗口即可。 主进程和三个子进程的程序全部编写完后,直接在 Qt 上编译运行。程序运行结 果如下所示: 6 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 详细代码见 Error! Reference source not found.。 7 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 4.1.3 源代码 (1) 文件拷贝源代码 #include #include #include #include #include #include #include #define SIZE 10 /每次读取的字符数目 char * srcFile=/home/ilbear/桌面/教程.docx; char *goalFile=/home/ilbear/桌面/教程副本.docx; int main(int argc, const char *argv) int src, goal; int read_len; char buffSIZE; src=open(srcFile,O_RDONLY); if(srcsetupUi(this); setWindowTitle(get); setWindowFlags(Qt:Dialog); move(0,0); resize(500,500); char str128,f_id128; sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(get); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); 9 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 timer-start(1); MainWindow:MainWindow() delete ui; void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str); #子进程子进程 copy mainwindow.cpp #include mainwindow.h #include ui_mainwindow.h #include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory1(share1),sharememory2(share2) char str128,f_id128; ui-setupUi(this); setWindowTitle(copy); setWindowFlags(Qt:Dialog); move(500,500); resize(500,500); sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(copy); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); timer-start(1); MainWindow:MainWindow() delete ui; void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str); #子进程子进程 put mainwindow.cpp #include mainwindow.h #include ui_mainwindow.h 10 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 #include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory2(share2) char str128,f_id128; ui-setupUi(this); setWindowTitle(put); setWindowFlags(Qt:Dialog); move(1000,0); resize(500,500); sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(put); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); timer-start(1); MainWindow:MainWindow() delete ui; void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str); 4.2实验二 4.2.1 实验要求 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编 写一个应用程序,调用新增加的系统调用。 4.2.2 具体实现 (1) 系统调用的原理 用户进程不能访问内核所占内存空间,也不能调用内核函数。进程调用一个特殊 的指令,这个指令会跳到一个事先定义的内核中的一个位置。在 Intel CPU 中,由中 断 INT 0 x80 实现。 (与 DOS 功能调用 int0 x21 很相似)跳转到的内核位置叫做 sysem_call。检查系统调用号,这个号码代表进程请求哪种服务。然后,它查看系统 11 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回 后,做一些系统检查,最后返回到进程(如果这个进程时间用尽,就返回到其他进 程) 。 (2) 编写新的系统调用程序 新的系统调用程序实现的功能是:将一个文件中的内容拷贝到另一个文件中。这 个系统调用的参数是两个 char*型的字符指针 SourceFile、GoalFile,分别表示源文件 和目标文件的路径名。用户进程中的 open、read、write、close 函数此时对应内核函 数 sys_open、 sys_read、 sys_write、 sys_close 函数。循环拷贝的判断条件还是 sys_read 的返回值,当其大于 0 的时候执行循环,否则表示源文件已拷贝到了目标文件。 mm_segment_t 类型的变量 fs 的作用是在读写文件前得到当前 fs,避免使用的缓冲区 超过了用户空间的地址范围而报错。 详细代码见 Error! Reference source not found.。 (3) 编译内核 下载并解压内核 先到 Linux 官方网站 /下载内核 linux-3.14.36.tar.xz。打开终 端,使用 sudo su 获取 root 权限,然后使用 cp linux-3.14.36.tar.xz /usr/src 命令将 linux-3.14.36.tar.xz 复制到文件夹/usr/src 下,复制完毕之后将其解压,用到的命令为: xz -d linux-3.14.36.tar.xz 和 tar xvf linux-3.14.36.tar。 修改内核 新的内核解压完毕后,使用 cd /usr/src/linux-3.14.36 命令进入目录 /usr/src/linux- 3.14.36。然后使用命令 sudo gedit kernel/sys.c 打开 sys.c,将新的系统调用程序复制 到该文件的文件末尾,保存退出,系统调用程序详细代码见 4.2.3。 使用命令 sudo gedit arch/x86/syscalls/syscall_64.tbl 打开 syscall_64.tbl 添加系统 调用号。在该文件中添加一行内容 317 common mycall sys_mycall,其中系统调用号 317 不是固定的,只要该文件中没有出现的数字都可以使用。添加之后保存退出。 使用命令 sudo gedit include/asm-generic/syscalls.h 打开 syscalls.h,在“#endif /* _ASM_GENERIC_SYSCALLS_H */ 这一行的上面一行添加新的系统调用程序的函 数定义,即: #ifndef sys_mycall 12 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 asmlinkage int sys_mycall(char* sourceFile,char* destFile); #endif 然后保存退出。 编译内核 在编译内核之前先要安装 ncurses 库,使用命令 sudo apt-get install libncurses5-dev 安装。安装完毕后,进入 /usr/src/linux-3.14.36 目录下,新建一个脚本文件 mysyscall.sh,通过命令 gedit mysyscall.sh 打开该脚本文件进行编辑。将以下内容添 加到脚本中: #!/bin/bash make mrproper make menuconfig make dep make clean make bzImage j4 make modules j4 make modules_install j4 make install j4 mkinitramfs -o /boot/initrd.img-3.14.34 update-grub reboot 保存退出,然后修改脚本文件的权限,使其可以对内核文件进行操作,修改权限 的命令为 chmod 777 mysyscall.sh。权限修改成功后,在终端中运行该脚本文件. /mysyscall.sh,内核开始编译,期间会出现配置 linux 过程,直接先 save,然后 OK, 再 exit 即可,继续等待编译结束。编译完成后,电脑会自动重启,重启选择进入 Ubuntu 高级选项,在选项列表中选择新内核 linux-3.14.36 进入,打开终端输入 uname -a 查看系统版本号,执行情况如下所示: 说明已经成功进入新的内核 linux-3.14.36 中。 (4) 编写系统调用测试程序 需要用到的头文件是 syscall.h、unistd.h、stdlib.h。在 main 函数中直接调用头文 13 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 件 syscall.h 中定义的函数 syscall,该函数有三个参数,第一个参数是系统调用号 (317) ,第二个参数是源文件(main.c,即测试程序的源代码文件) ,第三个参数是 目标文件(yyk.text) 。 程序运行结果为:在 main.c 所在目录下新建了一个 yyk.text 文件,并将 main.c 中的代码拷贝到了 yyk.text 中。详细代码见 Error! Reference source not found.。 4.2.3 源代码 (1) 系统调用程序 asmlinkage int sys_mycall(char* SourceFile,char* GoalFile) int source=sys_open(SourceFile,O_RDONLY,0); int goal=sys_open(GoalFile,O_WRONLY|O_CREAT|O_TRUNC,0600); char buff4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source0 sys_write(goal,buff,i); while(i); else printk(Error!); sys_close(source); sys_close(goal); set_fs(fs); return 10; (2) 测试程序 #include #include #include int main() syscall(317,main.c,yyk.text); return 0; 14 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 4.3实验三 4.3.1 实验要求 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序, 其功能可以简单。 (实现字符设备的驱动) 4.3.2 具体实现 (1)Linux 核心是一种 monolithic 类型的内核,即单一的大核心,另外一种形式是 MicroKernel,核心的所有功能部件都被拆成独立部分, 这些部分之间通过严格的通 讯机制进行联系。Linux 内核是一个整体结构,因此向内核添加任何东西.或者删除 某些功能,都十分困难 。为了解决这个问题,引入了模块机制,从而可以动态的在 内核中添加或者删除模块。模块一旦被插入内核,就和内核其他部分一样。 Linux 内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低级硬件处理 例程。对用户程序而言,设备驱动程序隐藏了设备的具体细节, 对各种不同设备提 供了一致的接口,一般来说是把设备映射为一个特殊的设备文 件,用户程序可以像 对其它文件一样对此设备文件进行操作。 Linux 支持 3 种设备:字符设备、块设备和网络设备。设备由一个主设备号和一 个次设备号标识。主设备号唯一标识了设备类型, 即设备驱动程序类型,它是块设 备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释 ,一般用于 识别在若干可能的硬件设备中,I/O 请求所涉及到的那个设备。 典型的 Linux 模块实现机制有如下几步: 注册设备:在系统初启或者加载模块的时候,必须将设备登记到相应的设备 数组,并返回主设备号。 定义功能函数:对于每一个驱动函数来说,都有一些和此设备密切相关的功 能函数。以最常用的块设备或者字符设备来说,都存在着诸如 open()、read()这一类 的操作。当系统调用这些调用时,将自动的使用驱动函数中特定的模块来实现具体 的操作。 卸载设备:在不用这个设备时,可以将它卸载,主要是从/proc 中取消这个设备 的特殊文件。 15 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 (2) 编写 Makefile 文件 Makefile 文件用于编译设备驱动程序,其内容如下: ifneq ($(KERNELRELEASE),) #kbuild syntax. #模块的文件组成 mymodule-objs :=MyDeviceDriver.o #生成的模块文件名 obj-m := MyDeviceDriver.o else PWD :=$(shell pwd) KVER :=$(shell uname -r) KDIR :=/lib/modules/$(KVER)/build all: $(MAKE) -C $(KDIR) M=$(PWD) clean: #rm -f *.cmd *.o *.mod *.ko rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions #$(MAKE) -C $(KDIR) M=$(PWD) clean endif (3)编写设备功能函数 编写设备驱动程序的主要工作就是编写子功能函数,并填充 file_operations 的各个 域 。 结构体 file_operations 的具体定义如下: struct file_operations struct module *owner;/拥有该结构的模块的指针,一般为 THIS_MODULES loff_t (*llseek) (struct file *, loff_t, int);/用来修改文件当前的读写位置 ssize_t (*read) (struct file *, char _user *, size_t, loff_t *);/从设备中同步读取数据 ssize_t (*write) (struct file *, const char _user *, size_t, loff_t *);/向设备发送数据 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);/初始化一个 异步的读取操作 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);/初始化一个 异步的写入操作 int (*readdir) (struct file *, void *, filldir_t);/仅用于读取目录,对于设备文件,该字段为 NULL unsigned int (*poll) (struct file *, struct poll_table_struct *); /轮询函数,判断目前是否可 以进行非阻塞的读写或写入 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); /执行设备 I/O 控制命 令 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); /不使用 BLK 文件系统, 将使用此种函数指针代替 ioctl long (*compat_ioctl) (struct file *, unsigned int, unsigned long); /在 64 位系统上,32 位的 ioctl 调用将使用此函数指针代替 int (*mmap) (struct file *, struct vm_area_struct *); /用于请求将设备内存映射到进程地址 空间 int (*open) (struct inode *, struct file *); /打开 int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); /关闭 int (*fsync) (struct file *, struct dentry *, int datasync); /刷新待处理的数据 int (*aio_fsync) (struct kiocb *, int datasync); /异步刷新待处理的数据 16 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 int (*fasync) (int, struct file *, int); /通知设备 FASYNC 标志发生变化 int (*lock) (struct file *, int, struct file_lock *); 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); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock *); ; 子功能函数详细代码见 Error! Reference source not found.。 (4) 设备驱动程序安装 make clean,清除 make 产生的残留 make,重新调用 Makefile 编译设备驱动程序 insmod -f MyDeviceDriver.ko,加载生成的 MyDeviceDriver.ko 模块 cat /proc/devices,获取设备驱动程序的主设备号 mknod /dev/MyDeviceDriver c 250 0,创建设备文件,250 为主设备号,0 为从 设备号 (5)测试驱动程序 此设备驱动程序实现的功能是将一个字符串中内容拷贝到另外一个字符串中。测 试程序编写完成后,在终端输入 gcc test.c -o test 进行编译。测试结果如下: 详细代码见 Error! Reference source not found.。 4.3.3 源代码 (1) 设备驱动程序 #include 17 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 #include #include #include #include #include #include #include #define DEV_SIZE /设备申请的最大内存空间 struct Device char *data;/数组指针,用于存放从用户读入的数据 long size;/存储的数据长度 *devp; struct cdev cdev;/字符设备结构体 static int devNum_major = 0;/主设备号变量 /对应用户态的 lseek static loff_t my_llseek(struct file *file,loff_t offset, int whence) loff_t cfo=0;/文件当前偏移量,current file offset switch(whence) case 0:/SEEK_SET cfo=offset;break; case 1:/SEEK_CUR cfo=file-f_pos+offset;break; case 2:/SEEK_END cfo=DEV_SIZE-1+offset;break; if (cfoDEV_SIZE)/文件偏移量越界 return -EINVAL; file-f_pos = cfo; return cfo; /对应用户态的 read,写数据到用户空间 static ssize_t my_read(struct file *file, char _user *buf, size_t count, loff_t *p_cfo) int val = 0; struct Device *dev = file-private_data; /设备描述结构体指针,获取设 备信息 if (copy_to_user(buf, (void*)(dev-data + *p_cfo), count)/如果成功返 回 0;如果失败,返回未完成 copy 的长度 18 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 val = -EFAULT; else *p_cfo += count;/copy 成功,文件偏移量加上 count val = count; return val; /对应用户态的 write,从用户空间读入数据 static ssize_t my_write(struct file *file, const char _user *buf, size_t count, loff_t *p_cfo) int val = 0; struct Device *dev = file-private_data; if (copy_from_user(dev-data + *p_cfo, buf, count)/如果成功返回 0; 如果失败,返回未完成 copy 的长度 val = -EFAULT; else *p_cfo += count;/copy 成功,文件偏移量加上 count val = count; return val; static int my_open(struct inode *inode, struct file *file) file-private_data = devp; return 0; struct file_operations fops= .owner = THIS_MODULE, .llseek = my_llseek, .read = my_read, .write = my_write, .open = my_open, ; int init_module(void) int dev_num; dev_num = register_chrdev(0,MyDeviceDriver, if (dev_num 0) 19 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 printk(KERN_INFO MyDeviceDriver: FAIL to get major numbern); return dev_num; if (devNum_major = 0) devNum_major = dev_num; /初始化 cdev 结构 cdev_init( cdev.owner = THIS_MODULE; cdev.ops = cdev_add(/注册 1 个字符设备 /为设备描述结构体分配内存 devp = kmalloc(sizeof(struct Device), GFP_KERNEL); if (!devp) dev_num = -ENOMEM; printk(KERN_INFO MyDeviceDriver: FAIL to get memoryn); return dev_num; (*devp).size = DEV_SIZE; (*devp).data = kmalloc(DEV_SIZE, GFP_KERNEL); memset(*devp).data, 0, (*devp).size);/初始化为 0 return 0; void cleanup_module(void) cdev_del(/注销设备 kfree(devp);/注销设备结构体 kfree(*devp).data);/注销设备内存空间 unregister_chrdev(devNum_major,MyDeviceDriver);/卸载主设备号 MODULE_LICENSE(GPL); (2) 驱动程序测试程序 #include #include #include #define BUFFER_SIZE int main(void) int dev,i=0; char c; char sourceBUFFER_SIZE;/写入 MyDeviceDriver 设备的内容 char goalBUFFER_SIZE; /MyDeviceDriver 设备的内容读入到该 goal 中 printf(input the string you want to write in your device:n); while(c=getchar()!=n) 20 华华 中中 科科 技技 大大 学学 课课 程程 设设 计计 报报 告告 sourcei+=c; printf(n); if(dev=open(/dev/MyDeviceDriver,O_RDWR)=-1) /打开 MyDeviceDriver 设备失败 printf(FAIL to open MyDeviceDriver!n); else/成功 printf(SUCCESS to open MyDeviceDriver!n); printf(source:n%snn,source); write(dev,source,sizeof(source); /把 sourc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论