@@ -91,22 +91,26 @@ func (f *Formatter) move_window(addr lba) error {
91
91
return nil
92
92
}
93
93
94
- type bootsector struct {
94
+ // biosParamBlock a.k.a BPB is the BIOS Parameter Block for FAT32 volumes.
95
+ // It provides details on the filesystem type (FAT12, FAT16, FAT32),
96
+ // sectors per cluster, total sectors, FAT size, and more, which are essential
97
+ // for understanding the filesystem layout and capacity.
98
+ type biosParamBlock struct {
95
99
data []byte
96
100
}
97
101
98
102
// SectorSize returns the size of a sector in bytes.
99
- func (bs * bootsector ) SectorSize () uint16 {
103
+ func (bs * biosParamBlock ) SectorSize () uint16 {
100
104
return binary .LittleEndian .Uint16 (bs .data [bpbBytsPerSec :])
101
105
}
102
106
103
107
// SetSectorSize sets the size of a sector in bytes.
104
- func (bs * bootsector ) SetSectorSize (size uint16 ) {
108
+ func (bs * biosParamBlock ) SetSectorSize (size uint16 ) {
105
109
binary .LittleEndian .PutUint16 (bs .data [bpbBytsPerSec :], size )
106
110
}
107
111
108
112
// SectorsPerFAT returns the number of sectors per File Allocation Table.
109
- func (bs * bootsector ) SectorsPerFAT () uint32 {
113
+ func (bs * biosParamBlock ) SectorsPerFAT () uint32 {
110
114
fatsz := uint32 (binary .LittleEndian .Uint16 (bs .data [bpbFATSz16 :]))
111
115
if fatsz == 0 {
112
116
fatsz = binary .LittleEndian .Uint32 (bs .data [bpbFATSz32 :])
@@ -115,29 +119,29 @@ func (bs *bootsector) SectorsPerFAT() uint32 {
115
119
}
116
120
117
121
// SetSectorsPerFAT sets the number of sectors per File Allocation Table.
118
- func (bs * bootsector ) SetSectorsPerFAT (fatsz uint32 ) {
122
+ func (bs * biosParamBlock ) SetSectorsPerFAT (fatsz uint32 ) {
119
123
binary .LittleEndian .PutUint16 (bs .data [bpbFATSz16 :], 0 )
120
124
binary .LittleEndian .PutUint32 (bs .data [bpbFATSz32 :], fatsz )
121
125
}
122
126
123
127
// NumberOfFATs returns the number of File Allocation Tables. Should be 1 or 2.
124
- func (bs * bootsector ) NumberOfFATs () uint8 {
128
+ func (bs * biosParamBlock ) NumberOfFATs () uint8 {
125
129
return bs .data [bpbNumFATs ]
126
130
}
127
131
128
132
// SetNumberOfFATs sets the number of FATs.
129
- func (bs * bootsector ) SetNumberOfFATs (nfats uint8 ) {
133
+ func (bs * biosParamBlock ) SetNumberOfFATs (nfats uint8 ) {
130
134
bs .data [bpbNumFATs ] = nfats
131
135
}
132
136
133
137
// SectorsPerCluster returns the number of sectors per cluster.
134
138
// Should be a power of 2 and not larger than 128.
135
- func (bs * bootsector ) SectorsPerCluster () uint16 {
139
+ func (bs * biosParamBlock ) SectorsPerCluster () uint16 {
136
140
return uint16 (bs .data [bpbSecPerClus ])
137
141
}
138
142
139
143
// SetSectorsPerCluster sets the number of sectors per cluster. Should be power of 2.
140
- func (bs * bootsector ) SetSectorsPerCluster (spclus uint16 ) {
144
+ func (bs * biosParamBlock ) SetSectorsPerCluster (spclus uint16 ) {
141
145
bs .data [bpbSecPerClus ] = byte (spclus )
142
146
}
143
147
@@ -146,18 +150,18 @@ func (bs *bootsector) SetSectorsPerCluster(spclus uint16) {
146
150
// redundant sectors with these first two. The number of reserved sectors is usually
147
151
// 32 for FAT32 systems (~16k for 512 byte sectors).
148
152
// Sectors 6 and 7 are usually the backup boot sector and the FS information sector, respectively.
149
- func (bs * bootsector ) ReservedSectors () uint16 {
153
+ func (bs * biosParamBlock ) ReservedSectors () uint16 {
150
154
return binary .LittleEndian .Uint16 (bs .data [bpbRsvdSecCnt :])
151
155
}
152
156
153
157
// SetReservedSectors sets the number of reserved sectors at the beginning of the volume.
154
- func (bs * bootsector ) SetReservedSectors (rsvd uint16 ) {
158
+ func (bs * biosParamBlock ) SetReservedSectors (rsvd uint16 ) {
155
159
binary .LittleEndian .PutUint16 (bs .data [bpbRsvdSecCnt :], rsvd )
156
160
}
157
161
158
162
// TotalSectors returns the total number of sectors in the volume that
159
163
// can be used by the filesystem.
160
- func (bs * bootsector ) TotalSectors () uint32 {
164
+ func (bs * biosParamBlock ) TotalSectors () uint32 {
161
165
totsec := uint32 (binary .LittleEndian .Uint16 (bs .data [bpbTotSec16 :]))
162
166
if totsec == 0 {
163
167
totsec = binary .LittleEndian .Uint32 (bs .data [bpbTotSec32 :])
@@ -167,111 +171,111 @@ func (bs *bootsector) TotalSectors() uint32 {
167
171
168
172
// SetTotalSectors sets the total number of sectors in the volume that
169
173
// can be used by the filesystem.
170
- func (bs * bootsector ) SetTotalSectors (totsec uint32 ) {
174
+ func (bs * biosParamBlock ) SetTotalSectors (totsec uint32 ) {
171
175
binary .LittleEndian .PutUint16 (bs .data [bpbTotSec16 :], 0 )
172
176
binary .LittleEndian .PutUint32 (bs .data [bpbTotSec32 :], totsec )
173
177
}
174
178
175
179
// RootDirEntries returns the number of sectors occupied by the root directory.
176
180
// Should be divisible by SectorSize/32.
177
- func (bs * bootsector ) RootDirEntries () uint16 {
181
+ func (bs * biosParamBlock ) RootDirEntries () uint16 {
178
182
return binary .LittleEndian .Uint16 (bs .data [bpbRootEntCnt :])
179
183
}
180
184
181
185
// SetRootDirEntries sets the number of sectors occupied by the root directory.
182
- func (bs * bootsector ) SetRootDirEntries (entries uint16 ) {
186
+ func (bs * biosParamBlock ) SetRootDirEntries (entries uint16 ) {
183
187
binary .LittleEndian .PutUint16 (bs .data [bpbRootEntCnt :], entries )
184
188
}
185
189
186
190
// RootCluster returns the first cluster of the root directory.
187
- func (bs * bootsector ) RootCluster () uint32 {
191
+ func (bs * biosParamBlock ) RootCluster () uint32 {
188
192
return binary .LittleEndian .Uint32 (bs .data [bpbRootClus32 :])
189
193
}
190
194
191
195
// SetRootCluster sets the first cluster of the root directory.
192
- func (bs * bootsector ) SetRootCluster (cluster uint32 ) {
196
+ func (bs * biosParamBlock ) SetRootCluster (cluster uint32 ) {
193
197
binary .LittleEndian .PutUint32 (bs .data [bpbRootClus32 :], cluster )
194
198
}
195
199
196
200
// Version returns the filesystem version, should be 0.0 for FAT32.
197
- func (bs * bootsector ) Version () (major , minor uint8 ) {
201
+ func (bs * biosParamBlock ) Version () (major , minor uint8 ) {
198
202
return bs .data [bpbFSVer32 ], bs .data [bpbFSVer32 + 1 ]
199
203
}
200
204
201
- func (bs * bootsector ) ExtendedBootSignature () uint8 {
205
+ func (bs * biosParamBlock ) ExtendedBootSignature () uint8 {
202
206
return bs .data [bsBootSig32 ]
203
207
}
204
208
205
209
// BootSignature returns the boot signature at offset 510 which should be 0xAA55.
206
- func (bs * bootsector ) BootSignature () uint16 {
210
+ func (bs * biosParamBlock ) BootSignature () uint16 {
207
211
return binary .LittleEndian .Uint16 (bs .data [bs55AA :])
208
212
}
209
213
210
214
// FSInfo returns the sector number of the FS Information Sector.
211
215
// Expect =1 for FAT32.
212
- func (bs * bootsector ) FSInfo () uint16 {
216
+ func (bs * biosParamBlock ) FSInfo () uint16 {
213
217
return binary .LittleEndian .Uint16 (bs .data [bpbFSInfo32 :])
214
218
}
215
219
216
220
// DriveNumber returns the drive number.
217
- func (bs * bootsector ) DriveNumber () uint8 {
221
+ func (bs * biosParamBlock ) DriveNumber () uint8 {
218
222
return bs .data [bsDrvNum32 ]
219
223
}
220
224
221
225
// VolumeSerialNumber returns the volume serial number.
222
- func (bs * bootsector ) VolumeSerialNumber () uint32 {
226
+ func (bs * biosParamBlock ) VolumeSerialNumber () uint32 {
223
227
return binary .LittleEndian .Uint32 (bs .data [bsVolID32 :])
224
228
}
225
229
226
230
// VolumeLabel returns the volume label string.
227
- func (bs * bootsector ) VolumeLabel () [11 ]byte {
231
+ func (bs * biosParamBlock ) VolumeLabel () [11 ]byte {
228
232
var label [11 ]byte
229
233
copy (label [:], bs .data [bsVolLab32 :])
230
234
return label
231
235
}
232
236
233
- func (bs * bootsector ) SetVolumeLabel (label string ) {
237
+ func (bs * biosParamBlock ) SetVolumeLabel (label string ) {
234
238
n := copy (bs .data [bsVolLab32 :bsVolLab32 + 11 ], label )
235
239
for i := n ; i < 11 ; i ++ {
236
240
bs .data [bsVolLab32 + i ] = ' '
237
241
}
238
242
}
239
243
240
244
// FilesystemType returns the filesystem type string, usually "FAT32 ".
241
- func (bs * bootsector ) FilesystemType () [8 ]byte {
245
+ func (bs * biosParamBlock ) FilesystemType () [8 ]byte {
242
246
var label [8 ]byte
243
247
copy (label [:], bs .data [bsFilSysType32 :])
244
248
return label
245
249
}
246
250
247
251
// JumpInstruction returns the x86 jump instruction at the beginning of the boot sector.
248
- func (bs * bootsector ) JumpInstruction () [3 ]byte {
252
+ func (bs * biosParamBlock ) JumpInstruction () [3 ]byte {
249
253
var jmpboot [3 ]byte
250
254
copy (jmpboot [:], bs .data [0 :])
251
255
return jmpboot
252
256
}
253
257
254
258
// OEMName returns the Original Equipment Manufacturer name at the start of the bootsector.
255
- func (bs * bootsector ) OEMName () [8 ]byte {
259
+ func (bs * biosParamBlock ) OEMName () [8 ]byte {
256
260
var oemname [8 ]byte
257
261
copy (oemname [:], bs .data [bsOEMName :])
258
262
return oemname
259
263
}
260
264
261
265
// SetOEMName sets the Original Equipment Manufacturer name at the start of the bootsector.
262
266
// Will clip off any characters beyond the 8th.
263
- func (bs * bootsector ) SetOEMName (name string ) {
267
+ func (bs * biosParamBlock ) SetOEMName (name string ) {
264
268
n := copy (bs .data [bsOEMName :bsOEMName + 8 ], name )
265
269
for i := n ; i < 8 ; i ++ {
266
270
bs .data [bsOEMName + i ] = ' '
267
271
}
268
272
}
269
273
270
- func (bs * bootsector ) VolumeOffset () uint32 {
274
+ func (bs * biosParamBlock ) VolumeOffset () uint32 {
271
275
return binary .LittleEndian .Uint32 (bs .data [bpbHiddSec :])
272
276
}
273
277
274
- func (bs * bootsector ) String () string {
278
+ func (bs * biosParamBlock ) String () string {
275
279
return string (bs .Appendf (nil , '\n' ))
276
280
}
277
281
@@ -298,7 +302,7 @@ func labelAppendUint32(label string, dst []byte, data uint32, sep byte) []byte {
298
302
return labelAppendUint (label , dst , uint64 (data ), sep )
299
303
}
300
304
301
- func (bs * bootsector ) Appendf (dst []byte , separator byte ) []byte {
305
+ func (bs * biosParamBlock ) Appendf (dst []byte , separator byte ) []byte {
302
306
appendData := func (name string , data []byte , sep byte ) {
303
307
dst = labelAppend (dst , name , data , sep )
304
308
}
@@ -332,7 +336,7 @@ func (bs *bootsector) Appendf(dst []byte, separator byte) []byte {
332
336
}
333
337
334
338
// bootcode returns the boot code at the end of the boot sector.
335
- func (bs * bootsector ) bootcode () []byte {
339
+ func (bs * biosParamBlock ) bootcode () []byte {
336
340
return bs .data [bsBootCode32 :bs55AA ]
337
341
}
338
342
0 commit comments