为您推荐:
精华内容
最热下载
问答
  • 5星
    25.85MB qq_19388797 2021-09-09 16:13:52
  • 5星
    469KB weixin_46414659 2021-04-02 17:24:37
  • 5星
    163KB qq_41934573 2021-05-04 14:18:22
  • 5星
    122B m0_60347252 2021-08-21 11:22:14
  • 5星
    40KB weixin_51194902 2021-01-08 12:19:19
  • 5星
    181.43MB qq_19388797 2021-09-09 16:13:06
  • 5星
    1.51MB weixin_41356941 2021-03-09 10:55:33
  • 5星
    387KB weixin_44510615 2021-06-23 18:04:15
  • 5星
    367.04MB l346008087 2020-12-28 13:27:25
  • 5星
    1KB qq_43045275 2021-05-20 17:09:55
  • 76KB weixin_38669628 2019-08-03 01:19:07
  • 所以这时候我们直接改动文件头进行online: [oracle@ogg1 lib]$ bbed parfile=par.txt Password: BBED: Release 2.0.0.0.0 - Limited Production on Tue Oct 28 05:20:19 2014 Copyright (c) 1982, 2009, Oracle...
    SYS@orcl11g>alter database datafile 6 online;
    alter database datafile 6 online
    *
    ERROR at line 1:
    ORA-01113: file 6 needs media recovery
    ORA-01110: data file 6: '/opt/oracle/oradata/orcl11g/zbdba01.dbf'
    有时候我们数据文件offline之后。再online须要介质恢复    
    SYS@orcl11g>select file#,name,status from v$datafile;
         FILE# NAME                                                         STATUS
    ---------- ------------------------------------------------------------ ------------------------------------------------------------
             1 /opt/oracle/oradata/orcl11g/system01.dbf                     SYSTEM
             2 /opt/oracle/oradata/orcl11g/sysaux01.dbf                     ONLINE
             3 /opt/oracle/oradata/orcl11g/undotbs01.dbf                    ONLINE
             4 /opt/oracle/oradata/orcl11g/users01.dbf                      ONLINE
             5 /opt/oracle/oradata/orcl11g/zbdba.dbf                        ONLINE
             6 /opt/oracle/oradata/orcl11g/zbdba01.dbf                      RECOVER
             7 /opt/oracle/oradata/orcl11g/test.dbf                         ONLINE
    
    
    
    可是我们归档已经丢失,无法完毕介质恢复:
    SYS@orcl11g>recover datafile 6;
    ORA-00279: change 1986632 generated at 10/28/2014 05:16:11 needed for thread 1
    ORA-00289: suggestion : /opt/oracle/flash_recovery_area/ORCL11G/archivelog/2014_10_28/o1_mf_1_74_b4yqrglr_.arc
    ORA-00280: change 1986632 for thread 1 is in sequence #74
    
    
    Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
    
    ORA-00308: cannot open archived log '/opt/oracle/flash_recovery_area/ORCL11G/archivelog/2014_10_28/o1_mf_1_74_b4yqrglr_.arc'
    ORA-27037: unable to obtain file status
    Linux-x86_64 Error: 2: No such file or directory
    Additional information: 3
    
    所以这时候我们直接改动文件头进行online:
    [oracle@ogg1 lib]$ bbed parfile=par.txt
    Password:
    
    BBED: Release 2.0.0.0.0 - Limited Production on Tue Oct 28 05:20:19 2014
    
    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
    
    ************* !!! For Oracle Internal Use only !!! ***************
    
    BBED>
    BBED>
    BBED> info all
    File#  Name                                                        Size(blks)
    -----  ----                                                        ----------
         1  /opt/oracle/oradata/orcl11g/system01.dbf                             0
         2  /opt/oracle/oradata/orcl11g/sysaux01.dbf                             0
         3  /opt/oracle/oradata/orcl11g/undotbs01.dbf                            0
         4  /opt/oracle/oradata/orcl11g/users01.dbf                              0
         5  /opt/oracle/oradata/orcl11g/zbdba.dbf                                0
         6  /opt/oracle/oradata/orcl11g/zbdba01.dbf                              0
         7  /opt/oracle/oradata/orcl11g/test.dbf                                 0
    
    BBED> set file 1 block 1
            FILE#           1
            BLOCK#          1
    
    BBED> p kcvfhckp
    struct kcvfhckp, 36 bytes                   @484    
       struct kcvcpscn, 8 bytes                 @484    
          ub4 kscnbas                           @484      0x001e526c
          ub2 kscnwrp                           @488      0x0000
       ub4 kcvcptim                             @492      0x3362e202
       ub2 kcvcpthr                             @496      0x0001
       union u, 12 bytes                        @500    
          struct kcvcprba, 12 bytes             @500    
             ub4 kcrbaseq                       @500      0x0000004d
             ub4 kcrbabno                       @504      0x000001a6
             ub2 kcrbabof                       @508      0x0010
       ub1 kcvcpetb[0]                          @512      0x02
       ub1 kcvcpetb[1]                          @513      0x00
       ub1 kcvcpetb[2]                          @514      0x00
       ub1 kcvcpetb[3]                          @515      0x00
       ub1 kcvcpetb[4]                          @516      0x00
       ub1 kcvcpetb[5]                          @517      0x00
       ub1 kcvcpetb[6]                          @518      0x00
       ub1 kcvcpetb[7]                          @519      0x00
    
    BBED> p kcvfhcpc
    ub4 kcvfhcpc                                @140      0x000000f9
    
    BBED> p kcvfhccc
    ub4 kcvfhccc                                @148      0x000000f8
    
    BBED> set file 6 block 1
            FILE#           6
            BLOCK#          1
    
    BBED> p kcvfhckp
    struct kcvfhckp, 36 bytes                   @484    
       struct kcvcpscn, 8 bytes                 @484    
          ub4 kscnbas                           @484      0x001e5048
          ub2 kscnwrp                           @488      0x0000
       ub4 kcvcptim                             @492      0x3362e11b
       ub2 kcvcpthr                             @496      0x0001
       union u, 12 bytes                        @500    
          struct kcvcprba, 12 bytes             @500    
             ub4 kcrbaseq                       @500      0x0000004a
             ub4 kcrbabno                       @504      0x00005801
             ub2 kcrbabof                       @508      0x0010
       ub1 kcvcpetb[0]                          @512      0x02
       ub1 kcvcpetb[1]                          @513      0x00
       ub1 kcvcpetb[2]                          @514      0x00
       ub1 kcvcpetb[3]                          @515      0x00
       ub1 kcvcpetb[4]                          @516      0x00
       ub1 kcvcpetb[5]                          @517      0x00
       ub1 kcvcpetb[6]                          @518      0x00
       ub1 kcvcpetb[7]                          @519      0x00
    
    BBED> p kcvfhcpc
    ub4 kcvfhcpc                                @140      0x0000043c
    
    BBED> p kcvfhccc
    ub4 kcvfhccc                                @148      0x0000043b
    
    BBED> modify /x 6c52 offset 484
    Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
    File: /opt/oracle/oradata/orcl11g/zbdba01.dbf (6)
    Block: 1                Offsets:  484 to  995           Dba:0x01800001
    ------------------------------------------------------------------------
    6c521e00 00000000 1be16233 01000000 4a000000 01580000 10000000 02000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    0d000d00 0d000100 00000000 00000000 00000000 02008001 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    
    <32 bytes per line>
    
    BBED> modify /x 02e2 offset 492
    File: /opt/oracle/oradata/orcl11g/zbdba01.dbf (6)
    Block: 1                Offsets:  492 to 1003           Dba:0x01800001
    ------------------------------------------------------------------------
    02e26233 01000000 4a000000 01580000 10000000 02000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 0d000d00 0d000100
    00000000 00000000 00000000 02008001 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    
    <32 bytes per line>
    
    BBED> modify /x f900 offset 140
    File: /opt/oracle/oradata/orcl11g/zbdba01.dbf (6)
    Block: 1                Offsets:  140 to  651           Dba:0x01800001
    ------------------------------------------------------------------------
    f9000000 7fe16233 3b040000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    06000000 05005a42 44424100 00000000 00000000 00000000 00000000 00000000
    00000000 06000000 00000000 00000000 a3d96233 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 6b946b29 01000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 6c521e00 00000000
    02e26233 01000000 4a000000 01580000 10000000 02000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 0d000d00 0d000100
    
    <32 bytes per line>
    
    BBED> modify /x f800 offset 148
    File: /opt/oracle/oradata/orcl11g/zbdba01.dbf (6)
    Block: 1                Offsets:  148 to  659           Dba:0x01800001
    ------------------------------------------------------------------------
    f8000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 06000000 05005a42
    44424100 00000000 00000000 00000000 00000000 00000000 00000000 06000000
    00000000 00000000 a3d96233 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 6b946b29 01000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 6c521e00 00000000 02e26233 01000000
    4a000000 01580000 10000000 02000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 0d000d00 0d000100 00000000 00000000
    
    <32 bytes per line>
    
    BBED> sum apply
    Check value for File 6, Block 1:
    current = 0x1924, required = 0x1924
    
    BBED> verify
    DBVERIFY - Verification starting
    FILE = /opt/oracle/oradata/orcl11g/zbdba01.dbf
    BLOCK = 1
    
    
    DBVERIFY - Verification complete
    
    Total Blocks Examined         : 1
    Total Blocks Processed (Data) : 0
    Total Blocks Failing   (Data) : 0
    Total Blocks Processed (Index): 0
    Total Blocks Failing   (Index): 0
    Total Blocks Empty            : 0
    Total Blocks Marked Corrupt   : 0
    Total Blocks Influx           : 0
    Message 531 not found;  product=RDBMS; facility=BBED
    
    
    BBED> show all
            FILE#           6
            BLOCK#          1
            OFFSET          148
            DBA             0x01800001 (25165825 6,1)
            FILENAME        /opt/oracle/oradata/orcl11g/zbdba01.dbf
            BIFILE          bifile.bbd
            LISTFILE        filelist.txt
            BLOCKSIZE       8192
            MODE            Edit
            EDIT            Unrecoverable
            IBASE           Dec
            OBASE           Dec
            WIDTH           80
            COUNT           512
            LOGFILE         log.bbd
            SPOOL           No
    
    BBED> p kcvfhckp
    struct kcvfhckp, 36 bytes                   @484    
       struct kcvcpscn, 8 bytes                 @484    
          ub4 kscnbas                           @484      0x001e526c
          ub2 kscnwrp                           @488      0x0000
       ub4 kcvcptim                             @492      0x3362e202
       ub2 kcvcpthr                             @496      0x0001
       union u, 12 bytes                        @500    
          struct kcvcprba, 12 bytes             @500    
             ub4 kcrbaseq                       @500      0x0000004a
             ub4 kcrbabno                       @504      0x00005801
             ub2 kcrbabof                       @508      0x0010
       ub1 kcvcpetb[0]                          @512      0x02
       ub1 kcvcpetb[1]                          @513      0x00
       ub1 kcvcpetb[2]                          @514      0x00
       ub1 kcvcpetb[3]                          @515      0x00
       ub1 kcvcpetb[4]                          @516      0x00
       ub1 kcvcpetb[5]                          @517      0x00
       ub1 kcvcpetb[6]                          @518      0x00
       ub1 kcvcpetb[7]                          @519      0x00
    
    BBED> p kcvfhcpc
    ub4 kcvfhcpc                                @140      0x000000f9
    
    BBED> p kcvfhccc
    ub4 kcvfhccc                                @148      0x000000f8
    
    BBED> 
    
    改动完毕后我们再次恢复该数据文件:
    SYS@orcl11g>startup
    ORACLE instance started.
    Total System Global Area  417546240 bytes
    Fixed Size                  2213936 bytes
    Variable Size             318769104 bytes
    Database Buffers           92274688 bytes
    Redo Buffers                4288512 bytes
    Database mounted.
    Database opened.
    SYS@orcl11g>recover datafile 6;
    Media recovery complete.
    SYS@orcl11g>alter database datafile 6 online;
    
    Database altered.





    转载于:https://www.cnblogs.com/yxysuanfa/p/6889332.html

    展开全文
    diandingyin9417 2019-10-06 06:10:54
  • 文件头是位于文件开头的一段承担一定任务的数据 以下是常见的文件头: 相应的还有文件结尾 zip文件的结尾以一串504B0506开始 rar文件以C43D7B00400700结尾 JPG文件结尾为FFD9 PNG文件 结尾为000049454E44AE426082 ...

    常见的文件头识别和修复

    文件头是位于文件开头的一段承担一定任务的数据

    以下是常见的文件头:
    在这里插入图片描述
    相应的还有文件结尾
    zip文件的结尾以一串504B0506开始
    rar文件以C43D7B00400700结尾
    JPG文件结尾为FFD9
    PNG文件 结尾为000049454E44AE426082
    Gif文件结尾为3B

    其中PNG文件头还包含IHDR信息
    在这里插入图片描述
    其中最常见的就是修改高度

    在这里插入图片描述
    在这里插入图片描述
    将00FF改为01FF
    在这里插入图片描述
    在这里插入图片描述

    一个zip文件头中的一些信息

    在这里插入图片描述50 4B 03 04:这是头文件标记
    0A 00:解压文件所需 pkware 版本
    00 00:全局方式位标记(有无加密)
    00 00:压缩方式
    6D A9:最后修改文件时间
    FA 50:最后修改文件日期
    9A EB F4 D1:CRC-32校验
    04 00 00 00:压缩后尺寸
    04 00 00 00:未压缩尺寸
    08 00:文件名长度
    00 00:扩展记录长度
    66 6C 61 67 2E 74 78 74 66 6C 61 67 压缩源文件目录区
    50 4B 01 02:目录中文件文件头标记
    3F 00:压缩使用的 pkware 版本
    0A 00:解压文件所需 pkware 版本
    00 00:全局方式位标记(有无加密,这个更改这里进行伪加密,改为09 00打开就会提示有密码了)
    00 00:压缩方式


    rar文件格式


    [2018年 网鼎杯CTF 第1场]clip

    解压后用winhex或HxD打开,发现有两个png文件
    在这里插入图片描述
    在这里插入图片描述
    但都没有文件尾,第二个的png文件头也不完整,所以提取出来后手动修复
    在这里插入图片描述
    在这里插入图片描述
    将这两张图片放ps里拼一下就能得到flag
    (ps:因为png的文件头和文件尾不完整,所以binwalk里分析不出来,foremost也无法分离)


    bugku:一个普通的压缩包

    解压flag.rar会提示secret.png文件头损坏
    在这里插入图片描述
    用winhex或者HxD查看
    在这里插入图片描述
    将7A改为74,就能正常解压出png文件(在rar中,74表示后面是个文件
    在这里插入图片描述
    同样用winhex或者HxD查看png发现是GIF文件
    在这里插入图片描述
    后缀改为gif,接下来就是放stegsolve以及ps分离一下
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    ps拼一下,扫就有flag
    在这里插入图片描述

    by xiaolong


    参考
    zip文件头
    一个普通的压缩包wp


    展开全文
    xiaolong22333 2020-08-09 14:25:39
  • 于是打开16进制编辑器,搜索找到了wav文件头,把文件头前的都删除,修复后果然能播放成功。其它某些格式或许也可以参考。好在,大部分文件的文件头位移的不大,大都在了靠前的位置,而在文件末尾,所以损失不大。 ...

    几年前用某软件无损调整机械硬盘4k对齐时,手贱用别的软件改了盘符(因为4k对齐等待的时间太久,觉得无聊,加上以为那磁盘被占用了,反正改不动的,就改着玩),导致进程异常中断了。磁盘里大量文件损坏。猜测是文件发生了偏位。我比较在意里面的wav录音文件,也是大量损坏,个别能播放。

    以前研究了没有很好的结果,只修复了一些mp3格式,最近想再研究一下那堆wav。起初我依照网上的一些经验,打开winhex 16进制编辑器,给坏文件添加或替换上了好的文件里的文件头,结果大概率带来噪音。通过随意删减,有极其小概率误打误撞能修的能听。但碰运气得来的不能用来举一反三。

    继续到网上查阅wav格式的原理资料,大部分讲的是文件头的知识,没有细说播放器怎么读取的,解释不了为什么一个正常的wav文件随意删除几个字节就会变的全是噪音(做实验得知的,当时觉得这个是关键所在,解答了这个问题我才能修复)。我看的似懂非懂,很难学以致用来修复我文件。只能放弃这条“正面把原理研究透”的路。

    结合之前数据位移的想法,用批量验证,得以挑出来一个特定长度的文件头,用copy /b把它和损坏文件拼接后,有大概率可以修复文件。但也有的不能成功。

    (这里插入一段,两周后当我已经把所有文件已经修复的差不多了,进一步实验验证、再回头看资料才得知,存在一个读取周期,比如1024字节(对应我的那些单声道文件),或2048字节(对应双声道),只要把残缺的内容给刚好补足为周期长度的整数倍,就能修复地声音正常。这就是我当时碰撞成功的原理。另外文件头一定要和内容匹配才行,比如双声道和单声道,它们的文件头是有差异的。请看下图。)

    在这里插入图片描述

    至少证明了偏位理论可行,而且一堆文件还偏的比较有规律。突然想到或许没必要加文件头,说不定还在里面。于是搜索16进制,真找到了wav文件头,把文件头前的东西都删除,修复后果然能播放成功。其它某些格式的损坏文件或许也可以参考。好在,大部分文件的文件头位移的不算多,大都时后移了一些但仍然在本文件靠前的位置,而没有到别的文件里的末尾去,所以损失不大。但是一个一个手修有点麻烦。

    但有了方法就好办了,找朋友做了个软件,把我那些文件批量处理,搜索到文件头就切成一个文件,于是有头的都变得能听了。这样就剩下了一批无头的,大部分是3M左右大小的,1到2分钟左右时长的文件,也不想直接丢弃了。于是我用之前挑出的那个特定长度的文件头来拼接。这时遇到了一个麻烦,我的那些文件碎片(来自别的文件的末尾,有的甚至原本都不是音频文件),由于不只是一个录音笔录的,而且损坏后变的比较乱了,导致一个文件夹下,有的需要双声道的头,有的需要单声道的头,还不一定哪个数量多。当头拼错了,声音会很古怪(像电影中外星人大魔头的浑浊声音)。于是我找到了双声道的规律,做了一单一双共两个文件头,找朋友做了个软件,批量智能的判别无头片段是单是双、再和对应的文件头合并。

    至此,除了极少数我估计实质并不是音频内容的片段(修了也全是噪音、听起来和自然界的声音完全不相似的噪音)没办法弄,也就是说丢失了那些文件大小的wav内容,算是比较圆满的解决了大量wav录音文件损坏问题,弥补了当年的过错。

    在此警示,重要文件狡兔三窟,做事情时要稳、不要贱,也不要偷懒用那些号称能无损做很多操作的磁盘管理软件。

    本来可以在硬盘刚发生问题后,用winhex搜索整个分区,按文件类型恢复数据,它会自动帮你找到文件头并切割好。因为如果单纯的用软件恢复分区文件,而不按类型恢复,很可能是文件错位了不能用的。但是我当时没有这么做,只用了超级硬盘数据恢复软件,做了普通的恢复,后来还把文件搬走了,原硬盘也做了格式化、放了新文件。

    展开全文
    weixin_45490942 2020-05-25 10:39:02
  •   注意:本文章主要是翻译自 FatFs...因此,以下翻译原文有些差别。具体表现为下文中的英文部分全部是原文,没有任何更改;中文部分添加了一些额外内容! FAT Filesystem FAT文件系统   This is a documentati...

      注意:本文章最初是翻译自 FatFs 官网的 The basics of FAT filesystem。但是,原文大多都是文字说明,因此在翻译时,添加了大量的图片示例以及一些额外的章节。
      因此,以下翻译与原文有很多差别。具体表现为下文中的英文部分全部是原文,没有任何更改;中文部分添加了一些额外内容!

    FAT Filesystem FAT文件系统

      This is a documentation about FAT filesystem written based on the FAT32 Filesystem Specification (FAT specs below) to know how FAT filesystem works and how to manage it. It is written according to the contents of the FAT specs and the behavior of the standard system (real DOS and Windows), however, there are many improvements and ommissions from the FAT specs. If the behavior of standard system is differ from the FAT specs, it is written in accordance with the real systems rather than FAT specs. And there is a possibility that there is any unintended or intended error in this documentation, so that you need to refer the primary sources of FAT filesystem and make sure behavior of the real systems when write FAT driver or utility. For exFAT filesystem, please refer here in addition to this documentation.
      这是一个关于 FAT 文件系统的文档,该文件基于 FAT32 文件系统规范(以下称为 FAT 规范(FAT specs))编写,以了解 FAT 文件系统的工作原理以及如何管理它。 它是根据 FAT 规范的内容和标准系统(实际的 DOS 和 Windows)的行为编写的,因而,相比 FAT 规范有许多改进和省略。 如果标准系统的行为与 FAT 规范不同,则它是根据实际系统而不是 FAT 规范编写的。并且本文档中可能存在任何意外或预期的错误,因此您需要参考 FAT 文件系统的源文件,并在编写 FAT 驱动程序或实用程序时确保实际系统的行为。对于 exFAT 文件系统,除了本文档之外,请参阅此处

    Introduction 简介

      The filesystem generally denotes the entire system to manage data on the storage, however, this document describes the data format of FAT filesystem on the storage device.
      文件系统通常表示管理存储器上的数据的整个系统,不过,该文档描述了存储设备上的 FAT 文件系统的数据格式。
      The FAT file system originated around 1980 and is the filesystem that was first supported by MS-DOS. It was originally developped a simple filesystem suitable for floppy disk less than 500k bytes in size. Over the time, its specs has been expanded to support larger media as increasing its capacity. FAT is the abbreviation of File Allocation Table, which is the array to manage allocation of data area and the name of the file system itself. Currently there are three FAT sub-types, FAT12, FAT16 and FAT32. These are developped in order of the number and completely backward compatible with older one. (FAT16 always include FAT12, FAT32 includes all FAT types)
      FAT 文件系统起源于 1980 年左右,是 MS-DOS 首先支持的文件系统。 它最初是为了适用于大小小于 500k 字节的软盘而开发了一个简单的文件系统。 随着时间的推移,其规范已经扩大到支持更大容量的媒介的能力。FAT 是文件分配表(File Allocation Table)的缩写,它是管理数据区域分配和文件系统本身名称的合称。 目前有三种 FAT 子类型,FAT12,FAT16 和 FAT32。它们按数字大小顺序开发,完全向后兼容旧版本。 (FAT16 始终包含 FAT12,FAT32 包括所有 FAT 类型)

    About Notations in this Document 关于本文档中的符号

      Numbers starting with “0x” are assumed to be hexadecimal numbers, and others are decimal numbers.
      以 “0x” 开头的数字假定为十六进制数字,其他数字为十进制数字。
      The prefix K, M, G and T of each unit is assumed to be 210, 220, 230 and 240 respectively.
      假定每个单位的前缀 K,M,G 和 T 分别为 210, 220, 230 和 240。
      The fragment of program codes contained in this document is written assuming C language, but it is not strict to the syntax.
      本文档中包含的程序代码片段是假定使用 C 语言编写的,但并不严格符合语法。
      32-bit value and 16-bit value are arbitrary mixed in the fragment of the program code. The programmer needs be aware of the data loss due to the type conversion and how to avoid it. Also, every data type is assumed to be unsigned. Do not calculate in signed because it may result in unintended results.
      32 位值和 16 位值在程序代码段中任意混合。程序员需要知道由于类型转换而造成的数据丢失以及如何避免它。此外,假定每种数据类型都是无符号的。不要在带符号的情况下计算,因为这可能会导致意想不到的结果

    Basics of FAT File System FAT文件系统基础

    FAT Volume FAT 卷

      A FAT file system completes itself is called logical volume (or logical drive). The FAT logical volume consists of three or four areas, each of them consists of one or more sectors and located on the volume in order of as follows. (FAT volume map)
      FAT 文件系统将自身称为逻辑卷(或逻辑驱动器)。 FAT 逻辑卷由三个或四个区域组成,每个区域由一个或多个扇区组成,并按以下顺序位于卷上。 (FAT volume map 即下图。后文的介绍都是基于该图示来说明的)
    在这里插入图片描述

    1. Reserved area (volume configuration data) 保留区域(卷配置数据)
    2. FAT area (allocation table for data area) FAT区域(数据区域的分配表)
    3. Root directory area (not present on FAT32 volume) 根目录区域(FAT32 卷上不存在)
    4. Data area (contents of file and directory) 数据区(文件和目录的内容)

    Sector 扇区

      Sector is the smallest unit of data block on the storage to read and write the storage device. The common sector size is 512 bytes and a larger sector size is sometimes used for some type of storage media. Each sector on the storage device is addressed by a sector number assgined in order from top of the storage device. Since volumes are not that always placed at top of the storage, in this document, “sector number” denotes the relative location origin from top of the volume and “physical sector number” denotes the absolute location origin from top of the storage device.
      扇区是存储器上读写存储设备的最小数据块单元。 一般的扇区大小为 512 字节,有时某些类型的存储介质会使用更大的扇区。 存储设备上的每个扇区由从存储设备顶部按顺序分配的扇区号寻址。 由于卷不总是位于存储器的顶部,因此在本文档中,“扇区号” 表示从卷顶部开始的相对位置,“物理扇区号” 表示从存储设备顶部开始的绝对位置。

    Data Forms on the Storage 存储器上的数据形式

      The FAT file system was initially developed for IBM PC with x86 processors. The most important thing is that data structures in the FAT filesystem on the storage is stored in little endian. If the architecture of the platform to access the FAT filesystem is big endian, an endian conversion is required when accessing the structures of the FAT filesystem. Also, word data in multiple bytes are not that always aligned to the word boundaries. If the processor cannot access the unaligned word data, it will need to access the data in byte-by-byte. For this reason, accessing the FAT volume as C structure member discards the code portability. Accessing the FAT volume in byte-by-byte as simple byte array instead of C structure gives the best code portability.
      FAT 文件系统最初是为使用 x86 处理器的 IBM PC 开发的。 最重要的是存储器上的 FAT 文件系统中的数据结构以小端模式存储的。 如果访问 FAT 文件系统的平台的体系结构是大端模式,那么在访问 FAT 文件系统的结构时需要进行字节序转换。 此外,含多个字节的字数据并不总是与字边界对齐的。 如果处理器无法访问未对齐的字数据,则需要逐字节访问数据。 因此,以 C 结构成员的方式访问 FAT 卷会丢弃代码可移植性。 以以字节为单位的简单字节数组而不是 C 结构成员的方式访问 FAT 卷,可提供最佳的代码可移植性。

    Boot Sector and BPB 引导扇区和BPB

      The most important data structure in the FAT volume is BPB (BIOS Parameter Block), where the configuration parameters of the FAT volume are stored. The BPB is placed in the boot sector. The boot sector is often referred to as VBR (Volume Boot Record) or PBR (Private Boot Record), but it is simply the first sector of the reserved area, the first sector of the volume.
      FAT 卷中最重要的数据结构是 BPB(BIOS Parameter Block,BIOS 参数块),其中存储 FAT 卷的配置参数。 BPB 位于引导扇区中。 引导扇区通常称为 VBR(Volume Boot Record,卷引导记录)或 PBR(Private Boot Record,专用引导记录),但它只是保留区域的第一个扇区,即卷的第一个扇区。
      BPB has often been changed as the function of the FAT file system is enhanced. The first confusion that occurred was due to the newly-establishment of BPB. In the MS-DOS Ver.1, there was no BPB in the boot sector. In the first version of the FAT file system, there is only a few disk format (single-sided and double-sided 5.25 inch floppy disk), and the disk format is determined by referring to the first byte (lower 8 bits of the first FAT item) of FAT starting at the next sector of the boot sector.
      随着 FAT 文件系统功能的增强,BPB 经常被更改。 发生的第一次混乱是由于 BPB 的第一次出现。 在 MS-DOS Ver.1 中,引导扇区中没有 BPB。 在 FAT 文件系统的第一个版本中只有少数磁盘格式(单面和双面 5.25 英寸软盘),并且磁盘格式是通过参考引导扇区的后一个扇区的开始的第一个字节(第一个字节的低 8 位)来确定。
      At the MS-DOS Ver.2, this method of determination of disk format is superseded by referring the BPB in the boot sector and the determination by referring the first byte of FAT has not been supported any longer. Now all FAT volumes must have a BPB in the boot sector. BPB was sometimes changed and it brought confusions about determination of disk format. (e.g. Which is the correct parameter? What means this parameter? How should I use this parameter?) The authorized volume recognization method is described in FAT specs a time later.
      在 MS-DOS Ver.2 中,确定磁盘格式的方法被通过参考引导扇区中的 BPB 取代,并且不再支持通过参考 FAT 的第一个字节来确定的这种方法。 现在所有 FAT 卷必须在引导扇区中具有 BPB。 BPB 有时会发生变化,并且会对确定磁盘格式的界定产生混淆。 (例如,哪个是正确的参数?这个参数是什么意思?应该如何使用这个参数?)一段时间后,FAT 规范中描述了授权的卷识别方法。
      At the first time, problems about deterioration of disk usage efficiency and limitation of the number of files on a volume appered due to the disk size got lager by widespread use of hard disks and FAT16 has newly supported at MS-DOS Ver.3. However, a new problem occurred immediately after this change. Since the size of field to indicating the size of the volume was 16 bits, the supported volume size is less than 65536 sectors (32 MB at 512 bytes/sector). For this reason, a 32-bit field has been added to at MS-DOS Ver.3.31 and it can support 128 MB for FAT12 and 2 GB for FAT16 (at 32 KB/cluster).
      随着硬盘的广泛使用,磁盘容量越来越大,第一次出现了磁盘使用效率恶化和卷上文件数量限制的问题。在 MS-DOS Ver.3 中新引入了对 FAT16 的支持。 但是,此更改后立即出现了一个新的问题。 由于指示卷大小的字段大小为 16 位,因此支持的卷大小小于 65536 个扇区(512 字节/扇区为 32 MB)。 因此,在 MS-DOS Ver.3.31 中添加了一个 32 位字段,它可以支持 FAT12 的 128 MB 和 FAT16 的 2 GB( 32 KB/cluster)。
      The last change of BPB was at Windows 95 OSR2 where the FAT32 appeared. At that time, number of files and maximum capacity of the FAT16 volume had reached at some applications. The FAT32 as final version of FAT filesystem removed the limitations of FAT16 and spports upto 2 TB of volume size (at 512 bytes/sector). However Microsoft recommends any filesystem other than FAT, such as NTFS for fixed disk and exFAT for removable disk, for the volumes larger than 32 GB.
      BPB 的最后一次更改是在 Windows 95 OSR2 上出现了 FAT32 时。 那时,某些应用程序已达到 FAT16 卷的文件数和最大容量。 作为 FAT 文件系统的最终版本的 FAT32 取消了 FAT16 的限制并且支持高达 2TB 的卷大小(512字节/扇区)。 但是,对于大于 32 GB 的卷,Microsoft 建议使用 FAT 以外的其他任何文件系统,例如固定磁盘的 NTFS 和可移动磁盘的 exFAT。
      The following table shows the data fields of the boot sector. Any field named with heading BPB_ are part of the BPB. Any field named with heading BS_ is not a part of BPB but it only a part of the boot sector.
      下表显示了引导扇区的数据字段。 任何以 BPB_ 开头的字段都是 BPB 内容的一部分。 任何以 BS_ 开头的字段都不是 BPB 的一部分,但它只是引导扇区的一部分。
      The fields in the first 36 bytes are common field for all FAT types and the fields from byte offset 36 depends on whether the FAT type is FAT32 or FAT12/FAT16. The method of determining FAT type is described at next section.
      前 36 个字节中的字段是所有 FAT 类型的公共字段,36 字节偏移后的字段取决于 FAT 类型是 FAT32 还是 FAT12/FAT16。 确定 FAT 类型的方法在下一节中描述。
    FAT12/16/32 common field (offset from 0 to 35)

    Field name 字段名Offset 偏移Size 大小Description 描述
    BS_JmpBoot03Jump instruction to the bootstrap code (x86 instruction) used by OS boot sequence. There are two type of formats for this field and the former format is prefered.
    操作系统引导序列使用的跳转到引导代码(x86指令)的指令。 该字段有如下的两种格式,优先选择前一种格式。
    0xEB, 0x??, 0x90 (Short jump + NOP)
    0xE9, 0x??, 0x?? (Near jump)
    ?? is the arbitrary value depends on where to jump is. In case of any format out of these formats, the volume will not be recognized by Windows.
    ?? 表示任意值,取决于跳转的位置。 如果是以上两种格式之外的任何格式,Windows 都将无法识别该卷。
    BS_OEMName38“MSWIN 4.1” is recommended but also “MSDOS 5.0” is often used. There are many misconceptions about this field. This is only a name. Microsoft’s OS does not pay any attention to this field, but some FAT drivers do some reference. This string is recommended because it is considered to minimize compatibility problems. You can set something else, but some FAT drivers may not recognize that volume. This field usually indicates name of the system created the volume.
    该字段建议使用值 “MSWIN 4.1”,但也经常使用 “MSDOS 5.0”。 关于这个区域存在许多误解。 这只是一个名字。 微软的操作系统并不关心这个区域,但是一些 FAT 驱动程序会作为一些参考。 建议使用推荐的字符串,因为它被视为最小化兼容性问题。 您可以设置成其他值,但某些 FAT 驱动程序可能无法识别该卷。 此字段通常表示创建该卷的系统的名称。
    BPB_BytsPerSec112Sector size in unit of byte. Valid values for this field are 512, 1024, 2048 or 4096. Microsoft’s OS properly supports these sector sizes, but many FAT drivers assume the sector size is 512 and do not check this field. For this reason, 512 should be used for maximum compatibility. However, you should not misunderstand that it is only related to compatibility. This value must be the same as the sector size of the storage contains the FAT volume.
    扇区大小,以字节为单位。 此字段的有效值为 512, 1024, 2048 或 4096。Microsoft 的操作系统正确支持这些扇区大小,但许多 FAT 驱动程序假定扇区大小为 512 并且不检查此字段。 因此,应使用 512 以实现最大兼容性。 但是,您不应该误解它只与兼容性有关。 此值必须与包含 FAT 卷的存储的扇区大小相同。
    BPB_SecPerClus131Number of sectors per allocation unit. In the FAT file system, the allocation unit is called Cluster. This is a block of one or more consecutive sectors and the data area is managed in this unit. The number of sectors per cluster must be a power of 2. Therefore, valid values are 1, 2, 4,… and 128. However, any value whose cluster size (BPB_BytsPerSec * BPB_SecPerClus) exceeds 32 KB should not be used. Recent systems, such as Windows, supprts cluster size larger than 32 KB, such as 64 KB, 128 KB, and 256 KB, but such volumes will not be recognized correctly by MS-DOS or old disk utilities.
    每个分配单元的扇区数。 在 FAT 文件系统中,分配单元称为簇(Cluster)。 这是一个由一个或多个连续扇区的组成的块,并且数据区域在该单元中进行管理。 每个簇的扇区数必须是 2 的幂。因此,幂有效值为 1,2,4,…和 128。但是,不应使用其簇大小(BPB_BytsPerSec * BPB_SecPerClus)超过 32 KB 的任何值。 较新的系统(如Windows)支持大小超过 32 KB 的簇大小,例如 64 KB,128 KB 和 256 KB,但 MS-DOS 或旧磁盘实用程序无法正确识别此类卷。
    BPB_RsvdSecCnt142Number of sectors in reserved area. This field must not be 0 because there is the boot sector itself contains this BPB in the reserved area. To avoid compatibility problems, it should be 1 on FAT12/16 volume. This is because some old FAT drivers ignore this field and assume that the size of reserved area is 1. On the FAT32 volume, it is typically 32. Microsoft’s OS properly supports any value of 1 or larger.
    保留区域的扇区数。 该字段不能为 0,因为包含 BPB 的引导扇区本身就位于保留区域中。 为避免兼容性问题,FAT12/16 卷应为 1。 这是因为一些旧的 FAT 驱动程序忽略此字段并假设保留区域的大小为 1。在 FAT32 卷上,它通常为 32。Microsoft 的操作系统正确支持 1 或更大的任何值。
    BPB_NumFATs161Number of FATs. The value of this field should always be 2. Also any value eaual to or greater than 1 is valid but it is strongly recommended not to use values other than 2 to avoid compatibility problem. Microsoft’s FAT driver properly supports the values other than 2 but some tools and FAT drivers ignore this field and operate with number of FAT is 2.
    FAT 的数量。 此字段的值应始终为 2。此外,任何等于或大于 1 的值都有效,但强烈建议不要使用 2 以外的值以避免兼容性问题。 Microsoft 的 FAT 驱动程序正确支持 2 以外的值,但某些工具和 FAT 驱动程序忽略此字段并且将 FAT 的数量当做 2 来处理。
    The standard value for this field 2 is to provide redudancy for the FAT data. The value of FAT entry is typically read from the first FAT and any change to the FAT entry is refrected to each FATs. If a sector in the FAT area is damaged, the data will not be lost because it is duplicated in another FAT. Therefore it can minimize risk of data loss. On the non-disk based storages, such as memory card, such redundancy is a useless feature, so that it may be 1 to save the disk space. But some FAT driver may not recognize such a volume properly.
    该字段的标准值 2 ,用以为 FAT 数据提供一个冗余的备份。 通常从第一个 FAT 读取 FAT 条目的值,并且对 FAT 条目的任何更改都会重新映射到每个 FAT。 如果 FAT 区域中的扇区损坏,则数据不会丢失,因为它在另一个 FAT 中重复。 因此,它可以将数据丢失的风险降至最低。在诸如存储卡之类的非基于磁盘的存储器上,这种冗余是无用的特征,因此可以是 1 以节省磁盘空间。 但是一些 FAT 驱动程序可能无法正确识别这样的卷。
    BPB_RootEntCnt172On the FAT12/16 volumes, this field indicates number of 32-byte directory entries in the root directory. The value should be set a value that the size of root directory is aligned to the 2-sector boundary, BPB_RootEntCnt * 32 becomes even multiple of BPB_BytsPerSec. For maximum compatibility, this field should be set to 512 on the FAT16 volume. For FAT32 volumes, this field must be 0.
    在 FAT12/16 卷上,此字段指示根目录中 32 字节的目录条目的数量。 该值应设置为根目录的大小与 2 扇区边界对齐的值,BPB_RootEntCnt * 32 甚至变为 BPB_BytsPerSec 的倍数。 为获得最大兼容性,FAT16 卷上的此字段应设置为 512。 对于 FAT32 卷,此字段必须为 0。
    BPB_TotSec16192Total number of sectors of the volume in old 16-bit field. This value is the number of sectors including all four areas of the volume. When the number of sectors of the FAT12/16 volumes is 0x10000 or larger, an invalid value 0 is set in this field, and the true value is set to BPB_TotSec32. For FAT32 volumes, this field must always be 0.
    旧 16 位字段中卷的扇区总数。该值是包括卷的所有四个区域在内的扇区总数。 当 FAT12/16 卷的扇区数为 0x10000 或更大时,在该字段中应设置为无效值 0,并将实际值设置到 BPB_TotSec32 字段中。 对于 FAT32 卷,此字段必须始终为 0。
    BPB_Media211The valid values for this field is 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE and 0xFF. 0xF8 is the standard value for non-removable disks and 0xF0 is often used for non partitioned removable disks. Other important point is that the same value must be put in the lower 8-bits of FAT[0]. This comes from the media determination of MS-DOS Ver.1 and not used for any purpose any longer.
    该字段的有效值为 0xF0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE 和 0xFF 之一。 0xF8 是不可移动磁盘的标准值,0xF0 通常用于非分区可移动磁盘。 其他重要的一点是必须将相同的值放在 FAT[0] 的低 8 位中。 这来自 MS-DOS Ver.1 的媒体确定,不再用于任何目的。
    BPB_FATSz16222Number of sectors occupied by a FAT. This field is used for only FAT12/16 volumes. On the FAT32 volumes, it must be an invalid value 0 and BPB_FATSz32 is used instead. The size of the FAT area becomes BPB_FATSz?? * BPB_NumFATs sectors.
    FAT 占用的扇区数。 该字段仅用于 FAT12/16 卷。 在 FAT32 卷上,它必须是无效值 0,而是使用 BPB_FATSz32 字段。 FAT 区域的大小变为 BPB_FATSz ?? * BPB_NumFATs 个扇区。(注:?? 在 FAT12/16 中是 16,在 FAT32 中是 32)
    BPB_SecPerTrk242Number of sectors per track. This field is relevant only for media that have geometry and used for only disk BIOS of IBM PC.
    每个轨道的扇区数。 此字段仅适用于具有几何体且仅用于 IBM PC 的磁盘 BIOS 的介质。
    BPB_NumHeads262Number of heads. This field is relevant only for media that have geometry and used for only disk BIOS of IBM PC.
    头数。 此字段仅适用于具有几何体且仅用于 IBM PC 的磁盘 BIOS 的介质。
    BPB_HiddSec284Number of hidden physical sectors preceding the FAT volume. It is generally related to storage accessed by disk BIOS of IBM PC, and what kind of value is set is platform dependent. This field should always be 0 if the volume starts at the beginning of the storage, e.g. non-partitioned disks, such as floppy disk.
    FAT 卷之前隐藏的物理扇区数。 它通常与 IBM PC 的磁盘 BIOS 访问的存储有关,设置的值与平台有关。 如果卷从存储器的开头开始,则该字段应始终为 0,例如, 非分区磁盘,例如软盘。
    BPB_TotSec32324Total number of sectors of the FAT volume in new 32-bit field. This value is the number of sectors including all four areas of the volume. When the value on the FAT12/16 volume is less than 0x10000, this field must be invalid value 0 and the true value is set to BPB_TotSec16. On the FAT32 volume, this field is always valid and old field is not used.
    新 32 位字段中 FAT 卷的扇区总数。 该值是包括卷的所有四个区域在内的扇区总数。 当 FAT12/16 卷上的值小于 0x10000 时,该字段必须是无效值 0,并且将实际值设置到 BPB_TotSec16 中。 在 FAT32 卷上,此字段始终有效,不使用旧字段。

      Since the following fields change depending on whether the volume is FAT12/16 or FAT32, the FAT type must be determined prior to refer these fields. Also there are some fields exist in only FAT32 volumes and not exist in FAT12/16 volumes.
      由于以下字段根据卷是 FAT12/16 还是 FAT32 而变化,因此必须在引用这些字段之前确定 FAT 类型。 还有一些字段仅存在于 FAT32 卷中,而不存在于 FAT12/16 卷中。
    Fields for FAT12/16 volumes (offset from 36) FAT12/16 卷字段(从 36 偏移)

    Field name 字段名Offset 偏移Size 大小Description 描述
    BS_DrvNum361Drive number used by disk BIOS of IBM PC. This field is used in MS-DOS bootstrap, 0x00 for floppy disk and 0x80 for fixed disk. Actually it depends on the OS.
    IBM PC 的磁盘 BIOS 使用的驱动器号。 此字段用于 MS-DOS 引导程序,0x00 表示软盘,0x80 表示固定磁盘。 实际上它取决于操作系统。
    BS_Reserved1371Reserved (used by Windows NT). It should be set 0 when create the volume.
    保留(由 Windows NT 使用)。 创建卷时应将其设置为 0。
    BS_BootSig381Extended boot signature (0x29). This is a signature byte indicates that the following three fields are present.
    扩展引导签名(0x29)。 这是一个签名字节,表示存在以下三个字段。
    BS_VolID394Volume serial number used with BS_VolLab to track a volume on the removable storage. It enables to detect a wrong media change by FAT driver. This value is typically generated with current time and date on formatting.
    与 BS_VolLab 一起使用的卷序列号,用于跟踪可移动存储上的卷。 它可以通过 FAT 驱动程序检测错误的介质更改。 通常使用格式化时的当前时间和日期生成此值。
    BS_VolLab4311This field is the 11-byte volume label and it matches volume label recorded in the root directory. FAT driver should update this field when the volume label in the root directory is changed. MS-DOS does it but Windows does not do it. When volume label is not present, "NO NAME " should be set in this field.
    此字段是 11 字节的卷标,它与根目录中记录的卷标签匹配。 当根目录中的卷标更改时,FAT 驱动程序应更新此字段。 MS-DOS 做到了这点,但 Windows 没有这样做。 如果不存在卷标,则应在此字段中设置 “NO NAME”。
    BS_FilSysType548"FAT12 ", "FAT16 " or "FAT ". Many people think that this string has any effect in determination of the FAT type but it is clearly a misrecognization. From the name of this field, you will find that this is not a part of BPB. Since this string is often incorrect or not set, Microsoft’s FAT driver does not use this field to determine the FAT type. However, some old FAT drivers use this string to determine the FAT type, so that it should be set based on the FAT type of the volume to avoid compatibility problems.
    取值"FAT12 ", "FAT16 " or "FAT "之一。很多人认为这个字符串对 FAT 类型的确定有影响,但显然是个错误的认识。 从该字段的名称,您会发现这不是 BPB 的一部分。 由于此字符串通常不正确或未设置,因此 Microsoft 的 FAT 驱动程序不使用此字段来确定 FAT 类型。 但是,一些旧的 FAT 驱动程序使用此字符串来确定 FAT 类型,因此应根据卷的 FAT 类型进行设置,以避免兼容性问题。
    BS_BootCode62448Bootstrap program. It is platform dependent and filled with zero when not used.
    Bootstrap 程序。 它取决于平台,在不使用时填充为零。
    BS_BootSign51020xAA55. A boot signature indicating that this is a valid boot sector.
    取值 0xAA55。一个引导签名,表明这是一个有效的引导扇区。
    512When the sector size is larger than 512 bytes, rest field in the sector should be filled with zero.
    当扇区大小大于 512 字节时,扇区中的剩余部分应填充为零。

    Fields for FAT32 volumes (offset from 36) FAT32 卷字段(从 36 偏移)

    Field name 字段名Offset 偏移Size 大小Description 描述
    BPB_FATSz32364Size of a FAT in unit of sector. The size of the FAT area is BPB_FATSz32 * BPB_NumFATs sector. This is an only field needs to be referred prior to determine the FAT type while this field exists in only FAT32 volume. But this is not a problem because BPB_FATSz16 is always invalid in FAT32 volume.
    以扇区为单位的 FAT 大小(注:即 FAT 区域的扇区数量。与 BPB_FATSz16 含义相同 )。 FAT 区域的大小是 BPB_FATSz32 * BPB_NumFATs 个扇区。 这是在确定 FAT 类型之前需要引用的唯一字段,而该字段仅存在于 FAT32 卷中。 但这不是问题,因为 BPB_FATSz16 在 FAT32 卷中始终无效。
    BPB_ExtFlags402Bit3-0: Active FAT starting from 0. Valid when bit7 is 1.
    Bit6-4: Reserved (0).
    Bit7: 0 means that each FAT are active and mirrored. 1 means that only one FAT indicated by bit3-0 is active.
    Bit15-8-4: Reserved (0).
    BPB_FSVer422FAT32 version. Upper byte is major version number and lower byte is minor version number. This document describes FAT32 version 0.0. This field is for futuer extension of FAT32 volume to manage the filesystem verison. However, FAT32 volume will not be updated any longer.
    FAT32 版本。 高位字节是主要版本号,低位字节是次要版本号。 本文档描述了 FAT32 版本 0.0。 此字段用于将来扩展 FAT32 卷以管理文件系统版本。 但是,FAT32 卷不会再更新。
    BPB_RootClus444First cluster number of the root directory. It is usually set to 2, the first cluster of the volume, but it does not need to always be 2.
    根目录的第一个簇的编号。 它通常设置为 2,即卷的第一个簇,但它不必始终为 2。
    BPB_FSInfo482Sector of FSInfo structure in offset from top of the FAT32 volume. It is usually set to 1, next to the boot sector.
    FSInfo 结构的扇区相对于 FAT32 卷的顶部的偏移。 它通常设置为 1,紧挨着引导扇区。
    BPB_BkBootSec502Sector of backup boot sector in offset from top of the FAT32 volume. It is usually set to 6, next to the boot sector but 6 and any other value is not recommended.
    备份引导扇区相对于 FAT32 卷顶部的偏移扇区。它通常设置为 6,紧挨着引导扇区。6 以外的其他值不推荐使用。
    BPB_Reserved5212Reserved (0). 保留,全 0
    BS_DrvNum641Same as the description of FAT12/16 field. 与 FAT12/16 中该字段含义相同。
    BS_Reserved1651Same as the description of FAT12/16 field. 与 FAT12/16 中该字段含义相同。
    BS_BootSig661Same as the description of FAT12/16 field. 与 FAT12/16 中该字段含义相同。
    BS_VolID674Same as the description of FAT12/16 field. 与 FAT12/16 中该字段含义相同。
    BS_VolLab7111Same as the description of FAT12/16 field. 与 FAT12/16 中该字段含义相同。
    BS_FilSysType828Always "FAT32 " and has not any effect in determination of FAT type. 取值总是 "FAT32 " 并且与确定 FAT 类型没有任何关系。
    BS_BootCode3290420Bootstrap program. It is platform dependent and filled with zero when not used. Bootstrap 程序。它取决于平台,在不使用时填充为零。
    BS_BootSign51020xAA55. A boot signature indicating that this is a valid boot sector.取值总是 0xAA55。一个引导签名,表明这是一个有效的引导扇区。
    512When the sector size is larger than 512 bytes, rest part in the sector should be filled with zero. 当扇区大小大于 512 字节时,扇区中的剩余部分应填零。

      There is another important thing about boot sector. The boot sector needs to be valid only if the boot signature (BS_Sign) contains 0xAA55. If not, the boot sector is invalid. Many FAT documents describe about this field, “Boot signature is put at the end of the boot sector”. This is correct only if the sector size is 512, but it is incorrect in other case. The boot signature must always be put at offset 510 (also it is not bad for both offset 510 and the end of the sector contain this signature). Microsoft’s disk formatter fills the rest part of boot sector with zeros if the sector size is larger than 512.
      关于引导扇区还有另一个重要的事情。 仅当引导签名(BS_Sign)包含 0xAA55 时,引导扇区才是有效。 如果不是,则引导扇区无效。 许多 FAT 文档对这个字段有这么一个描述:“引导签名被放在引导扇区的末尾”。 仅当扇区大小为 512 时这个描述才是正确的,在其他情况下则这个描述是不正确的。 引导签名必须始终放在偏移 510 处(对于偏移 510 和扇区的末尾都包含该签名也是不错的)。 如果扇区大小大于 512,则 Microsoft 的磁盘格式化程序用零填充引导扇区的其余部分。
      Size of the volume, the value of BPB_TotSec??, might be smaller than the container (storage or partition) where the volume is contained in. It is not a problem at all. The FAT volume sometimes gets this state due to alignment or resize of volume. Such an alignment hole wastes disk space, but it does not mean insanity of the FAT volume itself.
      卷的大小(BPB_TotSec?? 的值)可能小于包含卷的容器(存储或分区)。这根本不是问题。 由于卷的对齐或调整大小,FAT 卷有时会出现这种情况。 这样的对齐浪费了磁盘空间,但并不意味着 FAT 卷本身的错乱。
      However, if BPB_TotSec?? is larger than the volume’s container, it can be said that the FAT volume is serious state, corrupted volume or incorrectly created volume. Any operation to such volume can result a catastrophic data loss, so that the FAT driver should reject the volume if it detected such condition.
      但是,如果 BPB_TotSec?? 大于卷的容器大小,可以说 FAT 卷是严重状态,卷损坏或卷创建错误。 对此类卷的任何操作都可能导致灾难性数据丢失,因此如果 FAT 驱动程序检测到此类情况,则应拒绝该卷。

    Calculating Parameters 计算参数

      The offset and size of each area are calculated from the parameters in BPB as shown below.
      每个区域的偏移量和大小由 BPB 中的参数计算,如下所示。
      Since the FAT area is next to the reserved area, its offset and size are:
      由于 FAT 区域 位于保留区域的旁边,因此其偏移量和大小为:

    FatStartSector = BPB_ResvdSecCnt;
    FatSectors = BPB_FATSz * BPB_NumFATs;
    

    The offset and size of the root directory are:
    根目录区域 的偏移量和大小为:

    RootDirStartSector = FatStartSector + FatSectors;
    RootDirSectors = (32 * BPB_RootEntCnt + BPB_BytsPerSec - 1)/BPB_BytsPerSec;
    

      The 32 in the equation is the size of a directory entry. A remainder at the divsion is rounded up, but such configuration that gives remainder is not recommended. On the FAT32 volumes, BPB_RootEntCnt is always 0 and the root directory area is not exist. The data area becomes the rest of these areas and it is obtained as follows.
      等式中的 32 是目录项的大小。除法中的余数是四舍五入的,但是不建议使用这种给出余数的配置。在 FAT32 卷上,BPB_RootEntCnt 总是 0,根目录区域不存在。数据区域变成这些区域的其余部分,得到如下结果。

    DataStartSector = RootDirStartSector + RootDirSectors;
    DataSectors = BPB_TotSec - DataStartSector;
    

      If the volume does not start from the top of the storage, for example when the storage is partitioned, these start sector numbers are not equal to the physical sector number.
      如果卷不是从存储的顶部开始,例如,当存储被分区时,这些起始扇区号不等于物理扇区号。

    FAT and Cluster FAT 区域和数据区的簇

      The another important area is FAT. What this structure does is define a linked list of the extents (cluster chain) of a file. Note that both directroy and file is contained in the file and nothing different on the FAT. The directory is really a file with a special attribute that indicates its content is a directory table.
      另一个重要的区域是 FAT 区域。这个结构的作用是定义一个文件的区段(簇链)的链表。注意,directroy 和 file 都包含在文件中,FAT 上没有什么不同。目录实际上是一个具有特殊属性的文件,该属性指示其内容是一个目录表。关于目录在下文的 FAT 目录 章节还会有详细介绍!
      FAT 区域 通常至少有 2 个完全一样的 FAT 表,多余的 FAT 表作为备份使用。FAT 表用于指示一个文件的各个部分存放在何处。其中,一个 FAT 表条目对应数据区域的一个簇。如下图所示:
    在这里插入图片描述
    FAT 表条目大小根据 FAT 类型不同而变,FAT 表条目中,填写一下几种值

    • 链中下一个簇的地址
    • 一个特殊的簇链结束符(EOC,End Of Cluster-chain,或称End Of Chain)符号指示链的结束
    • 一个特殊的符号标示坏簇
    • 一个特殊的符号标示保留簇
    • 0来表示空闲簇

    关于这部分的详细信息(FAT 条目的大小,FAT 条目的取值等),后文还会有更信息的介绍。
      The data area is divided into blocks of a certain number of sectors (BPB_SecPerClus) called cluster and the data area is managed in this unit. Each item of FAT is associated with each cluster in the data area and the FAT value indicates the state of the corresponding cluster. However, the top two FAT items, FAT[0] and FAT[1], are reserved and not associated with any cluster. The third FAT item, FAT[2], is the item associated with the first cluster of data area and the valid cluster number starts at 2. As for the data recorded on the FAT, see Association of File and Cluster.
      数据区域被划分为包含一定数量扇区(BPB_SecPerClus)的被称为簇的块,并且在该单元中管理数据区域。 如下所示的数据区域结构
    在这里插入图片描述
    上图中省略的头部结构可以参看本章节开始的第一幅图。每个部分都有大小限制,上图中的字母仅仅是为了区分大小关系,具体各部分的大小限制请看如下文章的介绍。
      FAT 表中的每个 FAT 条目与数据区中的每个簇相关联,FAT 值指示相应簇的状态。 但是,前两个 FAT 项目 FAT[0] 和 FAT[1] 是保留的,不与任何簇关联。 第三个 FAT 项目 FAT[2] 是与第一个数据区域簇相关联的项,有效簇编号从 2 开始。 至于 FAT 上记录的数据,请参阅文件和簇关联
      FAT is usually duplicated for the redundancy because a damage of any FAT sector results a serious data loss. Number of FAT copyies indicated by BPB_NumFATs and the size of FAT area becomes BPB_FATSz * BPB_NumFATs. FAT driver typically refers only first FAT copy and any update to the FAT item is refrected every FAT copy.
      FAT 通常会有个冗余备份区,因为任何 FAT 扇区的损坏都会导致严重的数据丢失。 BPB_NumFAT 指示的 FAT 副本数量并且 FAT 区域的大小变为 BPB_FATSz * BPB_NumFATs。 FAT 驱动程序通常仅引用第一个 FAT 副本,并且任何更新对于 FAT 条目的更新,都会重新更新到每个 FAT 副本。如下图所示:
    在这里插入图片描述

    Determination of FAT sub-type FAT 子类型的确定

      There are three FAT types, FAT12, FAT16 and FAT32, need to be determined on mount a FAT volume. However there is considerable confusion over exactly how this works and it leads various degree of errors. It is really quite simple how this works.
      有三种 FAT 类型,FAT12,FAT16 和 FAT32,需要在安装 FAT 卷时确定。 然而,对于它是如何工作的并且它导致各种程度的错误存在相当大的混淆。 它的工作原理非常简单。
      The FAT type is determined by the count of clusters on the volume and NOTHING ELSE.
      FAT 类型由卷上的簇数和 NOTHING ELSE 确定。
      The count of clusters is that can exist in the data area, the quotient of size of the data area divided by cluster size. Remainder is ignored if it exist in the result.
      簇的数量可以由数据区域计算得出,值为数据区域的大小除以簇大小的商。 如果结果中存在余数,则忽略余数。

    CountofClusters = DataSectors/BPB_SecPerClus;
    

    Once you know the count of clusters you can determine the FAT type. This is done as follows:
    一旦知道了簇的数量,就可以确定 FAT 类型。 这样做如下:

    • A volume with count of clusters <=4085 is FAT12. 具有簇数 <= 4085 的卷是 FAT12。
    • A volume with count of clusters >=4086 and <=65525 is FAT16. 具有簇数 >= 4086 且 <= 4085 的卷是 FAT16。
    • A volume with count of clusters >=65526 is FAT32. 具有簇数 >= 65526 的卷是 FAT32。

      This is the only way to determine the FAT type. FAT12 volumes never have clusters more than 4085 and FAT16 volumes never have clusters less than 4086 or more than 65525. If you tried to create an illegal FAT volume out of this rule, the properly designed FAT driver will recognize it as a different FAT type and will not able to access such volume. Maximum cluster count for FAT32 volume is not defined and the practical limit is 268435445.
      这是确定 FAT 类型的唯一方法。 FAT12 卷永远不会有超过 4085 的簇,FAT16 卷永远不会有小于 4086 或超过 65525 的簇。如果您尝试使用此规则创建非法 FAT 卷,正确设计的 FAT 驱动程序会将其识别为不同的 FAT 类型和将无法访问此类卷。 FAT32 卷的最大簇数并没有定义,实际限制为 268435445。
      However, these boundaries are really not strictly settled. From the maximum possible values of the cluster number, it will gets as described above, but there are many variants (1, 2, 16 or more) over the existing documentations and software implementations. For example about maximum count of clusters of FAT12, the FAT specs says it is 4084, while MSDN page says it is 4085 and Windows works with 4085 (FAT driver) or 4086 (chkdsk). Even the authorized documentation and the standad system differ as to what the correct value is, so that it is recommended to avoid count of clusters close to the boundaries when create a FAT volume. The FAT specs says count of clusters should be at least 16 clusters off from the boundaries.
      但是,这些界限实际上并没有严格解决。 符合如上所述的簇号的最大可能值在现有文档和软件实现上存在许多变体(1, 2, 16 或更多)。 例如,关于 FAT12 簇的最大数量,FAT 规范表示它是 4084,而 MSDN 页面表示它是 4085,Windows 使用 4085(FAT 驱动程序)或 4086(chkdsk)。 即使授权文档和标准系统采用的正确值也不同,因此建议在创建 FAT 卷时避免簇数量接近限制边界。 FAT 规范说簇的数量应该至少距边界 16 个簇。
      Also, some FAT driver written in out of this rule seem to determine the FAT type without the count of clusters but the string of BS_FilSysType. In order to support such the wrong FAT drivers, it is recommended to initialize BS_FilSysType with a proper string based on actual FAT type when create a FAT volume.
      此外,根据这条规则编写的一些 FAT 驱动程序似乎在不计算簇数量的情况下确定 FAT 类型,而是使用 BS_FilSysType 字符串。 为了支持这种错误的 FAT 驱动程序,建议在创建 FAT 卷时使用基于实际 FAT 类型的正确字符串初始化 BS_FilSysType。
      You will understand what the count of clusters determins the FAT type means which FAT type can be legal depends on the volume size. For example under the condition of cluster size of from 512 to 32768 bytes, it can be saied as follows:
    您将了解,簇的数量确定 FAT 类型意味着哪种 FAT 类型合法取决于卷大小。 例如,在簇大小为 512 到 32768 字节的情况下,可以如下所示:

    FAT type FAT 类型Volume size 卷大小
    FAT12-128 MB
    FAT162 MB - 2 GB
    FAT3232 MB - 2 TB

    Accessing FAT Entries 访问 FAT 条目

      An important thing related to FAT is how to access the FAT entries. First of all, you need to know where the FAT entry is located in the FAT. At the FAT16/32, it is quite simple. FAT is a simple generic integer array. The difference from the on-memory array is that the FAT is not on the continuous memory but divided in multiple blocks and stored on the contiguous disk sectors origin from the first sector of the FAT. The location of the FAT entry FAT[N], the sector number and byte offset in the sector, can be got by following calculation.
      与 FAT 区域相关的一个重要事项是如何访问 FAT 条目。 首先,您需要知道 FAT 条目在 FAT 区域中的位置。 在 FAT16/32 中,它非常简单。 FAT 是一个简单的通用整数数组。 与内存中数组的不同之处在于 FAT 不在连续存储器上,而是分成多个块并存储在来自 FAT 的第一扇区的连续磁盘扇区上。 FAT 条目 FAT[N] 的位置,扇区中的扇区号和字节偏移量,可以通过以下计算得到。

    FAT16 entry location:
        ThisFATSecNum = BPB_ResvdSecCnt + (N * 2/BPB_BytsPerSec);
        ThisFATEntOffset = (N * 2) % BPB_BytsPerSec;
    
    FAT32 entry location:
        ThisFATSecNum = BPB_ResvdSecCnt + (N * 4/BPB_BytsPerSec);
        ThisFATEntOffset = (N * 4) % BPB_BytsPerSec;
    

      The 2 (FAT16) or 4 (FAT32) byte word from the location is the FAT entry to access. The byte order is little endian. The FAT entries never across sector boundaries at FAT16/32.
      上式中的 2(FAT16)或 4(FAT32)是 FAT 条目的大小。 字节顺序是小端。 FAT 条目从不跨越 FAT16/32 的扇区边界。
      There is another important thing about FAT32. The FAT entry of FAT32 volume occupies 32 bits, but its upper 4 bits are reserved, only lower 28 bits are valid. The reserved bits are initialized by zero when createing the FAT32 volume, and it should not be changed on the regular use. Therefore, when load the value from the FAT entry of the FAT32 volume, upper 4 bits needs to be and-masked with 0x0FFFFFFF. Also, when store a value into the FAT entry, the upper 4 bits in the FAT entry need to be preserved.
      关于 FAT32 还有另一个重要的事情。 FAT32 卷的 FAT 条目占用 32 位,但其高 4 位保留,只有低 28 位有效。 在创建 FAT32 卷时,保留位由零初始化,并且在常规使用时不应更改。 因此,当从 FAT32 卷的 FAT 条目加载值时,高 4 位需要用0x0FFFFFFF 进行掩码。 此外,当将值存储到 FAT 条目中时,需要保留 FAT 条目中的高 4 位。

    Load a value of FAT32 entry:
        ReadSector(SecBuff, ThisFATSecNum);
        ThisEntryVal = *(uint32*)&SecBuff[ThisFATEntOffset] & 0x0FFFFFFF;
    
    Store a value of FAT32 entry:
        ReadSector(SecBuff, ThisFATSecNum);
        tmp = *(uint32*)&SecBuff[ThisFATEntOffset];
        tmp = (tmp & 0xF0000000) | (NewEntryVal & 0x0FFFFFFF);
        *(uint32*)&SecBuff[ThisFATEntOffset] = tmp;
        WriteSector(SecBuff, ThisFATSecNum);
    

    It is a little difficult at the FAT12 volume. The FAT12 entry is in bit field and it needs a complicated operation.
    对于 FAT12 卷,则有点困难。 FAT12 条目位于字段中,需要复杂的操作。

    FAT12 entry location:
        ThisFATSecNum = BPB_ResvdSecCnt + ((N + (N/2))/BPB_BytsPerSec);
        ThisFATEntOffset = (N + (N/2)) % BPB_BytsPerSec;
    
    Load a value of FAT12 entry:
        ReadSector(SecBuff, ThisFATSecNum);
        if (N & 1) {    /* Odd entry */
            ThisEntryVal = (SecBuff[ThisFATEntOffset] >> 4)
                         | ((uint16)SecBuff[ThisFATEntOffset + 1] << 4);
        } else {        /* Even entry */
            ThisEntryVal = SecBuff[ThisFATEntOffset]
                         | ((uint16)(SecBuff[ThisFATEntOffset + 1] & 0x0F) << 8);
        }
    
    Store a value of FAT12 entry:
        ReadSector(SecBuff, ThisFATSecNum);
        if (N & 1) {    /* Odd entry */
            SecBuff[ThisFATEntOffset] = (SecBuff[ThisFATEntOffset] & 0x0F)
                                      | (NewEntryVal << 4);
            SecBuff[ThisFATEntOffset + 1] = NewEntryVal >> 4;
        } else {        /* Even entry */
            SecBuff[ThisFATEntOffset] = NewEntryVal;
            SecBuff[ThisFATEntOffset + 1] = (SecBuff[ThisFATEntOffset + 1] & 0xF0)
                                          | ((NewEntryVal >> 8) & 0x0F);
        }
        WriteSector(SecBuff, ThisFATSecNum);
    

      Unfortunately, this code does not work properly because the bit field spans over a sector boundary when ThisFATEntOffset points the last byte of the sector and it needs to be handled properly.
      不幸的是,这段代码不能正常工作,因为当 ThisFATEntOffset 指向扇区的最后一个字节时,位字段跨越扇区边界,需要正确处理。
      Following image shows the FAT usage of each FAT type
    下图显示了每种 FAT 类型的 FAT 使用情况
    在这里插入图片描述

    Association of File and Cluster 文件和簇的关联

      Files on the FAT volume are managed by directory, the array of 32-byte directory entry structures. Details of the directory entry is described below. The directory entry has the file name, file size, timestamp and the first cluster number of the file data. The cluster number is the entry point to follow the cluster chain of the file data. If the file size is zero, a zero is set to the first cluster number and no data cluster is allocated to the file.
      FAT 卷上的文件由目录管理,目录是 32 字节目录条目结构的数组。 目录条目的细节描述如下。 目录条目具有文件名,文件大小,时间戳和文件数据的第一个簇号。 簇号是跟随文件数据的簇链的入口点。 如果文件大小为零,则将零设置为第一个簇号,并且不为该文件分配数据簇。
      As described above, cluster number 0 and 1 are reserved and valid cluster number starts from 2. The cluster number 2 corresponds to the first cluster of the data area. Therefore, valid cluster number is from 2 to N + 1 and count of FAT entries is N + 2 in the volume with N clusters. The location of a data cluster N is calculated as follows:
      如上所述,簇号 0 和 1 保留,并且有效簇号从 2 开始。簇号 2 对应于数据区域的第一簇。 因此,有效簇号从 2 到 N + 1,并且在具有 N 个簇的卷中 FAT 条目的数量是 N + 2。 数据簇 N 的位置计算如下:

    FirstSectorofCluster = DataStartSector + (N - 2) * BPB_SecPerClus;
    

      If the file size is larger than the sector size, file data is spanning over multiple sectors in the cluster. If the file size is larger than the cluster size, file data is spanning over multiple clusters in the cluster chain. The value of the FAT entry indicates following cluster number if exist, so that the any byte offset in the file can be reached by following the cluster chain. The cluster chain cannot be followed backward. The FAT entry with last link of cluster chain has a special value (end of chain, EOC, mark), which is never matches any valid cluster number. The EOC mark for each FAT type is as follows:
      如果文件大小大于扇区大小,则文件数据跨越簇中的多个扇区。 如果文件大小大于簇大小,则文件数据跨越簇链中的多个簇。 FAT 条目的值表示如果存在以下簇号,则可以通过跟随簇链到达文件中的任何字节偏移量。 簇链不能向后追踪。 具有簇链的最后一个链接的 FAT 条目具有特殊值(链的末尾,EOC,标记),它永远不会匹配任何有效的簇号。 每种 FAT 类型的 EOC 标记如下:

    • FAT12: 0xFF8 - 0xFFF (typically 0xFFF)
    • FAT16: 0xFFF8 - 0xFFFF (typically 0xFFFF)
    • FAT32: 0x0FFFFFF8 - 0x0FFFFFFF (typically 0x0FFFFFFF)

      There is also a special value, bad cluster mark. The bad cluster mark indicates that there is a defective sector in the cluster and it cannot be used. The bad cluster found on the format, surface inspection or disk repair is recorded in the FAT as bad cluster mark. The value of bad cluster mark is 0xFF7 for FAT12, 0xFFF7 for FAT16 and 0x0FFFFFF7 for FAT32.
      还有一个特殊值,坏簇标记。 坏簇标记表示簇中存在缺陷扇区,无法使用。 在格式化,表面检查或磁盘修复中发现的坏簇在 FAT 中记录为坏簇标记。 FAT12 的坏簇标记值为 0xFF7,FAT16 为 0xFFF7,FAT32 为 0x0FFFFFF7。
      The value of bad cluster mark never be equal to any valid cluster number on the FAT12/16 volume. However, it can be equal to any allocatable cluster number because the maximum count of clusters is not defined in FAT32. Such FAT32 volumes can make disk utilities confuse, so that you should avoid creating such FAT32 volume. Therefore, the upper limit of cluster count of FAT32 volume is practicaly 268435445 (about 256 M clusters).
      坏簇标记的值永远不会等于 FAT12/16 卷上的任何有效簇号。 但是在 FAT32 中,它可以等于任何可分配的簇号,因为在 FAT32 中未定义簇的最大数量。 这样的 FAT32 卷可能会使磁盘实用程序混淆,因此您应该避免创建此类 FAT32 卷。 因此,FAT32 卷的簇数的上限实际为 268435445(约256M簇)。
      Some system has a limitation on the maximum cluster count due to implementation reasons. For example, Windows9X/Me supports the FAT size 16 MB maximum and it limits number of clusters about 4 M clusters maximum.
      由于实现原因,某些系统对最大簇数有限制。 例如,Windows9X/Me 支持最大 16 MB 的 FAT 大小,并且它最多限制大约 4M 个簇的簇数量。
      The initial value of each allocatable FAT entry, FAT[2] and followings, is zero, which indicats the cluster is not in use and free for a new allocation. If the value is not zero, it means the cluster is in use or bad. Free cluster count is not recoreded anywhere in the FAT12/16 volume and full FAT scan is needed to get this information. FAT32 supports FSInfo to store the free cluster count to avoid full FAT scan because of its very large FAT structure.
      每个可分配的 FAT 条目(FAT[2] 及其后的)初始值为零,表示簇未使用且可用于新分配。 如果该值不为零,则表示簇正在使用或不良。 FAT12/16 卷中的任何位置都不会记录空闲簇计数,并且需要完整的 FAT 扫描才能获取此信息。 FAT32 支持 FSInfo 存储空闲簇计数,以避免完全 FAT 扫描,因为它具有非常大的 FAT 结构。
      The top two FAT entry, FAT[0] and FAT[1], are reserved and not associated with any cluster. These FAT entries are initialized on creating the volume as follows:
      前两个 FAT 条目 FAT[0] 和 FAT[1] 是保留的,不与任何簇相关联。 这些 FAT 条目在创建卷时初始化,如下所示:

    • FAT12: FAT[0] = 0xF??; FAT[1] = 0xFFF;
    • FAT16: FAT[0] = 0xFF??; FAT[1] = 0xFFFF;
    • FAT32: FAT[0] = 0xFFFFFF??; FAT[1] = 0xFFFFFFFF;

      ?? in the value of FAT[0] is the same value of BPB_Media but the entry has not any function. Some bits in the FAT[1] records error history.
      FAT[0] 的值中的 ?? 与 BPB_Media 的值相同,但该条目没有任何功能。 FAT[1] 中的某些位记录错误历史记录。

    • Volume dirty flag: (FAT16: bit15、FAT32: bit31): Cleared on boot, restored on clean shutdown. Clearing before boot indicates a possibility of insanity in the volume. 在启动时清除,在完全关闭时恢复。在启动前清除指示卷中有精神错乱的可能性。
    • Hard error flag: (FAT16: bit14、FAT32: bit30): Cleared on unrecoverable read/write error, set after surface inspection. 清除不可恢复的读/写错误,在表面检查后设置。

    These flags indicates possibility of an error on the volume. Some OSs supporing this feature check these flags on boot and launch disk inspection tool automatically. Windows 9X family uses these flags. Windows NT family does not use these flags but alternatives in the BPB.
    这些标志表示卷上可能出错。 某些支持此功能的操作系统会在启动时检查这些标志并自动启动磁盘检查工具。 Windows 9X 系列使用这些标志。 Windows NT 系列不使用这些标志,而是使用 BPB 中的替代标志。
      There are two more important things about the FAT area. One is that the last sector of a FAT may not be fully used. In most case, FAT ends at the middle of the sector. FAT driver should not have any assumption about unused part. It should be initialized by zero on formatting the volume and should not change afterwards. The other is that the BPB_FATSz16/32 can indicates a value lager than the volume requires. In other wards, unused sectors can follow the used FAT sectors. It may a result of data area alignment or something. Also these sector are initialized to zero on formatting.
      关于 FAT 区域有两个更重要的事情。 一个是 FAT 的最后一个扇区可能没有被完全使用。 在大多数情况下,FAT 结束于扇区的中间。 FAT 驱动程序不应该对未使用的部分有任何假设。 它应该在格式化卷时初始化为零,之后不应更改。 另一个是 BPB_FATSz16/32 可以指示比卷要求的更大的值。 换句话说,未使用的扇区可以跟随使用的 FAT 扇区。 它可能是数据区域对齐的结果。 这些扇区在格式化时也被初始化为零。
      Following table shows the range of FAT values and meaning for each FAT type.
      下表显示了每种 FAT 类型的 FAT 值范围和含义。

    FAT12FAT16FAT32Meaninig
    0x0000x00000x00000000Free 空闲簇
    0x0010x00010x00000001Reserved 保留簇
    0x002 - 0xFF60x0002 - 0xFFF60x00000002 - 0x0FFFFFF6In use (value is link to next) 被占用的簇;指向下一个簇
    0xFF70xFFF70x0FFFFFF7Bad cluster 坏簇
    0xFF8 - 0xFFF0xFFF8 - 0xFFFF0x0FFFFFF8 - 0x0FFFFFFFIn use (end of chain) 文件最后一个簇

    下图显示了 从 FAT 区中的 FAT 条目 到 数据区簇的关系(简化形式)
    在这里插入图片描述

    FAT 区域示例

      上面详细介绍了 FAT 区域的内容。每个版本的 FAT 文件系统使用不同大小的 FAT 条目。这个大小已经由名字表示出来,例如 FAT16 文件系统的每个条目使用 16位表示,FAT32 文件系统使用 32 位表示。下面我们以图示的形式来看一下。

    FAT12

      FAT12 文件系统每个 FAT 条目使用 12 个比特位,因此两个条目跨越 3 个字节。 它始终是小端。如果这三个字节被视为一个小端 24 位数,则 12 个最低有效位表示第一个条目(fe簇0),12 个最高有效位表示第二个(fe簇1) 。 换句话说,虽然行中第一个簇的低 8 位存储在第一个字节中,但前 4 位存储在第二个字节的低半字节中,而后续簇中的低 4 位存储在第二个字节中。 存储在第二个字节的高半字节中,在第三个字节中存储在高位的 8 位中。
    在这里插入图片描述

    • 蓝色:非碎片文件的第二个链:簇 2 -> 簇 3 -> 簇 4 -> 簇 5 -> 簇 6 -> 簇 7 -> 簇 8(结束),共 7 个簇
    • 黄色:第三个链,用于碎片化的、可能增长的文件:簇 9 -> 簇 A -> 簇 14 -> 簇 15 -> 簇 16 -> 簇 19 -> 簇 1A(结束),共 7 个簇
    • 橙色:第四个链。用于一个非碎片的、可能被截断的文件:簇 B -> 簇 C -> 簇 D -> 簇 E -> 簇 F -> 簇 10 -> 簇 11(结束),共 7 个簇
    • 白色:空闲簇未使用
    • 浅红色:坏簇
    • 浅绿色:第五个链,指示子目录

    FAT16

      FAT16 文件系统每个 FAT 条目使用 16 位,因此一个条目以小端字节顺序跨越两个字节:
    在这里插入图片描述

    • 蓝色:非碎片文件的第二个链:簇 2 -> 簇 3 -> 簇 4 -> 簇 5 -> 簇 6 -> 簇 7 -> 簇 8(结束),共 7 个簇
    • 黄色:第三个链,用于碎片化的、可能增长的文件:簇 9 -> 簇 A -> 簇 14 -> 簇 15 -> 簇 16 -> 簇 19 -> 簇 1A(结束),共 7 个簇
    • 橙色:第四个链。用于一个非碎片的、可能被截断的文件:簇 B -> 簇 C -> 簇 D -> 簇 E -> 簇 F -> 簇 10 -> 簇 11(结束),共 7 个簇
    • 白色:空闲簇未使用
    • 浅红色:坏簇
    • 浅绿色:第五个链,指示子目录

    FAT32

      FAT32文件系统每个FAT条目使用32位,因此一个条目以小端字节顺序跨越四个字节。 每个条目的高四个比特位保留用于其他目的,在格式化期间清除,否则不应更改。 在将条目解释为 28 位簇地址之前,必须将它们屏蔽掉。
    在这里插入图片描述

    • 绿色:根目录的第一个链,由 FAT32 BPB 中的一个条目指向:簇 2(结束),共 1 个簇
    • 蓝色:非碎片文件的第二个链:簇 2 -> 簇 3 -> 簇 4 -> 簇 5 -> 簇 6 -> 簇 7 -> 簇 8(结束),共 7 个簇
    • 黄色:第三个链,用于碎片化的、可能增长的文件:簇 9 -> 簇 A -> 簇 14 -> 簇 15 -> 簇 16 -> 簇 19 -> 簇 1A(结束),共 7 个簇
    • 橙色:第四个链。用于一个非碎片的、可能被截断的文件:簇 B -> 簇 C -> 簇 D -> 簇 E -> 簇 F -> 簇 10 -> 簇 11(结束),共 7 个簇
    • 白色:空闲簇未使用
    • 浅红色:坏簇
    • 浅绿色:第五个链,指示子目录

    FSInfo Sector Structure and Backup Boot Sector FSInfo扇区结构和备份引导扇区

      The size of FAT is up to 6 KB on FAT12 volume and up to 128 KB on FAT16 volume, but it typically reach several MB on FAT32 volume. For this reason, FAT32 volume supports FSInfo structure in order to avoid to read over an entire FAT to look for free clusters or get count of free clusters. This structure is put in the FSInfo sector indicated by BPB_FSInfo.
      在 FAT12 卷上 FAT 区域的大小最多为 6KB,在 FAT16 卷上最大为 128KB,但在 FAT32 卷上它通常达到几 MB。 出于这个原因,FAT32 卷支持 FSInfo 结构,以避免读取整个 FAT 以查找空闲簇或获取空闲簇的数量。 此结构放在 BPB_FSInfo 指示的FSInfo 扇区中。
    FAT32 FSInfo sector

    Field name 字段名Offset 偏移Size 大小Description 描述
    FSI_LeadSig040x41615252. This is a lead signature used to validate that this is in fact an FSInfo sector. 取值 0x41615252。这是用于验证这实际上是 FSInfo 扇区的主要签名。
    FSI_Reserved14480Reserved. This field should be always initialized to zero. 保留。 该字段应始终初始化为零。
    FSI_StrucSig48440x61417272. Another signature that is more localized in the sector to the location of the fields that are used.取值 0x41615252。这是用于验证这实际上是 FSInfo 扇区的主要签名。
    FSI_Free_Count4884This field indicates the last known free cluster count on the volume. If the value is 0xFFFFFFFF, it is actually unknown. This is not necessarily correct, so that the FAT driver needs to make sure it is valid for the volume.此字段指示卷上最后一次已知的可用簇计数。 如果值为 0xFFFFFFFF,则实际上是未知的。 这不一定正确,因此 FAT 驱动程序需要确保它对卷有效。
    FSI_Nxt_Free4924This field gives a hint for the FAT driver, the cluster number at which the driver should start looking for free clusters. Because a FAT32 FAT is large, it can be rather time consuming if there are a lot of allocated clusters at the start of the FAT and the driver starts looking for a free cluster starting at the first cluster. Typically this value is set to the last cluster number that the driver allocated. If the value is 0xFFFFFFFF, there is no hint and the driver should start looking at cluster 2. This may not be correct, so that the FAT driver needs to make sure it is valid for the volume.
    该字段为 FAT 驱动程序提供一个提示,FAT 驱动程序应该从此簇号开始寻找空闲簇。因为 FAT32 FAT 很大,如果在 FAT 的开始有很多分配的簇,并且驱动程序从第一个簇开始寻找空闲簇,那么它可能会非常耗时。 通常,此值设置为驱动程序分配的最后一个簇编号。 如果值为 0xFFFFFFFF,则没有提示,驱动程序应该从簇 2 开始查看。这可能不正确,因此 FAT 驱动程序需要确保它对该卷有效。
    FSI_Reserved249612Reserved. This field should be always initialized to zero. 保留。 该字段应始终初始化为零。
    FSI_TrailSig50840xAA550000. This trail signature is used to validate that this is in fact an FSInfo sector. 取值 0xAA550000。该跟踪签名用于验证这实际上是一个FSInfo扇区。
    512When the sector size is larger than 512, rest bytes should be initialized to zero.当扇区大小大于512时,剩余字节应初始化为零。

      Another feature of FAT32 volume is backup boot sector. This is a feature to provide redundancy for the only boot sector existing on the FAT volume. This can increase the possibility of volume recovery if the boot sector is corrupted for any reason. The location of backup boor sector is indicated by BPB_BkBootSec. 6 is strongly recommended for this field because the boot loader and FAT driver are hard coded to try reading the boot sector at sector 6 when it failed to load the main boot sector. The FAT32 boot sector is actually three 512-byte sectors long. There is a copy of all three of these sectors starting at the sector indicated by BPB_BkBootSec. A copy of the FSInfo sector is also there, even though the BPB_FSInfo field in this backup boot sector is set to the same value as the value in sector 0. All three sectors have boot signature, 0xAA55, at the offset 510.
      FAT32 卷的另一个特征是备份引导扇区。这是为 FAT 卷上存在的唯一引导扇区提供冗余的功能。如果引导扇区因任何原因损坏,这将增加卷恢复的可能性。备份扇区的位置由 BPB_BkBootSec 指示。强烈建议在此字段中使用 6,因为引导加载程序和 FAT 驱动程序被硬编码,以便在未能加载主引导扇区时尝试读取扇区 6 的引导扇区。FAT32 引导扇区实际上有三个 512 字节长的扇区。所有这三个扇区都有一个副本,从BPB_BkBootSec 指示的扇区开始。即使备份引导扇区中的 BPB_FSInfo 字段被设置为与扇区 0 中的值相同的值,FSInfo扇区的副本也在那里。所有三个扇区都在偏移量 510 处具有引导签名 0xAA55。

    FAT Directory FAT 目录(FAT 根目录区域)

      FAT 卷上的文件由根目录管理,根目录是 32 字节目录条目结构的数组(根目录表)。 目录条目的细节描述如下。 目录条目具有文件名,文件大小,时间戳和文件数据的第一个簇号。 簇号是跟随文件数据的簇链的入口点。 如果文件大小为零,则将零设置为第一个簇号,并且不为该文件分配数据簇。
    在这里插入图片描述
      对于 FAT12 和 FAT16 ,根目录位于紧跟在最后一个 FAT 之后的固定位置,在扇区中具有固定大小根据 BPB_RootEntCnt 值计算。对于 FAT32,根目录可以是可变大小的簇链,就像任何其他目录一样。FAT32 卷上的根目录的第一个出存储在 BPB_RootClus 中。

      This section describes only short file name (SFN), the basic feature of FAT volume. The directory is really a file with a special attribute. It contains table of directory entries that contain meta data of the files on the volume. Size of a directory entry is 32 byte long and it corresponds with a file or diretory on the volume. Maximum size of a directory is 2 MB (65536 entries).
      本节仅介绍短文件名(SFN),即 FAT 卷的基本特性。目录实际上是一个具有特殊属性的文件。 它包含目录条目表,其中包含卷上文件的元数据。 目录条目的大小为 32 字节长,它对应于卷上的文件或指令。 目录的最大大小为 2 MB(65536个条目)。
      The root directory is only a special directory needs to be always exist and it becomes top node of the hierarchy in the volume. On the FAT12/16 volume, the root directory is not a file but put on the root directory area separated form the data area. The count of root directory entries is determined on the formatting and indicated in BPB_RootEntCnt. On the FAT32 volume, there is no difference between the sub-directories except for it does not have any entry to indicate it and the start cluster number is indicated by BPB_RootClus.
      根目录只是一个特殊目录,需要始终存在,并且它成为卷中层次结构的顶级节点。 在 FAT12/16 卷上,根目录不是文件,而是放在与数据区分开的根目录区。 根目录条目的计数是根据格式确定的,并在 BPB_RootEntCnt 中指示。 在 FAT32 卷上,子目录之间没有区别,只是没有任何条目来表示它,并且起始簇号由 BPB_RootClus 指示。
      Another difference from the sub-directory is that it does not contain dot entries (".", “…”) what always exist in the sub-directory and it can contain a volume label (an entry with ATTR_VOLUME_ID attribute). Following table shows directory entry structure
      与子目录的另一个不同之处在于它不包含在子目录中始终存在的点条目(“ . ”,“ … ”),它可以包含卷标(具有ATTR_VOLUME_ID 属性的条目)。 下表显示了目录条目结构
    Directory entry structure

    Field name 字段名Offset 偏移Size 大小Description 描述
    DIR_Name011Short file name (SFN) of the object. 对象的短文件名(SFN)。
    DIR_Attr111File attribute in combination of following flags. Upper 2 bits are reserved and must be zero.文件属性,由以下标志组合而成。 高 2 位保留,必须为零。
    0x01: ATTR_READ_ONLY (Read-only)
    0x02: ATTR_HIDDEN (Hidden)
    0x04: ATTR_SYSTEM (System)
    0x08: ATTR_VOLUME_ID (Volume label)
    0x10: ATTR_DIRECTORY (Directory)
    0x20: ATTR_ARCHIVE (Archive)
    0x0F: ATTR_LONG_FILE_NAME (LFN entry)
    DIR_NTRes121Optional flags that indicates case information of the SFN. 可选标志,指示SFN的案例信息。
    0x08: All alphabetical characters in the body are lower capital.正文中所有字母都是小写字母。
    0x10: All alphabetical characters in the extensiton are lower capital. 扩展中的所有字母字符都是小写字母。
    DIR_CrtTimeTenth131Optional sub-second information corresponds to DIR_CrtTime. The time resolution of DIR_CrtTime is 2 seconds, so that this field gives a count of sub-second and its valid value range is from 0 to 199 in unit of 10 miliseconds. If not supported, set zero and do not change afterwards. 可选的亚秒信息对应于 DIR_CrtTime。 DIR_CrtTime 的时间分辨率为2秒,因此该字段给出亚秒计数,其有效值范围为 0 到 199,单位为 10 毫秒。 如果不支持,请设置为零,之后不要更改。
    DIR_CrtTime142Optional file creation time. If not supported, set zero and do not change afterwards. 可选的文件创建时间。 如果不支持,请设置为零,之后不要更改。
    DIR_CrtDate162Optional file creation date. If not supported, set zero and do not change afterwards. 可选的文件创建日期。 如果不支持,请设置为零,之后不要更改。
    DIR_LstAccDate182Optional last accesse date. There is no time information about last accesse time, so that the resolution of last accesse time is 1 day. If not supported, set zero and do not change afterwards. 可选的上次访问日期。 没有关于上次访问时间的时间信息,因此最后访问时间的分辨率为1天。 如果不支持,请设置为零,之后不要更改。
    DIR_FstClusHI202Upeer part of cluster number. Always zero on the FAT12/16 volume. 簇号的上半部分。 FAT12/16 卷始终为零。
    DIR_WrtTime222Last time when any change is made to the file (typically on closeing). 对文件进行任何更改时的上次时间(通常在关闭时)。
    DIR_WrtDate242Last data when any change is made to the file (typically on closeing).对文件进行任何更改时的最后数据(通常在关闭时)。
    DIR_FstClusLO262Lower part of cluster number. Always zero if the file size is zero. 簇号的下半部分。 如果文件大小为零,则始终为零。其表示文件或者目录的第一个簇号。如果是 FAT32 则,需要还需要 + DIR_FstClusHI。
    DIR_FileSize284Size of the file in unit of byte. Not used when it is a directroy and the value must be always zero.文件大小,以字节为单位。 当它是目录时不使用,值必须始终为零。

      The first byte of DIR_Name field, DIR_Name[0], is an impotant data to indicates state of the directory entry. When the value is 0xE5, it indicates that the entry is not used (free for new allocation). When the value is 0x00, it indicates that the entry is not used (same as 0xE5) and in addition, there is no allocated entry after this one (all of the DIR_Name[0] in all of the entries after this one are also set to 0). Any other value in the DIR_Name[0] indicates the entry in in use. There is an exception about the file name with heading character 0xE5. In this case, 0x05 is set instead.
      DIR_Name 字段的第一个字节 DIR_Name[0] 是一个重要数据,用于指示目录条目的状态。 当值为 0xE5 时,表示该条目未被使用(新分配可用)。 当值为 0x00 时,表示该条目未被使用(与 0xE5 相同),此外,在此之后没有分配的条目(在此之后的所有条目中的所有 DIR_Name[0] 也被设置到 0)。 DIR_Name[0] 中的任何其他值表示正在使用的条目。 标题字符为 0xE5 的文件名有一个例外。 在这种情况下,改为设置 0x05。
      DIR_Name field is a 11-byte string and divided in two parts, body and extension. The file name is stored in 8-byte body + 3-byte extension. The period in the file name to separate body and exitension is removed on the directory entry. If any part of the name does not fit to the part, rest bytes in the part is filled with spaces (0x20). The code page used for the file name depends on the system.
      DIR_Name 字段是一个 11 字节的字符串,分为两部分,正文和扩展。 文件名以 8 字节正文 + 3字节扩展名存储。 在目录条目上,文件名中用于分隔正文和扩展名的句点要删除。 如果名称的任何部分与该部分不匹配,则该部分中的剩余字节用空格(0x20)填充。文件名使用的代码页取决于系统。

    FileName           DIR_Name[]       Description
    "FILENAME.TXT"    "FILENAMETXT"     Dot is removed.
    "DOG.JPG"         "DOG     JPG"     Each part is padded with spaces.
    "file.txt"        "FILE    TXT"     Each character is upper-case converted.
    "蜃気楼.JPG"      "・気楼  JPG"     The first byte of "蜃", 0xE5, is replaced with 0x05
    "NOEXT"           "NOEXT      "     No extension
    ".cnf"                              (illegal) Any name without body is not allowed
    "new file.txt"                      (illegal) Space is not allowed.
    "file[1].2+2"                       (illegal) [ ] + are not allowed.
    "longext.jpeg"                      (illegal) Out of 8.3 format.
    "two.dots.txt"                      (illegal) Out of 8.3 format.
    

    Allowable charactes for the file name are 0~9 A~Z ! # $ % & ’ ( ) - @ ^ _ ` { } ~ and extended characters (\x80 - \xFF). Lower-case characters (a-z) appeared in the input file name are replaced with upper-case characters prior to matching and recording. As for the extended characters, there are many differnce on the replacement between each system, such as ä→Ä (CP852) and ä→A (CP850). Therefore, using any extended character can cause compatibility problem in the different systems (e.g. file open failur). As for the extended characters on the Japanese environment, refer to the Compatibility described below.
      文件名的允许字符是 0~9 A~Z ! # $ % & ’ ( ) - @ ^ _ ` { } ~ 和扩展字符(\x80 - \xFF)。 在匹配和记录之前,输入文件名中出现的小写字符(a-z)将替换为大写字符。 至于扩展字符,每个系统之间的替换有很多不同,例如ä→Ä(CP852)和ä→A(CP850)。 因此,使用任何扩展字符都可能导致不同系统中的兼容性问题(例如文件打开失败)。 至于日语环境中的扩展字符,请参阅下面描述的兼容性。
      Every file names in a directory is unique each other. Any other enrty with the same name never exists. DIR_Attr field indicates the attribute of the entry.
      目录中的每个文件名彼此都是唯一的。 任何其他具有相同名称的条目永远不存在。 DIR_Attr 字段指示条目的属性。
    File attribute

    Flag 标志Meaning 含义
    ATTR_READ_ONLYRead-only File. Any changes to the file or delete should be rejected. 只读文件。对文件的任何更改或删除都应被拒绝。
    ATTR_HIDDENNormal directoly listing should not show this file. (system dependent) 正常的目录列表不应显示此文件。 (取决于系统)
    ATTR_SYSTEMIndicates this is an system file. (system dependent) 表示这是一个系统文件。 (取决于系统)
    ATTR_DIRECTORYIndicates this is a container of a directory. 表示这是目录的容器。
    ATTR_ARCHIVEThis is for backup utilities. Set by FAT driver on new creation, modification or renaming to the file is made. The backup utilities able to easily find the file to be backed up and it clears the attribute after the back up process.这是用于备份实用程序的。在创建、修改或重命名文件时由FAT驱动程序设置。备份实用程序能够轻松找到要备份的文件,并在备份过程之后清除该属性。
    ATTR_VOLUME_IDAn entry with this attribute has the volume label of the volume. Only one entry can be exist in the root directory. DIR_FstClusHI, DIR_FstClusLO and DIR_FileSize field must be always zero. Some system may set ATTR_ARCHIVE, but it has no meaning. 具有此属性的条目具有卷的卷标签。根目录中只能存在一个条目。DIR FstClusHI、DIR FstClusLO 和 DIR FileSize 字段必须始终为零。一些系统可能会设置 ATTR_ARCHIVE,但它没有任何意义。
    ATTR_LONG_NAMEThis combination of attributes indicates the entry is a part of long file name. Details are described below.这种属性组合表明条目是长文件名的一部分。细节如下所述。

    Directory Operations 目录操作

    Creating File 创建文件

      To create a file, FAT driver finds a free entry in the directory to create in. If no free entry is found in the directry, stretch the directry a cluster to allocate a new free entry, but size of a directory cannot exceed 2 MB (65536 entries). Size of static directory (root directory on the FAT12/16 volume) is fixed and cannot be changed. The new entry has its name in the DIR_Name, ATTR_ARCHIVE flag in the DIR_Attr and DIR_FstClusHI, DIR_FstClusLO, DIR_FileSize has 0 for the initial value. When any data is written to the file and file size changed form 0, a new cluster chain is created and the first cluster numner is stored to DIR_FstClusHI, DIR_FstClusLO. The cluster chain is streached as file size increse.
      要创建文件,FAT 驱动程序会在要创建的目录中找到一个空闲条目。如果在目录中找不到空闲条目,则将目录扩展一个簇,以分配一个新的空闲条目,但是目录的大小不能超过 2 MB (65536个条目)。 静态目录的大小( FAT12/16 卷上的根目录)是固定的,不能更改。 新条目的名称在 DIR_Name,DIR_Attr 中的 ATTR_ARCHIVE 标志和 DIR_FstClusHI,DIR_FstClusLO,DIR_FileSize 的初始值为 0。 当任何数据写入文件并且文件大小从 0 改变时,会创建一个新的簇链,并且第一个簇编号会存储到 DIR_FstClusHI,DIR_FstClusLO。随着文件大小的增加,簇链被拉伸。
    在这里插入图片描述

    Creating Sub-directory 创建子目录

      To create a sub-directory, FAT driver creates a directory entry as creating a file. The entry needs to have ATTR_DIRECTORY attribute. The sub-directry has no size information and DIR_FileSize field must be always zero. A cluster is initially allocated to the sub-directory and the cluster number is set to the DIR_FstClusHI, DIR_FstClusLO field. Each entries in the cluster is initialized to zero. When the directory table gets full, the cluster chain is stretched and cluster is initialized to zero. The maximum length of a direcotry is 2 MB (64 K entries).
      要创建子目录,FAT 驱动程序会创建一个目录条目作为创建文件。 该条目需要具有 ATTR_DIRECTORY 属性。 子目标没有大小信息,DIR_FileSize 字段必须始终为零。 最初将簇分配给子目录,并将簇号设置到 DIR_FstClusHI,DIR_FstClusLO 字段。 簇中的每个条目都初始化为零。 当目录表变满时,将拉伸簇链并将簇初始化为零。 目录的最大长度为 2 MB(64 K条目)。
      Sub-directory has two special entries (dot entry) at top of the directory, DIR[0] as ". " and DIR[1] as "… ". These entries have ATTR_DIRECTORY attribute, however, they do not have any cluster but point another directory’s cluster instead. “.” entry points this directoy and “…” entry points the parent directory. If the parent directory is the root directory, set zero to the DIR_FstClusHI, DIR_FstClusLO field even if at FAT32 volume.
      子目录在目录顶部有两个特殊条目(点条目),DIR[0] 为 “ . ”,DIR[1] 为 “ … ”。 这些条目具有 ATTR_DIRECTORY 属性,但是,它们没有任何簇,而是指向另一个目录的簇。 “ . ” 入口指向该目录和 “…” 入口指向父目录。 如果父目录是根目录,则将 DIR_FstClusHI,DIR_FstClusLO 字段设置为 0。即使是在 FAT32 卷上,也是这样。

    Deleting File 删除文件

      To remove a file, set 0xE5 to the DIR_Name[0] to free the entry. If the file has a cluster chain, also the chain needs to be removed from the FAT.
      要删除文件,将 DIR_Name[0] 设置为 0xE5 以释放条目。如果文件有簇链,那么也需要从 FAT 中删除该链。
    在这里插入图片描述

    Deleting Sub-directory 删除子目录

      It is same as deleting a file. All nodes below the directory needs to be scanned and all files and directories in the directory need to be deleted prior to delete the directory otherwise those objects’ clusters get lost clusters.
      这与删除文件是一样的。在删除目录之前,需要扫描目录下的所有节点,并删除目录中的所有文件和目录,否则这些对象的簇将丢失簇。

    Volume Label 卷标签

      FAT volume can have a its own name called volume label, which is recorded as a directory entry with ATTR_VOLUME_ID attribute in the root directory. The volume label is not a file but only a name of the volume. Its name space is independent of the files and the name can be duplicated with any other file in the directory. Allowable characters for the volume label is similar to the SFN entry but it can contain spaces anywhere the name and cannot contain period.
      FAT 卷可以有一个称为卷标的自己的名称,它被记录为根目录中具有 ATTR_VOLUME_ID 属性的目录条目。 卷标不是文件,只是卷的名称。 它的名称空间与文件无关,名称可以与目录中的任何其他文件重复。 卷标的允许字符类似于 SFN 条目,但它可以在名称的任何位置包含空格,并且不能包含句点。
      The LFN extension is not applied to the volume label. When any change to the volume label is made, it should be reflected to BS_VolLab, but Windows does not do it. Windows has a problem on the behavior at the volume label beginning with a 0xE5. It does not replace it with 0x05 and the change will have no effect, so that such volume label shoud not be used.
      LFN 扩展名未应用于卷标。 如果对卷标签进行了任何更改,则应将其反映到 BS_VolLab,但 Windows 不会这样做。 Windows 在以 0xE5 开头的卷标签上的行为存在问题。 它不会用 0x05 替换它,并且更改将不起作用,因此不应使用此类卷标。

    Timestamp 时间戳

      There are some fields related to the time and data in the directory entry. Most FAT driver supports only DIR_WrtTime, DIR_WrtDate field which is mandatory to be supported and optional fields are not supprted. The non supporting field should be initialized to zero on creation of entry and do not chane afterwards. The format of the time and date is described as follows:
      目录条目中有一些与时间和数据相关的字段。大多数 FAT 驱动程序只支持 DIR_WrtTime, DIR_WrtDate字段,且是必须支持的。其他可选字段可以不用支持。不支持的字段在创建条目时应初始化为零,之后不更改。时间和日期的格式如下所述:

    Field name 字段名Bit fields BIT 字段
    DIR_WrtDate
    DIR_CrtDate
    DIR_LstAccDate
    Bit 15-9: Count of years from 1980 in range of from 0 to 127 (1980-2107). 从1980年开始的年数从0到127(1980-2107)。
    Bit 8-5: Month of year inrange of from 1 to 12. 从1到12的年份。
    Bit 4-0: Day of month in range of from 1 to 31. 每月的日期范围为1到31。
    DIR_WrtTime
    DIR_CrtTime
    Bit 15-11: Hours in range of from 0 to 23. 小时数从0到23。
    Bit 10-5: Minutes in range from 0 to 59. 分钟范围从0到59。
    Bit 4-0: 2 second count in range of form 0 to 29 (0-58 seconds). 2秒计数,范围从0到29 (0-58秒)。

    Long File Name 长文件名

      When add the long file name (LFN) as a new feature to the FAT filesystem, a backward compatibility with the existing systems is required. Following are concrete examples required.
      当将长文件名(LFN)作为新特性添加到FAT文件系统时,需要与现有系统向后兼容。下面是需要的具体例子。

    • The existence of LFN needs to be invisible on the existing systems, especially any file API on the MS-DOS and Windows. LFN 的存在需要在现有系统上不可见,尤其是 MS-DOS 和 Windows 上的任何文件 API。
    • LFN needs to be located physically near the direcroty entry of the corresponding file to prevent bad effect to the performance. LFN 需要物理上位于相应文件的目录条目附近,以防止对性能产生不良影响。
    • If disk utility found the LFN information recorded somewhere on the FAT volume, the filesystem needs to keep sanity and be not affected. 如果磁盘实用程序发现在 FAT 卷上某处记录了 LFN 信息,则文件系统需要保持健全并且不受影响。

      To achieve these requirement, LFN information is recorded as directory entry with a special attribute. As described above, the attribute for the LFN entry (ATTR_LONG_NAME) is defined in combination of existing attribute bits (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID), and mask value (ATTR_LONG_NAME_MASK = ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID | ATTR_DIRECTORY | ATTR_ARCHIVE) is also defined. When DIR_Attr masked with (ATTR_LONG_NAME_MASK matched with ATTR_LONG_NAME, the entry is an LFN entry and its field is defined as below.
      为了达到这些要求,LFN 信息被记录为具有特殊属性的目录条目。 如上所述,LFN 条目(ATTR_LONG_NAME)的属性是由现有属性位(ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)和掩码值(ATTR_LONG_NAME_MASK = ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID | ATTR_DIRECTORY | ATTR_ARCHIVE)的组合定义的。 也定义了。 当 DIR_Attr 被屏蔽时ATTR_LONG_NAME_MASK 与 ATTR_LONG_NAME 匹配,该条目是 LFN 条目,其字段定义如下。
    Directory entry structuer for LFN

    Field name 字段名Offset 偏移Size 大小Description 描述
    LDIR_Ord01Sequence number (1-20) to identify where this entry is in the sequence of LFN entries to compose an LFN. One indicates the top part of the LFN and any value with LAST_LONG_ENTRY flag (0x40) indicates the last part of the LFN. 序列号(1-20),用于标识此条目在 LFN 条目序列中的位置,以组成 LFN。 一个表示 LFN 的顶部,任何带有 LAST_LONG_ENTRY 标志的值(0x40)表示 LFN 的最后一部分。
    LDIR_Name1110Part of LFN from 1st character to 5th character. LFN 的一部分,从第 1 个字符到第 5 个字符。
    LDIR_Attr111LFN attribute. Always ATTR_LONG_NAME and it indicates this is an LFN entry. LFN 属性。 始终是 ATTR_LONG_NAME,它表示这是 LFN 条目。
    LDIR_Type121Must be zero. 必须是 0
    LDIR_Chksum131Checksum of the SFN entry associated with this entry. 与此条目关联的 SFN 条目的校验和。
    LDIR_Name21412Part of LFN from 6th character to 11th character. LFN 的一部分,从第 6 个字符到第 11 个字符。
    LDIR_FstClusLO262Must be zero to avoid any wrong repair by old disk utility. 必须为零,以避免旧磁盘工具的任何错误修复。
    LDIR_Name3284Part of LFN from 12th character to 13th character. LFN 的一部分,从第 12 个字符到第 13 个字符。

      LFN entry is always associated with the corresponding SFN entry in order to add LFN to the file. LFN entries never exist independent of SFN. Therfore each file has only SFN or both of SFN and LFN. LFN entry has only name information in it and nothing else about the file. If an LFN entry without association with the SFN entry is exist, such stray LFN entry is invalid and considered garbage. This is for backward compatibility with old system. If an LFN is given to the file, the LFN is the primary name of the file and the SFN is an alternative. Old system without support of LFN does not recognize LFN entry, but it can access with SFN. LFN system can access the file with LFN or SFN. Following table shows how the set of LFN and SFN is recorded on the directory.
      LFN 条目始终与相应的 SFN 条目相关联,以便将 LFN 添加到文件中。 LFN 条目从不独立于 SFN 存在。 因此,每个文件只有 SFN 或者 SFN 和 LFN。 LFN 条目只包含其中的名称信息,而没有关于该文件的任何其他信息。 如果存在没有与 SFN 条目关联的 LFN 条目,则这种杂散 LFN 条目无效并被视为垃圾。 这是为了向后兼容旧系统。 如果为文件指定了LFN,则 LFN 是文件的主要名称,SFN 是另一种选择。 不支持 LFN 的旧系统无法识别 LFN 条目,但可以使用 SFN 进行访问。 LFN 系统可以使用 LFN 或 SFN 访问文件。 下表显示了如何在目录中记录 LFN 和 SFN 集。
    Association of LFN “MultiMediaCard System Summary.pdf” with a file

    LocationFirst byteName fieldAttributeContent
    DIR[N-3]0x43ary.pdf–VSHRLFN 3rd part (lfn[26…38])
    DIR[N-2]0x02d System Summ–VSHRLFN 2nd part (lfn[13…25])
    DIR[N-1]0x01MultiMediaCar–VSHRLFN 1st part (lfn[0…12])
    DIR[N]‘M’MULTIM~1PDFA-----Associated SFN entry

      If the LFN is longer than 13 characters, it is divided into some LFN entries. The maximum name length for LFN is 255, so that an LFN occupies upto 20 LFN entries. LFN is put on the directory at just before the associated SFN entry. For the example shown above, an LFN with 33 character in length consist of 3 LFN entries that have 0x43, 0x02, 0x01 in LDIR_Ord. The character code used for the LFN is Unicode in UTF-16 encoding while the character code for SFN is ANSI/OEM code in local code page depends on the system. If the last part does not fit 13 characters, it is terminated with a null character (U+0000) and rest of name field must be filled with U+FFFF. LDIR_Ord must start at 1 and be recorded in descending order. The block of LFN+SFN are recorded on a contiguous entries. If any of these condition about LFN entry is not met, the LFN is invalid any longer.
      如果 LFN 超过 13 个字符,它将被分成一些 LFN 条目。LFN 的最大名称长度是 255,因此一个 LFN 最多可以容纳 20 个 LFN 条目。LFN 就在相关的 SFN 条目的前面。对于上面显示的示例,长度为 33 个字符的 LFN 由 3 个 LFN 条目组成,它们在 LDIR_Ord 中具有 0x43、0x02、0x01。LFN 使用的字符代码是 UTF-16 编码的 Unicode,而 SFN 的字符代码是本地代码页中的 ANSI/OEM 代码,具体取决于系统。如果最后一部分不适合 13 个字符,则以空字符(U+0000)结束,其余的名称字段必须用 U+FFFF 填充。LDIR_Ord 必须从 1 开始,并按降序记录。LFN+SFN 的区块记录在相邻的条目上。如果不满足关于 LFN 条目的任何一个条件,则 LFN 不再有效。

       如果文件的名称是 Unicode 或不遵循 MS-DOS 8.3 命名约定,则会分配其他目录条目来存储长文件名:补充条目位于文件的主条目之前。 下图显示了一个名为 “The quick brown fox.” 的文件的示例目录条目:系统创建了8.3 格式的名称 THEQUI~1 FOX (在目录条目中没有看到 “ . ” 因为它被认为是在第八个字符之后)并且使用了两个以上的目录条目来存储Unicode 长文件名; 图中的每一行由 16 个字节组成。
    在这里插入图片描述
      Furthermore, a check sum is used to make sure of relevance between LFN and SFN. Each LFN entry has a check sum of associated SFN in LDIR_Chksum. The check sum is generated in the algorithm shown below.
      此外,校验和用于确保 LFN 和 SFN 之间的相关性。 每个 LFN 条目都具有 LDIR_Chksum 中相关 SFN 的校验和。 校验和在下面显示的算法中生成。

    uint8_t create_sum (const DIR* entry)
    {
        int i;
        uint8_t sum;
    
        for (i = sum = 0; i < 11; i++) { /* Calculate sum of DIR_Name[] field */
            sum = (sum >> 1) + (sum << 7) + entry->DIR_Name[i];
        }
        return sum;
    }
    

      If any check sum in the LFN entries does not match, the LFN is invalid. This is to prevent wrong association due to any changes (delete, create or rename) to the direcotry by the non-LFN system. However, stray LFN entries continue to occupy the directory and the disk usage gets worse. This will be a problem at the fixed length directory (root directory on FAT12/16 volume). These garbage entries are removed by disk utirities.
      如果 LFN 条目中的任何校验和不匹配,则 LFN 无效。 这是为了防止由于非 LFN 系统对目录的任何更改(删除,创建或重命名)导致的错误关联。 但是,杂散 LFN 条目继续占用目录,磁盘使用情况变得更糟。 这将是固定长度目录(FAT12/16 卷上的根目录)中的问题。 这些垃圾条目被磁盘删除。

    Namespace 命名空间

    Short File Name 短文件名

      SFN, often called the 8.3 format name, is a traditional style file name originally used on the MS-DOS in format of body (1-8 character) plus optional extension (1-3 characters). These two parts are separated with a dot (.). The allowable charactes for the SFN are ASCII alphanumerics, non-ASCII characters (\x80 - \xFF) and some ASCII marks ($ % ’ - _ @ ~ ` ! ( ) { } ^ # &).
      SFN,通常称为 8.3 格式名称,是最初在 MS-DOS 上使用的传统样式文件名,其格式为 SFN Body(1-8个字符). SFN Extension(1-3个字符)。 这两个部分用点(.)分隔。 SFN 的允许字符是 ASCII 字母和数字,非 ASCII 字符(\ x80 - \ xFF)和一些 ASCII 标记($%’ - _ @〜!(){} ^#&)。如下图所示:
    在这里插入图片描述
      SFN is stored in the SFN entry in OEM code set (used on MS-DOS) depends on the locale. Lower-case character in the file name is converted to upper-case and then stored or matched, so that the case information of SFN file name is lost.
      SFN 存储在 OEM 代码集中的 SFN 条目中(在 MS-DOS 上使用),这取决于系统区域设置。将文件名中的小写字符转换为大写字符,然后存储和匹配,从而丢失 SFN 的大小写信息。

    Long File Name 长文件名

      Length of LFN can be upto 255 characters. The allowable characters for the LFN are white space and some ASCII marks (+ , ; = [ ]) in addition to the SFN characters. Dots can be embedded anywhere in the file name except the trailing dots and spaces are truncated off on the file API. Leading spaces and dots are valid but some user interface, such as Windows common dialog, rejects such file name.
      LFN 的长度可以达到 255 个字符。 除了 SFN 字符外,LFN 还允许的字符是空格和一些 ASCII 标记(+,;=[])。点可以嵌入文件名的任何位置,但文件 API 中的尾随点和空格会被截断。前导空格和点是有效的,但是一些用户界面,如 Windows 公共对话框,拒绝这样的文件名。
      LFN is stored in the LFN entry as is without any process like SFN. Character code used by LFN is Unicode.
      LFN 存储在 LFN 条目中,无需进行大小写转换。 LFN 使用的字符编码是 Unicode。
      Because different character codes are used by SFN (OEM code set) and LFN (Unicode), generic implementation needs to convert those codes. This is not the matter on the OEM code is single byte code, however, when the OEM code page is in double byte character set (DBCS), a huge (several hundreds KB) conversion table is needed, so that it is difficult to implement LFN in the small embedded systems with a limited memory.
      由于 SFN(OEM 代码集)和 LFN(Unicode)使用不同的字符代码,因此通常的实现中需要转换这些代码。 OEM 是单个字节编码并没有什么问题,但是,当 OEM 代码页是双字节字符集(DBCS)时,需要一个巨大的(几百KB)转换表,因此在具有有限的内存的小型嵌入式系统中很难实现 LFN 。

    Name Matching 名称匹配

      There are two format of file names, LFN and SFN. Both file name for the file is generated at a time. A file name is unique in the directory and never matchs with any name no matter between different formats. LFN can contain lower-case characters and matched in case insensitive, so that “LongFileName.Txt”, “longfilename.txt”, “LONGFILENAME.TXT” these three names match each other. Therfore name matching on directory search are done in case insensitive.
      文件名有两种格式,LFN 和 SFN。文件的两个文件名同时生成。文件名在目录中是唯一的,并且即使在不同格式之间都不会与任何名称匹配。 LFN 可以包含小写字符并且在不区分大小写的情况下匹配,因此“LongFileName.Txt”,“longfilename.txt”,“LONGFILENAME.TXT” 这三个名称相互匹配。 目录搜索中的名称匹配是在不区分大小写的情况下完成的。
      When search a file with a file name that fits SFN format, Both LFNs and SFNs in the directory are checked for match. When search a file with a file name out of SFN format, only LFNs are checked for match.
      当搜索具有适合 SFN 格式的文件名的文件时,将检查目录中的 LFN 和 SFN 是否匹配。 搜索文件名超出SFN 格式的文件时,仅检查 LFN 是否匹配。
      The character code set on the file API would be either OEM code or Unicode. When it is in OEM code, some characters in the LFN may not able to be converted to OEM code. In this case, FAT driver should return SFN instead.
      文件 API 中设置的字符代码可以是 OEM 代码,也可以是 Unicode 代码。当使用 OEM 代码时,LFN 中的一些字符可能无法转换为 OEM 代码。在这种情况下,FAT 驱动程序应该返回 SFN。

    Generating SFN 生成 SFN

      On the LFN system, any fine name given to the file API needs to be used as LFN. SFN needs to be generated from the file name and the FAT driver should not allow to specify LFN and SFN individually. This is to avoid any confusion about file name between uses and applicaations, to achive consistency in the file name of a file and to avoid name conflict and any troublesome. SFN is generated as body(+numeric-tail)(+extension) in following procedure.
      在支持 LFN 的系统上,传递给文件 API 的任何良好名称都需要被视为 LFN。SFN 需要从输入文件名生成,FAT 驱动程序不应该允许单独指定 LFN 和 SFN。这是为了避免用户和应用程序之间文件名的混淆,实现文件名的一致性,避免文件名冲突和一些麻烦。SFN 作为 body(+ number -tail)(+extension) 在以下过程中生成。

    1. Trailing dots and spaces are truncated off if exist. (a precondition of file name on the FAT file system) 如果存在尾随点和空格,则将其截断。(FAT文件系统文件名的先决条件)
    2. If any space is exist, remove it and set lossy conversion flag. 如果存在任何空格,请删除它并设置有损转换标志。
    3. If any leading dot is exist, remove it and set lossy conversion flag. 如果存在任何前导点,请将其删除并设置有损转换标志。
    4. If two or more dots are exist, remove all dots except for last one and set lossy conversion flag. 如果存在两个或多个点,则删除除最后一个点以外的所有点并设置有损转换标志。
    5. If any character not allowed for SFN is exist, replace it with an underscore () and set lossy conversion flag. 如果存在任何不允许存在SFN的字符,请将其替换为下划线()并设置有损转换标志。
    6. Lower-case characters including non-ASCII characters are converted into upper-case. 包含非 ASCII 字符的小写字符将转换为大小写。
    7. When character code on the API is Unicode, convert it to OEM code set string. If any Unicode character could not be converted to OEM code, replace it with an underscore and set lossy conversion flag. 当 API 上的字符代码是 Unicode 时,将其转换为 OEM 代码集字符串。 如果无法将任何一个 Unicode 字符转换为 OEM 代码,请将其替换为下划线并设置有损转换标志。
    8. Fill 11-byte SFN output buffer with spaces. 用空格填充11字节SFN输出缓冲区。
    9. Creating SFN body. Copy from top of the LFN to the SFN body part in byte-by-byte until end of LFN, a dot is read or SFN body is full. If the LFN body is longer than 8 bytes, set lossy conversion flag. 创建 SFN 正文。 从 LFN 的顶部逐字节地复制到 SFN 主体部分,直到 LFN 结束或者找到点或者 SFN 主体已满。 如果 LFN 主体长于 8 个字节,则设置有损转换标志。
    10. Creating SFN extension. If a dot is exist, copy from next of dot to the SFN extension part in byte-by-byte until end of LFN or SFN extension is full. If the LFN extensiton is longer than 8 bytes, set lossy conversion flag. 创建 SFN 扩展。 如果存在点,则从点的下一个位置逐字节复制到 SFN 扩展部分,直到 LFN 结束或 SFN 扩展已满。 如果 LFN 扩展长度超过 3 个字节,请设置有损转换标志。

      Here an SFN as body(+extension) is created. If lossy conversion flag is set, it means the input file name does not fit 8.3 format and is not used for match. The lossy converted SFN cannot be used for new file creation. It needs to put a numeric-tail to the body to make it be unique. The format of the numeric-tail is ~n (n is 1-6 digit decimal). The value needs to be changed if the SFN conflicts with an existing SFN entry in the directory. It is typically searched in the order from 1, but it depends on implementation. For example, Windows NT family uses any hash value at 5th trial.
      以上步骤创建一个 SFN 的主体部分(+ 扩展名)。 如果设置了有损转换标志,则表示输入文件名不是 8.3 格式,不能用于匹配和记录。 有损转换的 SFN 不能用于新文件创建。 它需要在主体上添加一个数字尾部,以使 SFN 在目录中唯一。 数字尾的格式是 ~n(n是1-6位十进制数)。 需要截断名称正文以添加数字尾部。 通常以 〜1 的顺序搜索唯一名称,但这取决于实现。 例如,Windows NT 系列在第 5 次试用时使用了一些哈希值。

    Suppressing LFN Entry 抑制 LFN 条目

      When the file name is in 8.3 format, generated SFN becomes same as the LFN (except for upper-case conversion). In this case, the LFN entry is suppressed and not created if the follwing conditions each is true.
      当文件名为 8.3 格式时,生成的 SFN 与 LFN 相同(大小写转换除外)。 在这种情况下,如果下面的两个条件都为真,则可以抑制 LFN 条目,而不创建 LFN 条目。

    • Does not contain lower-case character, 不包含任何小写字符,
    • and does not contain any non-ASCII character. 并且不包含任何非 ASCII 字符。

    For example, “HELLO.TXT” is the case. On the Window NT family, also following condition is tested.
    例如,“HELLO.TXT” 就是这种情况。 在 Window NT 系列上,还测试了以下条件。

    • Either or both of body and extension contains any lower-case character, 正文和扩展中的任何一个或两个都包含任何小写字符,
    • and both of body and extension are not mixed-case, 正文和扩展都不是大小写混合的,
    • and does not contain any non-ASCII character. 并且不包含任何非 ASCII 字符。

      If it is the case, lower capital information is stored in the DIR_NTRes of SFN entry and the LFN entry is suppressed. The file name satisfies this condition, such as “lower12.dll”, “system32”, “FDCMD.exe”, is very common for most existing files. This enables to save the space of direcrory. On the some systems, such as Windows 9X family, DIR_NTRes field is not supported and these entries are recognized as old SFN entries and the files will appear in the directory listing as “LOWER12.DLL”, “SYSTEM32”, “FDCMD.EXE”. It is not a problem because name matching is done in case insensitive on the FAT file system. However, it can confuse some Unix based application running on the Windows 9X family OS when it refers a volume written by Window NT family OS.
      如果是以上说的这种情况,则较低的资本信息记录在 SFN 条目的 DIR_NTRes 中,并且 LFN 条目被抑制。 文件名满足此条件,例如 “lower12.dll”,“system32”,“FDCMD.exe”,对于大多数现有文件来说非常常见。 这样可以节省可怕的空间。 在某些 LFN 感知系统(如 Windows 9X 系列)上,不支持 DIR_NTRes 字段,这些条目被识别为旧的 SFN 条目,文件将在目录列表中显示为 “LOWER12.DLL”,“SYSTEM32”,“FDCMD.EXE”。 这不是问题,因为名称匹配是在 FAT 文件系统不区分大小写的情况下完成的。 但是,当它引用 由Window NT 系列操作系统编写的卷时,它可能会混淆在 Windows 9X 系列操作系统上运行的某些基于 Unix 的应用程序。

    Compatibility 兼容性

    Non LFN Aware System 非 LFN 感知系统

      The support of LFN is most important on the fixed disks, however it is supported on removable media as well. The removavle media is shared by various systems with or without support for LFN, so that the downward compatibility is important for the implementation of LFN and it provides support for LFN without breaking compatibility with the existing FAT format. An FAT volume with any LFN exists can be read by down level systems without any compatibility problems. An exsisting FAT volume does not need to go through any comversion process prior to start using LFN and any current files remain not modified. The LFN entry is added on a long name is created. When rename a current file with LFN, the SFN entry will be moved within the directory to create an entry block. The LFN entries are hidden at the generic file APIs on the down level systems and it does not cause any problem on geneic use. The user can read any file with 8.3 format name and put a new file without any side effect.
      LFN 的支持在固定磁盘上最为重要,但它也支持可移动媒体。 在支持或不支持 LFN 的情况下,各种系统共享可移除媒体,因此向下兼容性对于 LFN 的实现是重要的,并且它提供对 LFN 的支持而不破坏与现有 FAT 格式的兼容性。 具有任何 LFN 的 FAT 卷可以由下级系统读取而没有任何兼容性问题。 在开始使用 LFN 之前,现有的 FAT 卷不需要经历任何修改过程,并且任何当前文件都不会被修改。 LFN 条目添加在创建的长名称上。 使用 LFN 重命名当前文件时,SFN 条目将在目录中移动以创建条目块。 LFN条目隐藏在下层系统的通用文件API中,并且不会对基因使用造成任何问题。 用户可以使用 8.3 格式名称读取任何文件,并放置一个没有任何副作用的新文件。
      Down level systems do not aware of existence of LFN, so that some LFN entry can be broken by a directory operation. For instance, when a file with LFN is renamed, LDIR_Chksum in the LFN entries gets mismatch and as the result the LFN will be lost. Renaming or deleting volume label can break some LFN entry as well. This is unfortunate, but the file data itself is kept safe.
      低层系统不知道LFN的存在,因此一些LFN条目可以被目录操作破坏。 例如,当重命名具有LFN的文件时,LFN条目中的LDIR_Chksum变得不匹配,结果LFN将丢失。 重命名或删除卷标也可以打破一些LFN条目。 这很不幸,但文件数据本身是安全的。

    Upper-case Conversion of Japanese MS-DOS 日语 MS-DOS 的大写转换

      Upper-case conversion for SFN is applied to non-ASCII characters as well. However, it is not applied to non-ASCII characters on the Japanese MS-DOS and non-ASCII characters are stored without upper-case conversion. It is changed at Windows NT family and it creates SFN entry with upper-case conversion for all charactres. As the result, it brings a serious compatibility problem on us. For instance, create a file “Fat.TXT” (name body is non-ASCII full-width character) on the MS-DOS. And then mount the volume on the Windows XP, and the file is no longer accessible. This is because Windows NT family finds the SFN entry with upper-case converted name “FAT.TXT” and it never matches the SFN created by MS-DOS. The only workaround is to avoid using such file name. Also Windows 9X family creates the SFN without upper-case converson, but it is not the problem because LFN entry is created and it can be opened on the Windows NT family.
      SFN 的大写转换也适用于非ASCII字符。 但是,它不适用于日语MS-DOS上的非ASCII字符,并且存储非ASCII字符而不进行大写转换。 它在Windows NT系列中进行了更改,它为所有字符创建了带大写转换的SFN条目。 结果,它给我们带来了严重的兼容性问题。 例如,在MS-DOS上创建一个文件“Fat.TXT”(名称正文是非ASCII全角字符)。 然后在Windows XP上安装卷,则无法再访问该文件。 这是因为Windows NT系列找到具有大写转换名称“FAT.TXT”的SFN条目,它永远不会匹配MS-DOS创建的SFN。 唯一的解决方法是避免使用此类文件名。 此外,Windows 9X系列创建没有大写转换的SFN,但这不是问题,因为创建了LFN条目并且可以在Windows NT系列上打开它。

    Differnet OEM Code Page 不同的OEM代码页

      Some OEM code pages are in DBCS. The trailing byte of a double-byte character can match any illigal character for file name, especially most FAT driver uses \ (\x5C) for directory separator for the path name. If the file name contains such character, the file will not able to be accessed on the system with SBCS. There is similar ploblem between SBCS systems due to upper-case conversions of non-ASCII characters which differ between each SBCS systems. When exchange files between the systems with different code page, any file name with non-ASCII character should not be used.
      某些OEM代码页位于DBCS中。 双字节字符的尾随字节可以匹配文件名的任何illigal字符,尤其是大多数FAT驱动程序使用\(\ x5C)作为路径名的目录分隔符。 如果文件名包含此类字符,则无法在具有SBCS的系统上访问该文件。 由于每个SBCS系统之间不同的非ASCII字符的大写转换,SBCS系统之间存在类似的问题。 在具有不同代码页的系统之间交换文件时,不应使用任何具有非ASCII字符的文件名。
      There is no problem on the LFN because file name is stored on the directory in Unicode. However, when character code on the file API is OEM code (this is incomplete support for LFN), some problems related to different code page can occuer.
      LFN没有问题,因为文件名以Unicode格式存储在目录中。 但是,当文件API上的字符代码是OEM代码时(这是对LFN的不完全支持),可能会出现与不同代码页相关的一些问题。

    Mac OS X

      Mac OS X supports the file names with trailing dots or spaces and it can mount the FAT volume as well. However, such file name is not allowed on the FAT volume. If a file to be created on the FAT volume is such name, Mac OS X replace the last character with an escape character (space:U+F028, dot:U+F029). Application program needs to consider it when exchange the file between Mac and another systems via a removable media.

    Physical Drive Partitioning 物理驱动器分区

      This is not related to the FAT filesystem, but it is a basis of disk usage. You need to know when write a FAT driver for embedded systems.
      这与FAT文件系统无关,但它是磁盘使用的基础。 您需要知道何时为嵌入式系统编写FAT驱动程序。
      To use the huge disk space of harddisk drive efficiently, it is often used in divided into some partitions. For example, divide a 10 GB harddisk into 3 partitions, 1, 3 and 6 GB, and create volumes for swap, system and data. For generic use, only one partition is created and used in one volume per disk drive.
      为了有效地利用硬盘驱动器的巨大磁盘空间,常常将其划分为若干分区。例如,将一个10gb的硬盘划分为3个分区,1、3和6 GB,并为交换、系统和数据创建卷。对于一般使用,每个磁盘驱动器在一个卷中只创建和使用一个分区。
      There are two partitioning rules, FDISK format and SFD format. The FDISK format is usually used for harddisk and memory card. It can divide a physical drive into one or more partitions with a partition table put on the MBR (maser boot record, the first sector of the physical drive). The SFD (super-floppy disk) format is non-partitioned disk format. The volume starts at the first sector of the physical drive without any disk partitioning. It is usually used for floppy disk, Microdrive, optical disk and most type of super-floppy media. Some systems support only either one of the two formats and the other is not supported.
      有两种分区规则,FDISK格式和SFD格式。 FDISK格式通常用于硬盘和存储卡。 它可以将物理驱动器划分为一个或多个分区,并将分区表放在MBR上(maser引导记录,物理驱动器的第一个扇区)。 SFD(超级软盘)格式是非分区磁盘格式。 卷从物理驱动器的第一个扇区开始,没有任何磁盘分区。 它通常用于软盘,Microdrive,光盘和大多数类型的超软盘介质。 某些系统仅支持两种格式中的一种,另一种不支持。
    MBR and Partition table

    Field nameOffsetSizeDescription
    MBR_bootcode0446Boot program. Depends on the system. Filled with zeros when not used.
    MBR_Partation144616Partition table enrty 1. Indicates partition type and status.
    MBR_Partation246216Partition table enrty 2.
    MBR_Partation347816Partition table enrty 3.
    MBR_Partation449416Partition table enrty 4.
    MBR_Sig51020xAA55. Indicates this is a valid MBR.

      Following table shows the field of partition table entry and upto four entry can be recorded in the MBR. This means a storage device can be divided four partitions. There is a type of partition which can contain some partitions in it, but for details of it, prease refer to others.

    Partition table entry

    Field nameOffsetSizeDescription
    PT_BootID01Boot indicator.
    Not bootable (0x00) or Bootable (0x80).
    Bootable is to make the system boots from this partition, but it is system dependent. Only one partition can be set to bootable.
    PT_StartHd11Indicates head number of partition start sector in CHS form (0 - 254).
    PT_StartCySc22Indicates cylinder number (bit9-0: 0-1023) and sector number in the cylinder (bit15-10: 1-63) of partition start sector in CHS form.
    PT_System41Type of this partition. Typical valuse are:
    0x00: Blank entry. Any other field must be zero.
    0x01: FAT12 (CHS/LBA, < 65536 sectors)
    0x04: FAT16 (CHS/LBA, < 65536 sectors)
    0x05: Extended partition (CHS/LBA)
    0x06: FAT12/16 (CHS/LBA, >= 65536 sectors)
    0x07: HPFS/NTFS/exFAT (CHS/LBA)
    0x0B: FAT32 (CHS/LBA)
    0x0C: FAT32 (LBA)
    0x0E: FAT12/16 (LBA)
    0x0F: Extended partition (LBA)
    PT_EndHd11Indicates head number of partition end sector in CHS form (0 - 254).
    PT_EndCySc22Indicates cylinder number (bit9-0: 0-1023) and sector number in the cylinder (bit15-10: 1-63) of partition end sector in CHS form.
    PT_LbaOfs84Indicates partition start sector in 32-bit LBA (1 - 0xFFFFFFFF).
    PT_LbaSize124Partition size in unit of sector (1 - 0xFFFFFFFF).

      Ecah partition occupy any part of drive without overlapping each other and the first sector of the partition is the VBR. In most case, only first entry is used and rest of entries are left blanked.

      There are two formart to express allocation of the partitions, CHS and LBA. Both parameters are stored on the entry. CHS field is used for the drives that have geometry, but this is actually depends on the system. LBA field is used for the drives controled in LBA. If the partition overlaps an area where cannot be expressed in CHA (8 GB and above), CHS field is no longer valid and only LBA field can be used.

    参考

    1. 原文链接:http://elm-chan.org/docs/fat_e.html
    2. https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#CLUST_0
    3. http://www.ntfs.com/fat-filenames.htm#Folder Entries
    4. http://www.cse.scu.edu/~tschwarz/COEN252_09/Lectures/FAT.html
    5. http://www.c-jump.com/CIS24/Slides/FAT/lecture.html
    展开全文
    ZCShouCSDN 2019-07-28 08:53:13
  • hebtu666 2021-04-11 01:11:23
  • github_39577257 2020-05-22 21:33:23
  • beiya123 2017-03-09 11:33:41
  • mmoaay 2015-10-27 10:29:25
  • Eastmount 2021-11-22 19:27:16
  • wzy0623 2020-09-29 14:37:17
  • weixin_33315077 2021-02-28 15:24:58
  • lb812913059 2018-03-27 19:57:54
  • wangwangli6 2020-03-09 11:04:01
  • baidu_19620507 2020-04-30 12:08:38
  • qq_43532054 2020-11-15 13:52:10
  • java_java_cl 2020-07-17 17:20:47
  • bisal 2013-10-14 13:39:46
  • m0_37989980 2020-02-21 19:57:24
  • a4221722 2016-08-25 17:30:15
  • qq_39223444 2021-08-18 20:17:59
  • w397090770 2021-01-19 09:00:00
  • qq_29277155 2016-10-23 10:46:14
  • tq6791868 2019-07-16 21:38:23
  • beiya123 2018-01-09 18:30:00
  • c_programj 2021-06-01 21:04:05
  • heng139 2020-03-17 10:20:42
  • llooyyuu 2020-04-23 15:23:56

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,961
精华内容 7,184
关键字:

修复文件头数据与类型不匹配