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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

操作系统课设.docx

1、操作系统课设课 程 设 计 报 告课程名称: 计算机操作系统专业班级: 学 号: 姓 名: 指导教师: 报告日期: 计算机科学与技术学院1实验目的掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法;2实验环境本次课程设计采用的操作系统环境是windows8、Ubuntu双系统,Ubuntu系统版本号为14.04,内核版本号为linux 3.13.0;采用的编程环境为CodeBlocks IDE和QtCreator。3实验内容3.1实验一掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。(1)编写一个C程序,其内容为

2、实现文件拷贝的功能。(2)编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。3.2实验二掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。实现的功能是:文件拷贝。3.3实验三掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动)3.4实验四(选做)了解和掌握/proc文件系统的特点和使用方法(1)了解/proc文件的特点和使用方法;(2)监控系统状态,显示系统中若干部件使用状态;(3)用图形界面实现系统监控状态;3.5实验五(选做

3、)设计并实现一个模拟的文件系统。多用户的多级目录的文件系统设计。多用户、多级目录、login(用户登录)、系统初始化(建文件卷,提供登录模块)、文件的创建、文件的打开、文件的读写、文件关闭、删除文件、创建目录(建立子目录)、改变当前目录、列出文件目录、退出。4设计与实现4.1实验一4.1.1实验要求掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。4.1.2具体实现本实验内容是用CodeBlocks IDE实现的,该软件整合了函数库和编译器,因此使用起来非常方便。(1)编写一个C程序,其内容为实现文件拷贝的功能。在windows操作系统上实现的文件拷贝功能

4、一般使用fopen、fread、fwrite三个来自标准C函数库的函数执行对文件的打开、读、写操作,而本次实验要求使用Linux系统的系统调用open、read、write实现上述三个操作。用到的主要头文件如下:stdio.h标准输入输出头文件string.h字符串处理相关头文件unistd.hLinux系统调用头文件,比如read、writefcntl.h包含open系统调用errno.h包含一些调试错误时用到的变量具体实现思路:打开两个文件(分别是源文件和目标文件,可以是任意字符流形式存储的文件,包括文本文件、照片等),调用read函数读取源文件的内容,将read的返回值作为while循环

5、的判断条件,当返回值大于0(即还未读取完毕源文件中的内容)时,调用write执行向目标文件写的操作,否则跳出循环,表示源文件已经被拷贝到目标文件,然后调用close关闭源文件和目标文件。代码编写完成后,在CodeBlocks上编译运行即可。程序运行之前,桌面上只有“教程.docx”,运行之后,桌面上新建了“教程副本.docx”,并且“教程.docx”中的内容被复制到了“教程副本.docx”,程序运行结果如下所示:详细代码见4.1.3。(2)编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。本次实验使用的图形库是跨平台的开发工具Qt。首先

6、下载Qt的安装包并安装。Qt安装完之后,先新建一个Qt控制台应用MAIN作为主进程,用于调用三个并发的子进程。在主进程的main函数中,使用fork创建三个子进程,若进程创建成功(即fork函数返回值等于0),则使用execv函数进入对应的子进程(get、copy、put)。主进程程序编写完成后,再新建三个Qt Widgets Application,分别作为三个子进程get、copy、put(所实现的功能并不是拷贝)。由于三个子进程窗口显示的内容形式一模一样,所以以子进程get为例。get进程的窗口显示了一下四个内容:当前时间、子进程名称、子进程的pid和父进程MAIN的pid。用Qt的对象

7、QDateTime获取系统当前时间,然后将时间转换成一个字符串写在一个QLabel类的实例中,然后将该实例添加至窗口;直接把当前进程名称写在一个标签上然后添加至窗口;使用getpid和getppid函数分别获取当前进程号和父进程号,然后调用sprintf把进程号转换成字符串类型之后写在标签上并添加至窗口即可。主进程和三个子进程的程序全部编写完后,直接在Qt上编译运行。程序运行结果如下所示:详细代码见4.1.3。4.1.3源代码(1)文件拷贝源代码#include #include #include #include #include #include #include #define SIZE

8、 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(src0) printf(Fail to open %sn.,srcFile); exit(1); goal=open(goalFile,O_WRONLY|O_CREAT,0666); i

9、f(goal0) write(goal,buff,read_len); close(src); close(goal); return 0;(2)三个并发进程#主进程MAIN#include #include #include #include #include #include int main(int argc, char *argv) QCoreApplication a(argc, argv); pid_t p1,p2,p3; if(p1=fork()=0) execv(/home/ilbear/桌面/build-get-Desktop_Qt_5_4_1_GCC_64bit-Debug

10、/get,NULL); else if(p2=fork()=0) execv(/home/ilbear/桌面/build-copy-Desktop_Qt_5_4_1_GCC_64bit-Debug/copy,NULL); else if( p3=fork()=0) execv(/home/ilbear/桌面/build-put-Desktop_Qt_5_4_1_GCC_64bit-Debug/put,NULL); waitpid(p1,NULL,0); waitpid(p2,NULL,0); waitpid(p3,NULL,0); return a.exec();#子进程getmainwind

11、ow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory1(share1) ui-setupUi(this); setWindowTitle(get); setWindowFlags(Qt:Dialog); move(0,0); resize(500,500); char str128,f_

12、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(); timer-start(1);MainWindow:MainWindow() delete ui;void Ma

13、inWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str);#子进程copymainwindow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMa

14、inWindow(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

15、-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

16、-dd hh:mm:ss dddd); ui-labelCurDate-setText(str);#子进程putmainwindow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory2(share2) char str128,f_id128; ui-setupUi(this); setWi

17、ndowTitle(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(time

18、rUpDate(); 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)

19、系统调用的原理用户进程不能访问内核所占内存空间,也不能调用内核函数。进程调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置。在Intel CPU中,由中断INT 0x80实现。 (与DOS功能调用int0x21很相似)跳转到的内核位置叫做sysem_call。检查系统调用号,这个号码代表进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(如果这个进程时间用尽,就返回到其他进程)。(2)编写新的系统调用程序新的系统调用程序实现的功能是:将一个文件中的内容拷贝到另一个文件中。

20、这个系统调用的参数是两个char*型的字符指针SourceFile、GoalFile,分别表示源文件和目标文件的路径名。用户进程中的open、read、write、close函数此时对应内核函数 sys_open、 sys_read、 sys_write、 sys_close函数。循环拷贝的判断条件还是 sys_read的返回值,当其大于0的时候执行循环,否则表示源文件已拷贝到了目标文件。 mm_segment_t类型的变量fs的作用是在读写文件前得到当前fs,避免使用的缓冲区超过了用户空间的地址范围而报错。详细代码见4.2.3。(3)编译内核下载并解压内核先到Linux官方网站http:/w

21、ww.kernel.org/下载内核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 ker

22、nel/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_

23、SYSCALLS_H */ 这一行的上面一行添加新的系统调用程序的函数定义,即:#ifndef sys_mycallasmlinkage 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打开该脚本文件进行编辑。将以下内容添加到脚本中:#

24、!/bin/bashmake mrproper make menuconfig make depmake clean make bzImage j4make modules j4make modules_install j4make install j4mkinitramfs -o /boot/initrd.img-3.14.34 update-grub reboot保存退出,然后修改脚本文件的权限,使其可以对内核文件进行操作,修改权限的命令为chmod 777 mysyscall.sh。权限修改成功后,在终端中运行该脚本文件./mysyscall.sh,内核开始编译,期间会出现配置linux

25、过程,直接先save,然后OK,再exit即可,继续等待编译结束。编译完成后,电脑会自动重启,重启选择进入Ubuntu高级选项,在选项列表中选择新内核linux-3.14.36进入,打开终端输入uname -a查看系统版本号,执行情况如下所示:说明已经成功进入新的内核linux-3.14.36中。(4)编写系统调用测试程序需要用到的头文件是syscall.h、unistd.h、stdlib.h。在main函数中直接调用头文件syscall.h中定义的函数syscall,该函数有三个参数,第一个参数是系统调用号(317),第二个参数是源文件(main.c,即测试程序的源代码文件),第三个参数是目

26、标文件(yyk.text)。程序运行结果为:在main.c所在目录下新建了一个yyk.text文件,并将main.c中的代码拷贝到了yyk.text中。详细代码见4.2.3。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

27、 = get_fs(); set_fs(get_ds(); int i; if(source0 & goal0) do i=sys_read(source,buff,4096); 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;4.3实验三4.3.1实验

28、要求掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动)4.3.2具体实现(1)Linux核心是一种monolithic类型的内核,即单一的大核心,另外一种形式是MicroKernel,核心的所有功能部件都被拆成独立部分, 这些部分之间通过严格的通讯机制进行联系。Linux内核是一个整体结构,因此向内核添加任何东西.或者删除某些功能,都十分困难 。为了解决这个问题,引入了模块机制,从而可以动态的在内核中添加或者删除模块。模块一旦被插入内核,就和内核其他部分一样。Linux内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低级硬件处理例程。对用户程序而言,设备驱动程序隐藏了设备的具体细节, 对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文 件,用户程序可以像对其它文件一样对此设备文件进行操作。Linux支持3种设备:字符设备、块设备和网络设备。设备由一个主设备号和一个次设备号标识。主设备号唯一标识了设备类型, 即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释 ,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的那个设备。典型的Linux模块实现机制有如下几步:注册设备:在系统初启或者加载模块的时候,必须将设备登记到相应的设备数组,并返回主

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2