SD filesystem Research on TQ2440

step1: 读物理扇区,得到引导扇区(逻辑扇区0)的偏移地址。利用Read_Block读取0地址处512bytes.

struct partsector
{
    BYTE psPartCode[512-64-2];
    BYTE psPart[64];
    BYTE psBOOTSIG0;
    BYTE psBOOTSIG1;
#define psBOOTSIG0 0x55;
#define psBOOTSIG1 0xaa;
};

使用psPart处开始的64byte的前16byte.

struct partrecord //  16 字节
{           
    BYTE    prIsActive;                    // 0x80 代表该分区为缺省分区
    BYTE    prStartHead;                // 该分区入口的磁头地址
    WORD    prStartCylSect;           // 该分区入口的扇区地址和柱面地址
    BYTE    prPartType;                    // 该分区类型
    BYTE    prEndHead;                    // 该分区结束的扇区地址
    WORD    prEndCylSect;                // 该分区结束柱面地址
    DWORD    prStartLBA;                // 该分区内第一个扇区地址
    DWORD    prSize;                        // 该分区内包含的扇区总数
};

那么可以从prStartLBA读取引导扇区。为了后面的举例这里取prStartLBA=97;

step2:读取引导扇区,获取文件系统基本配置信息。利用Read_Block读取prStartLBA地址处512bytes.

struct bootsector710
{
    BYTE    bsJump[3];                    // 跳转指令
    BYTE    bsOEMName[8];                // 厂商标识和OS版本
    BYTE    bsBPB[53];                    // BIOS 参数块
    BYTE    bsExt[26];                    // 扩展BPB
    BYTE    bsBootCode[418];            // 引导扇区代码
    BYTE    bsBootSectSig2;               
    BYTE    bsBootSectSig3;
    BYTE    bsBootSectSig0;                // 引导扇区签名0x55
    BYTE    bsBootSectSig1;                // 引导扇区签名0xAA
#define BOOTSIG0        0x55
#define BOOTSIG1        0xaa
#define BOOTSIG2        0
#define BOOTSIG3        0
};

使用bsBPB开始的53个byte.

struct bpb710
{
        WORD    bpbBytesPerSec;    // 每扇区字节数
        BYTE      bpbSecPerClust;    // 每簇扇区数
        WORD    bpbResSectors;    // 保留区域中的保留扇区数
        BYTE      bpbFATs;        // FAT表的分数
        WORD    bpbRootDirEnts;    // 根目录项数
        WORD    bpbSectors;        // 存储卷上的的扇区总数
        BYTE      bpbMedia;        // 存储介质描述
        WORD    bpbFATsecs;        // FAT表所占的扇区数
        WORD    bpbSecPerTrack;    // 每道扇区数
        WORD    bpbHeads;        // 磁头数
        DWORD  bpbHiddenSecs;    //隐藏扇区数
        DWORD  bpbHugeSectors;    // 总扇区数
        DWORD  bpbBigFATsecs;//每个FAT所占扇区数
        WORD    bpbExtFlags;    //扩展标识
#define FATNUM    0xf           
#define FATMIRROR 0x80           
        WORD    bpbFSVers;    // 文件系统版本
#define FSVERS    0               
        DWORD  bpbRootClust;    //根目录簇号
        WORD    bpbFSInfo;    // 文件系统信息扇区号
        WORD      bpbBackup;    // 备份引导扇区
};

所以可以得到的信息有,并举例:

bpbBytesPerSec = 512;    // 每扇区字节数
bpbSecPerClust = 4;    // 每簇扇区数
bpbResSectors = 4,那么第一个FAT所在扇区为引导扇区(97)+保留扇区(4)=扇区101;    // 保留区域中的保留扇区数
bpbFATs=2,即有2个FAT表;        // FAT表的分数
bpbRootDirEnts = 512,表示根目录有512登记项,根目录大小固定为32个扇区;    // 根目录项数

bpbFATsecs = 242,表示每个FAT占用242个扇区;

Step3: 如何计算得到进一步的信息。

可以得到重要的信息有:

1.每个扇区多少字节

2.每个簇有多少扇区

3.保留扇区数

4.有多少个FAT表

5.根目录容许的登记项数目

6.每个FAT表多少个扇区

7.总的扇区数

8.文件系统类型

将要计算得到的重要信息:

主要是各个区的偏移地址。

1. FAT1地址为引导扇地址+保留扇区数

FAT1.offset = prStartLBA + bpbResSectors

2. 如果存在FAT2, 那么FAT2地址为FAT1偏移地址+每个FAT占扇区数

FAT2.offset = FAT1.offset + bpbFATsecs

3. FDT即根目录地址为FAT1+FAT表数*每个FAT占扇区数

FDT.offset = FAT1.offset + bpbFATs*  bpbFATsecs

step4: FDT表和FAT表的具体介绍,这将帮助我们寻找正确的簇。

首先FDT表,每个FDT表固定有32个扇区和512个文件登记信息,所以每个文件登记信息为32byte.

struct file_entry //32byte
{
    BYTE  file_name[8];
    BYTE  file_ext[3];
    BYTE  file_attri;
    BYTE  lower_case;
    BYTE  file_creat_ms;
    WORD  file_creat_time;
    WORD  file_creat_year_month;
    WORD  file_askfor;
    WORD  file_cluster_high16;
    WORD  file_revise_time;
    WORD  file_revise_year_month;
    WORD  file_start_cluster;
    DWORD file_length;
};

FDT表最重要的就是后6个byte。最后4个byte表数该文件长度,从而推断这个文件占用多少簇。倒数5到6这2个字节指明这个文件开始的簇号,知道文件的首簇号就可以查看FAT表的相应信息,就可得到该文件占用的所有簇的簇号。

其次FAT表记录每个数据簇的状态,且每个数据簇的状态占用2个字节

如果这2个字节等于0xFFFF,代表该簇已经被使用,并且文件在该数据簇中结束。

如果这2个字节等于0x0001-0xFFFE,代表该簇被使用,并且文件没有结束,文件的下一数据簇的簇号就等于这2个字节的大小。

这样就可以依次将文件的所有簇号获得并保存。

step5 : 依据FDT表给出的簇号读取文件。

(1) 从文件得到首簇号为0x2fe4,那么其在FAT中的位置为FAT地址(0xca00)+0x2fe4*2=0x129c8.

(2) 到0x129c8获取下一簇号为0x46f4, 那么下一簇地址为0xca00+0x46f4*2=0x157e8.

(3) 到0x157e8获取其值为0xFFFF,表明文件到此结束。

(4) 首先读取首簇号的文件内容,其内容地址为数据簇0地址(0x4c200)+0x2fe4*4*512 = 0x183e200,那么其扇区为0x183e200/512=49649,也就是说从49649开始到496512的4个扇区都是首数据簇给出的文件内容。

个人原创,转载的话请注明出处,^_^

转载于:https://www.cnblogs.com/artechliu/archive/2011/06/16/2082599.html

猜你喜欢

转载自blog.csdn.net/weixin_33728708/article/details/93938962
sd
今日推荐