Lines Matching +full:u +full:- +full:boot
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
31 __RCSID("$NetBSD: boot.c,v 1.22 2020/01/11 16:29:07 christos Exp $");
46 readboot(int dosfs, struct bootblock *boot) in readboot() argument
53 perr("could not read boot block"); in readboot()
58 pfatal("Invalid signature in boot block: %02x%02x", in readboot()
63 memset(boot, 0, sizeof *boot); in readboot()
64 boot->ValidFat = -1; in readboot()
69 boot->bpbBytesPerSec = block[11] + (block[12] << 8); in readboot()
70 if (boot->bpbBytesPerSec < DOSBOOTBLOCKSIZE_REAL || in readboot()
71 boot->bpbBytesPerSec > DOSBOOTBLOCKSIZE || in readboot()
72 !powerof2(boot->bpbBytesPerSec)) { in readboot()
73 pfatal("Invalid sector size: %u", boot->bpbBytesPerSec); in readboot()
78 boot->bpbSecPerClust = block[13]; in readboot()
79 if (boot->bpbSecPerClust == 0 || !powerof2(boot->bpbSecPerClust)) { in readboot()
80 pfatal("Invalid cluster size: %u", boot->bpbSecPerClust); in readboot()
84 /* Reserved sectors: must be non-zero */ in readboot()
85 boot->bpbResSectors = block[14] + (block[15] << 8); in readboot()
86 if (boot->bpbResSectors < 1) { in readboot()
87 pfatal("Invalid reserved sectors: %u", in readboot()
88 boot->bpbResSectors); in readboot()
93 boot->bpbFATs = block[16]; in readboot()
94 if (boot->bpbFATs == 0) { in readboot()
95 pfatal("Invalid number of FATs: %u", boot->bpbFATs); in readboot()
100 boot->bpbRootDirEnts = block[17] + (block[18] << 8); in readboot()
101 if (!boot->bpbRootDirEnts) { in readboot()
103 boot->flags |= FAT32; in readboot()
107 boot->bpbSectors = block[19] + (block[20] << 8); in readboot()
108 if (boot->bpbSectors != 0 && (boot->flags & FAT32)) { in readboot()
109 pfatal("Invalid 16-bit total sector count on FAT32: %u", in readboot()
110 boot->bpbSectors); in readboot()
115 boot->bpbMedia = block[21]; in readboot()
117 /* FAT12/FAT16: 16-bit count of sectors per FAT */ in readboot()
118 boot->bpbFATsmall = block[22] + (block[23] << 8); in readboot()
119 if (boot->bpbFATsmall != 0 && (boot->flags & FAT32)) { in readboot()
120 pfatal("Invalid 16-bit FAT sector count on FAT32: %u", in readboot()
121 boot->bpbFATsmall); in readboot()
126 boot->SecPerTrack = block[24] + (block[25] << 8); in readboot()
127 boot->bpbHeads = block[26] + (block[27] << 8); in readboot()
130 boot->bpbHiddenSecs = block[28] + (block[29] << 8) + in readboot()
134 boot->bpbHugeSectors = block[32] + (block[33] << 8) + in readboot()
136 if (boot->bpbHugeSectors == 0) { in readboot()
137 if (boot->flags & FAT32) { in readboot()
140 } else if (boot->bpbSectors == 0) { in readboot()
144 boot->NumSectors = boot->bpbSectors; in readboot()
146 if (boot->bpbSectors != 0) { in readboot()
150 boot->NumSectors = boot->bpbHugeSectors; in readboot()
153 if (boot->flags & FAT32) { in readboot()
160 /* 32-bit count of sectors per FAT */ in readboot()
161 boot->FATsecs = block[36] + (block[37] << 8) in readboot()
165 boot->ValidFat = block[40] & 0x0f; in readboot()
179 boot->bpbRootClust = block[44] + (block[45] << 8) in readboot()
183 boot->bpbFSInfo = block[48] + (block[49] << 8); in readboot()
185 /* Sector number of the backup boot block, ignored */ in readboot()
186 boot->bpbBackup = block[50] + (block[51] << 8); in readboot()
189 if (boot->bpbFSInfo == 0) { in readboot()
200 if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, in readboot()
201 SEEK_SET) != boot->bpbFSInfo * boot->bpbBytesPerSec in readboot()
226 if (lseek(dosfs, boot->bpbFSInfo * in readboot()
227 boot->bpbBytesPerSec, SEEK_SET) in readboot()
228 != boot->bpbFSInfo * boot->bpbBytesPerSec in readboot()
236 boot->bpbFSInfo = 0; in readboot()
239 boot->FSFree = fsinfo[0x1e8] + (fsinfo[0x1e9] << 8) in readboot()
242 boot->FSNext = fsinfo[0x1ec] + (fsinfo[0x1ed] << 8) in readboot()
248 boot->FATsecs = boot->bpbFATsmall; in readboot()
251 if (boot->FATsecs < 1 || boot->FATsecs > UINT32_MAX / boot->bpbFATs) { in readboot()
252 pfatal("Invalid FATs(%u) with FATsecs(%zu)", in readboot()
253 boot->bpbFATs, (size_t)boot->FATsecs); in readboot()
257 boot->FirstCluster = (boot->bpbRootDirEnts * 32 + in readboot()
258 boot->bpbBytesPerSec - 1) / boot->bpbBytesPerSec + in readboot()
259 boot->bpbResSectors + boot->bpbFATs * boot->FATsecs; in readboot()
261 if (boot->FirstCluster + boot->bpbSecPerClust > boot->NumSectors) { in readboot()
262 pfatal("Cluster offset too large (%u clusters)\n", in readboot()
263 boot->FirstCluster); in readboot()
271 boot->NumClusters = in readboot()
272 (boot->NumSectors - boot->FirstCluster) / boot->bpbSecPerClust; in readboot()
274 if (boot->flags & FAT32) { in readboot()
275 if (boot->NumClusters > (CLUST_RSRVD & CLUST32_MASK)) { in readboot()
276 pfatal("Filesystem too big (%u clusters) for FAT32 partition", in readboot()
277 boot->NumClusters); in readboot()
280 if (boot->NumClusters < (CLUST_RSRVD & CLUST16_MASK)) { in readboot()
281 pfatal("Filesystem too small (%u clusters) for FAT32 partition", in readboot()
282 boot->NumClusters); in readboot()
285 boot->ClustMask = CLUST32_MASK; in readboot()
287 if (boot->bpbRootClust < CLUST_FIRST || in readboot()
288 boot->bpbRootClust >= boot->NumClusters) { in readboot()
289 pfatal("Root directory starts with cluster out of range(%u)", in readboot()
290 boot->bpbRootClust); in readboot()
293 } else if (boot->NumClusters < (CLUST_RSRVD&CLUST12_MASK)) { in readboot()
294 boot->ClustMask = CLUST12_MASK; in readboot()
295 } else if (boot->NumClusters < (CLUST_RSRVD&CLUST16_MASK)) { in readboot()
296 boot->ClustMask = CLUST16_MASK; in readboot()
298 pfatal("Filesystem too big (%u clusters) for non-FAT32 partition", in readboot()
299 boot->NumClusters); in readboot()
303 switch (boot->ClustMask) { in readboot()
305 boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec) / 4; in readboot()
308 boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec) / 2; in readboot()
311 boot->NumFatEntries = (boot->FATsecs * boot->bpbBytesPerSec * 2) / 3; in readboot()
315 if (boot->NumFatEntries < boot->NumClusters) { in readboot()
316 pfatal("FAT size too small, %u entries won't fit into %u sectors\n", in readboot()
317 boot->NumClusters, boot->FATsecs); in readboot()
324 * which is CLUST_FIRST to denote the first out-of-range cluster number. in readboot()
326 boot->NumClusters += CLUST_FIRST; in readboot()
328 boot->ClusterSize = boot->bpbBytesPerSec * boot->bpbSecPerClust; in readboot()
330 boot->NumFiles = 1; in readboot()
331 boot->NumFree = 0; in readboot()
337 writefsinfo(int dosfs, struct bootblock *boot) in writefsinfo() argument
341 if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET) in writefsinfo()
342 != boot->bpbFSInfo * boot->bpbBytesPerSec in writefsinfo()
347 fsinfo[0x1e8] = (u_char)boot->FSFree; in writefsinfo()
348 fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8); in writefsinfo()
349 fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16); in writefsinfo()
350 fsinfo[0x1eb] = (u_char)(boot->FSFree >> 24); in writefsinfo()
351 fsinfo[0x1ec] = (u_char)boot->FSNext; in writefsinfo()
352 fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8); in writefsinfo()
353 fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16); in writefsinfo()
354 fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24); in writefsinfo()
355 if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET) in writefsinfo()
356 != boot->bpbFSInfo * boot->bpbBytesPerSec in writefsinfo()