西安交通大学操作系统实验报告.docx

上传人:b****6 文档编号:4511403 上传时间:2022-12-01 格式:DOCX 页数:36 大小:548.56KB
下载 相关 举报
西安交通大学操作系统实验报告.docx_第1页
第1页 / 共36页
西安交通大学操作系统实验报告.docx_第2页
第2页 / 共36页
西安交通大学操作系统实验报告.docx_第3页
第3页 / 共36页
西安交通大学操作系统实验报告.docx_第4页
第4页 / 共36页
西安交通大学操作系统实验报告.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

西安交通大学操作系统实验报告.docx

《西安交通大学操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《西安交通大学操作系统实验报告.docx(36页珍藏版)》请在冰豆网上搜索。

西安交通大学操作系统实验报告.docx

西安交通大学操作系统实验报告

操作系统实验报告

实验一:

用户接口实验

一.实验目的

1.理解面向操作命令的接口Shell。

2.学会简单的shell编码。

3.理解操作系统调用的运行机制。

4.掌握创建系统调用的方法。

操作系统给用户提供了命令接口和程序接口(系统调用)两种操作方式。

用户接口实验也因此而分为两大部分。

首先要熟悉Linux的基本操作命令,并在此基础上学会简单的shell编程方法。

然后通过想Linux内核添加一个自己设计的系统调用,来理解系统调用的实现方法和运行机制。

在本次实验中,最具有吸引力的地方是:

通过内核编译,将一组源代码变成操作系统的内核,并由此重新引导系统,这对我们初步了解操作系统的生成过程极为有利。

二.实验内容

1)控制台命令接口实验

该实验是通过“几种操作系统的控制台命令”、“终端处理程序”、“命令解释程序”和“Linux操作系统的bash”来让实验者理解面向操作命令的接口shell和进行简单的shell编程。

Ø查看bash版本。

Ø编写bash脚本,统计/my目录下c语言文件的个数

2)系统调用实验

该实验是通过实验者对“Linux操作系统的系统调用机制”的进一步了解来理解操作系统调用的运行机制;同时通过“自己创建一个系统调用mycall()”和“编程调用自己创建的系统调用”进一步掌握创建和调用系统调用的方法。

Ø编程调用一个系统调用fork(),观察结果。

Ø编程调用创建的系统调用foo(),观察结果。

Ø自己创建一个系统调用mycall(),实现功能:

显示字符串到屏幕上。

Ø编程调用自己创建的系统调用。

三.实验步骤

系统调用实验:

1.首先将Linux-3.0.tar.bz2拷贝到/usr/src目录下

——命令:

cplinux-3.0.tar.bz2/usr/src/

2.打开终端,获得root权限

——命令:

sudo–s

3.进入/usr/src目录

——命令:

cd/usr/src

4.解压linux源码

——命令:

tarxvzflinux-3.0.tar.bz2

5.进入目录linux-3.0.5

——命令:

cdlinux-3.0

6.添加系统调用

——操作:

geditkernel/myservice.c在文本编辑器中添加

#include

#include

asmlinkagevoidsys_mycall()

{

printk(KERN_INFO"Hello,world!

\n");

return;

}

7.修改kernel/Makefile添加生成myservice.c添加到Makefile的编译规则中:

obj-y+=myservice.o

8..修改arch/x86/include/asm/unistd_32.h,添加以下内容:

#define__NR_mycallSYS_ID

//SYS_ID表示新添加系统调用的调用号

并修改文件中的NR_syscalls,将其值增加1

9.修改arxh/x86/include/asm/syscalls.h添加以下内容:

asmlinkagevoidsys_mycall();

10.修改arch/x86/kernel/syscall_table_32.S,添加以下内容:

.longsys_mycall

11.配置内核(仅仅修改localversions即可)——命令:

makemenuconfig

12.编译内核——命令:

make–j4bzImage(开4个线程编译)

13.编译内核模块——命令:

make–j4modules

14.安装内核模块——命令:

makemodules_install

15.安装内核——命令:

makeinstall

16.重启系统,在系统选择页面选择进入自己编译的linux-3.0内核

17.在桌面建立测试的C程序test.c程序内容如下:

#include

intmain(intargc,char*argv[])

{

syscall(SYS_ID);//SYS_ID表示新添加系统调用的调用号

return0;

}

18.编译程序——gcctest.c–oa.out

19.运行程序——./a.out

20.查看内核日志(printk的输出信息在内核日志中):

dmesg

四.实验结果

1.成功完成内核编译的任务,结果显示图如下:

2.下图为添加系统调用结果

五.实验小结

这次实验的内核编译需要进行一系列比较花时间的操作过程,但同时也锻炼了实际动手能力,在实践中对于操作系统这门课有了进一步的了解。

同时,在本次实验中,学习了linux系统的使用方法,掌握了很多的基本命令,也明白了添加系统调用的方法,为以后的学习提供了很大的帮助。

 

 

实验四:

一个简单文件系统的实现

一.实验目的

1.熟悉Ext文件系统的原理

2.根据Ext文件系统的数据结构和构建方法,自行实现一个简单的内存文件系统

二.实验内容

1.设计并实现一个一级(单用户)文件系统程序

a.提供以下操作:

a)文件创建/删除接口命令create/delete

b)目录创建/删除接口命令mkdir/rmdir

c)显示目录内容命令ls

b.创建的文件不要求格式和内容

2.设计并实现一个二级文件系统程序

a.提供用户登录;

b.文件、目录要有权限

三.实验原理

Ext文件系统结构:

1.引导块BootBlock

每个硬盘分区的开头1024字节,即0byte至1023byte是分区的启动扇区。

存放由ROMBIOS自动读入的引导程序和数据,但这只对引导设备有效,而对于非引导设备,该引导块不含代码。

这个块与ext2没有任何关系。

2.超级块SuperBlock

每个分区均有一个superblock块,定义了文件系统的全局信息,包括块的大小,总块数,空闲块,索引结点数,各种位图和i节点表的地址和大小等信息。

3.数据块位图

这是ext2管理存储空间的方法。

即位图法。

每个位对应一个数据块,位值为0表示空闲,1表示已经分配。

数据块位图定义为一个块大小。

于是,一个组中的数据块个数就决定了。

假设块大小为b字节。

可以区别的块数为b*8个

4.数据块DataBlocks

每个组的数据最大个数是在块大小定义后就确定了的。

所以组容量也就确定了。

假设块大小为b字节。

那么组容量就确定为(b*8)*b 字节

若1块=4K,则组块大小=4K*8*4K=128M

5.inode位图

与数据块位图相似,用来表示索引结点是否已经被使用。

假设块大小为b字节,每个索引结点数据结构大小为128字节。

最多可以有b*8个索引结点,索引结点表需要占用的存储空间大小为(b*8)*128字节。

即(b*8)*128/b=8*128个块

6.inode表

索引结点表由若干个索引结点数据结构组成,需要占用若干个块。

Ext2中的每个索引结点数据结构大小为128字节。

每个索引结点即对应一个文件或是目录。

是对其除文件名(目录名)以外的所有属性的描述。

例如:

文件类型,文件创建时间,访问时间,修改时间,文件所占数据块的个数,指向数据块的指针。

其中,数据块指针是由15个元组的数据组成

 

四.实验步骤运行结果

1.根据要求编写源程序,实验源代码见附录1。

2.运行程序,运行结果如图:

1.根据提示输入help,结果如图:

2.输入ls列出根目录下的项目,然后创建文件目录c再输入ls观察是否创建成功:

5.进入文件目录c并在c中创建文件a

6.打开a,并读取a

7.关闭a

7.删除a

9.删除文件目录c

五.实验小结

本次实验要求建立一个文件系统,由于在专业课上的基本知识学习比较薄弱,所以参考了网上的一些代码,进行了一些修改后最后获得结果。

最后,也算完成了一个简单的文件系统,具备了题目中的要求。

但在以后的学习中,还要对这一方面的知识进行一些补充。

附录1:

实验源码:

#include

#include

#include

#include

#defineDATA_BLOCK263680//数据块起始地址

#defineBLOCK_SIZE512//块大小

#defineDISK_START0//磁盘开始地址

#defineBLOCK_BITMAP512//块位图起始地址

#defineINODE_BITMAP1024//inode位图起始地址

#defineINODE_TABLE1536//索引节点表起始地址

#defineINODE_SIZE64//structinode的大小

structgroup_desc{

charbg_volume_name[16];//卷名

unsignedshortbg_block_bitmap;//保存块位图的块号

unsignedshortbg_inode_bitmap;//保存索引结点位图的块号

unsignedshortbg_inode_table;//索引结点表的起始块号

unsignedshortbg_free_blocks_count;//本组空闲块的个数

unsignedshortbg_free_inodes_count;//本组空闲索引结点的个数

unsignedshortbg_used_dirs_count;//本组目录的个数

charbg_pad[4];//填充(0xff)

};

structinode{

unsignedshorti_mode;//文件类型及访问权限

unsignedshorti_blocks;//文件的数据块个数

unsignedlongi_size;//大小(字节)

unsignedlongi_atime;//访问时间

unsignedlongi_ctime;//创建时间

unsignedlongi_mtime;//修改时间

unsignedlongi_dtime;//删除时间

unsignedshorti_block[8];//指向数据块的指针

chari_pad[24];//填充(0xff)

};

structdir_entry{//目录项结构

unsignedshortinode;//索引节点号

unsignedshortrec_len;//目录项长度

unsignedshortname_len;//文件名长度

charfile_type;//文件类型(1:

普通文件,2:

目录..)

charname[9];//文件名

};

charBuffer[512];//针对数据块的缓冲区

chartempbuf[4097];//

unsignedcharbitbuf[512];//位图缓冲区

unsignedshortindex_buf[256];

shortfopen_table[16];//文件打开表

unsignedshortlast_alloc_inode;//最近分配的节点号

unsignedshortlast_alloc_block;//最近分配的数据块号

unsignedshortcurrent_dir;//当前目录的节点号

structgroup_descsuper_block[1];//组描述符缓冲区

structinodeinode_area[1];//节点缓冲区

structdir_entrydir[32];//目录项缓冲区

charcurrent_path[256];//当前路径名

unsignedshortcurrent_dirlen;

FILE*fp;

 

voidupdate_group_desc()

{

fseek(fp,DISK_START,SEEK_SET);

fwrite(super_block,BLOCK_SIZE,1,fp);

}

voidreload_group_desc()//载入组描述符

{

fseek(fp,DISK_START,SEEK_SET);

fread(super_block,BLOCK_SIZE,1,fp);

}

voidupdate_inode_bitmap()//更新inode位图

{

fseek(fp,INODE_BITMAP,SEEK_SET);

fwrite(bitbuf,BLOCK_SIZE,1,fp);

}

voidreload_inode_bitmap()//载入inode位图

{

fseek(fp,INODE_BITMAP,SEEK_SET);

fread(bitbuf,BLOCK_SIZE,1,fp);

}

voidupdate_block_bitmap()//更新block位图

{

fseek(fp,BLOCK_BITMAP,SEEK_SET);

fwrite(bitbuf,BLOCK_SIZE,1,fp);

}

voidreload_block_bitmap()//载入block位图

{

fseek(fp,BLOCK_BITMAP,SEEK_SET);

fread(bitbuf,BLOCK_SIZE,1,fp);

}

voidupdate_inode_entry(unsignedshorti)//更新第i个inode入口

{

fseek(fp,INODE_TABLE+(i-1)*INODE_SIZE,SEEK_SET);

fwrite(inode_area,INODE_SIZE,1,fp);

}

voidreload_inode_entry(unsignedshorti)//载入第i个inode入口

{

fseek(fp,INODE_TABLE+(i-1)*INODE_SIZE,SEEK_SET);

fread(inode_area,INODE_SIZE,1,fp);

}

voidreload_dir(unsignedshorti)//更新第i个目录

{

fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);

fread(dir,BLOCK_SIZE,1,fp);

}

voidupdate_dir(unsignedshorti)//载入第i个目录

{

fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);

fwrite(dir,BLOCK_SIZE,1,fp);

}

voidreload_block(unsignedshorti)//载入第i个数据块

{

fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);

fread(Buffer,BLOCK_SIZE,1,fp);

}

voidupdate_block(unsignedshorti)//更新第i个数据块

{

fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);

fwrite(Buffer,BLOCK_SIZE,1,fp);

}

intalloc_block()//分配一个数据块,返回数据块号;

{

unsignedshortcur=last_alloc_block;

unsignedcharcon=128;

intflag=0;

if(super_block[0].bg_free_blocks_count==0)

{

printf("Thereisnoblocktobealloced!

\n");

return(0);

}

reload_block_bitmap();

cur=cur/8;

while(bitbuf[cur]==255)

{

if(cur==511)cur=0;

elsecur++;

}

while(bitbuf[cur]&con)

{

con=con/2;

flag++;

}

bitbuf[cur]=bitbuf[cur]+con;

last_alloc_block=cur*8+flag;

update_block_bitmap();

super_block[0].bg_free_blocks_count--;

update_group_desc();

returnlast_alloc_block;

}

voidremove_block(unsignedshortdel_num)//删除一个block

{

unsignedshorttmp;

tmp=del_num/8;

reload_block_bitmap();

switch(del_num%8)//更改block位图

{

case0:

bitbuf[tmp]=bitbuf[tmp]&127;break;

case1:

bitbuf[tmp]=bitbuf[tmp]&191;break;

case2:

bitbuf[tmp]=bitbuf[tmp]&223;break;

case3:

bitbuf[tmp]=bitbuf[tmp]&239;break;

case4:

bitbuf[tmp]=bitbuf[tmp]&247;break;

case5:

bitbuf[tmp]=bitbuf[tmp]&251;break;

case6:

bitbuf[tmp]=bitbuf[tmp]&253;break;

case7:

bitbuf[tmp]=bitbuf[tmp]&254;break;

}

update_block_bitmap();

super_block[0].bg_free_blocks_count++;

update_group_desc();

}

//

intget_inode()//分配一个inode,返回序号

{

unsignedshortcur=last_alloc_inode;

unsignedcharcon=128;

intflag=0;

if(super_block[0].bg_free_inodes_count==0)

{

printf("ThereisnoInodetobealloced!

\n");

return0;

}

reload_inode_bitmap();

cur=(cur-1)/8;

while(bitbuf[cur]==255)

{

if(cur==511)cur=0;

elsecur++;

}

while(bitbuf[cur]&con)

{

con=con/2;

flag++;

}

bitbuf[cur]=bitbuf[cur]+con;

last_alloc_inode=cur*8+flag+1;

update_inode_bitmap();

super_block[0].bg_free_inodes_count--;

update_group_desc();

returnlast_alloc_inode;

}

//

voidremove_inode(unsignedshortdel_num)

{

unsignedshorttmp;

tmp=(del_num-1)/8;

reload_inode_bitmap();

switch((del_num-1)%8)//更改block位图

{

case0:

bitbuf[tmp]=bitbuf[tmp]&127;break;

case1:

bitbuf[tmp]=bitbuf[tmp]&191;break;

case2:

bitbuf[tmp]=bitbuf[tmp]&223;break;

case3:

bitbuf[tmp]=bitbuf[tmp]&239;break;

case4:

bitbuf[tmp]=bitbuf[tmp]&247;break;

case5:

bitbuf[tmp]=bitbuf[tmp]&251;break;

case6:

bitbuf[tmp]=bitbuf[tmp]&253;break;

case7:

bitbuf[tmp]=bitbuf[tmp]&254;break;

}

update_inode_bitmap();

super_block[0].bg_free_inodes_count++;

update_group_desc();

}

//dir

voiddir_prepare(unsignedshorttmp,unsignedshortlen,inttype)//新目录和文件初始化.and..

{

reload_inode_entry(tmp);//得到新目录的节点入口地址

if(type==2)//目录

{

inode_area[0].i_size=32;

inode_area[0].i_blocks=1;

inode_area[0].i_block[0]=alloc_block();

dir[0].inode=tmp;

dir[1].inode=current_dir;

dir[0].name_len=len;

dir[1].name_len=current_dirlen;

dir[0].file_type=dir[1].file_type=2;

for(type=2;type<32;type++)

dir[type].inode=0;

strcpy(dir[0].name,".");

strcpy(dir[1].name,"..");

update_dir(inode_area[0].i_block[0]);

inode_area[0].i_mode=01006;//drwxrwxrwx:

目录

}

else

{

inode_area[0].i_size=0;

inode_area[0].i_blocks=0;

inode_area[0].i_mode=0407;//drwxrwxrwx:

文件

}

update_inode_entry(tmp);

}

//

unsignedshortreserch_file(chartmp[9],intfile_type,unsignedshort*inode_num,unsignedshort*block_num,unsign

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

当前位置:首页 > 高中教育 > 英语

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

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