当前位置:文档之家› 福州大学操作系统实验报告-文件系统的构建

福州大学操作系统实验报告-文件系统的构建

计算机操作系统实验三【实验名称】:文件系统的构建(实验3)【实验目的】:掌握磁盘的工作原理和操作系统进行文件管理的原理 【实验原理】:硬盘的MBR :MBR (Main Boot Record ),按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。

在总共512字节的主引导扇区中,MBR 只占用了其中的446个字节(偏移0000--偏移01BD ),另外的64个字节(偏移01BE--偏移01FD )交给了DPT(Disk Partition Table 硬盘分区表),最后两个字节"55,AA"(偏移01FE- 偏移01FF )是分区的结束标志。

这个整体构成了硬盘的主引导扇区。

大致的结构如图所示:硬盘依据分区表中的信息把硬盘划分为最多四个分区(对于扩展分区,可进一步划分为多个逻辑分区)。

U 盘采用类似的方法划分分区。

每个分区或软盘上可建立独立的文件系统。

下图是FAT 文件系统空间分布结构。

【实验内容】:在掌握磁盘的工作原理和操作系统进行文件管理原理的基础上,自行设计实现在磁盘上建立文件系统的软件,该软件应该具有与Format 类似的功能,至少支持一种文件系统格式,如FAT 、NTFS 或EXT2,至少能够对一种媒体进行格式化,如软盘,U 盘或硬盘(不得在实验室的机器上进行硬盘格式引导扇区FA T1FAT2根目录区文件数据区化的实验)等。

不能直接调用操作系统提供的格式化工具或类似SHFormatDrive ()的高层系统函数实现该软件。

在Windows环境可使用biosdisk()函数完成底层盘操作,在Linux环境上可参考format的源代码。

比较自己设计实现的软件与FORMAT,分析存在什么异同。

一、背景知识使用“DOC分区”体系时,磁盘的第一个——也就是0号扇区被称为主引导记录扇区,也称为主引导记录MBR(Master Boot recorder,MBR)。

1、MBR数据结构MBR由446个字节的引导代码、64字节的主分区(4个)表及两个字节的“55 AA”是分区的结束标志。

FAT文件系统的整体布局2、说明【1】保留区含有一个重要的数据结构——系统引导扇区(DBR)。

FAT12、FAT16的保留区通常只有一个扇区,而FAT32的保留扇区要多一些,除0号扇区外,还有其他一些扇区,其中包括了DBR的备份扇区。

【2】 FAT区由来年各个大小相等的FAT表组成——FAT1、FAT2,FAT2紧跟在FAT1之后。

【3】 FAT12、FAT16的根目录虽然也属于数据区,但是他们并不由簇进行管理。

也就是说FAT12、FAT16的根目录是没有簇号的,他们的2号簇从根目录之后开始。

而FAT32的根目录通常位于2号簇。

3、典型的FAT32_DBR【1】0x00~0x02:3个字节,跳转指令。

【2】0x03~0x0A:8个字节,文件系统标志和版本号,这里为MSDOC5.0。

【3】0x0B~0x0C:2个字节,每扇区字节数,512(0X02 00)。

【4】0x0D~0x0D:1个字节,每簇扇区数,8(0x08)。

【5】0x0E~0x0F:2个字节,保留扇区数,2050(0x0802)。

【6】0x10~0x10:1个字节,FAT表个数,2。

【7】0x11~0x12:2个字节,根目录最多可容纳的目录项数,FAT12/16通常为512。

FAT32不使用此处值,置0。

【8】0x13~0x14:2个字节,扇区总数,小于32MB时使用该处存放。

超过32MB时使用偏移0x20~0x23字节处的4字节存放。

笔者的SD卡容量为2GB,所以不使用该处,置0.【9】0x15~0x15:1个字节,介质描述符,0xF8表示本地硬盘。

【10】0x16~0x17:2个字节,每个FAT表的大小扇区数(FAT12/16使用,FAT32不使用此处,置0)。

【11】0x18~0x19:2个字节,每磁道扇区数,63(0x00 3F)。

【12】0x1A~0x1B:2个字节磁头数,255(0x00 FF)。

【13】0x1C~0x1F:4个字节,分区前已使用扇区数,【14】0x20~0x23:4个字节,文件系统大小扇区数。

【15】0x24~0x27:4个字节,每个FAT表的大小扇区数。

【16】0x28~0x29:2个字节,标记。

【17】0x2A~0x2B:2个字节,版本号。

【18】0x2C~0x2F:4个字节,根目录簇号,2。

(虽然在FAT32文件系统下,根目录可以存放在数据区的任何位置,但是通常情况下还是起始于2号簇)【19】0x30~0x31:2个字节,FSINFO(文件系统信息扇区)扇区号,1。

(上图的标注即用黄色条纹的标注有误,请读者注意)该扇区为操作系统提供关于空簇总数及下一可用簇的信息。

【20】0x32~0x33:2个字节,备份引导扇区的位置,6。

(上图的标注即用黄色条纹的标注有误,请读者注意)备份引导扇区总是位于文件系统的6号扇区。

【21】0x34~0x3F:12个字节,未使用。

【22】0x40~0x40:1个字节,BIOS INT 13H 设备号,0x80。

(这个我也不知道什么意思☺)【23】0x41~0x41:1个字节,未用。

【24】0x42~0x42:1个字节,扩展引导标志。

0x29。

【25】0x43~0x46:1个字节,卷序列号。

通常为一个随机值。

【26】0x47~0x51:11个字节,卷标(ASCII码),如果建立文件系统的时候指定了卷标,会保存在此。

笔者当时没有指定卷表,上图中的YCY是后来指定的。

【27】0x52~0x59:8个字节,文件系统格式的ASCII码,FAT32。

【28】 0x5A~0x1FD:410个字节,未使用。

该部分没有明确的用途。

本实验关键点:FAT1起始扇区 = DBR的扇区号 + 保留扇区号根目录起始扇区 = 保留扇区数 + 一个FAT的扇区数 × FAT表个数 + (起始始簇号-2) x 每簇的扇区数Fat32查找目录区簇号,在fat表中从根目录查起,直到其表项标记结束。

使用到的工具:winhex(自行网上下载),a.c,b.c,c.c(将下面源码复制进相应文件里即可,linux下运行没问题,windows会报错)二、实验方案(如图):获取FAT32引导记录更改记录写入引导记录清空分配表三、预计实验结果:将u盘格式化成fat32文件系统,8G容量。

四、关键代码:a.c文件读取FAT32 DBR 保存到tmp.txt#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>int main(){int fd;char mbr[512];FILE *fp;char tmp[20];printf("input:\n");scanf("%s",tmp);fd=open(tmp,O_RDWR);//打开驱动器read(fd,mbr,sizeof(mbr));close(fd);fp = fopen("tmp.txt","w");fwrite(mbr,sizeof(mbr),1,fp);fclose(fp);}b.c文件#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include<sys/types.h>#include<unistd.h>//DBR结构typedef struct FAT32_DBR{char BS_jmpBoot[3]; //跳转指令char BS_OEMName[8]; //操作系统的名称和版本号char BPB_BytesPerSec[2];//每扇区字节数char BPB_SecPerClus[1]; //每簇扇区数char BPB_RsvdSecCnt[2]; //保留扇区数目char BPB_NumFATs[1]; //此卷中FAT表数char BPB_RootEntCnt[2]; //FAT32为0char BPB_TotSec16[2]; //FAT32为0char BPB_Media[1]; //存储介质char BPB_FATSz16[2]; //FAT32为0char BPB_SecPerTrk[2]; //磁道扇区数char BPB_NumHeads[2]; //磁头数char BPB_HiddSec[4]; //FAT区前隐扇区数char BPB_TotSec32[4]; //该卷总扇区数char BPB_FATSz32[4]; //一个FAT表扇区数char BPB_ExtFlags[2]; //FAT32特有char BPB_FSVer[2]; //FAT32特有char BPB_RootClus[4]; //根目录簇号char FSInfo[2]; //保留扇区FSINFO扇区数char BPB_BkBootSec[2]; //通常为6char BPB_Reserved[12]; //扩展用char BS_DrvNum[1]; //char BS_Reserved1[1]; //char BS_BootSig[1]; //char BS_V olID[4]; //char BS_FilSysType[11]; //char BS_FilSysType1[8]; //"FAT32 "char left[422];//剩余空间}fat32;int main(){fat32 mymbr;int fd,i;FILE *fp;char tmp[20];char ini=0x00;char end2=0xff;printf("input:\n");scanf("%s",tmp);fp = fopen("tmp.txt","r");//从文件读取DBRfread(&mymbr,sizeof(fat32),1,fp);fd=open(tmp,O_RDWR);//打开驱动器if(fd<0){printf("error!\n");exit(1);}write(fd,&mymbr,sizeof(mymbr));//写入DBR printf("SUCCESS!\n");close(fd);fclose(fp);return 0;}c.c文件#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include<sys/types.h>#include<unistd.h>int main(){int fd,i;char tmp[20];char ini=0x00;int fat1,fat2,dir;fat1 = 1049600;fat2 = 8913408;dir = 16777216;fat1+=12;fat2+=12;printf("input:\n");scanf("%s",tmp);fd=open(tmp,O_RDWR);//打开驱动器if(fd<0){printf("error!\n");exit(1);}lseek(fd,fat1,SEEK_SET);//跳到fat1位置for(i=0;i<100000;i++)//清空分配表write(fd,&ini,1);lseek(fd,fat2,SEEK_SET);//跳到fat2位置for(i=0;i<100000;i++)//清空分配表write(fd,&ini,1);lseek(fd,dir,SEEK_SET);//跳到dir位置for(i=0;i<10000;i++)//清空目录表write(fd,&ini,1);printf("SUCCESS!\n");close(fd);return 0;}五、傻瓜式操作步骤及实验代码分析1,将上面代码存到a.c,b.c,c.c 3个文件中,放到linux同一目录下就好了2,在windows下将实验U盘格式化成fat32文件系统(右击格式化就好了)3,在linux下插入U盘运行a.c程序,输入u盘物理地址(一般是/dev/sdb或者/dev/sdb1不懂的话可以通过fdisk -l指令查看,那个个字母是小写L)会自动生成一个tmp.txt,复制到windows(这个就是标准的fat32文件系统dbr内容,可以通过winhex打开)4,windows打开winhex软件,打开tmp.txt文件后得到上图。

相关主题