OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9586|回复: 11

关于文件系统的根目录簇号的一个疑问。

[复制链接]

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2013-7-15
在线时间
4 小时
发表于 2013-7-28 18:30:49 | 显示全部楼层 |阅读模式
     最近这几天在啃代码,看到文件系统时。遇到一个问题。原子哥,给的资料,《fat文件系统原理》中有这么一段话。  
FAT16 文件系统从根目录所占的 32 个扇区之后的第一个扇区开始以簇为单位进行数据的处理,这之前仍以扇区为单位。对于根目录之后的第一个簇,系统并不编号为第 0 簇或第 1 簇 (可能是留作关键字的原因吧),而是编号为第 2簇,也就是说数据区顺序上的第 1 个簇也是编号上的第 2 簇。
     正如上面说说的,对于根目录之后的第一个簇,系统编号为第2簇。但是为什么我看fat代码的时候,是说fat16,根目录簇号为2。代码如下:(我用红色标出的那一句)
unsigned char FAT_Init(void)//Initialize of FAT  need initialize SD first
{      
 bootsector710 *bs  = 0;       //定义DBR结构体,包含BPB部分(12~90字节是BPB)
 bpb710        *bpb = 0;       //定义BPB结构体    
 partrecord    *pr  = 0;       //定义硬盘信息 结构休      (16字节)
 DWORD hidsec=0;             //隐藏的扇区数即为DBR在物理扇区的偏移量
 long long Capacity;  
 Capacity =(long long)SD_GetSectorCount()*512;   //得到SD容量,单位为字节           
 if(Capacity<0xff)return 1;      
 
 if(SD_ReadDisk(fat_buffer,0,1))return 2; //读物理扇区0。即MBR(其中MBR内的硬盘分区表中有DBR的地址信息),如没有MBR,则为DBR。经测试,我的SD卡是有MBR的
 if(fat_buffer[0]!=0XEB&&fat_buffer[0]!=0XE9)  //如物理0扇区第一字节不为0XEB或0XE9,则存在MBR,否则不存在
  {        
  //printf("此SD卡的物理扇区0为MBR\n");
  pr = (partrecord *)((partsector *)fat_buffer)->psPart;//first partition       第一分区
  hidsec=pr->prStartLBA;   //隐藏的扇区 即DBR的物理扇区偏移
  //printf("此SD卡的DBR的物理扇区为=%d\n",hidsec) ;
 }
 else
 {
  hidsec=0;      //无MBR,物理扇区0即为DBR
  //printf("此SD卡不存在MBR,物理扇区0即为DBR,物理扇区0即为逻辑扇区0.\n");
  }
 if(SD_ReadDisk(fat_buffer,hidsec,1))return 3;
 //printf("DBR物理扇区偏移量:%d \n",hidsec);
 bs = (bootsector710 *)fat_buffer;
 bpb = (bpb710 *)bs->bsBPB;
 if(bpb->bpbFATsecs)//detemine thd FAT type  do not support FAT12
 {
  FAT32_Enable=0;        //FAT16
  FATsectors     = bpb->bpbFATsecs; //FAT表占用的扇区数
  FirstDirClust = 2;       //为什么是2,到底是根目录的簇号是2,还是根目录以后的一个数据区的簇号是2
 }
 else
 {
  FAT32_Enable=1;        //FAT32
  FATsectors     = bpb->bpbBigFATsecs;//FAT占用的扇区数
  FirstDirClust = bpb->bpbRootClust;
 }  
 BytesPerSector   = bpb->bpbBytesPerSec;          //每扇区字节数
 SectorsPerClust   = (BYTE)bpb->bpbSecPerClust;    //每簇扇区数
 FirstFATSector   = bpb->bpbResSectors+hidsec;    //第一个FAT表扇区
 RootDirCount   = bpb->bpbRootDirEnts;           //根目录项数
 RootDirSectors   = (RootDirCount*32)>>9;          //根目录占用的扇区数
 FirstDirSector   = FirstFATSector+bpb->bpbFATs*FATsectors; //第一个目录扇区
 FirstDataSector   = FirstDirSector+RootDirSectors;   //第一个数据扇区
 //printf("每扇区字节数:%d \n",BytesPerSector);
 //printf("每簇扇区数:%d \n",SectorsPerClust);
 //printf("第一个FAT表扇区:%d \n",FirstFATSector);
 //printf("根目录项数:%d \n",RootDirCount);
 //printf("根目录占用的扇区数:%d \n",RootDirSectors);
 return 0;  
}  

我现在都搞不明白到底,簇2是从哪一个开始了。还请高手解答。小弟菜鸟。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2013-7-15
在线时间
4 小时
 楼主| 发表于 2013-7-28 18:48:14 | 显示全部楼层
FirstDirClust 这个变量,源代码里面注释为根目录簇号。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-28 19:41:25 | 显示全部楼层
我现在转投fatfs了...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2013-7-15
在线时间
4 小时
 楼主| 发表于 2013-7-28 20:05:29 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
哎,就这么一个小地方有点疑问。不知道簇号2 是从根目录开始,还是从根目录以后的数据区开始的。按照文档那段话来说,应该是从数据区开始的。但是代码里面说根目录簇号是2,很疑惑。希望论坛里面有人知道能解答吧。
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-28 20:20:12 | 显示全部楼层
回复【4楼】llfsunshine:
---------------------------------
根目录就是在第2簇
回复 支持 反对

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2013-7-15
在线时间
4 小时
 楼主| 发表于 2013-7-28 21:08:08 | 显示全部楼层
回复【5楼】ximilenfu:
---------------------------------
那《fat文件系统原理》中,这段话是错的?
FAT16 文件系统从根目录所占的 32 个扇区之后的第一个扇区开始以簇为单位进行数据的处理,这之前仍以扇区为单位。对于根目录之后的第一个簇,系统并不编号为第 0 簇或第 1 簇 (可能是留作关键字的原因吧),而是编号为第 2簇,也就是说数据区顺序上的第 1 个簇也是编号上的第 2 簇。
他说数据区第一个簇编号是2簇。我很疑惑。是不是这个文档他写错了?
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-28 21:57:27 | 显示全部楼层
回复【6楼】llfsunshine:
-------------------------
数据区放置根目录的开始簇,目录项的开始簇,文件的开始簇(这三种一般从第二簇开始),还有存放数据
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-29 18:12:31 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥,FAT32的BPB是不支持含有根目录项数(只对FAT12/16有用)(在FAT文件系统原理的17页),而你的代码里却用到了根目录项数求数据扇区数,而好像FAT32没明确划分数据扇区数(虽然经常是从第4簇开始)
你的代码:RootDirCount   = bpb->bpbRootDirEnts;//根目录下目录项数       //根目录项数
  RootDirSectors   = (RootDirCount*32)>>9;//根目录所占用的扇区数       //根目录占用的扇区数
  FirstDirSector   = FirstFATSector+bpb->bpbFATs*FATsectors; //第一个目录扇区
  FirstDataSector   = FirstDirSector+RootDirSectors; //第一个数据扇区
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-29 22:31:27 | 显示全部楼层
回复【8楼】ximilenfu:
---------------------------------
这个我已经放弃了...
现在全部改用fatfs.mini板虽然还在用这个代码,但是现在已经着手在改了,预计再过两个月就会发布mini板的全新例程了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-29 22:50:42 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------

好啊好哈,FAT32文件系统中没有“创建目录”,“创建文件”,“追加数据”,“文件定位”,fatfs要是有这些功能就好了,期待。。。。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-29 23:23:00 | 显示全部楼层
回复【10楼】ximilenfu:
---------------------------------
fatfs都有的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-29 23:44:27 | 显示全部楼层
回复【11楼】正点原子:
---------------------------------
原子哥太给力了。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-16 03:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表