操作系统课设Word文档格式.docx

上传人:b****5 文档编号:8453072 上传时间:2023-05-11 格式:DOCX 页数:56 大小:527.24KB
下载 相关 举报
操作系统课设Word文档格式.docx_第1页
第1页 / 共56页
操作系统课设Word文档格式.docx_第2页
第2页 / 共56页
操作系统课设Word文档格式.docx_第3页
第3页 / 共56页
操作系统课设Word文档格式.docx_第4页
第4页 / 共56页
操作系统课设Word文档格式.docx_第5页
第5页 / 共56页
操作系统课设Word文档格式.docx_第6页
第6页 / 共56页
操作系统课设Word文档格式.docx_第7页
第7页 / 共56页
操作系统课设Word文档格式.docx_第8页
第8页 / 共56页
操作系统课设Word文档格式.docx_第9页
第9页 / 共56页
操作系统课设Word文档格式.docx_第10页
第10页 / 共56页
操作系统课设Word文档格式.docx_第11页
第11页 / 共56页
操作系统课设Word文档格式.docx_第12页
第12页 / 共56页
操作系统课设Word文档格式.docx_第13页
第13页 / 共56页
操作系统课设Word文档格式.docx_第14页
第14页 / 共56页
操作系统课设Word文档格式.docx_第15页
第15页 / 共56页
操作系统课设Word文档格式.docx_第16页
第16页 / 共56页
操作系统课设Word文档格式.docx_第17页
第17页 / 共56页
操作系统课设Word文档格式.docx_第18页
第18页 / 共56页
操作系统课设Word文档格式.docx_第19页
第19页 / 共56页
操作系统课设Word文档格式.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统课设Word文档格式.docx

《操作系统课设Word文档格式.docx》由会员分享,可在线阅读,更多相关《操作系统课设Word文档格式.docx(56页珍藏版)》请在冰点文库上搜索。

操作系统课设Word文档格式.docx

要求用到Linux下的图形库(GTK/Qt)。

3.2实验二

掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。

实现的功能是:

文件拷贝。

3.3实验三

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

通过模块方法,增加一个新的设备驱动程序,其功能可以简单。

(实现字符设备的驱动)

3.4实验四(选做)

了解和掌握/proc文件系统的特点和使用方法

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

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

(3)用图形界面实现系统监控状态;

3.5实验五(选做)

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

多用户的多级目录的文件系统设计。

多用户、多级目录、login(用户登录)、系统初始化(建文件卷,提供登录模块)、文件的创建、文件的打开、文件的读写、文件关闭、删除文件、创建目录(建立子目录)、改变当前目录、列出文件目录、退出。

4设计与实现

4.1实验一

4.1.1实验要求

4.1.2具体实现

本实验内容是用CodeBlocksIDE实现的,该软件整合了函数库和编译器,因此使用起来非常方便。

在windows操作系统上实现的文件拷贝功能一般使用fopen、fread、fwrite三个来自标准C函数库的函数执行对文件的打开、读、写操作,而本次实验要求使用Linux系统的系统调用open、read、write实现上述三个操作。

用到的主要头文件如下:

stdio.h——标准输入输出头文件

string.h——字符串处理相关头文件

unistd.h——Linux系统调用头文件,比如read、write

fcntl.h——包含open系统调用

errno.h——包含一些调试错误时用到的变量

具体实现思路:

打开两个文件(分别是源文件和目标文件,可以是任意字符流形式存储的文件,包括文本文件、照片等),调用read函数读取源文件的内容,将read的返回值作为while循环的判断条件,当返回值大于0(即还未读取完毕源文件中的内容)时,调用write执行向目标文件写的操作,否则跳出循环,表示源文件已经被拷贝到目标文件,然后调用close关闭源文件和目标文件。

代码编写完成后,在CodeBlocks上编译运行即可。

程序运行之前,桌面上只有“教程.docx”,运行之后,桌面上新建了“教程副本.docx”,并且“教程.docx”中的内容被复制到了“教程副本.docx”,程序运行结果如下所示:

详细代码见4.1.3。

本次实验使用的图形库是跨平台的开发工具Qt。

首先下载Qt的安装包并安装。

Qt安装完之后,先新建一个Qt控制台应用MAIN作为主进程,用于调用三个并发的子进程。

在主进程的main函数中,使用fork创建三个子进程,若进程创建成功(即fork函数返回值等于0),则使用execv函数进入对应的子进程(get、copy、put)。

主进程程序编写完成后,再新建三个QtWidgetsApplication,分别作为三个子进程get、copy、put(所实现的功能并不是拷贝)。

由于三个子进程窗口显示的内容形式一模一样,所以以子进程get为例。

get进程的窗口显示了一下四个内容:

当前时间、子进程名称、子进程的pid和父进程MAIN的pid。

用Qt的对象QDateTime获取系统当前时间,然后将时间转换成一个字符串写在一个QLabel类的实例中,然后将该实例添加至窗口;

直接把当前进程名称写在一个标签上然后添加至窗口;

使用getpid和getppid函数分别获取当前进程号和父进程号,然后调用sprintf把进程号转换成字符串类型之后写在标签上并添加至窗口即可。

主进程和三个子进程的程序全部编写完后,直接在Qt上编译运行。

程序运行结果如下所示:

4.1.3源代码

(1)文件拷贝源代码

#include<

stdio.h>

stdlib.h>

string.h>

unistd.h>

fcntl.h>

sys/syscall.h>

errno.h>

#defineSIZE10///每次读取的字符数目

char*srcFile="

/home/ilbear/桌面/教程.docx"

;

char*goalFile="

/home/ilbear/桌面/教程副本.docx"

intmain(intargc,constchar*argv[])

{

intsrc,goal;

intread_len;

charbuff[SIZE];

src=open(srcFile,O_RDONLY);

if(src<

0)

{

printf("

Failtoopen%s\n."

srcFile);

exit

(1);

}

goal=open(goalFile,O_WRONLY|O_CREAT,0666);

if(goal<

goalFile);

exit

(1);

while((read_len=read(src,buff,SIZE))>

write(goal,buff,read_len);

close(src);

close(goal);

return0;

}

(2)三个并发进程

#主进程MAIN

QCoreApplication>

sys/types.h>

sys/wait.h>

sys/stat.h>

intmain(intargc,char*argv[])

QCoreApplicationa(argc,argv);

pid_tp1,p2,p3;

if((p1=fork())==0)

execv("

/home/ilbear/桌面/build-get-Desktop_Qt_5_4_1_GCC_64bit-Debug/get"

NULL);

else

if((p2=fork())==0)

/home/ilbear/桌面/build-copy-Desktop_Qt_5_4_1_GCC_64bit-Debug/copy"

if((p3=fork())==0)

/home/ilbear/桌面/build-put-Desktop_Qt_5_4_1_GCC_64bit-Debug/put"

waitpid(p1,NULL,0);

waitpid(p2,NULL,0);

waitpid(p3,NULL,0);

returna.exec();

#子进程get

mainwindow.cpp

#include"

mainwindow.h"

ui_mainwindow.h"

QtCore>

time.h>

MainWindow:

:

MainWindow(QWidget*parent):

QMainWindow(parent),

ui(newUi:

MainWindow),sharememory1("

share1"

ui->

setupUi(this);

setWindowTitle("

get"

);

setWindowFlags(Qt:

Dialog);

move(0,0);

resize(500,500);

charstr[128],f_id[128];

sprintf(str,"

%d"

getpid());

sprintf(f_id,"

getppid());

textBrowser->

setText("

textBrowser_2->

setText(str);

textBrowser_3->

setText(f_id);

QTimer*timer=newQTimer(this);

connect(timer,SIGNAL(timeout()),this,SLOT(timerUpDate()));

timer->

start

(1);

~MainWindow()

deleteui;

voidMainWindow:

timerUpDate()

QDateTimetime=QDateTime:

currentDateTime();

QStringstr=time.toString("

yyyy-MM-ddhh:

mm:

ssdddd"

labelCurDate->

#子进程copy

),sharememory2("

share2"

copy"

move(500,500);

resize(500,500);

#子进程put

MainWindow),sharememory2("

put"

move(1000,0);

ui->

4.2实验二

4.2.1实验要求

4.2.2具体实现

(1)系统调用的原理

用户进程不能访问内核所占内存空间,也不能调用内核函数。

进程调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置。

在IntelCPU中,由中断INT0x80实现。

(与DOS功能调用int0x21很相似)跳转到的内核位置叫做sysem_call。

检查系统调用号,这个号码代表进程请求哪种服务。

然后,它查看系统调用表(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,避免使用的缓冲区超过了用户空间的地址范围而报错。

详细代码见4.2.3。

(3)编译内核

①下载并解压内核

先到Linux官方网站http:

//www.kernel.org/下载内核linux-3.14.36.tar.xz。

打开终端,使用sudosu获取root权限,然后使用cplinux-3.14.36.tar.xz/usr/src命令将linux-3.14.36.tar.xz复制到文件夹/usr/src下,复制完毕之后将其解压,用到的命令为:

xz-dlinux-3.14.36.tar.xz和tarxvflinux-3.14.36.tar。

②修改内核

新的内核解压完毕后,使用cd/usr/src/linux-3.14.36命令进入目录/usr/src/linux-3.14.36。

然后使用命令sudogeditkernel/sys.c打开sys.c,将新的系统调用程序复制到该文件的文件末尾,保存退出,系统调用程序详细代码见4.2.3。

使用命令sudogeditarch/x86/syscalls/syscall_64.tbl打开syscall_64.tbl添加系统调用号。

在该文件中添加一行内容317commonmycallsys_mycall,其中系统调用号317不是固定的,只要该文件中没有出现的数字都可以使用。

添加之后保存退出。

使用命令sudogeditinclude/asm-generic/syscalls.h打开syscalls.h,在“#endif/*__ASM_GENERIC_SYSCALLS_H*/这一行的上面一行添加新的系统调用程序的函数定义,即:

#ifndefsys_mycall

asmlinkageintsys_mycall(char*sourceFile,char*destFile);

#endif

然后保存退出。

③编译内核

在编译内核之前先要安装ncurses库,使用命令sudoapt-getinstalllibncurses5-dev安装。

安装完毕后,进入/usr/src/linux-3.14.36目录下,新建一个脚本文件mysyscall.sh,通过命令geditmysyscall.sh打开该脚本文件进行编辑。

将以下内容添加到脚本中:

#!

/bin/bash

makemrproper

makemenuconfig

makedep

makeclean

makebzImage–j4

makemodules–j4

makemodules_install–j4

makeinstall–j4

mkinitramfs-o/boot/initrd.img-3.14.34

update-grub

reboot

保存退出,然后修改脚本文件的权限,使其可以对内核文件进行操作,修改权限的命令为chmod777mysyscall.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函数中直接调用头文件syscall.h中定义的函数syscall,该函数有三个参数,第一个参数是系统调用号(317),第二个参数是源文件(main.c,即测试程序的源代码文件),第三个参数是目标文件(yyk.text)。

程序运行结果为:

在main.c所在目录下新建了一个yyk.text文件,并将main.c中的代码拷贝到了yyk.text中。

4.2.3源代码

(1)系统调用程序

asmlinkageintsys_mycall(char*SourceFile,char*GoalFile)

intsource=sys_open(SourceFile,O_RDONLY,0);

intgoal=sys_open(GoalFile,O_WRONLY|O_CREAT|O_TRUNC,0600);

charbuff[4096];

mm_segment_tfs;

fs=get_fs();

set_fs(get_ds());

inti;

if(source>

0&

&

goal>

do

i=sys_read(source,buff,4096);

sys_write(goal,buff,i);

while(i);

printk("

Error!

"

sys_close(source);

sys_close(goal);

set_fs(fs);

return10;

(2)测试程序

syscall.h>

intmain()

syscall(317,"

main.c"

"

yyk.text"

4.3实验三

4.3.1实验要求

4.3.2具体实现

(1)Linux核心是一种monolithic类型的内核,即单一的大核心,另外一种形式是MicroKernel,核心的所有功能部件都被拆成独立部分,这些部分之间通过严格的通讯机制进行联系。

Linux内核是一个整体结构,因此向内核添加任何东西.或者删除某些功能,都十分困难。

为了解决这个问题,引入了模块机制,从而可以动态的在内核中添加或者删除模块。

模块一旦被插入内核,就和内核其他部分一样。

Linux内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低级硬件处理例程。

对用户程序而言,设备驱动程序隐藏了设备的具体细节,对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文件,用户程序可以像对其它文件一样对此设备文件进行操作。

Linux支持3种设备:

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

设备由一个主设备号和一个次设备号标识。

主设备号唯一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。

次设备号仅由设备驱动程序解释,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的

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

当前位置:首页 > 自然科学 > 物理

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

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