操作系统课程设计报告.docx

上传人:b****7 文档编号:23623126 上传时间:2023-05-19 格式:DOCX 页数:19 大小:1.04MB
下载 相关 举报
操作系统课程设计报告.docx_第1页
第1页 / 共19页
操作系统课程设计报告.docx_第2页
第2页 / 共19页
操作系统课程设计报告.docx_第3页
第3页 / 共19页
操作系统课程设计报告.docx_第4页
第4页 / 共19页
操作系统课程设计报告.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

操作系统课程设计报告.docx

《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(19页珍藏版)》请在冰豆网上搜索。

操作系统课程设计报告.docx

操作系统课程设计报告

课程设计报告

课程名称:

操作系统原理

 

院系:

计算机科学与技术

专业班级:

CS140______

学号:

U201414_____

姓名:

_________

指导教师:

_________

完成时间:

2017年3月11日_

 

 

1实验目的

·掌握Linux操作系统的使用方法;

·了解Linux系统内核代码结构;

·掌握实例操作系统的实现方法;

2实验环境

本次课程设计采用的操作系统环境是windows10、Ubuntu双系统,Ubuntu系统版本号为,内核版本号为linux;前两个实验在当前Ubuntu环境下完成,后两个实验在win10下虚拟机VirtualBox的Ubuntu(内核为)中完成。

3实验内容

3.1实验一

要求熟悉和理解Linux下的编程环境。

(1)编写一个C程序,用fread、fwrite等库函数实现文件拷贝功能。

(2)编写一个C程序,使用基于文本的终端图形编程库(curses)或图形界面(QT/GTK),分窗口显示三个并发进程的运行(一个窗口实时显示当前时间,一个窗口实时监测CPU的利用率,一个窗口做1到100的累加求和,刷新周期分别为1秒,2秒和3秒)。

3.2实验二

要求掌握添加系统调用的方法,采用编译内核方法,添加一个新的系统调用,实现文件拷贝的功能,另外编写一个应用程序,测试新增加的系统调用。

3.3实验三

掌握增加设备驱动程序的方法。

采用模块方法,添加一个新的字符设备驱动程序,实现打开/关闭,读/写等基本操作。

另外编写一个应用程序,测试新添加的驱动程序。

3.4实验四

要求理解和分析/proc文件。

(1)了解/proc文件的特点和使用方法;

(2)监控系统状态,显示系统部件的使用状态;

(3)用图形界面实现系统监控状态,包括CPU和内存利用率、所有进程信息等(可自己补充、添加其他功能);

3.5实验五(选做)

要求理解和掌握文件系统的设计方法(选做)。

设计、实现一个模拟的文件系统。

包括文件/目录创建/删除,目录显示等基本功能(可自行扩充文件读/写、用户登录、权限控制、读写保护等其他功能)。

4设计与实现

4.1实验一

4.1.1实验要求

要求熟悉和理解Linux下的编程环境。

4.1.2实验设计及调试

(1)编写一个C程序,其内容为实现文件拷贝的功能。

这个实验的思路是声明两个文件指针*fp_read和*fp_write,前者用来打开要读的文件,后者打开要写的文件,再创建一个1000个字节大小的缓冲区buff[],然后调用fread将内容从文件1读到buff里,再调用fwrite把内容从buff写到文件2中。

这个实验重点要掌握fread和fwrite的使用方法,注意它们的参数和返回值。

代码见附件中源码。

实验结果如下图:

图运行之前图

运行./lab1_1后结果如下图:

图运行之后图

由上图可见成功拷贝至

(2)编写一个C程序,本次实验使用的是图形界面GTK,分窗口显示三个并发进程的运行(一个窗口实时显示当前时间,一个窗口实时监测CPU的利用率,一个窗口做1到100的累加求和,刷新周期分别为1秒,2秒和3秒)。

这个实验要用到gtk,首先要配置gtk,在终端中输入:

sudoapt-getinstall

涉及到3个进程的并发,所以要调用函数fork来创建3个进程。

我的思路是在这3个进程中分别创建一个线程,去完成相应的功能:

显示当前时间,监测CPU利用率,做累加求和。

分别通过函数voidhavetime()、voidcpu_usage()、voidadd()实现,在main函数里,初步画出3个进程相应的界面。

具体的是调用gtk_window_new()函数创建一个窗口、gtk_window_set_title()设置窗口标题、gtk_window_set_position设置窗口在屏幕的位置、gtk_label_new()创建一个标签用来显示文本、gtk_container_add()把标签添加到窗口中、gtk_widget_show_all()来展示需要展示的控件。

例如创建第一个线程:

g_thread_create((GThreadFunc)havetime,NULL,FALSE,NULL);

通过在线程havetime()中实时更新标签label的内容,然后在main()中创建的窗口中展示来完成所要求的功能。

进程2和3所要求的功能也是通过这种方法实现。

注意用到gtk的编译命令与以往不同,为:

gcc-olab1_2`pkg-config--cflags--libsgtk+`

代码见附件中的源码,实验结果如下图:

图运行结果图

小插曲:

在调用sprintf(s,"CPU利用率为%f%%",usage)想把利用率的“%”拷进缓冲区s后打印出来时,一个百分号是不能够打印出来的,要写两个%,如想要打印两个%,则要写4个%,以此类推。

4.2实验二

4.2.1实验要求

要求掌握添加系统调用的方法,采用编译内核方法,添加一个新的系统调用,实现文件拷贝的功能,另外编写一个应用程序,测试新增加的系统调用。

4.2.2实验设计及调试

下载一个内核下载在/usr/src/目录下解压(用超级用户权限),

(1)编写新的系统调用程序

用户空间所使用的open、read、write、close函数此时对应内核函数为sys_open、sys_read、sys_write、sys_close。

首先通过sys_open()打开源文件和目标文件,分别返回文件描述符source和dest,然后把当前的用户地址范围保存在fs,再把当前内存访问地址范围设置为内核的内存地址访问范围,再通过sys_read()把源文件内容写到buf,再用sys_write()把buf内容写到dest,接着用sys_close()来关闭文件,最后再把内存访问地址范围设置为用户的。

保存fs是避免使用的缓冲区超过了用户空间的地址范围而报错。

把自己写的这个系统调用程序添加至/usr/src/目录下的最后。

(2)添加系统调用号

在/usr/src/目录下修改文件,添加一个自己的调用程序的系统调用号,我的之前用到了325好,所以添加326号,如下:

326commonmysyscallsys_mysyscall

(3)添加系统调用程序的声明

在/usr/src/目录下的最后加上自己添加的系统调用程序的声明如下:

asmlinkageintsys_mysyscall(char*sourceFile,char*destFile);

(4)编译、安装内核

在/usr/src/目录下对内核选项进行配置:

sudomakemenuconfig

图内核配置图

选择save后退出

接下来就是漫长的编译内核了(4个线程跑会快一些):

sudomake-j4

大概1个小时左右编译完毕,再安装内核:

sudomakemodules_install

lab2后如下图:

图运行之后的图

可见系统调用成功。

 

4.3实验三

4.3.1实验要求

掌握增加设备驱动程序的方法。

采用模块方法,添加一个新的字符设备驱动程序,实现打开/关闭,读/写等基本操作。

另外编写一个应用程序,测试新添加的驱动程序。

4.3.2实验设计及调试

(1)添加设备驱动原理:

linux设备一般分为:

字符设备、块设备和网络设备。

驱动程序运行在内核空间,应用程序通常通过文件系统接口函数访问/dev目录下的设备文件来访问驱动程序。

编写设备驱动程序的主要工作就是编写file_operations子函数,这次实验主要完成的就是file-operations数据结构中的.open\.release\.read\.write4个模块,file_operations结构的每个域都对应一个系统调用。

用户进程利用系统调用在对设备文件进行诸如read/write等操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取该数据结构相应的函数指针,接着把控制权交给该函数。

(2)编写Makefile文件

Makefile文件用于编译设备驱动程序,其内容如下:

iifeq($(KERNELRELEASE),)

KERNELDIR=/lib/modules/$(shelluname-r)/build

PWD:

=$(shellpwd)

modules:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modules

modules_install:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modules_install

clean:

rm-rf*.o*~core.depend.*.cmd*.ko*..tmp_versions

.PHONY:

modulesmodules_installclean

else

obj-m:

=

endif

(3)编写设备功能函数

编写设备驱动程序的主要工作就是编写子功能函数。

open()函数用来打开一个设备,在该函数中可以对设备进行初始化。

如果这个函数被赋值NULL,那么设备打开永远成功,并不会对设备产生影响。

release()函数用来释放open()函数中申请的资源,并在文件引用计数为0时,被系统调用。

其对应应用程序的close()方法,但并不是每一次调用close()方法,都会触发release()函数,只有在打开的所有设备文件都释放后,该函数才会被调用。

read()函数用来从设备中获取数据,成功时返回读取的字节数,失败时返回一个负的错误码。

write()函数用来写数据到设备中。

成功时该函数返回写入的字节数。

详细实现见附件中源码。

(4)设备驱动程序安装

1make,调用Makefile编译设备驱动程序

图make图

编译成功,生成文件

2sudoinsmod挂载模块,再查看设备的主设备号:

cat/proc/devices

图主设备号的图

可见系统为mydev生成的主设备号为248

3sudo/dev/mydevc2480

mydev是设备文件的名字,“c”是指创建的是字符设备文件,248是主设备号,0是从设备号。

图生成设备文件图

可见生成了正确的设备文件mydev

(5)测试驱动程序

测试程序实现的是先从设备中读出里面初始的字符串U3,再把一个字符串写进去,然后再读出来,测试程序详见附件源码,测试实验结果如下图:

先运行命令执行程序:

sudo./test

图结果图

可见打开、读、写均正确。

最后执行sudormmodmydev来删除模块

sudorm/dev/mydev来删除设备文件

4.4实验四

要求理解和分析/proc文件。

4.4.1实验要求

了解/proc文件的特点和使用方法;监控系统状态,显示系统部件的使用状态;用图形界面实现系统监控状态,包括CPU和内存利用率、所有进程信息等(可自己补充、添加其他功能)。

4.4.2实验设计及调试

这个实验主要是对/proc文件的理解和对gtk的熟练运用。

我用gtk里的笔记本构件画了3个页面,分别为pageone、pagetwo、pagethree。

pageone:

显示CPU利用率

计算和显示CPU直接用到的实验一第二个部分的显示CPU利用率部分,不同的是这儿用到了笔记本控件,要把“pageone”作为一个button加到notebook上,还要把算出来的CPU利用率作为一个标签内容加到notebook上,即:

hbox

 

scrolled_window

 

vbox

 

frame

 

button

clist

 

GtkWidget*button4=gtk_label_new("Pageone");

label1=gtk_label_new("begin");lab4

实验结果如下图、、:

图第一个页面图

图第二个页面图

图第三个页面图

 

5心得体会

本次课程设计,第一个题目第一问很简单,因为之前在实验中写过文件拷贝的程序,所以很快就顺利实现了,要注意fopen、fread、fwrite几个函数的用法,第二问刚开始不知怎么做,主要是因为之前没接触过gtk这种画界面的环境,在网上查阅相关资料后发现套路都是一样的,个人觉得把握住gtk中控件的概念,实现简单的界面都还是比较简单的,除了gtk,在CPU利用率的计算上还卡了一段时间,主要是没弄清到底应该怎么计算,查了大量资料后找到一种比较简单的计算方法去实现,结果也很准确;第二题和第三题是同一类型,都是需要对内核、系统调用、设备驱动文件有很好的理解才能很快做出来,自己还掌握得不是很好,所以也花了不少的时间去查资料、实现要求的功能,但现在回过头来看收获很大,对课上所学的部分内容有了更加深刻的理解,对linux系统调用和设备文件有了更深的认识;第四题确实是花的时间最多的,因为不仅涉及到复杂的gtk运用,还包括对/proc文件的理解,这两方面都是查了大量资料后才一点点完成的,时间花了,确实也有了成效,看到自己画的界面和读出的进程、CPU信息,成就感瞬间爆棚,但这还远远不够,相信以后学习工作中还会遇到更加困难的类似的问题,这次课设只是打下了个小小的基础,任重道远!

总之,这次课设受益匪浅。

 

6附录(源码)

实验一:

第一题:

#include<>

#definebuffer_size1000

intmain(intargc,char*argv[])

{

if(argc!

=3)ead=my_read,

.write=my_write,

.open=my_open,

.release=my_release

};

intinit_module(){

intret;

ret=register_chrdev(0,devname,&pstruct);

if(ret<0){

printk("registfailure\n");

return-1;

}

else{

printk("thedevicehasbeenregistered!

\n");

device_num=ret;

printk("<1>thevirtualdevice'smajornumber%d.\n",device_num);

printk("<1>Oryoucanseeitbyusing\n");

printk("<1>------more/proc/devices-------\n");

printk("<1>Totalktothedriver,createadevfilewith\n");

printk("<1>------'mknod/dev/myDevicec%d0'-------\n",device_num);

printk("<1>Use\"rmmode\"toremovethemodule\n");

return0;

}

}

voidcleanup_module(){

unregister_chrdev(device_num,devname);

printk("unregisteritsuccess\n");

}

staticintmy_open(structinode*inode,structfile*file){

printk("<1>maindevice:

%d\n",MAJOR(inode->i_rdev));

printk("<1>slavedevice:

%d\n",MINOR(inode->i_rdev));

printk("<1>%dtimestocallthedevice\n",++counter);

try_module_get(THIS_MODULE);

return0;

}

staticintmy_release(structinode*inode,structfile*file){

printk("Devicereleased!

\n");

module_put(THIS_MODULE);

return0;

}

staticssize_tmy_write(structfile*file,constchar__user*user,size_tt,loff_t*f){

if(copy_from_user(message,user,sizeof(message)))

{

return-EFAULT;

}

returnsizeof(message);

}

staticssize_tmy_read(structfile*file,char__user*user,size_tt,loff_t*f){

if(copy_to_user(user,message,sizeof(message)))

{

return-EFAULT;

}

returnsizeof(message);

}

:

#include

#include

#include<>

#include<>

#include<>

#include<>

#include<>

#defineMAX_SIZE1024

intmain(void)

{

intfd;

charbuf[MAX_SIZE];

charget[MAX_SIZE];

chardevName[20],dir[50]="/dev/";

system("ls/dev/");

printf("Pleaseinputthedevice'snameyouwannatouse:

");

gets(devName);

strcat(dir,devName);

fd=open(dir,O_RDWR|O_NONBLOCK);

if(fd!

=-1)

{

read(fd,buf,sizeof(buf));

printf("Thedevicewasinitedwithastring:

%s\n",buf);

/*测试写*/

printf("Pleaseinputastring:

\n");

gets(get);

write(fd,get,sizeof(get));

/*测试读*/

read(fd,buf,sizeof(buf));

system("dmesg");

printf("\nThestringinthedevicenowis:

%s\n",buf);

close(fd);

return0;

}

else

{

printf("Deviceopenfailed\n");

return-1;

}

}

makefile:

ifeq($(KERNELRELEASE),)

KERNELDIR=/lib/modules/$(shelluname-r)/build

PWD:

=$(shellpwd)

modules:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modules

modules_install:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modules_install

clean:

rm-rf*.o*~core.depend.*.cmd*.ko*..tmp_versions

.PHONY:

modulesmodules_installclean

else

obj-m:

=

endif

实验四:

#include

建笔记本控件

GtkWidget*notebook=gtk_notebook_new();

gtk_container_add(GTK_CONTAINER(window),notebook);

gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook),GTK_POS_TOP);立进程信息选项卡*/

intp=0,q=0,r=0,s=0;

charbufferf1[1000];

sprintf(bufferl,"Pagetwo");

GtkWidget*hbox=gtk_hbox_new(FALSE,5);

GtkWidget*scrolled_window=gtk_scrolled_window_new(NULL,NULL);示所有网页

gtk_widget_show_all(window);

事件循环

gtk_main();

return0;

}

 

参考文献:

[1]计算机操作系统实验指导.人民邮电出版社.2014年.

[2]计算机操作系统(第二版).人民邮电出版社.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 中职中专

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

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