西安交通大学操作系统实验报告Word格式.docx
《西安交通大学操作系统实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《西安交通大学操作系统实验报告Word格式.docx(36页珍藏版)》请在冰豆网上搜索。
![西安交通大学操作系统实验报告Word格式.docx](https://file1.bdocx.com/fileroot1/2022-12/1/83b59d60-3d5e-4816-a9dd-b8c5d6a89cbc/83b59d60-3d5e-4816-a9dd-b8c5d6a89cbc1.gif)
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<
linux/kernel.h>
linux/linkage.h>
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程序内容如下:
stdio.h>
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*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:
实验源码:
time.h>
string.h>
signal.h>
#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];
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()//载入组描述符
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位图
fread(bitbuf,BLOCK_SIZE,1,fp);
voidupdate_block_bitmap()//更新block位图
fseek(fp,BLOCK_BITMAP,SEEK_SET);
voidreload_block_bitmap()//载入block位图
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入口
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个目录
fwrite(dir,BLOCK_SIZE,1,fp);
voidreload_block(unsignedshorti)//载入第i个数据块
fread(Buffer,BLOCK_SIZE,1,fp);
voidupdate_block(unsignedshorti)//更新第i个数据块
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!
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;
switch(del_num%8)//更改block位图
case0:
bitbuf[tmp]=bitbuf[tmp]&
127;
break;
case1:
191;
case2:
223;
case3:
239;
case4:
247;
case5:
251;
case6:
253;
case7:
254;
super_block[0].bg_free_blocks_count++;
//
intget_inode()//分配一个inode,返回序号
unsignedshortcur=last_alloc_inode;
if(super_block[0].bg_free_inodes_count==0)
ThereisnoInodetobealloced!
reload_inode_bitmap();
cur=(cur-1)/8;
last_alloc_inode=cur*8+flag+1;
update_inode_bitmap();
super_block[0].bg_free_inodes_count--;
returnlast_alloc_inode;
voidremove_inode(unsignedshortdel_num)
tmp=(del_num-1)/8;
switch((del_num-1)%8)//更改block位图
super_block[0].bg_free_inodes_count++;
//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;
文件
update_inode_entry(tmp);
unsignedshortreserch_file(chartmp[9],intfile_type,unsignedshort*inode_num,unsignedshort*block_num,unsign