1 | /**************************************************************************** |
---|
2 | * This file defines the implementation of a simplified FAT32 file system * |
---|
3 | * supported by the ALMOS-MKH boot-loader. * |
---|
4 | * * |
---|
5 | * This implementation only supports block devices with block (sector) * |
---|
6 | * size of 512 bytes (value stored in BPB_BYTSPERSEC, see below). The * |
---|
7 | * max size for a single file is 4Gb - 1. * |
---|
8 | * * |
---|
9 | * A cluster is a smallest storage allocatable unit on the block device: * |
---|
10 | * any file (or directory) occupies at least one cluster, and a given * |
---|
11 | * cluster cannot be shared by 2 different files. This implementation * |
---|
12 | * supports cluster size of 4Kb (8 sectors, value stored in * |
---|
13 | * BPB_SECPERCLUS, see below). * |
---|
14 | * * |
---|
15 | * For partitioned devices such as hard drives, the first sector of the * |
---|
16 | * drive is the Master Boot Record defining partitions, while the first * |
---|
17 | * sector of partitions formatted with a FAT file system is the boot * |
---|
18 | * sector (Volume Boot Record). * |
---|
19 | * * |
---|
20 | * Here is the layout of a partition formatted with a FAT32 file system: * |
---|
21 | * +--------------------------------------------------------------------+ * |
---|
22 | * | Reserved Region, composed of: | * |
---|
23 | * | - Boot Sector (i.e VBR, logical sector 0), | * |
---|
24 | * | - FS Information Sector (logical sector 1, value stored in | * |
---|
25 | * | BPB_FSINFO, see below), | * |
---|
26 | * | - Other reserved sectors (optional). | * |
---|
27 | * |--------------------------------------------------------------------| * |
---|
28 | * | FAT Region: contains the File Allocation Table which are maps | * |
---|
29 | * | of the Data Region, indicating which clusters are used by files | * |
---|
30 | * | and directories. | * |
---|
31 | * | This may contains two copies of the FAT data structure (value | * |
---|
32 | * | stored in BPB_NUMFATS, see below) for the sake of redundancy | * |
---|
33 | * | checking, although rarely used. | * |
---|
34 | * |--------------------------------------------------------------------| * |
---|
35 | * | Data Region: this is where the actual file and directory data | * |
---|
36 | * | stored. The Root Directory Table is stored in the first cluster | * |
---|
37 | * | of the Data Region (value stored in BPB_ROOTCLUS, see below). | * |
---|
38 | * +--------------------------------------------------------------------+ * |
---|
39 | ****************************************************************************/ |
---|
40 | |
---|
41 | #ifndef BOOT_FAT32_H |
---|
42 | #define BOOT_FAT32_H |
---|
43 | |
---|
44 | /**************************************************************************** |
---|
45 | * Various signature values. * |
---|
46 | * Warning: don't forget that little-endian representation must be assumed * |
---|
47 | ****************************************************************************/ |
---|
48 | |
---|
49 | #define BOOT_SIGNATURE 0xAA55 |
---|
50 | #define FSI_SIGNATURE1 0x41615252 |
---|
51 | #define FSI_SIGNATURE2 0x61417272 |
---|
52 | #define FSI_SIGNATURE3 0xAA550000 |
---|
53 | |
---|
54 | /**************************************************************************** |
---|
55 | * Master Boot Record structure. * |
---|
56 | ****************************************************************************/ |
---|
57 | |
---|
58 | /* Boot code (first 446 bytes). */ |
---|
59 | |
---|
60 | /* Partition table (64 bytes). */ |
---|
61 | /* offset | size (both in bytes) */ |
---|
62 | #define FIRST_ENTRY_ACTIVE 446, 1 /* Status of first partition. */ |
---|
63 | #define FIRST_ENTRY_CHSFRST 447, 3 /* CHS address of first sector. */ |
---|
64 | #define FIRST_ENTRY_TYPE 450, 1 /* First partition type. */ |
---|
65 | #define FIRST_ENTRY_CHSLST 451, 3 /* CHS address of last sector. */ |
---|
66 | #define FIRST_ENTRY_LBAFRST 454, 4 /* LBA of first sector. */ |
---|
67 | #define FIRST_ENTRY_SIZE 458, 4 /* Count of sectors in partition. */ |
---|
68 | |
---|
69 | #define SECOND_ENTRY_ACTIVE 462, 1 /* Status of second partition. */ |
---|
70 | #define SECOND_ENTRY_CHSFRST 463, 3 /* CHS address of first sector. */ |
---|
71 | #define SECOND_ENTRY_TYPE 466, 1 /* Second partition type. */ |
---|
72 | #define SECOND_ENTRY_CHSLST 467, 3 /* CHS address of last sector. */ |
---|
73 | #define SECOND_ENTRY_LBAFRST 470, 4 /* LBA of first sector. */ |
---|
74 | #define SECOND_ENTRY_SIZE 474, 4 /* Count of sectors in partition. */ |
---|
75 | |
---|
76 | #define THIRD_ENTRY_ACTIVE 478, 1 /* Status of third partition. */ |
---|
77 | #define THIRD_ENTRY_CHSFRST 479, 3 /* CHS address of first sector. */ |
---|
78 | #define THIRD_ENTRY_TYPE 482, 1 /* Third partition type. */ |
---|
79 | #define THIRD_ENTRY_CHSLST 483, 3 /* CHS address of last sector. */ |
---|
80 | #define THIRD_ENTRY_LBAFRST 486, 4 /* LBA of first sector. */ |
---|
81 | #define THIRD_ENTRY_SIZE 490, 4 /* Count of sectors in partition. */ |
---|
82 | |
---|
83 | #define FOURTH_ENTRY_ACTIVE 494, 1 /* Status of fourth partition. */ |
---|
84 | #define FOURTH_ENTRY_CHSFRST 495, 3 /* CHS address of first sector. */ |
---|
85 | #define FOURTH_ENTRY_TYPE 498, 1 /* Fourth partition type. */ |
---|
86 | #define FOURTH_ENTRY_CHSLST 499, 3 /* CHS address of last sector. */ |
---|
87 | #define FOURTH_ENTRY_LBAFRST 502, 4 /* LBA of first sector. */ |
---|
88 | #define FOURTH_ENTRY_SIZE 506, 4 /* Count of sectors in partition. */ |
---|
89 | |
---|
90 | /* Signature (last 2 bytes). */ |
---|
91 | /* offset | size (both in bytes) */ |
---|
92 | #define MBR_SIGNATURE_POS 510, 2 /* Boot signature. */ |
---|
93 | |
---|
94 | /**************************************************************************** |
---|
95 | * Boot Sector structure. * |
---|
96 | ****************************************************************************/ |
---|
97 | |
---|
98 | /* First 11 bytes. */ |
---|
99 | /* offset | size (both in bytes) */ |
---|
100 | #define BS_JMPBOOT 0, 3 /* Jump instruction to boot code. */ |
---|
101 | #define BS_OEMNAME 3, 8 /* OEM identifier (meaningless). */ |
---|
102 | |
---|
103 | /* BIOS Parameter Block (next 25 bytes). */ |
---|
104 | /* offset | size (both in bytes) */ |
---|
105 | #define BPB_BYTSPERSEC 11, 2 /* Bytes per logical sector. */ |
---|
106 | #define BPB_SECPERCLUS 13, 1 /* Logical sectors per cluster. */ |
---|
107 | #define BPB_RSVDSECCNT 14, 2 /* Count of reserved sectors. */ |
---|
108 | #define BPB_NUMFATS 16, 1 /* Count of File Allocation Tables. */ |
---|
109 | #define BPB_ROOTENTCNT 17, 2 /* Must be 0 for FAT32. */ |
---|
110 | #define BPB_TOTSEC16 19, 2 /* Total sectors count on 16 bits. */ |
---|
111 | #define BPB_MEDIA 21, 1 /* Media descriptor. */ |
---|
112 | #define BPB_FATSZ16 22, 2 /* Must be 0 for FAT32. */ |
---|
113 | #define BPB_SECPERTRK 24, 2 /* Sectors per track for INT 0x13. */ |
---|
114 | #define BPB_NUMHEADS 26, 2 /* Number of heads for INT 0x13. */ |
---|
115 | #define BPB_HIDDSEC 28, 2 /* Hidden sectors preceding the |
---|
116 | partition that contains this FAT |
---|
117 | volume. */ |
---|
118 | #define BPB_TOTSEC32 32, 4 /* Total sectors count on 32 bits. */ |
---|
119 | |
---|
120 | /* FAT32 Extended BIOS Parameter Block (next 28 bytes). */ |
---|
121 | /* offset | size (both in bytes) */ |
---|
122 | #define BPB_FATSZ32 36, 4 /* Sectors per FAT on 32 bits. */ |
---|
123 | #define BPB_EXTFLAGS 40, 2 /* Mirroring flags. */ |
---|
124 | #define BPB_FSVER 42, 2 /* Version. */ |
---|
125 | #define BPB_ROOTCLUS 44, 4 /* Number of first cluster of the |
---|
126 | root directory. */ |
---|
127 | #define BPB_FSINFO 48, 2 /* Logical sector number of FS |
---|
128 | Information Sector. */ |
---|
129 | #define BPB_BKBOOTSEC 50, 2 /* Logical sector of Backup Boot |
---|
130 | Sector. */ |
---|
131 | #define BPB_RESERVED 52, 12 /* Reserved for future expansion. */ |
---|
132 | |
---|
133 | /* FAT12/FAT16 Extended BIOS Parameter Block (next 26 bytes). */ |
---|
134 | /* offset | size (both in bytes) */ |
---|
135 | #define BS_DRVNUM 64, 1 /* INT 0x13 drive number. */ |
---|
136 | #define BS_RESERVED1 65, 1 /* Reserved. */ |
---|
137 | #define BS_BOOTSIG 66, 1 /* Extended boot signature. */ |
---|
138 | #define BS_VOLID 67, 4 /* Volume ID (serial number). */ |
---|
139 | #define BS_VOLLAB 71, 11 /* Volume label. */ |
---|
140 | #define BS_FILSYSTYPE 82, 8 /* File system type: "FAT12 ", |
---|
141 | "FAT16 " or "FAT " */ |
---|
142 | |
---|
143 | /* File system and operating system specific boot code (next 420 bytes). */ |
---|
144 | /* offset | size (both in bytes) */ |
---|
145 | #define BS_CODE 90, 420 /* Executable code. */ |
---|
146 | |
---|
147 | /* Signature (last 2 bytes). */ |
---|
148 | /* offset | size (both in bytes) */ |
---|
149 | #define BS_SIGNATURE 510, 2 /* Boot signature. */ |
---|
150 | |
---|
151 | /**************************************************************************** |
---|
152 | * FS Information Sector structure. * |
---|
153 | * This sector is used for speeding up access times of certain operations. * |
---|
154 | ****************************************************************************/ |
---|
155 | |
---|
156 | /* offset | size (both in bytes) */ |
---|
157 | #define FSI_LEADSIG 0, 4 /* Lead signature. */ |
---|
158 | #define FSI_RESERVED1 4, 480 /* Reserved. */ |
---|
159 | #define FSI_STRUCSIG 484, 4 /* Another signature. */ |
---|
160 | #define FSI_FREE_COUNT 488, 4 /* Number of free clusters. */ |
---|
161 | #define FSI_NXT_FREE 492, 4 /* Most recently allocated cluster. */ |
---|
162 | #define FSI_RESERVED2 496, 12 /* Reserved. */ |
---|
163 | #define FSI_TRAILSIG 508, 4 /* Trail signature. */ |
---|
164 | |
---|
165 | /**************************************************************************** |
---|
166 | * File Allocation Table. * |
---|
167 | * The File Allocation Table is a table that indicates the status and * |
---|
168 | * location of all data clusters on the disk. It can be * |
---|
169 | * considered the "table of contents" of a disk. The cluster may be * |
---|
170 | * available for use, it may be reserved by the operating system, it may * |
---|
171 | * be unavailable due to a bad sector on the disk, or it may be in use * |
---|
172 | * by a file. The clusters of a file need not to be right next to each * |
---|
173 | * other on the disk. The FAT allows the operating system to follow the * |
---|
174 | * chain of clusters in a file. * |
---|
175 | * * |
---|
176 | * Since the first cluster of the Data Region is cluster #2, the first 2 * |
---|
177 | * entries of the FAT are unused. * |
---|
178 | * * |
---|
179 | * Note that despite its name FAT32 uses only 28 bits of the 32 possible * |
---|
180 | * bits to address the clusters on the disk: the upper 4 bits should be * |
---|
181 | * left untouched. * |
---|
182 | ****************************************************************************/ |
---|
183 | |
---|
184 | #define FAT_ENTRY_SIZE 4 /* Size of a FAT entry (in bytes) */ |
---|
185 | |
---|
186 | /* FAT entry values. */ |
---|
187 | #define FREE 0x00000000 /* Free cluster. */ |
---|
188 | #define RESERVED 0x00000001 /* Reserved for internal purposes. */ |
---|
189 | #define BAD 0x0FFFFFF7 /* Bad sector in cluster. */ |
---|
190 | |
---|
191 | // Value in this range should be interpreted as next cluster number. |
---|
192 | #define USED_MIN 0x00000002 /* Minimum value to be considered |
---|
193 | as used for data clusters. */ |
---|
194 | #define USED_MAX 0x0FFFFFEF /* Maximum value to be considered |
---|
195 | as used for data clusters. */ |
---|
196 | |
---|
197 | // Value in this range means this is the last cluster in file. |
---|
198 | #define EOC_MIN 0x0FFFFFF8 /* Minimum value to be considered |
---|
199 | as end-of-chain marker. */ |
---|
200 | #define EOC_MAX 0x0FFFFFFF /* Maximum value to be considered |
---|
201 | as end-of-chain marker. */ |
---|
202 | |
---|
203 | /**************************************************************************** |
---|
204 | * Directory table. * |
---|
205 | * A directory table is a special type of file that represents a directory. * |
---|
206 | * Each file or subdirectory stored within it is represented by a 32-byte * |
---|
207 | * entry in the table. All directory tables are stored in the Data Region. * |
---|
208 | * The actual number of entries in a directory stored in the Data Region * |
---|
209 | * can grow by adding another cluster to the chain in the FAT. * |
---|
210 | * * |
---|
211 | * A directory entry simply stores the information needed to know where * |
---|
212 | * a file's data or a folder's children are stored on the disk. * |
---|
213 | * * |
---|
214 | * The only special directory which must always be present is the root * |
---|
215 | * directory. For FAT32, it can be of variable size and is a cluster, * |
---|
216 | * just like any other directory is (this is not true for FAT12/FAT16). * |
---|
217 | * The first cluster of the root directory on a FAT32 volume is stored in * |
---|
218 | * BPB_ROOTCLUS. * |
---|
219 | * * |
---|
220 | * Each entry can be preceded by "fake entries" to support a VFAT long * |
---|
221 | * filename (LFN, see further below). When such a directory entry is * |
---|
222 | * encountered, it is given special treatment by the file system. * |
---|
223 | ****************************************************************************/ |
---|
224 | |
---|
225 | #define DIR_ENTRY_SIZE 32 /* Directory entry size (in bytes) */ |
---|
226 | #define PATH_MAX_SIZE 260 /* Max file path length (bytes) */ |
---|
227 | #define NAME_MAX_SIZE 256 /* Max file/dir name length (bytes) */ |
---|
228 | |
---|
229 | /**************************************************************************** |
---|
230 | * Standard 8.3 format. * |
---|
231 | * For a classic 8.3 filename entry, the DIR_NAME field is actually broken * |
---|
232 | * in 2 parts: the 8-characters main part of the name and the 3-characters * |
---|
233 | * extension. These 2 parts are "trailing space padded". * |
---|
234 | * * |
---|
235 | * Furthermore, all classic 8.3 filenames are uppercase. * |
---|
236 | ****************************************************************************/ |
---|
237 | |
---|
238 | /* offset | size (both in bytes) */ |
---|
239 | #define DIR_NAME 0, 11 /* Short file name. */ |
---|
240 | #define DIR_ATTR 11, 1 /* File attributes. */ |
---|
241 | #define DIR_NTRES 12, 1 /* Reserved for use by WINDOWS NT. */ |
---|
242 | #define DIR_CRTTIMETENTH 13, 1 /* Millisecond stamp at file |
---|
243 | creation time. */ |
---|
244 | #define DIR_CRTTIME 14, 2 /* Time file was created. */ |
---|
245 | #define DIR_CRTDATE 16, 2 /* Date file was created. */ |
---|
246 | #define DIR_LSTACCDATE 18, 2 /* Last access date. */ |
---|
247 | #define DIR_FSTCLUSHI 20, 2 /* High 16 bits of this entry's |
---|
248 | first cluster number. */ |
---|
249 | #define DIR_WRTTIME 22, 2 /* Time of last write. */ |
---|
250 | #define DIR_WRTDATE 24, 2 /* Date of last write. */ |
---|
251 | #define DIR_FSTCLUSLO 26, 2 /* Low 16 bits of this entry's |
---|
252 | first cluster number. */ |
---|
253 | #define DIR_FILESIZE 28, 4 /* This file's size in bytes. */ |
---|
254 | |
---|
255 | /* File attributes (DIR_ATTR values). */ |
---|
256 | #define ATTR_READ_ONLY 0x01 /* Writes to file should fail. */ |
---|
257 | #define ATTR_HIDDEN 0x02 /* Normal directory listings should |
---|
258 | not show this file. */ |
---|
259 | #define ATTR_SYSTEM 0x04 /* File belongs to the system, must |
---|
260 | not be physically moved. */ |
---|
261 | #define ATTR_VOLUME_ID 0x08 /* Volume label. */ |
---|
262 | #define ATTR_DIRECTORY 0x10 /* Container for other files. */ |
---|
263 | #define ATTR_ARCHIVE 0x20 /* Archive (file marked as dirty). */ |
---|
264 | #define ATTR_LONG_NAME 0x0F /* The file is part of the long |
---|
265 | long entry for some other file. */ |
---|
266 | |
---|
267 | /* Special values of the first byte DIR_NAME[0] of a FAT directory entry. */ |
---|
268 | #define FREE_ENTRY 0xE5 /* Directory entry is free. */ |
---|
269 | #define LAST_ENTRY 0x00 /* No subsequent entry in use. */ |
---|
270 | |
---|
271 | /**************************************************************************** |
---|
272 | * Long File Name format. * |
---|
273 | * Long File Names are stored on FAT file system using a trick: adding * |
---|
274 | * (possibly multiple) additional entries to the directory before the * |
---|
275 | * normal file entry. This means that long file name entries is always * |
---|
276 | * associated with a regular 8.3 entry that they always immediately * |
---|
277 | * precede (this because only short directory entries are visible to * |
---|
278 | * previous versions of MS-DOS). * |
---|
279 | * * |
---|
280 | * Note 1: every member of a set of long entries is uniquely numbered and * |
---|
281 | * the LDIR_ORD field of the last member of the set is or'd with a flag * |
---|
282 | * indicating that it is in fact the last member of the set. On the other * |
---|
283 | * hand, this field cannot have values of 0xE5 or 0x00 (see above). * |
---|
284 | * * |
---|
285 | * Note 2: an 8-bit checksum is computed on the name contained in the * |
---|
286 | * short directory entry at the time the short and long directory entries * |
---|
287 | * are created. This checksum is then placed in every long entry. All 11 * |
---|
288 | * characters of the name in the short entry are used in the checksum * |
---|
289 | * calculation. * |
---|
290 | * * |
---|
291 | * Note 3: if there are multiple LFN entries, firstly comes the LAST LFN * |
---|
292 | * entry (the last part of the file name). * |
---|
293 | ****************************************************************************/ |
---|
294 | |
---|
295 | /* offset | size (both in bytes) */ |
---|
296 | #define LDIR_ORD 0, 1 /* Order of this entry in the |
---|
297 | sequence of long directory |
---|
298 | entries. */ |
---|
299 | #define LDIR_NAME1 1, 10 /* Characters 1-5 of the long name |
---|
300 | sub-component in this entry. */ |
---|
301 | #define LDIR_ATTR 11, 1 /* Must be ATTR_LONG_NAME. */ |
---|
302 | #define LDIR_TYPE 12, 1 /* Always 0. */ |
---|
303 | #define LDIR_CHKSUM 13, 1 /* Checksum of name in the short |
---|
304 | directory entry at the end of |
---|
305 | the long directory set. */ |
---|
306 | #define LDIR_NAME2 14, 12 /* Characters 6-11 of the long name |
---|
307 | sub-component in this entry. */ |
---|
308 | #define LDIR_FSTCLUSLO 26, 2 /* Must be 0. */ |
---|
309 | #define LDIR_NAME3 28, 4 /* Characters 12-13 of the long name |
---|
310 | sub-component in this entry. */ |
---|
311 | |
---|
312 | /* Last long directory entry mask. */ |
---|
313 | #define LAST_LONG_ENTRY 0x40 |
---|
314 | |
---|
315 | |
---|
316 | /**************************************************************************** |
---|
317 | * This structure defines a FAT32 File System descriptor. * |
---|
318 | ****************************************************************************/ |
---|
319 | |
---|
320 | #include <hal_kernel_types.h> |
---|
321 | |
---|
322 | typedef struct fat_desc_s |
---|
323 | { |
---|
324 | unsigned char block_buffer[512]; /* Buffer for FS Information. */ |
---|
325 | uint32_t block_buffer_lba; /* LBA of block_buffer. */ |
---|
326 | uint32_t initialized; /* Status of the FAT32 File System. */ |
---|
327 | uint32_t sector_size; /* Must be 512 bytes. */ |
---|
328 | uint32_t cluster_size; /* Must be 4096 bytes. */ |
---|
329 | uint32_t fat_sectors; /* Count of sectors in FAT Region. */ |
---|
330 | uint32_t fat_lba; /* LBA of first FAT sector. */ |
---|
331 | uint32_t data_sectors; /* Count of sectors in Data Region. */ |
---|
332 | uint32_t data_lba; /* LBA of first data sector. */ |
---|
333 | uint32_t root_cluster; /* first cluster of root directory. */ |
---|
334 | uint32_t fsi_lba; /* LBA of FS Information. */ |
---|
335 | uint32_t free_cluster_hint; /* Start point for free cluster */ |
---|
336 | uint32_t free_clusters_nr; /* Total number of free clusters. */ |
---|
337 | } |
---|
338 | fat_desc_t; |
---|
339 | |
---|
340 | /**************************************************************************** |
---|
341 | * Basic operations of FAT32 File System. * |
---|
342 | ****************************************************************************/ |
---|
343 | |
---|
344 | extern fat_desc_t boot_fat; |
---|
345 | |
---|
346 | /**************************************************************************** |
---|
347 | * This function initializes the FAT32 File System. * |
---|
348 | * * |
---|
349 | * @ returns 0 on success, -1 on error. * |
---|
350 | ****************************************************************************/ |
---|
351 | int boot_fat32_init( void ); |
---|
352 | |
---|
353 | /**************************************************************************** |
---|
354 | * This function loads the 'pathname' file into the memory buffer at base * |
---|
355 | * address 'buff_addr' of 'buff_size'. It uses the 512-byte buffer defined * |
---|
356 | * in the FAT32 descriptor. * |
---|
357 | * @ pathname : file to be loaded pathname. * |
---|
358 | * @ buff_addr : memory address of file containing buffer. * |
---|
359 | * @ buff_size : size of file containing buffer (in bytes). * |
---|
360 | * * |
---|
361 | * @ returns 0 on success, -1 on error. * |
---|
362 | ****************************************************************************/ |
---|
363 | int boot_fat32_load( const char * pathname, |
---|
364 | uint32_t buff_addr, |
---|
365 | uint32_t buff_size ); |
---|
366 | |
---|
367 | #endif // BOOT_FAT32_H |
---|