《Orange‘s》FAT12文件系统
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文件系统的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- 【java】之算法复杂度o(1), o(n), o(logn), o(nlogn)
在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义: 这是算法的时空复杂度的表示.不仅仅用于表示时间复杂 ...
- MFC 解决中文乱码问题
新的编译工具默认的是unicode编码方式,许多在多字节下面显示中文的方法已经不再适用了按照道理说设置为unicode编码后应该会很好的支持中文, 但是实际情况很悲惨,显示的都是乱码. 看到网上的很多 ...
- linux下怎么清理缓存
free -m 命令可以查看内存使用情况 sysctl 命令可以临时改变某个系统参数 如:sysctl -w net.ipv4.ip_forward=1 是将forware参数临时改为1 当 ser ...
- Java笔记Spring(七)
DispatcherServlet初始化,继续分析日志 主要部分: 23-May-2018 17:47:55.457 INFO [RMI TCP Connection(3)-127.0.0.1] or ...
- int main(int argc,char* argv[]) 的含义和用法
1.基本概念 argc,argv 用命令行编译程序时有用. 主函数main中变量(int argc,char *argv[ ])的含义,有些编译器允许将main()的返回类型声明为void,这已不再是 ...
- DataStrom框架深造
根据前一版DataStrom的使用,继续进行了改造和升级;前一版框架只是对服务按照名称注册和调用固化接口 最近研究后台框架,接触了ZBUS框架,我很喜欢ZBUS的前一版,该作者继续升级,已经在向AMQ ...
- Nginx 负载配置
简版的,详细参数需要自己微调. nginx.conf http{ upstream name { server 127.0.0.1:8777; server 127.0.0.1:8778; serve ...
- windows 服务的安装与卸载之bat脚本命令
在windows 平台下,服务的安装与卸载可通过bat 脚本命令来完成,同时可编辑服务的描述,具体代码如下: 1.服务的安装DynamicPlanService_installer.bat: @ech ...
- python 模拟百度搜索
import urllib.request def Url(url): flag = input("请输入要搜索的关键字:") headers_ = { "User-Ag ...
- 批量查杀该死的VBscript “svchost.exe” 脚本挂马
今天写代码突然发现HTML文件最后多了一段VBscript代码: <SCRIPT Language=VBScript><!-- DropFileName = "svchos ...