当前位置:文档之家› 系统软件课程设计(操作系统)大纲

系统软件课程设计(操作系统)大纲

系统软件课程设计(操作系统)大纲
系统软件课程设计(操作系统)大纲

课程设计大纲

一、教学基本目标

本设计的目的是实现操作系统和相关系统软件的设计,其中涉及进程编程、I/O操作、存储管理、文件系统等操作系统概念。

二、教学基本内容

1.Shell编程:掌握Linux O.S.环境,掌握基本环境等

2.Linux系统调用:掌握系统调用的执行流程,增加一个新的系统调用。

3.Linux二级文件系统:编写程序实现模拟Linux文件系统

详见附录。

三、教学进度安排

1.课程设计要求说明4学时

2.软件设计16学时

3.上机编程32学时

4.调试4学时

5.检查考核8学时

四、课程设计报告要求

1.对进行认真分析,列出实验具体步骤,写出符合题目要求的程序清单,准备出调试程序使用的数据。

2.以完整的作业包的形式提交原始代码、设计文档和可运行程序。提交的软件应当包括:设计题目,程序清单,运行结果分析,所选取的算法及其优缺点,以及通过上机取得了哪些经验。程序清单要求格式规范,注意加注释(包含关键字、方法、变量等),在每个模块前加注释,注释不得少于20%。课程设计要求同时上交打印文档,设计报告包括设计题目,算法分析,关键代码及其数据结构说明,运行结果分析以及上机实践的经验总结。

五、考核方式与成绩评定方法

根据以下几方面情况评定实验成绩:

1.分析与设计能力

2.系统实现能力

3.系统文档以及设计报告的规范性

4.是否在规定时间内完成设计

5.工作态度

六、参考书

1.操作系统:精髓与设计原理(第7版)(英文版) 蒲晓蓉、周瑞、斯托林斯(William Stallings)、威廉?斯托林斯(William Stallings) 电子工业出版社(2013-07)

2. 计算机操作系统(第3版) 汤小丹、梁红兵、哲凤屏、汤子瀛西安电子科技大学出版社(2007-08)

3.计算机操作系统教程(第3版) 张尧学、史美林、张高清华大学出版社(2006-10)

七、审核:(系主任签字)审核:(实验室主任签字)

批准:(副院长签字)

实验一Shell编程

一、实验目的

学习如何编写一个Linux的外壳——Shell,即命令解释程序。学习怎样接受命令、解释命令、执行命令,特别是采用创建子进程的方式来执行一个程序,以及父进程如何继续子进程的工作。

二、实验内容

1、编写一个C语言程序作为Linux内核的shell命令行解释程序,所执行的结果需和系

统命令行方式保持一致,从而使学生了解系统是怎样进行命令的解析和执行的。同时,还提供认识进程创建、进程等待、进程执行、前/后台执行、管道和I/O重定向含义的机会。

基本运行方式如下:

用户敲入命令行

identifier [identifier[identifier……]]

shell应该解析命令行参数指针数组argv[argc]。使用Linux的系统调用

fork()、wait()和execv()等完成。

2、对用户编写的shell增加后台运行功能。即用户可以使用”&”作为一个命令

结束,以启动下一个命令。

3、修改程序,增加I/O重定向功能。即用户可以使用”<”、”>”和”|”符号改变程序/文件

的输入和输出。

三、实验提示

1、基本的Shell

(1)命令行工作方式

每个shell都有自己语言的语法和语义。在标准Linux shell中,一个命令行具有以下形式:

命令名参数1 参数2……

shell的工作是找到与命令名对应的可执行程序(命令),为其准备参数,并使用参数执行命令。

shell程序需具有以下几种功能和健壮性:

⑴支持目录检索功能,即文件不存在,继续打印提示符

⑵支持以“&”结束的输入,进行并发执行(前台与后台)

⑶支持输入输出重定向,“<”,“>”为标志符

⑷支持以“|”进行进程间通信操作(管道功能)

⑸支持一定的错误输入处理,例如:多于空格的出现,输入命令不存在,空输入等等

考虑shell为了完成工作必须采取以下步骤:

⑴打印提示符

存在一个默认的提示符,有时在硬化shell中,如单字符串%、#或>。当shell启动时,它查找在其上运行的机器名并将该字符串加到标准提示符前,如kiowa>。Shell也可以被设计为打印当前目录作为提示符的一部分,也即每次用户键入cd改变到不同的

目录时,提示字符串也会相应变化。一旦提示字符串确定下来,每当shell准备接受一个命令行时便把它打印到stdout。

⑵得到命令行

为了得到一个命令行,shell执行一个阻塞读操作让执行shell的进程进入睡眠状态,直到用户键入一个命令行作为对提示符的相应。一旦用户键入命令行(以一个NEWLINE (“\n”)字符结束),命令行字符串就被返回到shell。

⑶解析命令

命令行的语法非常琐细。解析程序从命令行的左边开始扫描直到它遇到一个空白字符(如空格、制表符或者NEWLINE)。第一个单词是命令的名称,而后面的单词则是参数。

⑷查找文件

shell为每一个用户提供一组环境变量。虽然这些环境变量可以随时通过set命令修改,但它们首先在用户的.login文件中定义。PATH环境变量是一个有序的绝对路径列表。

它指明了shell应该在什么地方寻找命令文件,如果.login具有一个类似以下的行set path=(./bin/usr/bin)

那么shell将首先在当前目录中寻找(因为第一个完全路径名是用“.”代表当前目录),然后是/bin,最后是/usr/bin。如果(从命令行)在任何指定的目录中都没有找到与命令行同名的文件,那么shell将提示用户无法找到命令。

⑸准备参数

shell简单地将参数传递到命令,作为指向字符串的argv数组。

⑹执行命令

shell必须执行指定文件的可执行程序。UNIX shell总是设计为当它执行一个程序时保护原始进程不被破坏。也就是说,因为一个命令可以是任何可执行文件,那么执行shell的进程必须保护它自己以防止可执行文件包含致命的错误。

(2)Linux提供的重要函数:

用户键入的命令可能有误,即便找到要求的可执行文件也可能包含致命的错误,因此要求shell程序每接受一个命令后,均创建子进程,让子进程来执行命令文件。如果命令正确,并创建子进程成功,父进程等待子进程完成。如果命令不正确或可执行文件有错或创建子进程失败,则给出相应的错误提示,撤消子进程,回到shell,等待用户输入下一个命令。这样shell进程不会受到伤害。

编写这个模拟shell,需要调用UNIX风格的系统调用fork()、exec()和wait()等.

⑴int fork(void)

创建一个新进程。调用fork的进程称为父进程,新进程是子进程。Fork系统调用为父子进程返回不同的值:子进程中返回0,父进程中返回子进程的PID,如创建不成功返回负数值。

⑵exec系列

exec系统调用用新程序覆盖调用它的进程的地址空间。exec把一个新的程序装入调用进程的内存空间,来改变调用进程的执行代码。当exec()返回时,进程从新程序的第一条指令恢复执行。exec没有建立一个与调用进程并发执行的新进程,而是用新进程取代了老进程。

exec加后缀,可有多种格式。

execl(path,arg0,arg1,…argn,(char *)0);

execv(path,argv);

execlp(file,arg0,arg1,…argn, (char *)0);

execvp(file,argv);

其中l代表长格式,v代表利用argv传参,e代表从envp传递环境变量,p代表从PATH指定路径搜索文件。

⑶wait系列

wait系统调用可以使进程等待子进程终止。该函数将阻塞调用进程,直到该进程的某一个子进程结束运行(如果子进程收到一个信号而结束运行,该函数也会返回)。子进程的结束状态保存在status指向的整数中。如果status为空,就不会返回子进程的结束状态。如果在调用wait之前子进程结束运行,wait会立即返回子进程的结束状态,wait返回值为子进程的进程ID。若子进程不存在,则返回-1。

wait(int *stat_loc); /*System V,BSD,and POSIX.1 */

wait3(stausp,options,rusagep); /* BSD */

waitpid(pid,*stat_loc,options); /* POSIX.1 */

waited(idtype,id,infop,options); /* SVR4 */

以上三个系统调用联用时,形成shell用于执行命令的一个代码框架。

if(fork()==0){

//这是子进程

//执行于和父进程相同的环境变量中

execvp(full_pathname,command->argv,0);

}else

{

//这是父进程――等待子进程终止

wait(status);

}

⑷int dup(int fd)

把一个程序的标准输出连接到管道的写入端,把另一个程序的标准输入连接到管道的读出端。返回一个新的文件描述符,该描述符和fd指向同一个文件。新的文件描述符具有同样的存取模式,以及同样的读/写偏移量。用这个函数可以进行输入/输出重定向。

输出重定向步骤如下:

fid=open(file,O_WRONLY|O_CREAT);

close(1);

dup(fid);

close(fid);

标准输入(stdin)、标准输出(stdout)和标准错误(stderr)分别占用0、1和2。要求先关闭标准输出,从而使1成为当前系统内可用作文件描述符的最小数(注意,0被标准输入占用),然后调用dup,使管道文件与文件描述符1(即标准输出)连接。

⑸int pipe(int pipeID[2])

管道是单处理器Linux系统的主要IPC机制。默认情况下,管道采取异步发送并阻塞接受操作。管道是先进现出缓冲区,它设计为带有与文件I/O接口十分相似的API。一个管道可能在任何给定时刻包含系统定义最大数量的字节,通常为4KB。一个进程可以通过将数据写入到管道的一端来发送数据,而另一进程可以通过管道的另一端读取来接受数据。管道在内核中由一个文件描述符代表。一个欲建立管道的进程通过以下形式来调用内核:int pipeID[2];

……

pipe(pipeID);

该函数可以创建两个文件描述符,pipeID[0]用于读,pipeID[1]用于写。这两个文件描述符连接起来就是一个管道。

对于使用管道作为IPC(进程间通信)的两个或多个进程,这些进程的共同祖先在创建进程之前就必须创建管道。因为fork命令创建一个含有打开文件表拷贝的子进程,子进程继承父进程所创建的管道。为了使用管道,它只需要读写适当的文件描述符。

例如,假如一个父进程创建了管道。那么它可以创建一个子进程并通过使用如下代码与之通信。

Pipe(pipeID);

If(fork()==0){ /* 子进程*/

……

read(pipeID[0],childBuf,len);

/* 处理childBuf中的消息*/

……

}else{

……

/* 发送一个消息到子进程*/

write(pipeID[1],msgTochild,len);

……

}

管道使得进程可以把信息从一个地址空间拷贝到另一个地址空间。管道的读写端可以通过与文件描述符相同的方式用于大多数系统调用。下例中解释了Linux 中如何使用管道来实现进程A和B(分别执行PROC_AP和PROC_B)之间的并发处理,其中A执行了一些计算,发送一个值x给B,接着执行第二阶段的计算,从B中读取值y,然后重复执行。同时B读取值x,执行第一阶段的计算,写入一个值到A,再执行更多的计算,然后重复执行。不打算使用管道的进程应该关闭以使可以检测到文件结束(EOF)条件。

int A_to_B[2],B_to_A[2];

main()

{

pipe(A_to_B);

pipe(B_to_A);

if (fork()==0) /*第一个子进程*/

{

close(A_to_B[0]);

close(B_to_A[1]);

execve("prog_A.out",...);

exit(1); /*错误终端子进程*/

}

if(fork()==0) /**另一个子进程/

{

close(A_to_B[1]);

close(B_to_A[0]);

execve("prog_B.out",...);

exit(1);

}

/*父进程代码*/

wait(...);

wait(...);

}

proc_A()

{

while(TRUE)

{

;

write(A_to_B[1],x,sizeof(int)); /*使用管道发送消息*/

;

read(B_to_A[0],y,sizeof(int)); /*使用管道得到消息*/

}

}

proc_B()

{

while(TRUE)

{

read(A_to_B[0],x,sizeof(int)); /*使用管道得到消息*/

;

write(B_to_A[1],y,sizeof(int)); /*使用管道发送消息*/

;

}

}

⑹int open(const char *path, int oflag)

打开文件,path参数是一个字符串,包含要打开文件的路径,oflag是标志集合,控制文件的打开方式。可用标志有:

O_RDONLY 只读方式打开

O_WRONLY 只写方式打开

O_RDWR 读/写方式打开

O_CERAT 如果文件已存在,则该选项不执行任何操作。

⑺int close(int fd)

关闭文件。如果关闭成功,返回0,发生错误返回-1。

⑻int access(const char *path,int amode)

测试路径是否存在。参数path中包含了需要检查的文件路径名,amode是下面几个常量进行或操作的结果:

R_OK 测试文件是否可读;

W_OK 测试文件是否可写;

X_OK 测试文件是否可执行;

F_OK 测试文件是否存在;

分离环境变量中的PATH参数可使用如下语句:

paths=(char *)getevn(“PATH”);

PATH中路径用“:”分割,可分别取出每个路径,后面再加上文件的相对路径名组成绝对路径,便可使用access函数进行检测。

⑼char getenv(char *name)

获得特定环境变量。参数name应当是要获取的环境变量的名字。如果该变量存在,就返回该变量的值;否则返回NULL。

read(),write()等等。

2、解决问题指导

(1)基本步骤

⑴打印提示符。

在打印提示符之前要使用get_current_dir_name()得到当前路径。返回一个指向当前目录绝对路径的字符串指针,然后在stdout中输出。

⑵解析用户输入的指令,包括命令和参数。

命令和参数被保存在字符串数据argv[argc]中。在这里要区分命令和参数,其中argv[0]是命令,程序要识别一般命令并并执行;能识别“>”、“<”和“|”,根据不同的符号转入到不同的程序模块,执行不同的过程。普通的命令在主函数main()中执行即可,当遇到“>”和“<”是转移到子函数redirect()执行;当遇到“|”则转移到子函数pipe()执行。

⑶寻找命令文件。

子函数is_fileexit()用来查找命令是否存在。Shell为每个用户提供了一组环境变量。这些变量定义在用户的.login文件中。其中路径变量PATH是一组绝对路径的列表,表明shell 如何搜索命令文件。只要我们获取了路径变量,然后依次搜索各个路径,就可以确定用户输入的命令文件的位置了。Leave指令用来退出自己的shell回到linux的shell下。

⑷执行命令。

通过调用fork()创建一个子进程,在子进程中执行命令。在子进程中通过使用execv()函数来执行命令。

⑸实现重定向的。

首先使用open()函数创建一个文件描述符,然后将其复制到文件描述表第二项。这样该进程的所有输出都写到重定向的文件中。使用dup(fid)函数将标准输出重定向到fd_out 上(就是重定向文件中)。

⑹管道的实现。

通过函数pipe(pipeID),则pipeID[0]是一个文件描述符,指向管道的读端;对应的,pipeID[1]是一个指向管道写端的指针。创建第一个子进程执行管道符前的命令,并将输出写到管道。然后,创建第二个进程执行管道符后的指令,并从管道读输入流。

(2)程序结构分析

⑴可以分成如下几个主要的文件:

main.c 基本调度shell 的执行流程

function.c 包括了shell 功能里的各个功能子模块

head.h 涵盖了要使用的头文件和基本的全局变量、数据结构

shellexe shell的可执行文件

d1,d2,testresult 为测试时,临时生成的文件

⑵主要的函数组成如下:

main ( ) 负责调度整个shell 执行的流程

init_shell ( ) 简单初始化shell 执行前的signal

init_command ( ) 初始化shell 执行命令前的全局变量初值

get_string ( ) 从screen 读取一个字符串

set_background( )检测是否存在&, 设置background 标志符

delete_space ( ) 过滤掉输入字符串中的多余的空格,包括前后和连续的多个空格split ( ) 将输入字符串,分拆成一个个单词

fill_cmds ( ) 将单词存储到shellcmd 结构、infile、outfile文件中去

searchfile ( ) 分离环境变量PATH中设定的路径,调度scanfile ( )

scanfile ( ) 在当前路径和PATH设定的路径中,检索每一个命令是否存在

execute ( ) 设置infile,outfile,循环调度do_execute ( )

do_execute ( ) 执行每一个shellcmd中的命令

head.h 包含了要使用的头文件和所有的全局变量和数据结构

⑶程序调用流程:

以上程序流程图仅作为编程参考。其中含有重复或不尽合理的地方。编程实现时,可以自己另外划分函数与模块功能。

要求学生编写的shell,符合所使用机器安装Linux系统的shell风格。因此,学生要先熟悉Linux的基本命令,命令行方式、参数等,再按要求完成程序功能。

有能力的学生,可以根据shell的基本语法和规则,结合编译知识,考虑试着在一个命令行中,同时实现“>、“<”、“|”、“&”等功能,或同时实现多管道、多重定向等功能。

实验二 Linux系统调用

一、实验目的

学习系统调用的执行流程,理解Linux系统调用,并且在内核中增加一个新的系统调用。

二、实验内容

1.下载最新版本的Linux内核源代码,在Linux系统中解压缩,大致观察内核源代码的

组成结构。然后编译这个版本的内核代码,并尝试用编译出的内核重新引导系统。

2.添加一个新的系统调用,完成任意一个功能,重新编译和运行内核,使新的系统调

用可用。

3.编写一个用户态的程序,使用增加的系统调用,以证明它确实可以用。

三、实验提示

1、内核及系统调用原理

Linux中有许多系统调用,如open()、read()、fork()、pipe()、socket()等,我们可以像使用普通的C库函数一样去使用这些系统调用,向操作系统发出请求,操作系统会尽量满足我们的请求。操作系统在处理每个系统调用的时候必须暂时切入核心态,待完成用户请求后再返回用户态继续执行。

一般在Linux系统中的/usr/src/linux*.*.*(*.*.*代表的是内核版本,如2.6.34)目录下就是内核源代码,如果没有类似目录,则是因为在安装Linux时没有选择安装内核源代码,这时可从Internet上免费下载。以2.6.34版本的内核为例,有两种类型的代码包:linux-2.6.34.tar.gz 和linux-2.6.34.tar.bz2,其内容完全一样,只是压缩程序不同:.gz是用gzip压缩的,.bz2是用bzip2压缩的。

Linux系统调用的执行原理和普通的C语言函数大不相同。当编写一个普通的C语言函数myfunc()时,这个函数将被编译成类似于下面所示的机器代码(以x86系列CPU、Visual C++中的编译器为例):

myfunc proc near

函数内容

……

ret

myfunc end

可以看到,普通C语言函数在这里被编译成一个过程,在过程执行结束后,用一条ret指令返回调用处,而调用这个函数的语句将被编译成一条call myfunc指令。

在x86 CPU的执行过程中,一旦遇到call指令,CPU会把下一条指令的地址压入栈中,然后将程序计数器IP设为目标函数的地址,从目标函数处开始执行。而遇到ret指令,CPU将从栈中弹出一个值,并把程序计数器设为这个值,从这里开始执行。不难看出,无论是call,还是ret指令,都没有让CPU从用户态切换到核心态,或者从核心态转回用户态。而系统调用必须在用户态被调用,在核心态执行,这个过程中不可避免地要进行用户态/核心态的切换,因此系统调用不能像普通函数那样用call和ret指令实现。

在x86 CPU 中,用户态和核心态之间的切换,一般使用init指令,也就是中断指令。Linux 系统调用正是通过中断实现的。Linux系统调用实际上是导出了可供用户态程序调用的内核

函数的名称,它们不能像普通的C库函数一样调用,而必须通过0x80号中断切换到核心态调用。

Linux系统调用是很多的,所有这些系统调用共享了0x80号中断,那么当0x80号中断发生的时候,系统如何得知当前被调用的是哪个呢?在Linux内核中,维护了一张系统调用人口表,这个入口表的源码集中在/usr/src/linux/arch/i386/kernel/entrys.S文件中,具有如下所示的形式:

.data

ENTRY(sys_call_table) /*入口*/

.long SYSMBOL_NAME(sys_ni_call) /*0,空项*/

.long SYSMBOL_NAME(sys_exit) /*1*/

.long SYSMBOL_NAME(sys_fork) /*2*/

.long SYSMBOL_NAME(sys_read) /*3*/

.long SYSMBOL_NAME(sys_write) /*4*/

.long SYSMBOL_NAME(sys_open) /*5*/

…………………………….

.long SYSMBOL_NAME(sys_signalstack)

.long SYSMBOL_NAME(sys_sendfile)

…………………………….

.long SYSMBOL_NAME(sys_ni_call) /*空项*/

.long SYSMBOL_NAME(sys_ni_call) /*空项*/

…………………………….

.endr /*结束*/

表项1包含了exit()系统调用(其实现为sys_exit内核函数),表项2包含了fork()系统调用,以此类推。sys_ni_call表示该表项暂时没有被使用。当增加一个新的系统调用时,可以找一个没有使用的表项,并且修改它。如下编辑该文件,增加自己的系统调用:

……………………………

.long SYSMBOL_NAME(sys_ni_call) /*222*/

.long SYSMBOL_NAME(sys_my_new_call) /*223,用户自定义系统调用*/

…………………………….

注意,Linux系统自身保留了221个系统调用,自己增加的系统调用至少要在第222项以后开始,还要小于256(内核2.4的有的版本可能保留了多达237个系统调用,因此,建议选择较为靠后的序号)。

为了使普通的C语言程序在重新编译内核之后也能调用新的内核函数,还要编辑内核目录下的include/asm/unistd.h文件:

#define _NR_exit 1

#define _NR_fork 2

#define _NR_read 3

#define _NR_write 4

#define _NR_open 5

………………………………………………

#define _NR_my_new_call 223

接下来,就要实现自己的内核函数了。可以单独在一个文件中添加该函数,也可以在已有的内核源代码中添加该函数。内核函数的实现具有以下形式:

asmlinkage (paramlist){}

其中,asmlinkage关键字指明了函数的参数的传递方式------必须使用堆栈进行。这里涉及一个问题------系统调用发生时,到底做了些什么?实际上,它要完成以下一系列的动作:(1)在系统调用表中找出对应于系统调用号的表项。

(2)确定系统调用的参数条目。

(3)将参数从用户地址空间拷贝到u区。

(4)保存当前进程的上下文。

(5)调用内核中的系统调用代码。

(6)返回用户进程。

这就决定了使用内核函数时,并不能直接使用指针型参数或者引用型参数,而必须使用copy_from_user和copy_to_user这两个内核API(也可以使用memcpy_fromfs和memcpy_tofs)实现参数的读入和写回。

如何在用户态调用内核系统函数呢?

原则上只有使用ini指令引发0x80中断一种方法。例如:当调用一个具有两个参数的系统调用sys_xxx_call()时,若要传入参数param1和param2并且将返回值存放在res中,调用语句将被编译成为下列代码:

long res;

_asm_ volatile(“int $0x80”\

: “=a”(res) \

:”0” (_NR_sys_xxx_call),”b”((long)(param1)), \

“c” ((long)(param2)));

return res;

这里用到了Linux中的x86汇编语言代码,和我们学习的x86汇编语言在语法上有所不同,但本质都是一样的。这几条语句的含义是:首先对参数进行压栈处理,然后把前面定义的_NR_sys_xxx_call这一编号放在eax寄存器(相当于16位x86处理器的ax寄存器)中,再执行int 80h发生中断,最后,待中断处理完成后,把eax寄存器中的值作为返回值,系统调用结束。

这里的关键在于,int 80h指令发生中断后,操作系统做了哪些事情?

事实上,在Linux操作系统启动的时候,就已经通过设置中断门,使得int 80h指令会转到内核的system_call处执行。

system_call定义在arch/i386/kernel/entry.S中:

ENTRY(system_call) //转到此处执行

pushl %eax //保存eax寄存器

SAVE_ALL //把寄存器压入堆栈

GET_CURRENT(%ebx)

testb $0x02,tsk_ptrace(%ebx)

jne tracesys

cmpl $(NR_syscalls),%eax

jae badsys

call *SYSMBOL_NAME(sys_call_table)(,%eax,4) //此时eax中存储的是系统调用的编号movl %eax,EAX(%esp) //把系统调用的返回值放入eax寄存器

ENTRY(ret_from_sys_call) //从系统调用返回

这里的关键在于call *SYSMBOL_NAME(sys_call_table)(,%eax,4),通过这条指令,将会根据eax中的系统调用编号,从sys_call_table中找到相应的处理程序,并且调用处理程序。

最后要注意的是,在编译使用内核函数的C文件时,要通知编译器把这些代码当做内核

代码而不是普通的用户代码来编译,这可以通过向编译器传递_KERNEL_标志来实现,同时需要使用-W编译选项来向装载程序传递一个参数all,表示忽略警告信息。最终的编译命令如下所示:

gcc –Wall –D_KERNEL_ xxx.c

当然,如果采用重新编译内核的方法,那么并不需要写编译命令,只要修改内核源码目录的Makefile,并将自己的源码文件添加至O_OBJS列表就可以了。因为Makefile的FLAGS标志已经包含上述编译选项了。另外,系统定义了syscall0~syscall5这六个宏,分别封装有0个到5个参数的内核函数。

2、解决问题指导

在编写核心态程序时,只能使用内核函数。在编写自己的代码之前,要搞清楚内核中相关的数据结构的定义。

以下的例子实现了枚举当前的所有进程,并且查询每个进程的gid、uid和pid,将所得的结果(进程信息数组,进程数)写在内核的系统日志中:

#include

#include

#include /*struct task_struct*/

asmlinkage int sys_mysyscall()

{

int i=0;

struct task_struct *p;

p=&init_task;

do

{

//获取该进程的信息

printk(“pid=%d ”,p->pid);

printk(“uid=%d ”,p->uid);

printk(“gid=%d ”,p->gid);

i++;

} while((p=p->next_task) && (p!=&init_task));

return i;

}

如何重新编译和引导新内核?

在使用新内核引导系统后,可以使用下面的测试程序,对新增的系统调用进行测试:#define _NR_my_syscall 223

/*这里告诉编译器,my_syscall系统调用的编号是223*/

int errno;

#include

_syscall0(int,my_syscall)

/*这里告诉编译器,请把my_syscall作为一个系统调用来编译,而不是普通函数*/

main()

{

My_syscall(); /*在main()函数里面使用了这个系统调用*/

}

编译并运行这个用户态程序,并使用dmesg命令查看内核的系统日志。如果能够看到一个列表,显示了进程的pid等信息,那么说明实验成功了。

如果修改了内核目录中的文件内容,请在完成测试之后,把环境恢复到最初的状态。如果试图在已经被别人修改过的环境中工作,那么会出现一些奇怪的问题。这个时候最好的解决办法是删除当前的内核源码,并把以前下载的源码压缩包重新解压缩,创造一个最初状态的工作环境。

3、编译Linux内核

(1)Linux内核源码的组织结构

Linux内核作为一个特殊的程序,同样需要经过编译、链接之后才能运行,仅仅是它执行时拥有特殊的权限,位于特定的空间,并且不会也不可能依赖于其它软件罢了。

Linux发展至今,其内核的组织结构日渐清晰,层次日渐分明。一旦基本系统安装完毕,具有系统管理员的用户即可编译内核。一般说来,Linux系统内核的源代码放置在/usr/src/linux目录下,它将依赖于体系结构的代码和独立于体系结构的代码分离开来,以下是几个重要的源代码目录:

arch目录该目录存放具体地依赖于体系结构实现的代码。在这个目录下,针对不同体系结构所移植的版本都有三个子目录:kernel、lib和mm。kernel子目录包含依赖于体系结构实现的一般内核功能,例如信号处理、时钟处理等。lib子目录包含库函数的本地实现,如果从依赖于体系结构的源代码编译,则运行得更快。mm子目录包含存储管理实现的代码。

drivers目录拥有50%以上的内核源代码,所有的驱动程序源代码均位于该目录之下。

fs目录存放所有的系统支持的文件系统的实现代码。

inlcude目录一些重要的头文件。

ipc目录处理进程间通信的全部所需的代码都放在ipc目录下。

init目录存放所有系统的初始化代码,许多重要的文件,例如main.c就位于该目录下。该目录还包含了许多核心代码,例如实现fork()的代码和最常执行的代码----cpuidle()循环。

lib目录放置内核其它部分经常所需要的代码。

kernel目录许多最常调用的内核函数放在该目录下。

mm目录包含所有Linux实现虚拟内存管理的源代码。

net目录存放所有提供网络支持的代码。

document目录存放大量的内核代码相关文档,以及用户开发和维护手册。

(2)如何配置及编译Linux内核

在能够实际地编译内核之前,必须告诉编译程序需要哪些功能,还必须告诉它是将这些功能模块编到内核去还是将其配置成动态可加载的模块。下表为内核配置命令:

make config将打开一个字符模式的对话框,在终端上一个接一个地问问题直到回答了所有的问题。对每一问题有三种可能的答案:Yes、No和Module。Module告诉内核配置在运行时使用动态可装载模块,而不是静态地将功能连接到内核中。

make menuconfig 和make xconfig分别打开一个文本图形对话框和一个GUI对话框,其功能和make config基本相同,但是可以只配置自己关心的部分。另外,如果不希望对原始配置做过多的修改,则可以选用make oldconfig选项。

make config命令中有几个重要的选项,其意义如下:

---Code maturity level options:代码成熟等级。此处只有一项:prompt for development and/or incomplete code/drivers,如果要试验现在仍处于试验阶段的功能,就必须把该项选择为Y,否则可以把它选择为N。

---Loadable module support:对模块的支持。

---Processor type and features:选择支持的CPU类型

---General setup:对最普通的一些属性进行设置。一般使用默认设置就可以。

---Memory Technology Device(MTD):MTD设备支持。

---Parallel port support:并口支持。

---Plug and Play configuration:即插即用设备。

---Block devices:块设备支持。

---Networking options:网络配置选项。

---Telephony Support:电话支持。

---SCSI support:SCSI设备的支持。

---Character devices:字符设备。

---File system:文件设备。

---Console drivers:控制台驱动。

---Sound:声卡驱动。

---USB support:USB支持。

一旦满意地配置好内核,就可以进行编译了。

/usr/src/linux目录下的makefile是构建Linux内核的顶层makefile。在该目录下只用以下几个命令(必须具有超级用户或者管理员权限)就可以将内核重新构建出来:#make clean

#make config

#make depend

#make

其中,make clean入口将删除旧的可装载对象文件和其他临时文件。make config入口会导致configure的bash脚本的执行,如果前面已经配置好了内核,那么这条命令可以不用。make depend入口是根据各个文件之间的依赖关系,确定合适的编译顺序。make入口将编译所有内核源代码,生成内核可执行文件vmlinux。

另外,make boot可以压缩vmlinux文件来建立一个可启动的内核映像并将其安装到/usr/src/linux/arch/i386/boot/zImage中。如果使用LILO引导,也可以使用命令make bzImage。这时,会在该目录下生成一个名为bzImage的文件,将上述文件重命名后,拷贝到/etc/lilo 所在的目录,在lilo.conf中增加新的引导选项,再次运行LILO,新的内核就可以被引导了。

实验三Linux二级文件系统

一、实验目的

(1)本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。

(2)结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。

(3)通过分对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力

二、实验内容

在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟Linux 文件系统。在现有机器硬盘上开辟100M的硬盘空间,作为设定的硬盘空间。编写一管理程序simdisk对此空间进行管理,以模拟Linux文件系统,要求:盘块大小1k,空闲盘块的管理:Linux位图法;结构:超级块, i结点区, 根目录区。

1.可以实现下列几条命令:

Info 显示整个系统信息(参考Linux文件系统的系统信息),文件可以根据用户进行读写保护。目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。

check 检测并恢复文件系统:对文件系统中的数据一致性进行检测,并自动根据文件系统的结构和信息进行数据再整理。

login 用户登录

dir 列目录

create 创建文件

delete 删除文件

open 打开文件

close 关闭文件

read 读文件

copy 拷贝文件

write 写文件

cd 进出目录

2.列目录时要列出文件名,物理地址,保护码和文件长度

3.源文件可以进行读写保护

4.程序的总体流程为:

初始化文件目录;

输出提示符,等待接受命令,分析键入的命令;

对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令,直到键入EXIT 退出为止。

三、实验提示

1.背景知识

(1)外存管理

文件系统是一个含有大量的文件及其属性,对文件进行操作、管理的软件,以及向用户提供使用文件的接口的一个集合。在逻辑上它的层次结构是这样的:

作为产品的操作系统有各自的文件系统。比如MS的WINDOWS系列使用的是FAT16、FAT32或NTFS的文件系统、LINUX使用的是EXT2、EXT3文件系统等等。

(2)linux的EXT2文件系统

linux使用一个叫虚拟文件系统的技术从而可以支持多达几十种的不同文件系统,而EXT2是linux自己的文件系统。它有几个重要的数据结构,一个是超级块,用来描述目录和文件在磁盘上的物理位置、文件大小和结构等信息。inode也是一个重要的数据结构。文件系统中的每个目录和文件均由一个inode描述。它包含:文件模式(类型和存取权限)、数据块位置等信息。

一个文件系统除了重要的数据结构之外,还必须为用户提供有效的接口操作。比如EXT2提供的OPEN/CLOSE接口操作。

(3)用内存来模拟外存

真正的文件系统对外存进行管理,涉及到许多硬件、设备管理方面的底层技术,一方面这些技术不属于操作系统核心内容,一方面过多的内容不免造成实验者顾此失彼,所以这里推荐一种使用内存来模拟外存的方式,可以跳过这些硬件技术而直接把精力放在数据结构设计和操作算法设计上面。

假定pInode是一个指向inode结构的指针,而且它已经放入的需要放入的数值了,现在需要将其写入到特定位置。可用如下代码:

……

fd=fopen(“filesystem”,”w+b”);//fd是FILE指针类型,w便是写方式,b表示二进制

fseek(fd, specific_area,SEEK_SET);// fd是文件指针;specific_area为整形,

// 为需要入pInode的位置

fwrite(pInode, sizeof(inode), 1,fd);// 写入pInode信息

2、原理算法

本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。

首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。

用户创建的文件,可以编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。

操作系统课程设计

课程设计报告 2015~2016学年第一学期 操作系统综合实践课程设计 实习类别课程设计 学生姓名李旋 专业软件工程 学号130521105 指导教师崔广才、祝勇 学院计算机科学技术学院 二〇一六年一月

- 1 -

- 2 -

一、概述 一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX 的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。UNIX中的文件系统磁盘存储区分配图如下: 本次课程设计是要实现一个简单的模拟Linux文件系统。我们在内存中开辟一个虚拟磁盘空间(20MB)作为文件存储器,并将该虚拟文件系统保存到磁盘上(以一个文件的形式),以便下次可以再将它恢复到内存的虚拟磁盘空间中。文件存储空间的管理可采用位示图方法。 二、设计的基本概念和原理 2.1 设计任务 多用户、多级目录结构文件系统的设计与实现。可以实现下列几条命令login 用户登录 logout 退出当前用户 dir 列文件目录 creat 创建文件 delete 删除文件 open 打开文件 close 关闭文件 - 3 -

read 读文件 write 写文件 mkdir 创建目录 ch 改变文件目录 rd 删除目录树 format 格式化文件系统 Exit 退出文件系统 2.2设计要求 1) 多用户:usr1,usr2,usr3,……,usr8 (1-8个用户) 2) 多级目录:可有多级子目录; 3) 具有login (用户登录)4) 系统初始化(建文件卷、提供登录模块) 5) 文件的创建:create (用命令行来实现)6) 文件的打开:open 7) 文件的读:read8) 文件的写:write 9) 文件关闭:close10) 删除文件:delete 11) 创建目录(建立子目录):mkdir12) 改变当前目录:cd 13) 列出文件目录:dir14) 退出:logout 新增加的功能: 15) 删除目录树:rd 16) 格式化文件系统:format 2.3算法的总体思想 - 4 -

操作系统课程设计文件系统管理)

操作系统课程设计Array文件系统管理 学院计算机学院 专业计算机科学与技术 班级 姓名 学号 2013年1月8日 广东工业大学计算机学院制 文件系统管理 一、实验目的 模拟文件系统的实现的基本功能,了解文件系统的基本结构和文件系统的管理方法看,加深了解文件系统的内部功能的实现。通过高级语言编写和实现一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作系统命令的实质内容和执行过程有比较深入的了解。 二、实验内容和要求 编程模拟一个简单的文件系统,实现文件系统的管理和控制功能。在用户程序中通过使用文件系统提供的create,open,read,write,close,delete等文件命令,对文件进行操作。 以下报告主要包括: 1.可行性分析 2.需求分析 3.概要设计

4.详细设计 5.测试 6.总结 三、可行性分析 1、技术可行性 对于图形编程还不了解,但是经过本学期的三次实验的练习,可以设计好命令操作界面。利用大二期间学习的数据结构可以模拟出此课程设计的要求。 2、经济可行性 课程设计作为本课程的练习及进一步加深理解。与经济无关,可以不考虑。(零花费,零收益) 3.法律可行性 自己编写的程序,仅为练习,不作其他用途,与外界没什么联系,可行。 四、需求分析 编写程序实现文件系统,主要有以下几点要求: 1、实现无穷级目录管理及文件管理基本操作 2、实现共享“别名” 3、加快了文件检索 五、概要设计 为了克服单级目录所存在的缺点,可以为每一位用户建立一个单独的用户文件目录UFD(User File Directory)。这些文件目录可以具有相似的结构,它由用户所有文件的文件控制块组成。此外,在系统中再建立一个主文件目录MFD (Master File Directory);在主文件目录中,每个用户目录文件都占有一个目

操作系统课程设计报告书

题目1 连续动态内存管理模拟实现 1.1 题目的主要研究内容及预期达到的目标 (1)针对操作系统中内存管理相关理论进行设计,编写程序并进行测试,该程序管理一块虚拟内存。重点分析三种连续动态内存分配算法,即首次适应算法、循环首次适应算法和最佳适应算法。 (2)实现内存分配和回收功能。 1.2 题目研究的工作基础或实验条件 (1)硬件环境:PC机 (2)软件环境:Windows XP,Visual C++ 6.0 1.3 设计思想 首次适应算法的实现:从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高址空间保留大的空闲区。 循环首次适应算法的实现:在分配内存空间时,不再每次从表头开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。 最佳适应算法的实现:从全部空闲区中找到能满足作业要求的、且最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表中的空闲分区要按从小到大进行排序,从表头开始查找第一个满足要求的自由分配。 1.4 流程图 内存分配流程图,如图1-1所示。

图1-1 内存分配流程图内存回收流程图,如1-2所示。

图1-2 内存回收流程图 1.5 主要程序代码 (1)分配内存 void allocate(char z,float l) { int i,k; float ad; k=-1; for(i=0;i= l && free_table[i].flag == 1) if(k==-1 || free_table[i].length

操作系统课程设计-模拟文件系统

目录 第1章需求分析 (1) 第2章概要设计 (1) 2.1 系统的主要功能 (1) 2.2系统模块功能结构 (1) 2.3运行环境要求 (2) 2.4数据结构设计 (2) 第3章详细设计 (3) 3.1模块设计 (3) 3.2算法流程图 (3) 第4章系统源代码 (4) 第5章系统测试及调试 (4) 5.1运行结果及分析 (4) 5.2系统测试结论 (5) 第6章总结与体会 (6) 第7章参考文献 (6) 附录 (7)

第1章需求分析 通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力;掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,并了解操作系统的发展动向和趋势。 模拟二级文件管理系统的课程设计目的是通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。 第2章概要设计 2.1 系统的主要功能 1) 系统运行时根据输入的用户数目创建主目录 2) 能够实现下列命令: Login 用户登录 Create 建立文件 Read 读取文件 Write写入文件 Delete 删除文件 Mkdir 建立目录

Cd 切换目录 Logout 退出登录 2.2系统模块功能结构 2.3运行环境要求 操作系统windows xp ,开发工具vc++6.0 2.4数据结构设计 用户结构:账号与密码结构 typedef struct users { char name[8]; char pwd[10]; }users;

操作系统课程设计报告

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: 13软件工程1班 提交时间: 2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。

二、环境条件 系统: WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。

(4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

操作系统课程设计完整版内含代码

操作系统课程设计LRU页面调度算法 学号: 姓名: 学院: 专业: 班级: 指导老师: 日期:

目录 一、实验题目 (1) 二、课程设计的目的 (1) 三、设计内容 (1) 四、设计要求 (1) 五、设计思想 (1) 六、主要数据结构及其说明 (2) 七、硬件支持 (3) 八、源程序文件 (3) 九、程序运行结果 (7) 十、实验体会 (8)

一实验题目 LRU页面调度算法 二课程设计的目的 操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合一起,独立分析和解决实际问题的机会。 1.进一步巩固和复习操作系统的基础知识。 2. 培养学生结构化程序、模块化程序设计的方法和能力。 3.提高学生调试程序的技巧和软件设计的能力。 4.提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。 三设计内容 程序应模拟实现LRU算法思想,对n个页面实现模拟调度。 四设计要求 1.不同的功能使用不同的函数实现(模块化),对每个函数的功能和调用接口要注释清楚。对程序其它部分也进行必要的注释。 2.对系统进行功能模块分析、画出总流程图和各模块流程图。 3.用户界面要求使用方便、简洁明了、美观大方、格式统一。所有功能可以反复使用,最好使用菜单。 4.通过命令行相应选项能直接进入某个相应菜单选项的功能模块。 5.所有程序需调试通过。 五设计思想 最近最久未使用(LRU)页调度算法是选择最近最久未使用的页面予以淘汰。 算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间,当所要访问的页面在内存块中时,就不淘汰页面,否则,淘汰页面中时间最长的,即淘汰最近最久未使用的页面。

操作系统课程设计报告

上海电力学院 计算机操作系统原理 课程设计报告 题目名称:编写程序模拟虚拟存储器管理 姓名:杜志豪.学号: 班级: 2012053班 . 同组姓名:孙嘉轶 课程设计时间:—— 评语: 成绩: 目录 一、设计内容及要求 (4) 1. 1 设计题目 (4) 1.2 使用算法分析: (4)

1. FIFO算法(先进先出淘汰算法) (4) 1. LRU算法(最久未使用淘汰算法) (5) 1. OPT算法(最佳淘汰算法) (5) 分工情况 (5) 二、详细设计 (6) 原理概述 (6) 主要数据结构(主要代码) (6) 算法流程图 (9) 主流程图 (9) Optimal算法流程图 (10) FIFO算法流程图 (10) LRU算法流程图 (11) .1源程序文件名 (11) . 2执行文件名 (11) 三、实验结果与分析 (11) Optimal页面置换算法结果与分析 (11) FIFO页面置换算法结果与分析 (16) LRU页面置换算法结果与分析 (20) 四、设计创新点 (24) 五、设计与总结 (27)

六、代码附录 (27) 课程设计题目 一、设计内容及要求 编写程序模拟虚拟存储器管理。假设以M页的进程分配了N

块内存(N

【精选】操作系统课程设计(文件系统管理)文件

评定等级 操作系统课程设计 文件系统管理 学院计算机学院 专业计算机科学与技术 班级 姓名 学号 2013年1月8日 广东工业大学计算机学院制

文件系统管理 一、实验目的 模拟文件系统的实现的基本功能,了解文件系统的基本结构和文件系统的管理方法看, 加深了解文件系统的内部功能的实现。通过高级语言编写和实现一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作系统命令的实质内容和执行过程有比较深入的了 解。 二、实验内容和要求 编程模拟一个简单的文件系统,实现文件系统的管理和控制功能。在用户程序中通过使用文件系统提供的create,open,read,write,close,delete 等文件命令,对文件进行操作。以下报告主要包括: 1.可行性分析 2.需求分析 3.概要设计 4.详细设计 5.测试 6.总结 三、可行性分析 1、技术可行性 对于图形编程还不了解,但是经过本学期的三次实验的练习,可以设计好命令操作界面。利用大二期间学习的数据结构可以模拟出此课程设计的要求。 2、经济可行性 课程设计作为本课程的练习及进一步加深理解。与经济无关,可以不考虑。(零花费,零收益) 3.法律可行性 自己编写的程序,仅为练习,不作其他用途,与外界没什么联系,可行。 四、需求分析 编写程序实现文件系统,主要有以下几点要求: 1、实现无穷级目录管理及文件管理基本操作 2、实现共享“别名” 3、加快了文件检索 五、概要设计 为了克服单级目录所存在的缺点,可以为每一位用户建立一个单独的用户文件目录 UFD (User File Directory )。这些文件目录可以具有相似的结构,它由用户所有文件的文件 控制块组成。此外,在系统中再建立一个主文件目录MFD (Master File Directory );在主文件目录中,每个用户目录文件都占有一个目录项,其目录项中包括用户名和指向该用户目 录的指针。

操作系统课程设计报告

课程设计说明书 设计题目:操作系统课程设计 班级:信息学管理与信息系统2011级 学号: 2 姓名:克乾

山东科技大学2013年12 月11 日

课程设计任务书 学院信息科学与工程专业信息学管理与信息系统班级2011-2 克乾 一、课程设计题目:操作系统课程设计 二、课程设计主要参考资料 (1)Abraham Silberschatz & Peter Baer Galvin & Greg Gagne. Operating System Concepts(第七版影印版). 高等教育. 2007.3. (2)c++面向对象程序设计电子工业 (3)计算机操作系统(第三版)电子科技大学 三、课程设计应解决的主要问题: (1)CPU调度算法的模拟实现 (2)死锁相关算法的实现 (3)磁盘调度算法的实现 四、课程设计相关附件(如:图纸、软件等): (1)程序源代码 (2) 五、任务发出日期:2013-10-1 课程设计完成日期:2014-1-1

指导教师签字:

指导教师对课程设计的评语成绩: 指导教师签字: 年月日

设计1 CPU调度算法的模拟实现一、设计目的 利用C++编写CPU调度算法,实现先来先服务调度算法FCFS、优先级调度算法PS、短作业优先调度算法SJF、时间片轮转调度算法RR的运行过程和实现的结果,针对模拟进程,利用编写的CPU调度算法对需要运行的进程进行调度。进行算法评价,计算平均周转时间和平均等待时间。 二、设计要求 针对模拟进程,利用CPU调度算法进行调度,最后要进行算法评价,计算平均周转时间和平均等待时间,并且输出调度结果和输出算法评价指标。 调度所需的进程参数由输入产生(手工输入或者随机数产生)。 三、设计说明 时间片轮转算法需要输入相应的时间片,所以独立编写一个程序,系统主体结构如下:

操作系统课程设计报告

; 一、概述 课程设计目的、意义: 课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。 主要任务: 模拟文件系统设计是设计和实现一个简单的文件系统。内容包括: 1.建立文件存储介质的管理机制 2.建立目录(采用一级目录结构) 3.文件系统功能(显示目录、创建、删除、打开、关闭、读、写) ~ 4.文件操作接口(显示目录、创建、删除、打开、关闭、读、写) 二、系统设计 课程设计的系统设计: 本系统模拟一个文件管理系统,要完成对文件的基本操作,文件的基本操作有文件、文件夹的打开、新建、删除和读取写入文件,创建更改目录,列出目录内容等信息。系统建立了文件目录树,存储文件系统中的所有文

件。对于用户名下的文件,用文件目录树的分枝来存贮。采用命令行操作界面很直观,也方便用户进行操作,用户只要按照操作界面所显示的命令来操作就行了。 整体设计框架: 系统初始化界面是由创建用户存储空间,管理文件,退出系统三个模块组成。用户创建由创建用户存储空间,进入目录,删除用户存储空间,显示所有用户存储空间,等模块组成。然后各个模块再由一些小模块组成。其中创建文件,打开关闭文件,读写文件等文件操作模块包括在进入目录模块里面。 三、系统实现 课程设计主要内容的实现程序代码: 《 #include <> #include <> #include <> typedef struct file{ char name[10]; struct file *next; }File; typedef struct content{ ! char name[10]; File *file;

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件 系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景

计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下: 钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

操作系统课程设计

湖南科技大学计算机科学与工程学院 操作系统课程设计报告 ******** *** 目录 实验一 Windows 进程管理 实验二 Linux 进程管理 实验三 互斥与同步 实验四 银行家算法的模拟与实现 实验五 内存管理 指导老师: *** 完成时间: **** ** **

实验六磁盘调度 实验七进程间通信 实验一 Windows进程管理 一、实验目的 1 )学会使用VC编写基本的Win3 2 Consol Application (控制台应用程序)。 2)2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟 悉操作系统的进程概念,理解Windows进程的"一生”。 3)3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步 的基本程序设计方法。 二、实验内容和步骤 (1)编写基本的 Win32 Consol Application 步骤1:登录进入 Windows系统,启动VC++ 6.0。 步骤2:在“ FILE”菜单中单击“ NEW”子菜单,在“ projects ”选项卡中选择 “Win32 ConsolApplication ”,然后在“ Project name 处输入工程名,在“Location ”处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“ FILE”菜单中单击“ NEW”子菜单,在“ Files ”选项卡中选择“ C++ Source File ” ,然后在“ File ”处输入C/C++源程序的文件名。 步骤4:将清单1-1所示的程序清单复制到新创建的C/C++源程序中。编译成可执行文件。 步骤5 :在“开始”菜单中单击“程序” -“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的 debug子目录,执行编译好的可执行程序,列出运行结果(如果运行不成功,则可能的原因是什么?) 如果运行不成功可能是路径有问题或者没有通过编译。

操作系统课程设计二级文件系统

操作系统课程设计报告 专业:计算机信息处理 学号:09103408 姓名:纪旻材 提交日期:2011-12-28

【设计目的】 1. 课程设计目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。 2. 结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。 3. 通过对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力 【设计内容】 1、delete 删除文件 2、open 打开文件 3、close 关闭文件 4、write 写文件 【实验环境】 Windows7系统

Visual studio 2010 【相关知识综述】 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。用户创建的文件,可以编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。 【设计思路】 1 主要数据结构 #define MAXNAME 25 /*the largest length of mfdname,ufdname,filename*/ #define MAXCHILD 50 /*the largest child每个用户名下最多有50个文件*/ #define MAX (MAXCHILD*MAXCHILD) /*the size of fpaddrno*/ typedef struct/*the structure of OSFILE定义主文件*/

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件

系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。

2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<

操作系统(一个小型操作系统的设计与实现)课程设计

南通大学计算机科学与技术学院操作系统课程设计报告 专业: 学生姓名: 学号: 时间:

操作系统模拟算法课程设计报告 设计要求 将本学期三次的实验集成实现: A.处理机管理; B.存储器管理; C.虚拟存储器的缺页调度。 设计流程图 主流程图 开始的图形界面 处理机管理存储器管理缺页调度 先来先服务时 间 片 轮 转 首 次 适 应 法 最 佳 适 应 法 先 进 先 出 L R U 算 法

A.处理机调度 1)先来先服务FCFS N Y 先来先服务算法流程 开始 初始化进程控制块,让进程控制块按进程到达先后顺序让进程排队 调度数组中首个进程,并让数组中的下一位移到首位 计算并打印进程的完成时刻、周转时间、带权周转时间 其中:周转时间 = 完成时间 - 到达时间 带权周转时间=周转时间/服务时间 更改计时器的当前时间,即下一刻进程的开始时间 当前时间=前一进程的完成时间+其服务时间 数组为空 结束

2)时间片轮转法 开始 输入进程总数 指针所指的进程是 否结束 输入各进程信息 输出为就绪状态的进程的信息 更改正在运行的进程的已运行时间 跳过已结束的程序 结束 N 指向下一个进程 Y 如果存在下一个进程的话 Y N 输出此时为就绪状态的进程的信息 时间片轮转算法流程图

B.存储器管理(可变式分区管理) 1)首次适应法 分配流程图 申请xkb内存 由链头找到第一个空闲区 分区大小≥xkb? 大于 分区大小=分区大小-xkb,修改下一个空闲区的后向指针内容为(后向指针)+xkb;修改上一个空闲区的前向指针为(前向指针)+xkb 将该空闲区从链中摘除:修改下一个空闲区的后向地址=该空闲区后向地址,修改上一个空闲区的前向指针为该空闲区的前向指针 等于 小于延链查找下 一个空闲区 到链尾 了? 作业等待 返回是 否 登记已分配表 返回分配给进程的内存首地址 开始

操作系统课程设计(文件系统)

操作系统课程设计 班级: 姓名: 学号: 使用语言:C++ 指导老师: 学院:

一、系统要求 1、实验目的 通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 2、实验内容 为linux系统设计一个简单的二级文件系统。要求做到以下几点: (1)可以实现下列几条命令(至少4条); login 用户登陆 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 (2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。 二、系统分析 1、设计思想 本文件为二级文件系统,即要实现对文件的增删改查,同时又具备登陆系统、注册用户的功能,各个用户之间的文件系统互不干扰。 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 系统采用结构体来存储用户、文件目录、文件数据内容: 0 48*5 48*5+44*50 48*5+44*50+264*200 每个分区都是由结构体组成,每个个去的结构体的个数由格式化系统是决定。整个系统的编码构成主要分为:

Allstruct.h 定义了每个分区的结构体; Mysys.h 声明了对系统操作的各种方法; Myuserfile.h 声明了对文件操作的各种方法; Mymain.cpp 整个系统的主函数,操作入口; Mysys.cpp 包含了mysys.h,实现了操作系统的各种方法;Myuserfile.cpp 包含了myuserfile.h,实现了操作文件的各种方法; 2、主要数据结构 Allstruct.h文件的内容: struct s_user //用户区结构体 { long isuse; //是否使用 char name[20]; //用户名 char psd[20]; //密码 long address; //目录地址 }; struct s_list //目录结构体 { long isuse; //是否使用 char name[20]; //文件名字 long myaddress; //本条目录地址 long pointaddress; //指向的文件的地址 long isfile; //是否锁定 long pointsize; //目标文件的大小 long nextaddress; //下条目录的地址 }; struct s_file //文件结构体 { long isuse; //是否使用 char content[256]; //文件内容 long next; //下个文件块地址 };

操作系统课程设计报告

操作系统课程设计实验报告 实验名称:进程控制 姓名/学号: 一、实验目的 学习、理解和掌握Linux与windows的进行控制系统调用的功能,熟悉主要的几个系统调用命令的格式和如何利用系统调用命令进行编程。通过学习,理解如何创建一个进程、改变进程执行的程序、进程和线程终止以及父子进程的同步等,从而提高对进程和线程控制系统调用的编程能力。 二、实验内容 设计并实现Unix的“time”命令。“mytime”命令通过命令行参数接受要运行的程序,创建一个独立的进程来运行该程序,并记录程序运行的时间。 三、实验环境 CPU: Inter ×2 2.10GHz RAM: 3.00GB Windows 7 旗舰版 Linux Ubuntu 10.04 编译: VS2010 四、程序设计与实现 4.1进程控制系统的调用 4.1.1 windows进程控制调用程序中使用的数据结构及主要符号说明 SYSTEMTIME starttime,endtime; //进程开始时间和结束时间 PROCESS_INFORMATION pi //该结构返回有关新进程及 //其主线程的信息 STARTUPINFO si //该结构用于指定新进程的主窗口特性4.1.2 linux进程控制调用程序中使用的数据结构及主要符号说明 struct timeval starttime,endtime //进程开始时间和结束时间 pid_t pid //进程标志符

4.2 程序流程图 图1 windows进程控制调用图2 linux进程控制调用程序运行流程图程序运行流程图 五、实验结果和分析 5.1 windows实验结果和分析

操作系统课程设计

计算机科学技术学院 操作系统原理课程设计报告 题目:进程管理系统 专业: 班级: 姓名: 学号: 指导老师: 年月日

《操作系统原理》课程设计任务书 一、课程设计题目(任选一个题目) 1.模拟进程管理 2.模拟处理机调度 3.模拟存储器管理 4.模拟文件系统 5.模拟磁盘调度 二、设计目的和要求 1.设计目的 《操作系统原理》课程设计是网络工程专业实践性环节之一,是学习完《操作系统原理》课程后进行的一次较全面的综合练习。其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。 2.基本要求: (1)选择课程设计题目中的一个课题,独立完成。 (2)良好的沟通和合作能力 (3)充分运用前序课所学的软件工程、程序设计、数据结构等相关知识 (4)充分运用调试和排错技术 (5)简单测试驱动模块和桩模块的编写 (6)查阅相关资料,自学具体课题中涉及到的新知识。 (7)课题完成后必须按要求提交课程设计报告,格式规范,内容详实。 三、设计内容及步骤 1.根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么。

2.根据实现的功能,划分出合理的模块,明确模块间的关系。 3.编程实现所设计的模块。 4.程序调试与测试。采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 5.结果分析。程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。 6.编写课程设计报告; 设计报告要求:A4纸,详细设计部分主要叙述本人的工作内容 设计报告的格式: (1)封面(题目、指导教师、专业、班级、姓名、学号) (2)设计任务书 (3)目录 (4)需求分析 (5)概要设计 (6)详细设计(含主要代码) (7)调试分析、测试结果 (8)用户使用说明 (9)附录或参考资料 四、进度安排 设计在学期的第15、16周进行,时间安排如下:

操作系统课程设计模拟文件系统

操作系统课程设计模拟文 件系统 Newly compiled on November 23, 2020

目录第1章需求分析 (1) 第2章概要设计 (1) 系统的主要功能 (1) 系统模块功能结构 (1) 运行环境要求 (2) 数据结构设计 (2) 第3章详细设计 (3) 模块设计 (3) 算法流程图 (3) 第4章系统源代码 (4) 第5章系统测试及调试 (4) 运行结果及分析 (4) 系统测试结论 (5) 第6章总结与体会 (6) 第7章参考文献 (6) 附录 (7) 第1章需求分析 通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力;掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,并了解操作系统的发展动向和趋势。

模拟二级文件管理系统的课程设计目的是通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。 第2章概要设计 系统的主要功能 1) 系统运行时根据输入的用户数目创建主目录 2) 能够实现下列命令: Login 用户登录 Create 建立文件 Read 读取文件 Write 写入文件 Delete 删除文件 Mkdir 建立目录 Cd 切换目录 Logout 退出登录 系统模块功能结构 运行环境要求 操作系统windows xp ,开发工具vc++ 数据结构设计 用户结构:账号与密码结构 typedef struct users { char name[8]; char pwd[10]; }users;

计算机操作系统课程设计

计算机操作系统课程设计 班级:计091-1 姓名: 学号: 使用语言:C++ 指导老师: 学院:

一、系统要求 1、实验目的 通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 2、实验内容 为linux系统设计一个简单的二级文件系统。要求做到以下几点: (1)可以实现下列几条命令(至少4条); login 用户登陆 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 (2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。

二、系统分析 1、设计思想 本文件为二级文件系统,即要实现对文件的增删改查,同时又具备登陆系统、注册用户的功能,各个用户之间的文件系统互不干扰。 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 系统采用结构体来存储用户、文件目录、文件数据内容: 0 48*5 48*5+44*50 48*5+44*50+264*200 每个分区都是由结构体组成,每个个去的结构体的个数由格式化系统是决定。

整个系统的编码构成主要分为: Allstruct.h 定义了每个分区的结构体; Mysys.h 声明了对系统操作的各种方法;Myuserfile.h 声明了对文件操作的各种方法; Mymain.cpp 整个系统的主函数,操作入口; Mysys.cpp 包含了mysys.h,实现了操作系统的各种方法;Myuserfile.cpp 包含了myuserfile.h,实现了操作文件的各种方法; 2、主要数据结构 Allstruct.h文件的内容: struct s_user //用户区结构体 { long isuse; //是否使用 char name[20]; //用户名 char psd[20]; //密码 long address; //目录地址 };

相关主题
文本预览
相关文档 最新文档