summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/core/fs/fat/fat_fs.h
blob: 7ea3db85c271e0740b6b5613d3a484ae71b17eb7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef FAT_FS_H
#define FAT_FS_H

#include <stdint.h>

#define FAT_DIR_ENTRY_SIZE 32
#define DIRENT_SHIFT 5

#define FAT_ATTR_READ_ONLY 0x01
#define FAT_ATTR_HIDDEN	   0x02
#define FAT_ATTR_SYSTEM	   0x04
#define FAT_ATTR_VOLUME_ID 0x08
#define FAT_ATTR_DIRECTORY 0x10
#define FAT_ATTR_ARCHIVE   0x20

#define FAT_MAXFILE	   256

#define FAT_ATTR_LONG_NAME (FAT_ATTR_READ_ONLY             \
                            | FAT_ATTR_HIDDEN              \
                            | FAT_ATTR_SYSTEM              \
                            | FAT_ATTR_VOLUME_ID)

#define FAT_ATTR_VALID	   (FAT_ATTR_READ_ONLY             \
                            | FAT_ATTR_HIDDEN              \
                            | FAT_ATTR_SYSTEM              \
                            | FAT_ATTR_DIRECTORY           \
                            | FAT_ATTR_ARCHIVE)

enum fat_type{ FAT12, FAT16, FAT32 };

/*
 * The fat file system structures 
 */

struct fat_bpb {
        uint8_t  jmp_boot[3];
        uint8_t  oem_name[8];
        uint16_t sector_size;
        uint8_t  bxSecPerClust;
        uint16_t bxResSectors;
        uint8_t  bxFATs;
        uint16_t bxRootDirEnts;
        uint16_t bxSectors;
        uint8_t  media;
        uint16_t bxFATsecs;
        uint16_t sectors_per_track;
        uint16_t num_heads;
        uint32_t num_hidden_sectors;
        uint32_t bsHugeSectors;
       
        union {
                struct {
                        uint8_t  num_ph_drive;
                        uint8_t  reserved;
                        uint8_t  boot_sig;
                        uint32_t num_serial;
                        uint8_t  label[11];
                        uint8_t  fstype[8];
                } __attribute__ ((packed)) fat12_16;

                struct {
                        uint32_t bxFATsecs_32;
                        uint16_t extended_flags;
                        uint16_t fs_version;
                        uint32_t root_cluster;
                        uint16_t fs_info;
                        uint16_t backup_boot_sector;
                        uint8_t  reserved[12];
                        uint8_t  num_ph_drive;
                        uint8_t  reserved1;
                        uint8_t  boot_sig;
                        uint32_t num_serial;
                        uint8_t  label[11];
                        uint8_t  fstype[8];
                } __attribute__ ((packed)) fat32;

        } __attribute__ ((packed));

        uint8_t pad[422];  /* padding to 512 Bytes (one sector) */

} __attribute__ ((packed));

/*
 * The fat file system info in memory 
 */
struct fat_sb_info {
	sector_t fat;             /* The FAT region */
	sector_t root;            /* The root dir region */
	sector_t data;            /* The data region */

	uint32_t clusters;	  /* Total number of clusters */
	uint32_t root_cluster;	  /* Cluster number for (FAT32) root dir */
	int      root_size;       /* The root dir size in sectors */
	
	int      clust_shift;      /* based on sectors */
	int      clust_byte_shift; /* based on bytes   */
	int      clust_mask;	   /* sectors per cluster mask */
	int      clust_size;

	int      fat_type;
} __attribute__ ((packed));

struct fat_dir_entry {
        char     name[11];
        uint8_t  attr;
        uint8_t  lcase;
        uint8_t  c_time_tenth;
        uint16_t c_time;
        uint16_t c_date;
        uint16_t a_date;
        uint16_t first_cluster_high;
        uint16_t w_time;
        uint16_t w_date;
        uint16_t first_cluster_low;
        uint32_t file_size;
} __attribute__ ((packed));

#define LCASE_BASE 8       /* basename is lower case */
#define LCASE_EXT  16      /* extension is lower case */

struct fat_long_name_entry {
        uint8_t  id;
        uint16_t name1[5];
        uint8_t  attr;
        uint8_t  reserved;
        uint8_t  checksum;
        uint16_t name2[6];
        uint16_t first_cluster;
        uint16_t name3[2];
} __attribute__ ((packed));

static inline struct fat_sb_info *FAT_SB(struct fs_info *fs)
{
        return fs->fs_info;
}

/* 
 * Count the root dir size in sectors
 */
static inline int root_dir_size(struct fs_info *fs, struct fat_bpb *fat)
{
    return (fat->bxRootDirEnts + SECTOR_SIZE(fs)/32 - 1)
	>> (SECTOR_SHIFT(fs) - 5);
}

/*
 * FAT private inode information
 */
struct fat_pvt_inode {
    uint32_t start_cluster;	/* Starting cluster address */
    sector_t start;		/* Starting sector */
    sector_t offset;		/* Current sector offset */
    sector_t here;		/* Sector corresponding to offset */
};

#define PVT(i) ((struct fat_pvt_inode *)((i)->pvt))

#endif /* fat_fs.h */