⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paul's 8051 code library understanding the fat32 filesystem.htm

📁 开放ATA,IDE,CF卡驱动必备手册
💻 HTM
📖 第 1 页 / 共 4 页
字号:
    <TD align=right>16 Bits</TD>
    <TD>Always 0xAA55</TD></TR></TBODY></TABLE>
<P>After checking the three fields to make sure the filesystem is using 512 byte 
sectors, 2 FATs, and has a correct signature, you may want to "boil down" these 
variables read from the MBR and Volume ID into just four simple numbers that are 
needed for accessing the FAT32 filesystem. Here are simple formulas in C syntax: 

<P><PRE>(unsigned long)fat_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors;
(unsigned long)cluster_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors + (Number_of_FATs * Sectors_Per_FAT);
(unsigned char)sectors_per_cluster = BPB_SecPerClus;
(unsigned long)root_dir_first_cluster = BPB_RootClus;
</PRE>
<P>As you can see, most of the information is needed only to learn the location 
of the first cluster and the FAT. You will need to remember the size of the 
clusters and where the root directory is located, but the other information is 
usually not needed (at least for simply reading files). 
<P>If you compare these formulas to the ones in Microsoft's specification, you 
should notice two differences. They lack "RootDirSectors", because FAT32 stores 
the root directory the same was as files and subdirectories, so RootDirSectors 
is always zero with FAT32. For FAT16 and FAT12, this extra step is needed to 
compute the special space allocated for the root directory. 
<P>Microsoft's formulas do not show the "Partition_LBA_Begin" term. Their 
formulas are all relative to the beginning of the filesystem, which they don't 
explicitly state very well. You must add the "Partition_LBA_Begin" term found 
from the MBR to compute correct LBA addresses for the IDE interface, because to 
the drive the MBR is at zero, not the Volume ID. 
<P>The rest of this page will usually refer to "fat_begin_lba", 
"cluster_begin_lba", "sectors_per_cluster", and "root_dir_first_cluster", rather 
than the individual fields from the MBR and Volume ID, because it is easiest to 
compute these numbers when starting up and then you no longer need all the 
details from the MBR and Volume ID. 
<TABLE cellSpacing=4 cellPadding=10 width="30%" align=right>
  <TBODY>
  <TR bgColor=#e8e8e8>
    <TD>
      <CENTER>
      <H3>Bad Sectors</H3></CENTER>In the old days, disk drives had "bad" 
      sectors. Brand new drives would often have several bad sectors, and as the 
      drive was used (or abused), additional sectors would become unusable. 
      <P>The FAT filesystems are designed to handle bad sectors. This is done by 
      storing two identical copies of the File Allocation Table. The idea is 
      that if a sector within one FAT becomes bad, the corresponding sector in 
      the other FAT will (hopefully) still be good. 
      <P>Bad sectors within the clusters are handled by storing a special code 
      within the FAT entry that represents the cluster that contains the bad 
      sector. If a file happened to be using that cluster, well, you lost part 
      of the file's data, but at least that cluster would be marked as bad so 
      that it would never be used again. The initial formatting of the disk 
      would write and read every sector and mark the bad clusters before they 
      could be used, so data loss could only occur when a previously-good sector 
      became bad. 
      <P>Fortunately, bad sectors today are only a distant memory, at least on 
      hard drives. Modern drives still internally experience media errors, but 
      they store <A 
      href="javascript:if(confirm('http://www.siam.org/siamnews/mtc/mtc193.htm%20%20\n\nThis%20file%20was%20not%20retrieved%20by%20Teleport%20Pro,%20because%20it%20is%20addressed%20on%20a%20domain%20or%20path%20outside%20the%20boundaries%20set%20for%20its%20Starting%20Address.%20%20\n\nDo%20you%20want%20to%20open%20it%20from%20the%20server?'))window.location='http://www.siam.org/siamnews/mtc/mtc193.htm'" 
      tppabs="http://www.siam.org/siamnews/mtc/mtc193.htm">Reed-Solomon error 
      correcting codes</A> for every sector. Sector data can be interleaved and 
      distributed over a wide area, so a physical defect (localized to one 
      place) can damage only a small part of many sectors, rather than all of a 
      few sectors. The error correction can easily recover the few missing bits 
      of each sector. Error correction also dramatically increases storage 
      capacity (despite using space to store redundant data), because the bits 
      can be packed so close together that a small number of errors begin to 
      occur, and the error correction fixes them. 
      <P>All modern drives also include extra storage capacity that is used to 
      <A 
      href="javascript:if(confirm('http://www.pcguide.com/ref/hdd/geom/format_Defect.htm%20%20\n\nThis%20file%20was%20not%20retrieved%20by%20Teleport%20Pro,%20because%20it%20is%20addressed%20on%20a%20domain%20or%20path%20outside%20the%20boundaries%20set%20for%20its%20Starting%20Address.%20%20\n\nDo%20you%20want%20to%20open%20it%20from%20the%20server?'))window.location='http://www.pcguide.com/ref/hdd/geom/format_Defect.htm'" 
      tppabs="http://www.pcguide.com/ref/hdd/geom/format_Defect.htm">automatically 
      remap damaged sectors</A>. When a sector is read and too many of the bits 
      needed error correction, the controller in the drive will "move" that 
      sector to a fresh portion of the space set aside for remapping sectors. 
      Remapping also dramatically reduces the cost of disk drives, because small 
      but common defects in manufacturing don't impact overall product quality. 
      <P>Because all modern drives use sophisticated error correction to 
      automatically detect and (almost always) correct for media errors, bad 
      sectors are virtually never seen at the IDE interface level. 
  </P></TD></TR></TBODY></TABLE>
<TABLE>
  <H2>How The FAT32 Filesystem Is Arranged</H2>The layout of a FAT32 filesystem 
  is simple. The first sector is always the Volume ID, which is followed by some 
  unused space called the reserved sectors. Following the reserved sectors are 
  two copies of the FAT (File Allocation Table). The remainder of the filesystem 
  is data arranged in "clusters", with perhaps a tiny bit of unused space after 
  the last cluster. 
  <P></P>
  <TBODY></TBODY></TABLE>
<TABLE width=432 align=center>
  <TBODY>
  <TR>
    <TD><IMG height=300 alt="Filesystem Layout Diagrag" 
      src="Paul's 8051 Code Library Understanding the FAT32 Filesystem.files/fat32_layout.gif" 
      width=420 
      tppabs="http://www.pjrc.com/tech/8051/ide/fat32_layout.gif"><BR><SMALL><B>Figure 
      5</B>: FAT32 Filesystem Overall Layout</SMALL></TD></TR></TBODY></TABLE>
<P>The vast majority of the disk space is the clusters section, which is used to 
hold all the files and directories. The clusters begin their numbering at 2, so 
there is no cluster #0 or cluster #1. To access any particular cluster, you need 
to use this formula to turn the cluster number into the LBA address for the IDE 
drive: 
<P><CODE>lba_addr = cluster_begin_lba + (cluster_number - 2) * 
sectors_per_cluster;</CODE> 
<P>Normally clusters are at least 4k (8 sectors), and sizes of 8k, 16k and 32k 
are also widely used. Some later versions of Microsoft Windows allow using even 
larger cluster sizes, by effectively considering the sector size to be some 
mulitple of 512 bytes. The FAT32 specification from Microsoft states that 32k is 
the maximum cluster size. 
<H2>Now If Only We Knew Where The Files Were....</H2>When you begin, you only 
know the first cluster of the root directory. Reading the directory will reveal 
the names and first cluster location of other files and subdirectories. A key 
point is that <FONT color=#b00000><B>directories only tell you how to find the 
first cluster number of their files and subdirectories</B></FONT>. You also 
obtain a variety of other info from the directory such as the file's length, 
modification time, attribute bits, etc, but a directory only tells you where the 
files begin. To access more than the first cluster, you will need to use the 
FAT. But first we need to be able to find where those files start. 
<P>In this section, we'll only briefly look at directories as much as is 
necessary to learn where the files are, then we'll look at how to access the 
rest of a file using the FAT, and later we'll revisit directory structure in 
more detail. 
<P>Directory data is organized in 32 byte records. This is nice, because any 
sector holds exactly 16 records, and no directory record will ever cross a 
sector boundry. There are four types of 32-byte directory records. 
<OL>
  <LI><B>Normal record with short filename</B> - Attrib is normal 
  <LI><B>Long filename text</B> - Attrib has all four type bits set 
  <LI><B>Unused</B> - First byte is 0xE5 
  <LI><B>End of directory</B> - First byte is zero </LI></OL>Unused directory 
records are a result of deleting files. The first byte is overwritten with 0xE5, 
and later when a new file is created it can be reused. At the end of the 
directory is a record that begins with zero. All other records will be non-zero 
in their first byte, so this is an easy way to determine when you have reached 
the end of the directory. 
<P>Records that do not begin with 0xE5 or zero are actual directory data, and 
the format can be determined by checking the Attrib byte. For now, we are only 
going to be concerned with the normal directory records that have the old 8.3 
short filename format. In FAT32, all files and subdirectories have short names, 
even if the user gave the file a longer name, so you can access all files 
without needing to decode the long filename records (as long as your code simply 
ignores them). Here is the format of a normal directory record: 
<P>
<TABLE width=592 align=center>
  <TBODY>
  <TR>
    <TD><IMG height=52 alt="Short Directory Entry" 
      src="Paul's 8051 Code Library Understanding the FAT32 Filesystem.files/dir_entry_short.gif" 
      width=581 
      tppabs="http://www.pjrc.com/tech/8051/ide/dir_entry_short.gif"><BR><SMALL><B>Figure 
      6</B>: 32 Byte Directory Structure, Short Filename 
  Format</SMALL></TD></TR></TBODY></TABLE>
<P>
<TABLE cellSpacing=0 cellPadding=4 align=center border=1>
  <TBODY>
  <TR>
    <TH>Field</TH>
    <TH>Microsoft's Name</TH>
    <TH>Offset</TH>
    <TH>Size</TH></TR>
  <TR>
    <TD>Short Filename</TD>
    <TD>DIR_Name</TD>
    <TD>0x00</TD>
    <TD align=right>11 Bytes</TH></TD>
  <TR>
    <TD>Attrib Byte</TD>
    <TD>DIR_Attr</TD>
    <TD>0x0B</TD>
    <TD align=right>8 Bits</TD></TR>
  <TR>
    <TD>First Cluster High</TD>
    <TD>DIR_FstClusHI</TD>
    <TD>0x14</TD>
    <TD align=right>16 Bits</TD></TR>
  <TR>
    <TD>First Cluster Low</TD>
    <TD>DIR_FstClusLO</TD>
    <TD>0x1A</TD>
    <TD align=right>16 Bits</TD></TR>
  <TR>
    <TD>File Size</TD>
    <TD>DIR_FileSize</TD>
    <TD>0x1C</TD>
    <TD align=right>32 Bits</TD></TR></TBODY></TABLE>
<P>The Attrib byte has six bits defined, as shown in the table below. Most 
simple firmware will check the Attrib byte to determine if the 32 bytes are a 
normal record or long filename data, and to determine if it is a normal file or 
a subdirectory. Long filename records have all four of the least significant 
bits set. Normal files rarely have any of these four bits set. 
<P>
<TABLE cellSpacing=0 cellPadding=4 align=center border=1>
  <TBODY>
  <TR>
    <TH>Attrib Bit</TH>
    <TH>Function</TH>
    <TH>LFN</TH>
    <TH>Comment</TH></TR>
  <TR>
    <TD>0 (LSB)</TD>
    <TD>Read Only</TD>
    <TD>1</TD>
    <TD>Should not allow writing</TD></TR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -