FAT12

层次

  • 扇区(Sector):磁盘上的最小数据单元
  • 簇(Cluster):一个或多个扇区
  • 分区(Partition):通常指整个文件系统

引导扇区

引导扇区是整块软盘的第0个扇区,在这个扇区中有一个重要的数据结构叫BPB(BIOS Patameter Block)。格式如下表所示:

其中以BPB_开头的域属于BPB,以BS_开头的不属于BPB,只是引导扇区的一部分。

紧跟着引导扇区的是两个完全相同的FAT表,每个占用9个扇区。第二个FAT表后是根目录区的第一个扇区。根目录区后面是数据区。如下图所示:

根目录区放的是文件条目,每个条目占32字节,格式如下:

根目录区和数据区

这部分来实操一下书中的一个小例子。

首先,使用bximage创建一个虚拟软盘x.img。

接着,在FreeDOS下创建文本文件RIVER.TXT,内容为riverriverriver。

TREE.TXT 内容为treetreetree。再添加一个HOUSE目录,在目录下添加两个文本文件CAT.TXT,DOG.TXT内容同上。 FreeDOS下可使用EDIT来创建文件。 刚开始我使用书中之前虚拟FreeDOS的bochsrc,发现EDIT不存在。和freedos自带的bochsrc比较了下,发现自带的启动的是c.img。另外,比较a.img和c.img,也会发现两者大小相差很大。于是我猜测c.img才是完整的freedos。于是直接在自带的bochsrc上修改,并拷贝了c.img。成功启动后果然可以使用edit了。如果懒得修改可以直接参考:

###############################################################
# Configuration file for Bochs
############################################################### # how much memory the emulated machine will have
megs: 32 # filename of ROM images
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin # what disk images will be used
floppya: 1_44=x.img, status=inserted
ata0-master: type=disk, path=c.img, cylinders=306, heads=4, spt=17
boot: c # where do we send log messages?
# log: bochsout.txt # disable the mouse
mouse: enabled=0 # enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map

启动后,首先格式化x.img。

format A:

格式化后,进入A分区创建上述文件。(注:edit使用Alt键可切换至菜单)

接下来我们计算一下根目录的偏移量。由前面可知,根目录区从第19扇区开始,每个扇区为512字节,别忘记扇区从0开始计数,所以第一个字节位于偏移19×512=0x2600处。接着查看一下x.img偏移0x2600处是什么:

看到了刚刚创建的几个文件和文件夹。以RIVER.TXT为例,它的各项值如下表所示:

分别是:文件名、大小、时间、’日期、文件开始簇号和文件大小。

需要注意的是,数据区的第一个簇的簇号是2,不是0或1。

RIVER.TXT的开始簇号就是2,也就是说此文件的数据开始于数据区第一个簇。

想计算出第一个簇即第一个扇区,必须要知道根目录区所占的扇区数。

在本例中,每扇区字节数为200h,根目录文件数最大值E0h,由上文可知一个文件条目为32字节,所以根目录占用空间大小为32×E0h=1C00h,对应1C00h/200h=Eh=14个扇区。本例刚好整除,否则扇区数还要加1。

所以,数据区开始扇区号=根目录开始扇区号+14=19+14=33。偏移量为33×512=0x4200,接下来看一下内容:

果然就是RIVER.TXT的内容。

FAT表区

FAT表有2个,FAT2可看作是FAT1的备份。先用xxd看下它的结构(FAT1的开始扇区号是1,偏移为512字节=0x200):

其中,每12位称为一个FAT项(即FAT12),代表一个簇。第0个和第1个FAT项始终不使用,从第2个FAT项开始表示数据区的每一个簇。照应了前文所说的数据区第一个簇的簇号是2。

通常,FAT项的值代表的是文件的下一个簇号,但如果值大于或等于0xFF8,则表示当前簇已经是本文件的最后一个簇。如果值为0xFF7,表示它是一个坏簇。

以文件RIVER.TXT为例,开始簇号为2,对应FAT表中的值为0xFFF,表示这个簇已经是最后一个。

要注意的是,一个FAT项可能会跨越两个扇区,这种情况在编码实现的过程中要考虑在内。

《Orange‘s》FAT12文件系统的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 【Eclipse】_Eclipse自动补全增强方法 & 常用快捷键

    一,Eclipse自动补全增强方法 在Eclipse中,从Window -> preferences -> Java -> Editor -> Content assist - ...

  2. kong插件应用

    插件概述 插件之于kong,就像Spring中的aop功能.在请求到达kong之后,转发给后端应用之前,你可以应用kong自带的插件对请求进行处理,合法认证,限流控制,黑白名单校验,日志采集等等.同时 ...

  3. Java核心-多线程-并发控制器-Semaphore信号量

    Semaphore是非常有用的一个多线程并发控制组件(Java还有CountDownLatch.CyclicBarrier.Exchanger多线程组件),它相当于是一个并发控制器,是用于管理信号量的 ...

  4. [UE4]镜像

    一.这是一个右手模型,通过镜像可以得到一个左右模型. 二.通过上图分析,镜面是X轴和Z轴形成的一个面,Y轴与XZ面垂直,因此就是镜像Y轴,将模型的Transform.Scale.Y设置为-1,即可得到 ...

  5. phpstorm 如何设置识别vue文件

    非常简单,步骤如下: 第一步: 设置->plugins->browser repositories 搜索vue.js,然后安装一下vue.js插件,重启ide. 第二步: Editor - ...

  6. 2、Redis 底层原理:Cluster 集群部署与详解

    Redis 简介 Redis 提供数据缓存服务,内部数据都存在内存中,所以访问速度非常快. 早期,Redis 单应用服务亦能满足企业的需求.之后,业务量的上升,单机的读写能力满足不了业务的需求,技术上 ...

  7. Linux7.2 UDEV

    1. 生成规则文件 touch /etc/udev/rules.d/99-oracle-asmdevices.rules 或者 touch /usr/lib/udev/rules.d/99-oracl ...

  8. php的运行模式

    1.php最常见的五种运行模式. CGI 通用网关接口 FastCGI 常驻内存的CGI CLI 命令行 Web模块  Apache等Web服务器 模块的形式加载php进程 ISAPI 已经不用了

  9. 封装poi导入篇

    前言 有封装的想法好久了,项目中有不少地方需要使用导入功能,导入虽说不能,但是每次都要为了特定类写一个特定方法,很麻烦,我很讨厌一直写这种东西了,正好趁着这次机会就写一个可以解决这种问题的小项目. m ...

  10. maven 版本发布添加上时间戳

    使用插件添加时间戳 我使用的是spring boot - 2.0.3.RELEASE版本 pom中加入 <!-- 加入这个 就可以直接在配置文件中取到时间戳了,注意: 由于${}方式会被mave ...