操作系统课设

操作系统课设
操作系统课设

课程设计报告课程名称:计算机操作系统

专业班级:

学号:

姓名:

指导教师:

报告日期:

计算机科学与技术学院

目录

1 实验目的

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

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

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

2 实验环境

本次课程设计采用的操作系统环境是windows8、Ubuntu双系统,Ubuntu系统版本号为14.04,内核版本号为linux 3.13.0;采用的编程环境为CodeBlocks IDE和QtCreator。

3 实验内容

3.1 实验一

掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。

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

(2)编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。

3.2 实验二

掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。实现的功能是:文件拷贝。

3.3 实验三

掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动)

3.4 实验四(选做)

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

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

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

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

3.5 实验五(选做)

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

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

4 设计与实现

4.1 实验一

4.1.1 实验要求

掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。

4.1.2 具体实现

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

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

在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。

(2)编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。

本次实验使用的图形库是跨平台的开发工具Qt。首先下载Qt的安装包并安装。Qt安装完之后,先新建一个Qt控制台应用MAIN作为主进程,用于调用三个并发的子进程。在主进程的main函数中,使用fork创建三个子进程,若进程创建成功(即fork函数返回值等于0),则使用execv函数进入对应的子进程(get、copy、put)。

主进程程序编写完成后,再新建三个Qt Widgets Application,分别作为三个子进程get、copy、put(所实现的功能并不是拷贝)。由于三个子进程窗口显示的内容形式一模一样,所以以子进程get为例。get进程的窗口显示了一下四个内容:当前时间、子进程名称、子进程的pid和父进程MAIN的pid。用Qt的对象QDateTime获取系统当前时间,然后将时间转换成一个字符串写在一个QLabel类的实例中,然后将该实例添加至窗口;直接把当前进程名称写在一个标签上然后添加至窗口;使用getpid和getppid 函数分别获取当前进程号和父进程号,然后调用sprintf把进程号转换成字符串类型之后写在标签上并添加至窗口即可。

主进程和三个子进程的程序全部编写完后,直接在Qt上编译运行。程序运行结果如下所示:

详细代码见4.1.3。

4.1.3 源代码

(1)文件拷贝源代码

#include

#include

#include

#include

#include

#include

#include

#define SIZE 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 buff[SIZE];

src=open(src);

if(src<0)

{

printf("Fail to open %s\n.",srcFile);

exit(1);

}

goal=open(goal);

if(goal<0)

{

printf("Fail to open %s\n.",goalFile);

exit(1);

}

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

{

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/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();

}

#子进程get

mainwindow.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 str[128],f_id[128];

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 MainWindow::timerUpDate()

{

QDateTime time = QDateTime::currentDateTime();

QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");

ui->labelCurDate->setText(str);

}

#子进程copy

mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include

#include

#include

#include

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow),sharememory1("share1"),sharememory2("share2") {

char str[128],f_id[128];

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->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-dd hh:mm:ss dddd");

ui->labelCurDate->setText(str);

}

#子进程put

mainwindow.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 str[128],f_id[128];

ui->setupUi(this);

setWindowTitle("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(timerUpDate()));

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)系统调用的原理

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

新的系统调用程序实现的功能是:将一个文件中的内容拷贝到另一个文件中。这个系统调用的参数是两个char*型的字符指针Source,分别表示源文件和目标文件的

路径名。用户进程中的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官方网站下载内核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 kernel/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_SYSCALLS_H */ 这一行的上面一行添加新的系统调用程序的函数定义,即:

#ifndef sys_mycall

asmlinkage int sys_mycall(char* source* destFile);

#endif

然后保存退出。

③编译内核

在编译内核之前先要安装ncurses库,使用命令sudo apt-get install libncurses5-dev安装。安装完毕后,进入/usr/src/linux-3.14.36目录下,新建一个脚本文件mysyscall.sh,通过命令gedit mysyscall.sh打开该脚本文件进行编辑。将以下内容添加到脚本中:

#!/bin/bash

make mrproper

make menuconfig

make dep

make clean

make bzImage –j4

make modules –j4

make modules_install –j4

make install –j4

mkinitramfs -o /boot/initrd.img-3.14.34

update-grub

reboot

保存退出,然后修改脚本文件的权限,使其可以对内核文件进行操作,修改权限的命令为chmod 777 mysyscall.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。

4.2.3 源代码

(1)系统调用程序

asmlinkage int sys_mycall(char* Source* GoalFile)

{

int source=sys_open(Source);

int goal=sys_open(Goal);

char buff[4096];

mm_segment_t fs;

fs = get_fs();

set_fs(get_ds());

int i;

if(source>0 && goal>0)

{

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 实验要求

掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动)

4.3.2 具体实现

(1)Linux核心是一种monolithic类型的内核,即单一的大核心,另外一种形式是MicroKernel,核心的所有功能部件都被拆成独立部分,这些部分之间通过严格的通讯机制进行联系。Linux内核是一个整体结构,因此向内核添加任何东西.或者删除某些功能,都十分困难。为了解决这个问题,引入了模块机制,从而可以动态的在内核中添加或者删除模块。模块一旦被插入内核,就和内核其他部分一样。

Linux内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低级硬件处理例程。对用户程序而言,设备驱动程序隐藏了设备的具体细节,对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文件,用户程序可以像对其它文件一样对此设备文件进行操作。

Linux支持3种设备:字符设备、块设备和网络设备。设备由一个主设备号和一个次设备号标识。主设备号唯一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的那个设备。

典型的Linux模块实现机制有如下几步:

①注册设备:在系统初启或者加载模块的时候,必须将设备登记到相应的设备数组,并返回主设备号。

②定义功能函数:对于每一个驱动函数来说,都有一些和此设备密切相关的功能函数。以最常用的块设备或者字符设备来说,都存在着诸如open()、read()这一类的操作。当系统调用这些调用时,将自动的使用驱动函数中特定的模块来实现具体的操作。

③卸载设备:在不用这个设备时,可以将它卸载,主要是从/proc 中取消这个设备的特殊文件。

(2)编写Makefile文件

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

ifneq ($(KERNELRELEASE),)

#kbuild syntax.

#模块的文件组成

mymodule-objs :=MyDeviceDriver.o

#生成的模块文件名

obj-m := MyDeviceDriver.o

else

PWD :=$(shell pwd)

KVER :=$(shell uname -r)

KDIR :=/lib/modules/$(KVER)/build

all:

$(MAKE) -C $(KDIR) M=$(PWD)

clean:

# r m -f *.cmd *.o *.mod *.ko

rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

# $(MAKE) -C $(KDIR) M=$(PWD) clean

endif

(3)编写设备功能函数

编写设备驱动程序的主要工作就是编写子功能函数,并填充s的各个域。

结构体s的具体定义如下:

struct {

struct module *owner;//拥有该结构的模块的指针,一般为THIS_MODULES

loff_t (*llseek) (struct file *, loff_t, int);//用来修改文件当前的读写位置

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//从设备中同步读取数据

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向设备发送数据

ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的读取操作

ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的写入操作

int (*readdir) (struct file *, void *, filldir_t);//仅用于读取目录,对于设备文件,该字段为NULL

unsigned int (*poll) (struct file *, struct poll_table_struct *); //轮询函数,判断目前是否可以进行非阻塞的读写或写入

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); //执行设备I/O控制命令

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); //不使用BLK文件系统,将使用此种函数指针代替ioctl

long (*compat_ioctl) (struct file *, unsigned int, unsigned long); //在64位系统上,32位的ioctl调用将使用此函数指针代替

int (*mmap) (struct file *, struct vm_area_struct *); //用于请求将设备内存映射到进程地址空间

int (*open) (struct inode *, struct file *); //打开

int (*flush) (struct file *, fl_owner_t id);

int (*release) (struct inode *, struct file *); //关闭

int (*fsync) (struct file *, struct dentry *, int datasync); //刷新待处理的数据

int (*aio_fsync) (struct kiocb *, int datasync); //异步刷新待处理的数据

int (*fasync) (int, struct file *, int); //通知设备FASYNC标志发生变化

int (*lock) (struct file *, int, struct *);

ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

int (*check_flags)(int);

int (*flock) (struct file *, int, struct *);

ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);

ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);

int (*setlease)(struct file *, long, struct **);

};

子功能函数详细代码见错误!未找到引用源。。

(4)设备驱动程序安装

①make clean,清除make产生的残留

②make,重新调用Makefile编译设备驱动程序

③insmod -f MyDeviceDriver.ko,加载生成的MyDeviceDriver.ko模块

④cat /proc/devices,获取设备驱动程序的主设备号

⑤mknod /dev/MyDeviceDriver c 250 0,创建设备文件,250为主设备号,0为

从设备号

(5)测试驱动程序

此设备驱动程序实现的功能是将一个字符串中内容拷贝到另外一个字符串中。测试程序编写完成后,在终端输入gcc test.c -o test进行编译。测试结果如下:

详细代码见4.3.3。

4.3.3 源代码

(1)设备驱动程序

#include

#include

#include

#include

#include

#include

#include

#include

#define DEV_SIZE 102400 //设备申请的最大内存空间

struct Device

{

char *data;//数组指针,用于存放从用户读入的数据

long size;//存储的数据长度

}*devp;

struct cdev cdev;//字符设备结构体

static int devNum_major = 0;//主设备号变量

//对应用户态的lseek

static loff_t my_llseek(struct file * offset, int whence)

{

loff_t cfo=0;//文件当前偏移量,current

switch(whence){

case 0://SEEK_SET

cfo=offset;break;

case 1://SEEK_CUR

cfo=file->f_pos+offset;break;

case 2://SEEK_END

cfo=DEV_SIZE-1+offset;break;

}

if ((cfo<0) || (cfo>DEV_SIZE))//文件偏移量越界

return -EINV AL;

file->f_pos = cfo;

return cfo;

}

//对应用户态的read,写数据到用户空间

static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *p_cfo)

{

int val = 0;

struct Device *dev = file->private_data; //设备描述结构体指针,获取设备信息

if (copy_to_user(buf, (void*)(dev->data + *p_cfo), count))//如果成功返回0;如果失败,返回未完成copy的长度

val = -EFAULT;

else

{

*p_cfo += count;//copy成功,文件偏移量加上count

val = count;

}

return val;

}

//对应用户态的write,从用户空间读入数据

static ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *p_cfo)

{

int val = 0;

struct Device *dev = file->private_data;

if (copy_from_user(dev->data + *p_cfo, buf, count))//如果成功返回0;如果失败,返回未完成copy的长度

val = -EFAULT;

else

{

*p_cfo += count;//copy成功,文件偏移量加上count

val = count;

}

return val;

}

static int my_open(struct inode *inode, struct file *file)

{

file->private_data = devp;

return 0;

}

struct fops={

.owner = THIS_MODULE,

.llseek = my_llseek,

.read = my_read,

.write = my_write,

.open = my_open,

};

int init_module(void)

{

int dev_num;

dev_num = register_chrdev(0,"MyDeviceDriver",&fops);

if (dev_num < 0) {

printk(KERN_INFO "MyDeviceDriver: FAIL to get major number\n");

return dev_num;

}

if (devNum_major == 0) devNum_major = dev_num;

//初始化cdev结构

cdev_init(&cdev, &fops);

cdev.owner = THIS_MODULE;

cdev.ops = &fops;

cdev_add(&cdev,MKDEV(devNum_major, 0), 1);//注册1个字符设备//为设备描述结构体分配内存

devp = kmalloc(sizeof(struct Device), GFP_KERNEL);

if (!devp)

{

dev_num = -ENOMEM;

printk(KERN_INFO "MyDeviceDriver: FAIL to get memory\n");

return dev_num;

}

(*devp).size = DEV_SIZE;

(*devp).data = kmalloc(DEV_SIZE, GFP_KERNEL);

memset((*devp).data, 0, (*devp).size);//初始化为0

return 0;

}

void cleanup_module(void)

{

cdev_del(&cdev);//注销设备

kfree(devp);//注销设备结构体

kfree((*devp).data);//注销设备内存空间

unregister_chrdev(devNum_major,"MyDeviceDriver");//卸载主设备号}

操作系统课程设计报告书

题目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

操作系统课程设计

课程设计报告 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 -

计算机操作系统安全实训心得总结

计算机操作系统安全实 训心得总结 文件编码(GHTU-UITID-GGBKT-POIU-WUUI-8968)

本次实训,是对我能力的进一步锻炼,也是一种考验。从中获得的诸多收获,也是很可贵的,是非常有意义的。在实训中我学到了许多新的知识。是一个让我把书本上的理论知识运用于实践中的好机会,原来,学的时候感叹学的内容太难懂,现在想来,有些其实并不难,关键在于理解。在这次实训中还锻炼了我其他方面的能力,提高了我的综合素质。 网络真的很强大,用在学习上将是一个非常高效的助手。几乎所有的资料都能够在网上找到。敢于攻坚,越是难的问题,越是要有挑战的心理。这样就能够达到废寝忘食的境界。当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。最好在做课设的过程中能够有记录的习惯,这样在写实验报告时能够比较完整的回忆起中间遇到的各种问题。当时遇到我以前从未遇到的问题,让我都不知道从何下手。在经过大量的资料查阅之后,我对这个错误有了一定的了解,并且能够用相应的办法来解决。 这次的实训给了自己好大的提升,无论是学习中、还是同学的交流中。每一次的交流和谈话都会使我对某个问题有一个新的认识。始终把学习作为获得新知、掌握方法、提高能力、解决问题的一条重要途径和方法,切实做到用理论武装头脑、指导实践、推动工作。思想上积极进取,积极的把自己现有的知识用于社会实践中,在实践中也才能检验知识的有用性。所以在这次的实习工作中给我最大的感触就是我们在学校学到了很多的理论知识,但很少用于社会实践中,这样理论和实践就大

操作系统课程设计报告

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: 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<

操作系统课设

课程设计报告课程名称:计算机操作系统 专业班级: 学号: 姓名: 指导教师: 报告日期: 计算机科学与技术学院

目录

1 实验目的 ·掌握Linux操作系统的使用方法; ·了解Linux系统内核代码结构; ·掌握实例操作系统的实现方法; 2 实验环境 本次课程设计采用的操作系统环境是windows8、Ubuntu双系统,Ubuntu系统版本号为14.04,内核版本号为linux 3.13.0;采用的编程环境为CodeBlocks IDE和QtCreator。 3 实验内容 3.1 实验一 掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。 (1)编写一个C程序,其内容为实现文件拷贝的功能。 (2)编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。 3.2 实验二 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。实现的功能是:文件拷贝。 3.3 实验三 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动) 3.4 实验四(选做) 了解和掌握/proc文件系统的特点和使用方法 (1)了解/proc文件的特点和使用方法; (2)监控系统状态,显示系统中若干部件使用状态; (3)用图形界面实现系统监控状态; 3.5 实验五(选做) 设计并实现一个模拟的文件系统。

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

操作系统实验心得

1-1:通过这次小实验,是我更加了解Linux一些常用指令的操作以及其作用,对于一个刚开始接触lniux操作系统的初学者来说非常有用,助于以后能够更进一步学习Linux操作系统。 1-2:在实验过程中,使用VI编辑器虽然不能像window操作系统那样对文本进行熟练度编辑,但是,VI编辑器使用命令来操作,将可以锻炼我的记忆力、对键盘的熟练读,还能帮助我们尽快适应linux操作系统的操作。 1-3:原本对liunx下的编译和调试环境不是很熟悉,但通过这次的实验,让我熟悉了linux 下的编译器和调试器的使用。 实验中使用了gcc命令,gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(#include)、预编译语句(如宏定义#define等)进行分析。 当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是链接。在链接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中链接到合适的地方。 1-4:API 接口属于一种操作系统或程序接口。通过实验,我了解了Windows的这种机制,加深了对API函数的理解。 2-1:通过本次实验了解了一些常用进程管理命令的使用,例如ps、kill命令,了解到换个kill与killall的不同,对于linux操作系统下的进程的学习打下基础,更好的学习进程。 2-2:本次实验是熟悉掌握Linux 系统常用进程创建与管理的系统调用,linux下使用fork()创建子进程,与windows下CreateProcess()创建子进程完全不同,通过比较小组更好的理解和掌握了进程的创建,对于进程的管理的理解也有了清晰地认识。 实验中遇到fork函数返回2次结果,经过分析结果如下: 由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。因为fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。 调用fork之后,数据、堆栈有两份,代码仍然为一份但是这个代码段成为两个进程的共享代码段都从fork函数中返回,箭头表示各自的执行处。当父子进程有一个想要修改数据或者堆栈时,两个进程真正分裂。 2-3:通过这次实验对熟悉掌握和了解windows平台常用进线程控制API,有了更深刻的认识,认识到API函数对windows编程的重要性,了解进程线程在内存中的执行,特别认识互斥体Mutex对象,API函数一定要多用,才能记得。 3-1:该程序的输入变量具有限制,若输入除0和1的数据,则将视为0处理.改进的方法为修改if 语句中的条件为:1,即只要输入为非零,则有效。即逻辑表达式的值为真。(在逻辑数学里非零则表示为真!) 为了能较好的实现进程的同步,可以另外设一个标志量,标志临界资源是否正被访问,当a,b,c

操作系统实验总结

《操作系统》 实验总结 学号: 学生姓名: 专业班级:

1.1进程创建 UNIX中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。每个区又分为若干页,每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。 在Linux中主要提供了fork、vfork、clone三个进程创建方法。在linux 源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到sys_fork(),sys_vfork(),sys_clone(),再在这三个函数中去调用do_fork()去做具体的创建进程工作。本次实验我们只使用fork。 fork创建一个进程时,子进程只是完全复制父进程的资源,复制出来的子进程有自己的task_struct结构和pid,但却复制父进程其它所有的资源。新旧进程使用同一代码段,复制数据段和堆栈段,这里的复制采用了注明的copy_on_write技术,即一旦子进程开始运行,则新旧进程的地址空间已经分开,两者运行独立。 fork()函数不需要参数,返回一个进程ID。返回值有三种情况: (1)对于父进程,fork函数返回新的子进程的ID。 (2)对于子进程,fork函数返回0。 (3)如果出错,fork函数返回-1。 1.2 进程控制 进程控制主要有: 1.exec( ) 系统调用exec( )系列,也可用于新程序的运行。exec( )系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,以更改新进程的用户级上下文。exec( )系列中的系统调用都完成相同的功能,它们把一个新程序装入内存,来改变调用进程的执行代码,从而形成新进程。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行,这样就产生了一个新进程,新进程的进程标识符id 与调用进程相同。 2.wait( ) 进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的

操作系统课程设计报告

上海电力学院 计算机操作系统原理 课程设计报告 题目名称:编写程序模拟虚拟存储器管理 姓名:杜志豪.学号: 班级: 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

操作系统实验总结

操作系统实验总结 学号: 姓名: 班级:

在本学期的计算机操作系统这门课学习当中,为了更好的了解操作系统相关知识,我们通过OS Lab平台做了几个实验。在实验室的过程中,我对课堂上学到的操作系统的一些知识有了新的认识,同时还接触到了操作系统的相关源代码,而且通过实验的运行效果了解了平时我们看不到的操作系统的一些状况,收获还是很大的。下面先简要归纳在实验课上我做的几个实验的主要实验内容和实验步骤: 实验一:实验环境的使用 实验步骤: 1.1启动OS Lab OS Lab每次启动后都会首先弹出一个用于注册用户信息的对话框(可以选择对话框标题栏上的“帮助”按钮获得关于此对话框的帮助信息)。在此对话框中填入学号和姓名后,点击“确定”按钮完成本次注册。观察OS Lab主窗口的布局。OS Lab主要由下面的若干元素组成:菜单栏、工具栏以及停靠在左侧和底部的各种工具窗口,余下的区域用来放置编辑器窗口。 1.2 学习OS Lab的基本使用方法 练习使用OS Lab编写一个Windows控制台应用程序,熟悉OS Lab的基本使用方法(主要包括新建项目、生成项目、调试项目等)。 实验二:操作系统的启动 实验步骤: 2.1 准备实验 启动OS Lab,新建一个EOS Kernel项目,在“项目管理器”窗口中打开boot文件夹中的boot.asm和loader.asm两个汇编文件,按F7生成项目,生成完成后,使用Windows资源管理器打开项目文件夹中的Debug文件夹。找到由boot.asm生成的软盘引导扇区程序boot.bin文件,找到由loader.asm生成的loader程序loader.bin文件,记录下此文件的大小1566字节。 2.2 调试EOS操作系统的启动过程 2.2.1 使用Bochs做为远程目标机 将调试时使用的远程目标机修改为Bochs 2.2.2 调试BIOS程序 按F5启动调试, Bochs在CPU要执行的第一条指令(即BIOS的第一条指令)处中断,从Console窗口显示的内容中,我们可以获得关于BIOS第一条指令的相关信息,然后查看CPU 在没有执行任何指令之前主要寄存器中的数据,以及内存中的数据。 2.2.3 调试软盘引导扇区程序 练习从0x7c00处调试软盘引导扇区程序;查看boot.lst文件;调试过程——软盘引导扇区程序的主要任务就是将软盘中的loader.bin文件加载到物理内存的0x1000处,然后跳转到loader程序的第一条指令(物理地址0x1000处的指令)继续执行loader程序; 2.2.4 调试加载程序 调试过程——Loader程序的主要任务是将操作系统内核(kernel.dll文件)加载到内存中,然后让CPU进入保护模式并且启用分页机制,最后进入操作系统内核开始执行(跳转到kernel.dll的入口点执行); 2.2.5 调试内核 2.2.6 EOS启动后的状态和行为 查看EOS的版本号;查看EOS启动后的进程和线程的信息;查看有应用程序运行时进程和线程的信息

操作系统课程设计实验报告

河北大学工商学院 课程设计 题目:操作系统课程设计 学部信息学部 学科门类电气信息 专业计算机 学号2011482370 姓名耿雪涛 指导教师朱亮 2013 年6月19日

主要内容 一、设计目的 通过模拟操作系统的实现,加深对操作系统工作原理理解,进一步了解操作系统的实现方法,并可练习合作完成系统的团队精神和提高程序设计能力。 二、设计思想 实现一个模拟操作系统,使用VB、VC、CB等windows环境下的程序设计语言,以借助这些语言环境来模拟硬件的一些并行工作。模拟采用多道程序设计方法的单用户操作系统,该操作系统包括进程管理、存储管理、设备管理、文件管理和用户接口四部分。 设计模板如下图: 注:本人主要涉及设备管理模块

三、设计要求 设备管理主要包括设备的分配和回收。 ⑴模拟系统中有A、B、C三种独占型设备,A设备1个,B设备2个,C设备2个。 ⑵采用死锁的预防方法来处理申请独占设备可能造成的死锁。 ⑶屏幕显示 注:屏幕显示要求包括:每个设备是否被使用,哪个进程在使用该设备,哪些进程在等待使用该设备。 设备管理模块详细设计 一、设备管理的任务 I/O设备是按照用户的请求,控制设备的各种操作,用于完成I/O 设备与内存之间的数据交换(包括设备的分配与回收,设备的驱动管理等),最终完成用户的I/O请求,并且I/O设备为用户提供了使用外部设备的接口,可以满足用户的需求。 二、设备管理函数的详细描述 1、检查设备是否可用(主要代码) public bool JudgeDevice(DeviceType type) { bool str = false; switch (type) { case DeviceType.a: {

操作系统课设

课 程 设 计 20 ——20 学年 第 学期 课程名称 操作系统 学 院 计算机科学与技术学院 专 业 班 级 姓 名 指导教师

课程设计任务书 题目: 系统调用 初始条件: 学习了高级语言程序设计、汇编语言、数据结构、计算机组成原理课程,掌握了一种计算机高级语言。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写 等具体要求) 学习在Linux中产生一个系统调用以及怎样通过往Linux内核中增加一个新函数从而在该内核空间中实现对用户空间的读写。这个函数的功能是返回当前 的系统时间。 实验条件要求:每人一台Linux主机且有超级用户权限。 时间安排: 指导教师签名: 20 年月日系主任(或责任教师)签名:年月日

目录 1.简介 (1) 1.1实验环境 (1) 1.2 Linux系统及内核 (1) 1.3 Linux系统调用 (2) 2.实验原理及详细步骤流程 (3) 2.1.实验原理和思路 (3) 2.2.详细步骤 (3) 2.2.1.环境搭建及前期准备 (3) 2.2.2.内核文件修改 (4) 2.2.3.编译并切换内核 (5) 2.2.4.测试新系统调用 (6) 3.过程分析及实验结果 (7) 2.1 过程分析 (7) 2.2.运行结果 (9) 4.调试记录 (9) 5.自我评价与总结 (10) 6.参考文献 (11) 评分表 (12)

一.简介 1.1.实验环境 1.2. Linux系统及内核 Linux是一种开源电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。Linux是一个一体化内核(monolithic kernel)系统。"内核"指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件。 操作系统的主要功能是为应用程序的运行创建良好的环境,为了达到这个目的,Linux内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给Linux内核,调用相应的的Linux内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。

计算机操作系统实训资料

计算机操作系统实验(训)指导书 学院:电子信息工程学院 班级:13计算机科学与技术本01班 学号: 姓名: 指导教师: 西安思源学院 电子信息工程学院

前言 操作系统是计算机科学与技术专业的一门重要的专业课,是一门实践性很强的技术课程。掌握操作系统原理、熟悉操作系统的使用是各层次计算机软硬件开发人员必不可少的基本技能。操作系统课程讲授理论原理比较容易,而如何指导学生进行实践则相对较难,导致学生不能深刻地理解操作系统的本质,也不能在实际中应用所学的操作系统理论知识及操作系统所提供的功能来解决实际问题。 本实验课程在操作系统原理课程教学中占有重要地位,目的是让学生及时掌握和巩固所学的基本原理和基础理论,加深理解。提高学生自适应能力,为将来使用和设计各类新的操作系统打下基础。 一般来说,学习操作系统分为以下几个层次: 1.学习并掌握操作系统的基本概念及原理,了解操作系统的实现机制。 2.掌握常用操作系统的使用、操作和维护,成为合格的系统管理员。 目前最常用的操作系统主要有UNIX、Linux、Windows等等。 3.通过分析操作系统源代码,掌握修改、编写操作系统的能力。开放源代码的操作系统Linux的出现为我们提供了机遇。 操作系统本身的构造十分复杂,如何在有效的时间内,使学生既能了解其实现原理又能对原理部分进行有效的实践,是操作系统教学一直在探索的内容。本实验课程以Windows和Linux操作系统为主要平台,从基本原理出发,通过几个实验,使学生能对操作系统的基本原理有更深入的了解,为将来从事操作系统方面的研究工作打下一定的基础。

目录 实验一Windows的用户界面 (4) 实验二Windows2003的任务与进程管理器 (6) 实验三Linux使用环境 (10) 实验四Linux进程管理、内存管理、设备管理 (13) 实验五Windows2003内存管理 (16) 实验六目录和文件管理 (19) 实验七用户与组群管理 (21)

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告学院:计算机学院 专业班级: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<

操作系统实验心得(精选多篇)

操作系统实验心得 每一次课程设计度让我学到了在平时课堂不可能学到的东西。所以我对每一次课程设计的机会都非常珍惜。不一定我的课程设计能够完成得有多么完美,但是我总是很投入的去研究去学习。所以在这两周的课设中,熬了2个通宵,生物钟也严重错乱了。但是每完成一个任务我都兴奋不已。一开始任务是任务,到后面任务就成了自己的作品了。总体而言我的课设算是达到了老师的基本要求。总结一下有以下体会。 1、网络真的很强大,用在学习上将是一个非常高效的助手。几乎所有的资料都能够在网上找到。从linux虚拟机的安装,到linux的各种基本命令操作,再到gtk的图形函数,最后到文件系统的详细解析。这些都能在网上找到。也因为这样,整个课程设计下来,我浏览的相关网页已经超过了100个(不完全统计)。当然网上的东西很乱很杂,自己要能够学会筛选。不能决定对或错的,有个很简单的方法就是去尝试。就拿第二个实验来说,编译内核有很多项小操作,这些小操作错了一项就可能会导致编译的失败,而这又是非常要花时间的,我用的虚拟机,编译一次接近3小时。所以要非常的谨慎,尽量少出差错,节省时间。多找个几个参照资料,相互比较,慢慢研究,最后才能事半功倍。 2、同学间的讨论,这是很重要的。老师毕竟比较忙。对于课程设计最大的讨论伴侣应该是同学了。能和学长学姐讨论当然再好不过了,没有这个机会的话,和自己班上同学讨论也是能够受益匪浅的。

大家都在研究同样的问题,讨论起来,更能够把思路理清楚,相互帮助,可以大大提高效率。 3、敢于攻坚,越是难的问题,越是要有挑战的心理。这样就能够达到废寝忘食的境界。当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。 4、最好在做课设的过程中能够有记录的习惯,这样在写实验报告时能够比较完整的回忆起中间遇到的各种问题。比如当时我遇到我以前从未遇到的段错误的问题,让我都不知道从何下手。在经过大量的资料查阅之后,我对段错误有了一定的了解,并且能够用相应的办法来解决。 在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的 1)访问系统数据区,尤其是往系统保护的内存地址写数据,最常见就是给一个指针以0地址 2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域 3)其他 例如: <1>定义了指针后记得初始化,在使用的时候记得判断是否为 null <2>在使用数组的时候是否被初始化,数组下标是否越界,数组元素是否存在等 <3>在变量处理的时候变量的格式控制是否合理等

操作系统课程设计报告

课程设计报告课程名称:操作系统原理 院系:计算机科学与技术 专业班级: CS140 ____ __ 学号: U201414_____ 姓名: ______ ___ 指导教师: _______ __ 完成时间: 2017年3月11日_

目录 1实验目的 (2) 2实验环境 (2) 3实验内容 (2) 3.1实验一 (2) 3.2实验二 (2) 3.3实验三 (3) 3.4实验四 (3) 3.5实验五(选做) (3) 4设计与实现 (3) 4.1实验一 (3) 4.2实验二 (6) 4.3实验三 (9) 4.4实验四 (11) 5心得体会 (14)

1 实验目的 ·掌握Linux操作系统的使用方法; ·了解Linux系统内核代码结构; ·掌握实例操作系统的实现方法; 2 实验环境 本次课程设计采用的操作系统环境是windows10、Ubuntu双系统,Ubuntu系统版本号为16.04,内核版本号为linux 4.4.4;前两个实验在当前Ubuntu环境下完成,后两个实验在win10下虚拟机VirtualBox的Ubuntu 15.10(内核为linux4.2.0-42)中完成。 3 实验内容 3.1 实验一 要求熟悉和理解Linux下的编程环境。 (1)编写一个C程序,用fread、fwrite等库函数实现文件拷贝功能。 (2)编写一个C程序,使用基于文本的终端图形编程库(curses)或图形界面(QT/GTK),分窗口显示三个并发进程的运行(一个窗口实时显示当前时间,一个窗口实时监测CPU的利用率,一个窗口做1到100的累加求和,刷新周期分别为1秒,2秒和3秒)。 3.2 实验二 要求掌握添加系统调用的方法,采用编译内核方法,添加一个新的系统调用,实现文件拷贝的功能,另外编写一个应用程序,测试新增加的系统调用。

操作系统课程设计

操作系统课程设计 Prepared on 22 November 2020

湖南科技大学计算机科学与工程学院 操作系统课程设计报告 学号: ******** 姓名:* * 班级: *** 指导老师: *** 完成时间: ****.**.** 目录 实验一 Windows进程管理 实验二 Linux进程管理 实验三互斥与同步 实验四银行家算法的模拟与实现 实验五内存管理 实验六磁盘调度 实验七进程间通信 实验一 Windows进程管理 一、实验目的 1)学会使用 VC 编写基本的 Win32 Consol Application(控制台应用程序)。 2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。

3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。 二、实验内容和步骤 (1)编写基本的 Win32 Consol Application 步骤1:登录进入 Windows 系统,启动 VC++ 。 步骤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 子目录,执行编译好的可 (2)创建进程 本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程 ID和它在进程列表中的位置。 步骤1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-2 中的程序编译成可执行文件。 步骤2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。 步骤3:在“命令提示符”窗口加入参数重新运行生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。 (3)父子进程的简单通信及终止进程

操作系统实验个人总结

操作系统实验个人总结 学号: 实验一进程控制与描述 一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows2000中进程的“一生”。 二、实验环境硬件环境:计算机一台,局域网环境;软件环境:Windows2000 Professional、Visual C++ 6、0企业版。 三、实验内容和步骤第一部分:程序1-1Windows2000 的GUI 应用程序Windows2000 Professional下的GUI应用程序,使用Visual C++编译器创建一个GUI应用程序,代码中包括了WinMain()方法,该方法GUI类型的应用程序的标准入口点。 # include # pragma comment(lib, “user 32、lib” ) int APIENTRY WinMain(HINSTANCE/* hInstance */ , HINSTANCE/* hPrevInstance */, LPSTR/* lpCmdLine */, int/* nCmdShow */ )

{ :: MessageBox( NULL, “hello, Windows2000” , “Greetings”, MB_OK) ; return(0) ; }在程序1-1的GUI应用程序中,首先需要Windows、h头文件,以便获得传送给WinMain() 和MessageBox() API函数的数据类型定义。接着的pragma指令指示编译器/连接器找到User 32、LIB库文件并将其与产生的EXE文件连接起来。这样就可以运行简单的命令行命令CL MsgBox、CPP来创建这一应用程序,如果没有pragma指令,则MessageBox() API函数就成为未定义的了。这一指令是Visual Studio C++ 编译器特有的。接下来是WinMain() 方法。其中有四个由实际的低级入口点传递来的参数。hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle() API函数将这些资源提取出来。系统利用实例句柄来指明代码和初始的数据装在内存的何处。句柄的数值实际上是EXE文件映像的基地址,通常为0x。下一个参数hPrevInstance是为向后兼容而设的,现在系统将其设为NULL。应用程序的命令行 (不包括程序的名称)

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: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<

相关文档
最新文档