操作系统实验报告



操作系统原理课内实验报告

实验一:用户接口实验

一.        实验目的

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

2.      学会简单的shell编码。

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

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

4.

二.        实验内容

1.      控制台命令接口实验

理解面向操作命令的接口shell和进行简单的shell编程。

2.      系统调用实验

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

三.        实验步骤

添加系统调用

1.      Linux-3.0.tar.bz2拷贝到/usr/src目录下——命令:cp  linux-3.0.tar.bz2  /usr/src/

2.      打开终端,获得root权限——命令:sudo –s

3.      进入/usr/src目录——命令:cd /usr/src

4.      解压linux源码——命令:tar xvzf linux-3.0.tar.bz2

5.      进入目录linux-3.0.5——命令:cd linux-3.0

6.      添加系统调用——:gedit kernel/myservice.c 在文本编辑器中添加

#include <linux/kernel.h>

#include <linux/linkage.h>

asmlinkage void sys_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_mycall               SYS_ID              //SYS_ID表示新添加系统调用的调用号

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

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

asmlinkage void sys_mycall();

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

.long sys_mycall

11.  配置内核(仅仅修改local versions即可)——命令:make menuconfig

12.  编译内核——命令:make –j4 bzImage(开4个线程编译)

13.  编译内核模块——命令:make –j4 modules

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

15.  安装内核——命令:make install

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

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

#include <stdio.h>

int main(int argc, char *argv[])

{

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

return 0;

}

18.  编译程序——gcc test.c –o a.out

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

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

      

四.        实验结果

1.      编译内核结果成功

2.      添加系统调用结果

五.        实验小结

这次实验过程比较坎坷,起初觉得在虚拟机中安装linux比较方便所以就在虚拟机中做的实验可是在重启系统时无法选择系统,总是进入到原来的内核,自己以为编译内核出了问题所以就编译了好几次内核,可是结果都是一样的。后来又在将linux直接装在计算机中,装成双系统,这次重启时可以进入自己编译的内核。在进入自己编译的内核时发现自己只编译了内核而没有添加系统调用,自己只好又编译了一次内核,最后这一次非常顺利,运行系统调用程序可以在内核日志中看到自己添加的Hello world!

这次实验我们学习了linux系统的使用方法,掌握了一些基本的linux命令,学习了添加系统调用的方法,更深入的了解了操作系统,为我们以后的工作学习打下坚实的基础。

实验四:一个简单文件系统的实现

一.        实验目的

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

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

二.        实验内容

1.      定义一个数组代表磁盘存储空间,在其上建立并维护超级块、位图、inode表等各种数据结构。

2.       在此基础上,实现文件系统的常用接口,如open,create,read,write,close等。

2.

三.        实验原理

1.       Ext文件系统结构:

1.

2.      引导块BootBlock

每个硬盘分区的开头1024字节,即0 byte至1023 byte是分区的启动扇区。存放由ROM BIOS自动读入的引导程序和数据,但这只对引导设备有效,而对于非引导设备,该引导块不含代码。这个块与ext2没有任何关系。

3.      超级块SuperBlock

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

4.      数据块位图

这是ext2管理存储空间的方法。即位图法。每个位对应一个数据块,位值为0表示空闲,1表示已经分配。数据块位图定义为一个块大小。于是,一个组中的数据块个数就决定了。假设块大小为b 字节。可以区别的块数为b*8个

5.      数据块 DataBlocks

每个组的数据最大个数是在块大小定义后就确定了的。所以组容量也就确定了。假设块大小为b 字节。那么组容量就确定为(b*8)*b 字节

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

6.       inode位图  

与数据块位图相似,用来表示索引结点是否已经被使用。假设块大小为b字节,每个索引结点数据结构大小为128字节。最多可以有b*8个索引结点,索引结点表需要占用的存储空间大小为(b*8)*128字节。即(b*8)*128/b=8*128个块

7.      inode

索引结点表由若干个索引结点数据结构组成,需要占用若干个块。Ext2中的每个索引结点数据结构大小为128字节。每个索引结点即对应一个文件或是目录。是对其除文件名(目录名)以外的所有属性的描述。例如:文件类型,文件创建时间,访问时间,修改时间,文件所占数据块的个数,指向数据块的指针。其中,数据块指针是由15个元组的数据组成

四.实验步骤运行结果

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

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

3.      根据提示输入help,结果如图“

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

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

       6. 打开a,并读取a

       7.    关闭a

8.      删除a

9.    删除文件目录c

.实验小结

       本实验为文件系统实验,实验要求实现一个简单的模拟ext文件系统,本次实验的编程比较复杂,实验遇到的主要问题是编写程序和实验的调试过程。特别在调试过程遇到了各种这样那样的问题。在遇到编译错误时采用的解决办法是在网上查找相关资料,通过和自己的程序对比来解决问题。

       通过操作系统上机实验,我不仅更加深刻理解和记忆文件系统的知识,还更加熟练了VC++的编程技能。

附录1

实验源码:

#include <stdio.h>

#include <time.h>

#include <string.h>

#include <signal.h>

#define DATA_BLOCK 263680    //数据块起始地址

#define BLOCK_SIZE 512    //块大小

#define DISK_START 0 //磁盘开始地址

#define BLOCK_BITMAP 512     //块位图起始地址

#define INODE_BITMAP 1024//inode 位图起始地址

#define INODE_TABLE 1536//索引节点表起始地址

#define INODE_SIZE 64      //struct inode的大小

struct group_desc{

    char bg_volume_name[16]; //卷名

    unsigned short bg_block_bitmap; //保存块位图的块号

    unsigned short bg_inode_bitmap; //保存索引结点位图的块号

    unsigned short bg_inode_table; //索引结点表的起始块号

    unsigned short bg_free_blocks_count; //本组空闲块的个数

    unsigned short bg_free_inodes_count; //本组空闲索引结点的个数

    unsigned short bg_used_dirs_count; //本组目录的个数

    char bg_pad[4]; //填充(0xff)

};

struct inode{

    unsigned short i_mode; //文件类型及访问权限      

    unsigned short i_blocks; //文件的数据块个数

    unsigned long i_size; //大小( 字节)

    unsigned long i_atime; //访问时间

    unsigned long i_ctime; //创建时间

    unsigned long i_mtime; //修改时间

    unsigned long i_dtime; //删除时间

    unsigned short i_block[8]; //指向数据块的指针

    char i_pad[24]; //填充(0xff)

};

struct dir_entry{   //目录项结构

    unsigned short inode; //索引节点号

    unsigned short rec_len; //目录项长度

    unsigned short name_len; //文件名长度

    char file_type; //文件类型(1: 普通文件, 2: 目录.. )

    char name[9]; //文件名

};

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

char tempbuf[4097]; //

unsigned char bitbuf[512]; //位图缓冲区

unsigned short index_buf[256];

short fopen_table[16]; //  文件打开表

unsigned short last_alloc_inode; //  最近分配的节点号

unsigned short last_alloc_block; //  最近分配的数据块号

unsigned short current_dir;   //      当前目录的节点号

struct group_desc super_block[1]; //   组描述符缓冲区

struct inode inode_area[1];  //   节点缓冲区

struct dir_entry dir[32];   //  目录项缓冲区

char current_path[256];    //    当前路径名

unsigned short current_dirlen;

FILE *fp;

void update_group_desc()

{

    fseek(fp,DISK_START,SEEK_SET);

    fwrite(super_block,BLOCK_SIZE,1,fp);

}

void reload_group_desc()//载入组描述符

{

    fseek(fp,DISK_START,SEEK_SET);

    fread(super_block,BLOCK_SIZE,1,fp);

}

void update_inode_bitmap()//更新inode位图

{

    fseek(fp,INODE_BITMAP,SEEK_SET);

    fwrite(bitbuf,BLOCK_SIZE,1,fp);

}

void reload_inode_bitmap()//载入inode位图

{

    fseek(fp,INODE_BITMAP,SEEK_SET);

    fread(bitbuf,BLOCK_SIZE,1,fp);

}

void update_block_bitmap()//更新block位图

{

    fseek(fp,BLOCK_BITMAP,SEEK_SET);

    fwrite(bitbuf,BLOCK_SIZE,1,fp);

}

void reload_block_bitmap()//载入block位图

{

    fseek(fp,BLOCK_BITMAP,SEEK_SET);

    fread(bitbuf,BLOCK_SIZE,1,fp);

}

void update_inode_entry(unsigned short i)//更新第i个inode入口

{

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

    fwrite(inode_area,INODE_SIZE,1,fp);

}

void reload_inode_entry(unsigned short i)//载入第i个inode入口

{

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

    fread(inode_area,INODE_SIZE,1,fp);

}

void reload_dir(unsigned short i)//更新第i个目录

{

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

    fread(dir,BLOCK_SIZE,1,fp);

}

void update_dir(unsigned short i)//载入第i个目录

{

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

    fwrite(dir,BLOCK_SIZE,1,fp);

}

void reload_block(unsigned short i)//载入第i个数据块

{

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

    fread(Buffer,BLOCK_SIZE,1,fp);

}

void update_block(unsigned short i)//更新第i个数据块

{

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

    fwrite(Buffer,BLOCK_SIZE,1,fp);

}

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

{

    unsigned short cur=last_alloc_block;

    unsigned char con=128;

    int flag=0;

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

    {

        printf("There is no block to be alloced!\n");

        return(0);

    }

    reload_block_bitmap();

    cur=cur/8;

    while(bitbuf[cur]==255)

    {

        if(cur==511)cur=0;

        else cur++;

    }

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

    return last_alloc_block;

}

void remove_block(unsigned short del_num)//删除一个block

{

    unsigned short tmp;

    tmp=del_num/8;

    reload_block_bitmap();

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

    {

        case 0:bitbuf[tmp]=bitbuf[tmp]&127;break;

        case 1:bitbuf[tmp]=bitbuf[tmp]&191;break;

        case 2:bitbuf[tmp]=bitbuf[tmp]&223;break;

        case 3:bitbuf[tmp]=bitbuf[tmp]&239;break;

        case 4:bitbuf[tmp]=bitbuf[tmp]&247;break;

        case 5:bitbuf[tmp]=bitbuf[tmp]&251;break;

        case 6:bitbuf[tmp]=bitbuf[tmp]&253;break;

        case 7:bitbuf[tmp]=bitbuf[tmp]&254;break;

    }

    update_block_bitmap();

    super_block[0].bg_free_blocks_count++;

    update_group_desc();

}

//

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

{

    unsigned short cur=last_alloc_inode;

    unsigned char con=128;

    int flag=0;

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

    {

        printf("There is no Inode to be alloced!\n");

        return 0;

    }

    reload_inode_bitmap();

    cur=(cur-1)/8;

    while(bitbuf[cur]==255)

    {

        if(cur==511)cur=0;

        else cur++;

    }

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

    return last_alloc_inode;

}

//

void remove_inode(unsigned short del_num)

{

    unsigned short tmp;

    tmp=(del_num-1)/8;

    reload_inode_bitmap();

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

    {

        case 0:bitbuf[tmp]=bitbuf[tmp]&127;break;

        case 1:bitbuf[tmp]=bitbuf[tmp]&191;break;

        case 2:bitbuf[tmp]=bitbuf[tmp]&223;break;

        case 3:bitbuf[tmp]=bitbuf[tmp]&239;break;

        case 4:bitbuf[tmp]=bitbuf[tmp]&247;break;

        case 5:bitbuf[tmp]=bitbuf[tmp]&251;break;

        case 6:bitbuf[tmp]=bitbuf[tmp]&253;break;

        case 7:bitbuf[tmp]=bitbuf[tmp]&254;break;

    }

    update_inode_bitmap();

    super_block[0].bg_free_inodes_count++;

    update_group_desc();

}

// dir

void dir_prepare(unsigned short tmp,unsigned short len,int type) //新目录和文件初始化.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);

}

//

unsigned short reserch_file(char tmp[9],int file_type,unsigned short *inode_num,unsigned short *block_num,unsigned short *dir_num)

{                      //查找文件并改写缓冲区里节点号,所在目录节点的数据块号(0~7)、目录项所在号

    unsigned short j,k;

    reload_inode_entry(current_dir);

    j=0;

    while(j<inode_area[0].i_blocks)

    {

        reload_dir(inode_area[0].i_block[j]);

        k=0;

        while(k<32)

        {

            if(!dir[k].inode||dir[k].file_type!=file_type||strcmp(dir[k].name,tmp))k++;

            else

            {

                *inode_num=dir[k].inode;

                *block_num=j;

                *dir_num=k;

                return 1;

            }

        }

        j++;

    }

    return 0;

}

//

void cd(char tmp[9])

{

    unsigned short i,j,k,flag;

    flag=reserch_file(tmp,2,&i,&j,&k);

    if(flag)

    {

        current_dir=i;

        if(!strcmp(tmp,"..")&&dir[k-1].name_len)

        {

            current_path[strlen(current_path)-dir[k-1].name_len-1]='\0';

            current_dirlen=dir[k].name_len;

        }

        else if(!strcmp(tmp,"."));

        else if(strcmp(tmp,".."))

        {

            current_dirlen=strlen(tmp);

            strcat(current_path,tmp);

            strcat(current_path,"/");

        }

    }

    else printf("The directory %s not exists!\n",tmp);

}

//

void del(char tmp[9])

{

    unsigned short i,j,k,m,n,flag;

    m=0;

    flag=reserch_file(tmp,1,&i,&j,&k);

    if(flag)

    {

        flag=0;

        while(fopen_table[flag]!=dir[k].inode&&flag<16)flag++;

        if(flag<16)fopen_table[flag]=0;

        reload_inode_entry(i);

        while(m<inode_area[0].i_blocks)remove_block(inode_area[0].i_block[m++]);

        inode_area[0].i_blocks=0;

        inode_area[0].i_size=0;

        remove_inode(i);

        reload_inode_entry(current_dir);

        dir[k].inode=0;

        //if(k!=0)dir[k-1].rec_len+=dir[k].rec_len ;

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

        inode_area[0].i_size-=16;

        m=1;

        while(m<inode_area[i].i_blocks)

        {

            flag=n=0;

            reload_dir(inode_area[0].i_block[m]);

            while(n<32)

            {

                if(!dir[n].inode)flag++;

                n++;

            }

            if(flag==32)

            {

                remove_block(inode_area[i].i_block[m]);

                inode_area[i].i_blocks--;

                while(m<inode_area[i].i_blocks)inode_area[i].i_block[m]=inode_area[i].i_block[++m];

            }

        }

        update_inode_entry(current_dir);

    }

    else printf("The file %s not exists!\n",tmp);

}

//

void mkdir(char tmp[9],int type)

{

    unsigned short tmpno,i,j,k,flag;

    reload_inode_entry(current_dir); //获得当前目录的索引节点给inode_area[0]

    if(!reserch_file(tmp,type,&i,&j,&k)) //未找到同名文件

    {

        if(inode_area[0].i_size==4096) //目录项已满

        {

            printf("Directory has no room to be alloced!\n");

            return;

        }

        flag=1;

        if(inode_area[0].i_size!=inode_area[0].i_blocks*512)//目录中有某些个块中32个项未满

        {

            i=0;

            while(flag&&i<inode_area[0].i_blocks)

            {

                reload_dir(inode_area[0].i_block[i]);

                j=0;

                while(j<32)

                {

                    if(dir[j].inode==0)

                    {

                        flag=0;

                        break;

                    }

                    j++;

                }

                i++;

            }

            tmpno=dir[j].inode=get_inode();

            dir[j].name_len=strlen(tmp);

            dir[j].file_type=type;

            strcpy(dir[j].name,tmp);

            update_dir(inode_area[0].i_block[i-1]);

        }

        else//全满

        {

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

            inode_area[0].i_blocks++;

            reload_dir(inode_area[0].i_block[inode_area[0].i_blocks-1]);

            tmpno=dir[0].inode=get_inode();

            dir[0].name_len=strlen(tmp);

            dir[0].file_type=type;

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

            //初始化新块

            for(flag=1;flag<32;flag++)dir[flag].inode=0;

            update_dir(inode_area[0].i_block[inode_area[0].i_blocks-1]);

        }

        inode_area[0].i_size+=16;

        update_inode_entry(current_dir);

        dir_prepare(tmpno,strlen(tmp),type);

    }

    else  //已经存在同名文件或目录

    {

        if(type==1)printf("File has already existed!\n");

        else printf("Directory has already existed!\n");

    }

}

//

void rmdir(char tmp[9])

{

    unsigned short i,j,k,flag;

    unsigned short m,n;

    if(!strcmp(tmp,"..")||!strcmp(tmp,"."))

    {

        printf("The directory can not be deleted!\n");

        return;

    }

    flag=reserch_file(tmp,2,&i,&j,&k);

    if(flag)

    {

        reload_inode_entry(dir[k].inode); //找到要删除的目录的节点并载入

        if(inode_area[0].i_size==32)  //只有.and ..

        {

            inode_area[0].i_size=0;

            inode_area[0].i_blocks=0;

            //reload_dir(inode_area[0].i_block[0]);

            //dir[0].inode=0;

            //dir[1].inode=0;

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

            reload_inode_entry(current_dir);//得到当前目录的节点并更改当前目录项

            remove_inode(dir[k].inode);

            dir[k].inode=0;

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

            inode_area[0].i_size-=16;

            flag=0;

            m=1;

            while(flag<32&&m<inode_area[0].i_blocks)

            {

                flag=n=0;

                reload_dir(inode_area[0].i_block[m]);

                while(n<32)

                {

                    if(!dir[n].inode)flag++;

                    n++;

                }

                if(flag==32)

                {

                    remove_block(inode_area[0].i_block[m]);

                    inode_area[0].i_blocks--;

                    while(m<inode_area[0].i_blocks)inode_area[0].i_block[m]=inode_area[0].i_block[++m];

                }

            }

        update_inode_entry(current_dir);

        }

        else printf("Directory is not null!\n");

    }

    else printf("Directory to be deleted not exists!\n");

}

//

void ls()

{

    

       int i,j,k,tmpno,no;

    i=0;

       printf("items type mode size\n");

    reload_inode_entry(current_dir);

    while(i<inode_area[0].i_blocks)

    {

        k=0;

        reload_dir(inode_area[0].i_block[i]);

        while(k<32)

        {

            if(dir[k].inode)

            {

                printf("%s",dir[k].name);

                if(dir[k].file_type==2)

                {

                    j=0;

                    reload_inode_entry(dir[k].inode);

                    if(!strcmp(dir[k].name,".."))while(j++<13)printf(" ");

                    else if(!strcmp(dir[k].name,"."))while(j++<14)printf(" ");

                    else while(j++<15-dir[k].name_len)printf(" ");

                    printf("<DIR>          ");

                    switch(inode_area[0].i_mode&7)

                    {

                        case 1:printf("____x");break;

                        case 2:printf("__w__");break;

                        case 3:printf("__w_x");break;

                        case 4:printf("r____");break;

                        case 5:printf("r___x");break;

                        case 6:printf("r_w__");break;

                        case 7:printf("r_w_x");break;

                    }

                    printf("         ----");

                }

                else if(dir[k].file_type==1)

                {

                    j=0;

                    reload_inode_entry(dir[k].inode);

                    while(j++<15-dir[k].name_len)printf(" ");

                    printf("<FILE>         ");

                    switch(inode_area[0].i_mode&7)

                    {

                        case 1:printf("____x");break;

                        case 2:printf("__w__");break;

                        case 3:printf("__w_x");break;

                        case 4:printf("r____");break;

                        case 5:printf("r___x");break;

                        case 6:printf("r_w__");break;

                        case 7:printf("r_w_x");break;

                    }

                    printf("         %d bytes     ",inode_area[0].i_size);

                }

                printf("\n");

            }

            k++;

            reload_inode_entry(current_dir);

        }

        i++;

    }

}

//       file 

unsigned short search_file(unsigned short Ino)//在打开文件表中查找是否已打开文件

{

    unsigned short fopen_table_point=0;

    while(fopen_table_point<16&&fopen_table[fopen_table_point++]!=Ino);

    if(fopen_table_point==16)return 0;

    return 1;

}

//

void read_file(char tmp[9])//读文件

{

    unsigned short flag,i,j,k;

    flag=reserch_file(tmp,1,&i,&j,&k); //返回文件目录项的信息

    if(flag)

    {

        if(search_file(dir[k].inode))

        {

            reload_inode_entry(dir[k].inode);

            if(!(inode_area[0].i_mode&4))//i_mode:111b:读,写,执行

            {

                printf("The file %s can not be read!\n",tmp);

                return;

            }

            for(flag=0;flag<inode_area[0].i_blocks;flag++)

            {

                reload_block(inode_area[0].i_block[flag]);

                Buffer[512]='\0';

                printf("%s",Buffer);

            }

            if(flag==0)printf("The file %s is empty!\n",tmp);

            else printf("\n");

        }

        else printf("The file %s has not been opened!\n",tmp);

    }

    else printf("The file %s not exists!\n",tmp);

}

void write_file(char tmp[9])//写文件

{

    unsigned short flag,i,j,k,size=0,need_blocks;

    flag=reserch_file(tmp,1,&i,&j,&k);

    if(flag)

    {

        if(search_file(dir[k].inode))

        {

            reload_inode_entry(dir[k].inode);

            if(!(inode_area[0].i_mode&2))//i_mode:111b:读,写,执行

            {

                printf("The file %s can not be writed!\n",tmp);

                return;

            }

            while(1)

            {

                tempbuf[size]=getchar();

                if(tempbuf[size]=='#')

                {

                    tempbuf[size]='\0';

                    break;

                }

                if(size>=4096)

                {

                    printf("Sorry,the max size of a file is 4KB!\n");

                    tempbuf[size]='\0';

                    break;

                }

                size++;

            }

            need_blocks=strlen(tempbuf)/512;

            if(strlen(tempbuf)%512)need_blocks++;

            if(need_blocks<9)

            {

                while(inode_area[0].i_blocks<need_blocks)

                {

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

                    inode_area[0].i_blocks++;

                }

                j=0;

                while(j<need_blocks)

                {

                    if(j!=need_blocks-1)

                    {

                        reload_block(inode_area[0].i_block[j]);

                        memcpy(Buffer,tempbuf+j*BLOCK_SIZE,BLOCK_SIZE);

                        update_block(inode_area[0].i_block[j]);

                    }

                    else

                    {

                        reload_block(inode_area[0].i_block[j]);

                        memcpy(Buffer,tempbuf+j*BLOCK_SIZE,strlen(tempbuf)-j*BLOCK_SIZE);

                        if(strlen(tempbuf)>inode_area[0].i_size)

                        {

                            Buffer[strlen(tempbuf)-j*BLOCK_SIZE]='\0';

                            inode_area[0].i_size=strlen(tempbuf);

                        }

                        update_block(inode_area[0].i_block[j]);

                    }

                    j++;

                }

                update_inode_entry(dir[k].inode);

            }

            else printf("Sorry,the max size of a file is 4KB!\n");

        }

        else printf("The file %s has not opened!\n",tmp);

    }

    else printf("The file %s does not exist!\n",tmp);

}

//

void close_file(char tmp[9])//关闭文件

{

    unsigned short flag,i,j,k;

    flag=reserch_file(tmp,1,&i,&j,&k);

    if(flag)

    {

        if(search_file(dir[k].inode))

        {

            flag=0;

            while(fopen_table[flag]!=dir[k].inode)flag++;

            fopen_table[flag]=0;

            printf("File: %s! closed\n",tmp);

        }

        else printf("The file %s has not been opened!\n",tmp);

    }

    else printf("The file %s does not exist!\n",tmp);

}

void open_file(char tmp[9])

{

    unsigned short flag,i,j,k;

    flag=reserch_file(tmp,1,&i,&j,&k);

    if(flag)

    {

        if(search_file(dir[k].inode))printf("The file %s has opened!\n",tmp);

        else

        {

            flag=0;

            while(fopen_table[flag])flag++;

            fopen_table[flag]=dir[k].inode;

            printf("File %s! opened\n",tmp);

        }

    }

    else printf("The file %s does not exist!\n",tmp);

}

//  format

void initialize_disk()

{

    int i=0;

    printf("Creating the ext2 file system\n");

    printf("Please wait ");

    while(i<1)

    {

        printf("... ");

       // sleep(1);

        i++;

    }

    printf("\n");

    last_alloc_inode=1;

    last_alloc_block=0;

    for(i=0;i<16;i++)fopen_table[i]=0;//清空缓冲表

    for(i=0;i<BLOCK_SIZE;i++)Buffer[i]=0;// 清空缓冲区,通过缓冲区清空文件,即清空磁盘

    fp=fopen("FS_zqw_zzw.txt","w+b");

    fseek(fp,DISK_START,SEEK_SET);

    for(i=0;i<4611;i++)fwrite(Buffer,BLOCK_SIZE,1,fp);//清空文件,即清空磁盘全部用0填充

    reload_group_desc();

    reload_inode_entry(1);

    reload_dir(0);

    strcpy(current_path,"[root@ /");  //该路径名

    strcpy(super_block[0].bg_volume_name,"EXT2FS"); //改卷名,初始化组描述符内容

    super_block[0].bg_block_bitmap=BLOCK_BITMAP;

    super_block[0].bg_inode_bitmap=INODE_BITMAP;

    super_block[0].bg_inode_table=INODE_TABLE;

    super_block[0].bg_free_blocks_count=4096;

    super_block[0].bg_free_inodes_count=4096;

    super_block[0].bg_used_dirs_count=0;// 初始化组描述符内容

    update_group_desc(); //更新组描述符内容

    reload_block_bitmap();

    reload_inode_bitmap();

    inode_area[0].i_mode=518;

    inode_area[0].i_blocks=0;

    inode_area[0].i_size=32;

    inode_area[0].i_atime=0;

    inode_area[0].i_ctime=0;

    inode_area[0].i_mtime=0;

    inode_area[0].i_dtime=0;

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

    inode_area[0].i_blocks++;

    current_dir=get_inode();

    update_inode_entry(current_dir);

    dir[0].inode=dir[1].inode=current_dir;

    dir[0].name_len=0;

    dir[1].name_len=0;

    dir[0].file_type=dir[1].file_type=2;//1:文件;2:目录

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

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

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

    printf("The ext2 file system has been installed!\n");

}

void initialize_memory()

{

    int i=0;

    last_alloc_inode=1;

    last_alloc_block=0;

    for(i=0;i<16;i++)fopen_table[i]=0;

    strcpy(current_path,"[root@ /");

    current_dir=1;

    fp=fopen("FS_zqw_zzw.txt","r+b");

    if(fp==NULL)

    {

        printf("The File system does not exist!\n");

        initialize_disk();

        return ;

    }

    reload_group_desc();

}

void format()

{

    initialize_disk();

    initialize_memory();

}

   

void help()

{

   

    printf("                         ext文件系统模拟                                                         \n");

   

    printf("    可以使用的命令:                                                         \n");

    printf("    1.进入文件目录   : cd+dir_name    7.创建文件目录  : mkdir+dir_name      \n");

    printf("    2.创建文件 : mkf+file_name        8.删除目录  : rmdir+dir_name          \n");

    printf("    3.删除文件  : rm+file_name        9.读取文件 : read+file_name           \n");

    printf("    4.打开文件  : open+file_name      10.写文件 : write+file_name           \n");

    printf("    5.关闭文件  : close+file_name     11.退出      : quit                   \n");

    printf("    6.列出项目 : ls                   12.查看帮助 : help                    \n");

    printf("    13.format disk : format                                                 \n");

  

}

// main

int main(char argc,char **argv)

{

    char command[10],temp[9];

    initialize_memory();

       printf("输入help查看帮助\n");

    while(1)

    {

        printf("%s]#",current_path);

        scanf("%s",command);

        if(!strcmp(command,"cd"))

        {

            scanf("%s",temp);

            cd(temp);

        }

        else if(!strcmp(command,"mkdir"))

        {

            scanf("%s",temp);

            mkdir(temp,2);

        }

        else if(!strcmp(command,"mkf"))

        {

            scanf("%s",temp);

            mkdir(temp,1);

        }

        else if(!strcmp(command,"rmdir"))

        {

            scanf("%s",temp);

            rmdir(temp);

        }

        else if(!strcmp(command,"rm"))

        {

            scanf("%s",temp);

            del(temp);

        }

        else if(!strcmp(command,"open"))

        {

            scanf("%s",temp);

            open_file(temp);

        }

        else if(!strcmp(command,"close"))

        {

            scanf("%s",temp);

            close_file(temp);

        }

        else if(!strcmp(command,"read"))

        {

            scanf("%s",temp);

            read_file(temp);

        }

        else if(!strcmp(command,"write"))

        {

            scanf("%s",temp);

            write_file(temp);

        }

        else if(!strcmp(command,"ls"))ls();

        else if(!strcmp(command,"format"))

        {

            char tempch;

            printf("Format will erase all the data in the Disk\n");

            printf("Are you sure?y/n:\n");

            scanf(" %c",&tempch);

            if(tempch=='Y'||tempch=='y')

            {

                fclose(fp);

                initialize_disk();

            }

            else

            printf("Format Disk canceled\n");

        }

        else if(!strcmp(command,"help"))help();

        else if(!strcmp(command,"quit"))break;

        else printf("No this Command,Please check!\n");

    }

    return 0;

}

相关推荐