1/*
2 * Copyright (c) 2000-2008, 2010-2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/* $FreeBSD: src/sys/msdosfs/bpb.h,v 1.7 1999/08/28 00:48:07 peter Exp $ */
24/*	$NetBSD: bpb.h,v 1.7 1997/11/17 15:36:24 ws Exp $	*/
25
26/*
27 * Written by Paul Popelka (paulp@uts.amdahl.com)
28 *
29 * You can do anything you want with this software, just don't say you wrote
30 * it, and don't remove this notice.
31 *
32 * This software is provided "as is".
33 *
34 * The author supplies this software to be publicly redistributed on the
35 * understanding that the author is not responsible for the correct
36 * functioning of this software in any circumstances and is not liable for
37 * any damages caused by this software.
38 *
39 * October 1992
40 */
41
42/*
43 * BIOS Parameter Block (BPB) for DOS 3.3
44 */
45struct bpb33 {
46	u_int16_t	bpbBytesPerSec;	/* bytes per sector */
47	u_int8_t	bpbSecPerClust;	/* sectors per cluster */
48	u_int16_t	bpbResSectors;	/* number of reserved sectors */
49	u_int8_t	bpbFATs;	/* number of FATs */
50	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */
51	u_int16_t	bpbSectors;	/* total number of sectors */
52	u_int8_t	bpbMedia;	/* media descriptor */
53	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */
54	u_int16_t	bpbSecPerTrack;	/* sectors per track */
55	u_int16_t	bpbHeads;	/* number of heads */
56	u_int16_t	bpbHiddenSecs;	/* number of hidden sectors */
57};
58
59/*
60 * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
61 * and bpbHugeSectors is not in the 3.3 bpb.
62 */
63struct bpb50 {
64	u_int16_t	bpbBytesPerSec;	/* bytes per sector */
65	u_int8_t	bpbSecPerClust;	/* sectors per cluster */
66	u_int16_t	bpbResSectors;	/* number of reserved sectors */
67	u_int8_t	bpbFATs;	/* number of FATs */
68	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */
69	u_int16_t	bpbSectors;	/* total number of sectors */
70	u_int8_t	bpbMedia;	/* media descriptor */
71	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */
72	u_int16_t	bpbSecPerTrack;	/* sectors per track */
73	u_int16_t	bpbHeads;	/* number of heads */
74	u_int32_t	bpbHiddenSecs;	/* # of hidden sectors */
75	u_int32_t	bpbHugeSectors;	/* # of sectors if bpbSectors == 0 */
76};
77
78/*
79 * BPB for DOS 7.10 (FAT32).  This one has a few extensions to bpb50.
80 */
81struct bpb710 {
82	u_int16_t	bpbBytesPerSec;	/* bytes per sector */
83	u_int8_t	bpbSecPerClust;	/* sectors per cluster */
84	u_int16_t	bpbResSectors;	/* number of reserved sectors */
85	u_int8_t	bpbFATs;	/* number of FATs */
86	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */
87	u_int16_t	bpbSectors;	/* total number of sectors */
88	u_int8_t	bpbMedia;	/* media descriptor */
89	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */
90	u_int16_t	bpbSecPerTrack;	/* sectors per track */
91	u_int16_t	bpbHeads;	/* number of heads */
92	u_int32_t	bpbHiddenSecs;	/* # of hidden sectors */
93	u_int32_t	bpbHugeSectors;	/* # of sectors if bpbSectors == 0 */
94	u_int32_t	bpbBigFATsecs;	/* like bpbFATsecs for FAT32 */
95	u_int16_t	bpbExtFlags;	/* extended flags: */
96#define	FATNUM		0xf		/* mask for numbering active FAT */
97#define	FATMIRROR	0x80		/* 0 == FAT is mirrored (like it always was) */
98	u_int16_t	bpbFSVers;	/* filesystem version */
99#define	FSVERS		0		/* currently only 0 is understood */
100	u_int32_t	bpbRootClust;	/* start cluster for root directory */
101	u_int16_t	bpbFSInfo;	/* filesystem info structure sector */
102	u_int16_t	bpbBackup;	/* backup boot sector */
103	/* There is a 12 byte filler here, but we ignore it */
104};
105
106
107/*
108 * The following structures represent how the bpb's look on disk.  Multi-byte
109 * integers are just character arrays of the appropriate length.  This is
110 * because the compiler forces alignment, and some of our fields aren't
111 * properly aligned.
112 *
113 * XXX The little-endian code here assumes that the processor can access
114 * 16-bit and 32-bit quantities on byte boundaries.  If this is not true,
115 * use the macros for the big-endian case.
116 */
117#include <machine/endian.h>
118#if (BYTE_ORDER == LITTLE_ENDIAN) 			/* && defined(UNALIGNED_ACCESS) */
119#define	getuint16(x)	*((u_int16_t *)(x))
120#define	getuint32(x)	*((u_int32_t *)(x))
121#define	putuint16(p, v)	(*((u_int16_t *)(p)) = (v))
122#define	putuint32(p, v)	(*((u_int32_t *)(p)) = (v))
123#else
124#define getuint16(x)	(((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8))
125#define getuint32(x)	(((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8) \
126			 + (((u_int8_t *)(x))[2] << 16)	\
127			 + (((u_int8_t *)(x))[3] << 24))
128#define putuint16(p, v)	(((u_int8_t *)(p))[0] = (v) & 0xFF,	\
129			 ((u_int8_t *)(p))[1] = ((v) >> 8) & 0xFF)
130#define putuint32(p, v)	(((u_int8_t *)(p))[0] = (v) & 0xFF,	\
131			 ((u_int8_t *)(p))[1] = ((v) >> 8) & 0xFF, \
132			 ((u_int8_t *)(p))[2] = ((v) >> 16) & 0xFF, \
133			 ((u_int8_t *)(p))[3] = ((v) >> 24) & 0xFF)
134#endif
135
136/*
137 * BIOS Parameter Block (BPB) for DOS 3.3
138 */
139struct byte_bpb33 {
140	u_int8_t bpbBytesPerSec[2];	/* bytes per sector */
141	u_int8_t bpbSecPerClust;		/* sectors per cluster */
142	u_int8_t bpbResSectors[2];	/* number of reserved sectors */
143	u_int8_t bpbFATs;			/* number of FATs */
144	u_int8_t bpbRootDirEnts[2];	/* number of root directory entries */
145	u_int8_t bpbSectors[2];		/* total number of sectors */
146	u_int8_t bpbMedia;		/* media descriptor */
147	u_int8_t bpbFATsecs[2];		/* number of sectors per FAT */
148	u_int8_t bpbSecPerTrack[2];	/* sectors per track */
149	u_int8_t bpbHeads[2];		/* number of heads */
150	u_int8_t bpbHiddenSecs[2];	/* number of hidden sectors */
151};
152
153/*
154 * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
155 * and bpbHugeSectors is not in the 3.3 bpb.
156 */
157struct byte_bpb50 {
158	u_int8_t bpbBytesPerSec[2];	/* bytes per sector */
159	u_int8_t bpbSecPerClust;		/* sectors per cluster */
160	u_int8_t bpbResSectors[2];	/* number of reserved sectors */
161	u_int8_t bpbFATs;			/* number of FATs */
162	u_int8_t bpbRootDirEnts[2];	/* number of root directory entries */
163	u_int8_t bpbSectors[2];		/* total number of sectors */
164	u_int8_t bpbMedia;		/* media descriptor */
165	u_int8_t bpbFATsecs[2];		/* number of sectors per FAT */
166	u_int8_t bpbSecPerTrack[2];	/* sectors per track */
167	u_int8_t bpbHeads[2];		/* number of heads */
168	u_int8_t bpbHiddenSecs[4];	/* number of hidden sectors */
169	u_int8_t bpbHugeSectors[4];	/* # of sectors if bpbSectors == 0 */
170};
171
172/*
173 * BPB for DOS 7.10 (FAT32).  This one has a few extensions to bpb50.
174 */
175struct byte_bpb710 {
176	u_int8_t bpbBytesPerSec[2];	/* bytes per sector */
177	u_int8_t bpbSecPerClust;	/* sectors per cluster */
178	u_int8_t bpbResSectors[2];	/* number of reserved sectors */
179	u_int8_t bpbFATs;		/* number of FATs */
180	u_int8_t bpbRootDirEnts[2];	/* number of root directory entries */
181	u_int8_t bpbSectors[2];		/* total number of sectors */
182	u_int8_t bpbMedia;		/* media descriptor */
183	u_int8_t bpbFATsecs[2];		/* number of sectors per FAT */
184	u_int8_t bpbSecPerTrack[2];	/* sectors per track */
185	u_int8_t bpbHeads[2];		/* number of heads */
186	u_int8_t bpbHiddenSecs[4];	/* # of hidden sectors */
187	u_int8_t bpbHugeSectors[4];	/* # of sectors if bpbSectors == 0 */
188	u_int8_t bpbBigFATsecs[4];	/* like bpbFATsecs for FAT32 */
189	u_int8_t bpbExtFlags[2];	/* extended flags: */
190	u_int8_t bpbFSVers[2];		/* filesystem version */
191	u_int8_t bpbRootClust[4];	/* start cluster for root directory */
192	u_int8_t bpbFSInfo[2];		/* filesystem info structure sector */
193	u_int8_t bpbBackup[2];		/* backup boot sector */
194	/* There is a 12 byte filler here, but we ignore it */
195};
196
197/*
198 * FAT32 FSInfo block.
199 */
200struct fsinfo {
201	u_int8_t fsisig1[4];
202	u_int8_t fsifill1[480];
203	u_int8_t fsisig2[4];
204	u_int8_t fsinfree[4];
205	u_int8_t fsinxtfree[4];
206	u_int8_t fsifill2[12];
207	u_int8_t fsisig3[4];
208};
209