ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:197.66KB ,
资源ID:8657288      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8657288.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(华科操作系统实验报告.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

华科操作系统实验报告.docx

1、华科操作系统实验报告 课 程 实 验 报 告课程名称: 操作系统课程设计 专业班级: 学 号: 姓 名: 指导教师: 报告日期: 计算机科学与技术学院 课程设计任务书一课设目的1.掌握Linux操作系统的使用方法;2.了解Linux系统内核代码结构;3.掌握实例操作系统的实现方法。二课设内容1.掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。(一)编一个C程序,其内容为实现文件拷贝的功能;(二)编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库。gtk/qt 2.掌握系统调用的实现过程,通过编译内核方法,增加一个新的

2、系统调用。另编写一个应用程序,调用新增加的系统调用(实现的功能为文件拷贝)。3.掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单(实现字符设备的驱动)。4.了解和掌握/proc文件系统的特点和使用方法 (选做)(一)了解/proc文件的特点和使用方法(二)监控系统状态,显示系统中若干部件使用情况(三)用图形界面实现系统监控状态。5.设计并实现一个模拟的文件系统(选做) 多用户的多级目录的文件系统设计。 多用户、多级目录、login (用户登录)、系统初始化(建文件卷、提供登录模块)、文件的创建、文件的打开、文件的读、文件的写、文件关闭、删除文件、创建目录(建立

3、子目录)、改变当前目录、列出文件目录、退出。三课设说明Linux系统版本:Fedora 5.0 6.0 ubuntu 10.04 11.10 内核版本: linux-2.6.x四考核要求1必须独立完成课程设计内容,不分小组,不能有相同的拷贝。2上机考试:学生根据老师提出的要求,演示所完成的系统;并回答老师的问题。3第三周五下午2:00全体到实验室做中期检查,只检查1、2题;第四周 周五下午2:00:最后检查。按学号次序逐个检查。4评分方法: 完成1、2题,得60-65分; 完成1、2、3题,得65-75分; 完成1、2、3、4(5)题,得80-100分; 报告:10分(倒扣分)上交:课程设计报

4、告(打印/电子档),内容包括调试记录和程序清单(附注释)。第六周五前以班为单位交指导老师。五参考资料 Linux的“man”帮助!Linux内核2.4版源代码分析大全Linux内核源代码分析Linux编程白皮书 课程内容与过程一掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。1)编一个C程序,其内容为实现文件拷贝的功能。1任务分析: 在Linux下,如果要编译一个C语言源程序,要使用到gcc编译器。gcc编译器中, -o选项表示我们要求输出的可执行文件名。-c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件。 -g选项表示我们要求编译器在编译

5、的时候提供我们以后对程序进行调试的信息。知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了。文件拷贝的C程序主要用到如下几个函数: open:打开文件 open()函数 功能描述:用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等各种参数。 所需头文件:#include ,#include ,#include 函数原型:int open(const char *pathname,int flags,int perms) 参数:pathname:被打开的文件名(可包括路径名如dev/ttyS0) flags:文件打开方式, O_RDONLY:以只读方式打开文件 O_

6、WRONLY:以只写方式打开文件 O_RDWR:以读写方式打开文件 O_CREAT:如果改文件不存在,就创建一个新的文件,并用第三个参数为其设置权限返回值:成功:返回文件描述符 失败:返回-1close:关闭文件 close()函数 功能描述:用于关闭一个被打开的的文件 所需头文件: #include 函数原型:int close(int fd) 参数:fd文件描述符 函数返回值:0成功,-1出错read:读操作 read()函数 功能描述: 从文件读取数据。 所需头文件: #include 函数原型:ssize_t read(int fd, void *buf, size_t count);

7、 参数:fd: 将要读取数据的文件描述词。 buf:指缓冲区,即读取的数据会被放到这个缓冲区中去。 count: 表示调用一次read操作,应该读多少数量的字符。 返回值:返回所读取的字节数;0(读到EOF);-1(出错)。write:写操作 write()函数 功能描述: 向文件写入数据。 所需头文件: #include 函数原型:ssize_t write(int fd, void *buf, size_t count); 返回值:写入文件的字节数(成功);-1(出错)2实现文件拷贝的源程序如下所示: #include #includeint main(int argc,char *arg

8、v) int sfd,tfd,num; char *buf; if(argc!=3) printf(ERROR!COPY FROM TOn); return -1; if(sfd=open(argv1,O_RDONLY,0)=-1) printf(ERROR,OPEN FILE FAILED !n); return -1; if(tfd=open(argv2,O_WRONLY|O_CREAT|O_TRUNC,0666)=-1) printf(TARGET FILE OPEN FAIL !n); return -1; while(num=read(sfd,buf,1)0) write(tfd,b

9、uf,num); close(sfd); close(tfd); exit(0);3程序运行结果 源程序通过gcc编译器编译后会生成可执行文件1,执行可执行文件1之前,/hukeled目录下的文件a内容如图1所示,文件b内容如图2所示。 图1 执行1前文件a中的内容 图2 执行1前文件b中的内容 执行1后,目录/hukeled下文件b中的内容如图3所示,由图可知文件a的内容正确无误的拷贝到了文件b中,故程序运行结果正确。 图3 执行1后文件b中的内容 同时,源程序还可以实现图片等字符流数据的拷贝。2)编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库。1任

10、务分析:程序是指令的有序集合,是一个静态概念,其本身并没有任何运行的含义。而进程是程序在处理机上的一次执行过程,是一个动态概念。一个程序可能有许多进程,而每一个进程又可以有许多子进程。为了区分各个不同的进程,系统给每一个进程分配了一个ID(就象我 们的身份证)以便识别。 为了充分的利用资源,系统还对进程区分了不同的状态,将进程分为新建、运行、阻塞、就绪和完成五个状态。当一个进程调用了fork以后,系统会创建一个子进程。这个子进程和父进程不同的地方只有他的进程ID和父进程ID,其他的都是一样,就像父进程克隆(clone)自己一样。当然创建两个一模一样的进程是没有意义的。为了区分父进程和子进程,我

11、们必须跟踪fork的返回值, 当fork调用失败的时候(内存不足或者是用户的最大进程数已到)fork返回-1。否则fork的返回值有重要的作用。对于父进程fork返回子进程的ID,而对于fork子进程返回0。我们可以根据这个返回值来区分父子进程。 Qt是一个跨平台的C+图形用户界面库,具有优良的跨平台特性:1)Qt支持下列操作系统: Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS, HP-UX, Digital UNIX (OSF/1, Tru64), Irix, FreeBSD, BSD/OS, SCO

12、, AIX, OS390,QNX 等等。2)面向对象3)Qt 的良好封装机制使得 Qt 的模块化程度非常高,可重用性较好,对于用户开发来说是非常 方便的。 Qt 提供了一种称为 signals/slots 的安全类型来替代 callback,这使得各个元件 之间的协同工作变得十分简单。4)丰富的 API5)Qt 包括多达 250 个以上的 C+ 类,还提供基于模板的 collections, serialization, file, I/O device, directory management, date/time 类。甚至还包括正则表达式的处理 功能。6)支持 2D/3D 图形渲染,支持

13、 OpenGL7)大量的开发文档8)XML 支持。 在编译qt程序时,需要用到与编译普通程序不同的命令。比如程序名为hello,则编译过程为: 用qt的工具qmake来生成工程文件:qmake-project;生成Makefile文件:qmakehello.pro;接下来就是make;运行程序./hello。2程序源代码为:int main(int argc, char *argv) QApplication a(argc, argv); MainWindow w; w.show(); pid_t p1,p2,p3; if (p1=fork() = 0) execv(/home/hukeled

14、/1.2/2,NULL); else if (p2=fork()=0) execv(/home/hukeled/1.2/3,NULL); return a.exec();二、 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,调用新增加的系统调用(实现的功能为文件拷贝)。 1 任务分析:一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作保护模式)。系统调用是这些规则的一个例外。其原理是进程先用适当的值填充寄存器,然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位

15、置是用户进程可读但是不可写的)。在Intel CPU中,这个由中断0x80实现。硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统内核。进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(或到其他进程,如果这个进程时间用尽)。 系统调用是应用程序和操作系统内核之间的功能接口,通过系统调用进程可由用户模式转入内核模式。在内核模式下完成相应的服务之后再返回到用户模式。系统调用

16、的主要目的是使得用户可以使用操作系统提供的有关设备管理、输入输出系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。 本次课设,我通过编译内核的方式,增加了一个系统调用,其功能为文件拷贝。2添加的系统调用源代码和测试程序系统调用源代码asmlinkage int sys_mycall(char* sourceFile,char* destFile) int source=sys_open(sourceFile,O_RDONLY,0); int dest=sys_open(destFile,O

17、_WRONLY|O_CREAT|O_TRUNC,0600); char buf4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source0 & dest0) do i=sys_read(source,buf,4096); sys_write(dest,buf,i); while(i); else printk(Error!); sys_close(source); sys_close(dest); set_fs(fs); return 1;测试程序源代码#include #include int main(in

18、t argc ,char * argv) syscall(351,argv1,argv2); return 0;3实验过程与步骤根据教程第一步:(1)获取系统的版本号,使用命令uname -a, 获取版本号为3.13.0(2)下载3.12.39的内核,解压到文件夹/usr/src中,解压命令: xz d linux-3.13.tar.xz tar xvf linux-3.13.tar(3)进入linux-3.13.0目录,清除残留的.config和.o文件,命令: make mrproper(4)安装ncurses-5.9:下载ncurses-5.9,按照安装linux-3.13的方法解压nc

19、urses-5.9到文件来/usr/src中,进入文件夹ncurses-5.9中配置环境:cd ncurses-5.9./configuremakemake install(5)make menuconfig选择编译配置选项。(6)确定依赖性:make dep(7)清理中间文件:make clean(8)生成新内核:make bzImage(9)生成modules:make modules(10)安装modules:make modules_install(11)安装内核make install(12)重启选用新内核第二步:添加自定义系统调用(1) 添加系统调用函数,修改文件:/kernel/

20、sys.casmlinkage int sys_mycall(char* sourceFile,char* destFile) int source=sys_open(sourceFile,O_RDONLY,0); int dest=sys_open(destFile,O_WRONLY|O_CREAT|O_TRUNC,0600); char buf4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source0 & dest0) do i=sys_read(source,buf,4096); sys_write(d

21、est,buf,i); while(i); else printk(Error!); sys_close(source); sys_close(dest); set_fs(fs); return 1;(2)添加系统调用号,修改文件 /arch/x86/syscalls/syscall_64.tbl 351 common mycall sys_mycall(3) 添加声明到头文件,修改文件,/include/asm-generic/syscalls.h asmlinkage int sys_mycall(char* sourceFile,char* destFile)(4)重新编译内核,只用第一

22、步中的(8), (11),重启即可。第三步:测试函数代码: int main(int argc, char * argv) syscall(351,argv1,argv2); return 0; 三、 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单(实现字符设备的驱动)。1任务分析:linxu系统中,在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:1对设备初始化和释放.2把数据从内核传送到硬件和从硬件读取数据.3读取应用程序传送给设备文件的数据和回送应用程序请求的数据.

23、4检测和处理设备出现的错误. Linux操作系统允许设备驱动程序作为可装载内核模块实现,这也就是说,设备的接口实现不仅可以在Linux 操作系统启动时进行注册,而且还可以在Linux 操作系统启动后装载模块时进行注册。总之,Linux操作系统支持多种设备。2设备驱动程序代码:#include linux/kernel.h#include linux/module.h#include linux/fs.h#include linux/init.h#include linux/types.h#include linux/errno.h#include linux/uaccess.h#include

24、 linux/kdev_t.h#include linux/string.h#define MAX_SIZE 20static int my_open(struct inode *inode, struct file *file);static int my_release(struct inode *inode, struct file *file);static ssize_t my_read(struct file *file, char _user *user, size_t t, loff_t *f);static ssize_t my_write(struct file *file

25、, const char _user *user, size_t t, loff_t *f); char messageMAX_SIZE = -congratulations-!;static int device_num = 0;/设备号static int counter = 0;/计数用static int mutex = 0;/互斥用static char* devName = mydevice;/设备名/added by wuyaoint mes_num=0;char tmp;/struct file_operations pStruct = open:my_open, releas

26、e:my_release, read:my_read, write:my_write, ;/* 注册模块 */int init_module() int ret; /* 函数中第一个参数是告诉系统,新注册的设备的主设备号由系统分配, * 第二个参数是新设备注册时的设备名字, * 第三个参数是指向file_operations的指针, * 当用设备号为0创建时,系统一个可以用的设备号创建模块 */ ret = register_chrdev(0, devName, &pStruct); if (ret 0) printk(regist failure!n); return -1; else pr

27、intk(the device has been registered!n); device_num = ret; printk(the virtual devices major number %d.n, device_num); printk(Or you can see it by usingn); printk(-more /proc/devices-n); printk(To talk to the driver,create a dev file withn); printk(-mknod /dev/myDevice c %d 0-n, device_num); printk(Us

28、e rmmode to remove the modulen); return 0; /* 注销模块,函数名很特殊 */void cleanup_module() unregister_chrdev(device_num, devName); printk(unregister it success!n);static int my_open(struct inode *inode, struct file *file) if(mutex) return -EBUSY; mutex = 1;/上锁 printk(main device : %dn, MAJOR(inode-i_rdev); printk(slave device : %dn, MINOR(inode-i_rdev); printk(%d times to call the devicen, +counter); try_module_get(THIS_MODULE); return 0;/* 每次使用完后会release */static int my_release(struct inode *inode, struct file *file) printk(Device released!n); module_put(THIS_MODULE); mutex = 0;/开锁

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1