blob: 9456ccd3a07accdb800a4f1e7ab3830f7970dfb1 [file] [log] [blame]
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001/* mkdosfs.c - utility to create FAT/MS-DOS filesystems
2
3 Copyright (C) 1991 Linus Torvalds <torvalds@klaava.helsinki.fi>
4 Copyright (C) 1992-1993 Remy Card <card@masi.ibp.fr>
5 Copyright (C) 1993-1994 David Hudson <dave@humbug.demon.co.uk>
6 Copyright (C) 1998 H. Peter Anvin <hpa@zytor.com>
7 Copyright (C) 1998-2005 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
8
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 On Debian systems, the complete text of the GNU General Public License
23 can be found in /usr/share/common-licenses/GPL-3 file.
24*/
25
26/* Description: Utility to allow an MS-DOS filesystem to be created
27 under Linux. A lot of the basic structure of this program has been
28 borrowed from Remy Card's "mke2fs" code.
29
30 As far as possible the aim here is to make the "mkdosfs" command
31 look almost identical to the other Linux filesystem make utilties,
32 eg bad blocks are still specified as blocks, not sectors, but when
33 it comes down to it, DOS is tied to the idea of a sector (512 bytes
34 as a rule), and not the block. For example the boot block does not
35 occupy a full cluster.
36
37 Fixes/additions May 1998 by Roman Hodek
38 <Roman.Hodek@informatik.uni-erlangen.de>:
39 - Atari format support
40 - New options -A, -S, -C
41 - Support for filesystems > 2GB
42 - FAT32 support */
43
44/* Include the header files */
45
46#include "version.h"
47
48#include <fcntl.h>
49#include <linux/hdreg.h>
50#if defined(_USING_BIONIC_)
51#include <linux/fs.h>
52#else
53#include <sys/mount.h>
54#endif
55#include <linux/fd.h>
56#include <endian.h>
57#include <mntent.h>
58#include <signal.h>
59#include <string.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <sys/ioctl.h>
63#include <sys/stat.h>
64#include <sys/time.h>
65#include <sys/types.h>
66#include <unistd.h>
67#include <time.h>
68#include <errno.h>
69
70#include <asm/types.h>
71
72#if __BYTE_ORDER == __BIG_ENDIAN
73
74#include <asm/byteorder.h>
75#ifdef __le16_to_cpu
76/* ++roman: 2.1 kernel headers define these function, they're probably more
77 * efficient then coding the swaps machine-independently. */
78#define CF_LE_W __le16_to_cpu
79#define CF_LE_L __le32_to_cpu
80#define CT_LE_W __cpu_to_le16
81#define CT_LE_L __cpu_to_le32
82#else
83#define CF_LE_W(v) ((((v) & 0xff) << 8) | (((v) >> 8) & 0xff))
84#define CF_LE_L(v) (((unsigned)(v)>>24) | (((unsigned)(v)>>8)&0xff00) | \
85 (((unsigned)(v)<<8)&0xff0000) | ((unsigned)(v)<<24))
86#define CT_LE_W(v) CF_LE_W(v)
87#define CT_LE_L(v) CF_LE_L(v)
88#endif /* defined(__le16_to_cpu) */
89
90#else
91
92#define CF_LE_W(v) (v)
93#define CF_LE_L(v) (v)
94#define CT_LE_W(v) (v)
95#define CT_LE_L(v) (v)
96
97#endif /* __BIG_ENDIAN */
98
99/* In earlier versions, an own llseek() was used, but glibc lseek() is
100 * sufficient (or even better :) for 64 bit offsets in the meantime */
101#define llseek lseek
102
103/* Constant definitions */
104
105#define TRUE 1 /* Boolean constants */
106#define FALSE 0
107
108#define TEST_BUFFER_BLOCKS 16
109#define HARD_SECTOR_SIZE 512
110#define SECTORS_PER_BLOCK ( BLOCK_SIZE / HARD_SECTOR_SIZE )
111
112/* Macro definitions */
113
114/* Report a failure message and return a failure error code */
115
116#define die( str ) fatal_error( "%s: " str "\n" )
117
118/* Mark a cluster in the FAT as bad */
119
120#define mark_sector_bad( sector ) mark_FAT_sector( sector, FAT_BAD )
121
122/* Compute ceil(a/b) */
123
124inline int cdiv(int a, int b)
125{
126 return (a + b - 1) / b;
127}
128
129/* MS-DOS filesystem structures -- I included them here instead of
130 including linux/msdos_fs.h since that doesn't include some fields we
131 need */
132
133#define ATTR_RO 1 /* read-only */
134#define ATTR_HIDDEN 2 /* hidden */
135#define ATTR_SYS 4 /* system */
136#define ATTR_VOLUME 8 /* volume label */
137#define ATTR_DIR 16 /* directory */
138#define ATTR_ARCH 32 /* archived */
139
140#define ATTR_NONE 0 /* no attribute bits */
141#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
142 /* attribute bits that are copied "as is" */
143
144/* FAT values */
145#define FAT_EOF (atari_format ? 0x0fffffff : 0x0ffffff8)
146#define FAT_BAD 0x0ffffff7
147
148#define MSDOS_EXT_SIGN 0x29 /* extended boot sector signature */
149#define MSDOS_FAT12_SIGN "FAT12 " /* FAT12 filesystem signature */
150#define MSDOS_FAT16_SIGN "FAT16 " /* FAT16 filesystem signature */
151#define MSDOS_FAT32_SIGN "FAT32 " /* FAT32 filesystem signature */
152
153#define BOOT_SIGN 0xAA55 /* Boot sector magic number */
154
155#define MAX_CLUST_12 ((1 << 12) - 16)
156#define MAX_CLUST_16 ((1 << 16) - 16)
157#define MIN_CLUST_32 65529
158/* M$ says the high 4 bits of a FAT32 FAT entry are reserved and don't belong
159 * to the cluster number. So the max. cluster# is based on 2^28 */
160#define MAX_CLUST_32 ((1 << 28) - 16)
161
162#define FAT12_THRESHOLD 4085
163
164#define OLDGEMDOS_MAX_SECTORS 32765
165#define GEMDOS_MAX_SECTORS 65531
166#define GEMDOS_MAX_SECTOR_SIZE (16*1024)
167
168#define BOOTCODE_SIZE 448
169#define BOOTCODE_FAT32_SIZE 420
170
171/* __attribute__ ((packed)) is used on all structures to make gcc ignore any
172 * alignments */
173
174struct msdos_volume_info {
175 __u8 drive_number; /* BIOS drive number */
176 __u8 RESERVED; /* Unused */
177 __u8 ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */
178 __u8 volume_id[4]; /* Volume ID number */
179 __u8 volume_label[11]; /* Volume label */
180 __u8 fs_type[8]; /* Typically FAT12 or FAT16 */
181} __attribute__ ((packed));
182
183struct msdos_boot_sector {
184 __u8 boot_jump[3]; /* Boot strap short or near jump */
185 __u8 system_id[8]; /* Name - can be used to special case
186 partition manager volumes */
187 __u8 sector_size[2]; /* bytes per logical sector */
188 __u8 cluster_size; /* sectors/cluster */
189 __u16 reserved; /* reserved sectors */
190 __u8 fats; /* number of FATs */
191 __u8 dir_entries[2]; /* root directory entries */
192 __u8 sectors[2]; /* number of sectors */
193 __u8 media; /* media code (unused) */
194 __u16 fat_length; /* sectors/FAT */
195 __u16 secs_track; /* sectors per track */
196 __u16 heads; /* number of heads */
197 __u32 hidden; /* hidden sectors (unused) */
198 __u32 total_sect; /* number of sectors (if sectors == 0) */
199 union {
200 struct {
201 struct msdos_volume_info vi;
202 __u8 boot_code[BOOTCODE_SIZE];
203 } __attribute__ ((packed)) _oldfat;
204 struct {
205 __u32 fat32_length; /* sectors/FAT */
206 __u16 flags; /* bit 8: fat mirroring, low 4: active fat */
207 __u8 version[2]; /* major, minor filesystem version */
208 __u32 root_cluster; /* first cluster in root directory */
209 __u16 info_sector; /* filesystem info sector */
210 __u16 backup_boot; /* backup boot sector */
211 __u16 reserved2[6]; /* Unused */
212 struct msdos_volume_info vi;
213 __u8 boot_code[BOOTCODE_FAT32_SIZE];
214 } __attribute__ ((packed)) _fat32;
215 } __attribute__ ((packed)) fstype;
216 __u16 boot_sign;
217} __attribute__ ((packed));
218#define fat32 fstype._fat32
219#define oldfat fstype._oldfat
220
221struct fat32_fsinfo {
222 __u32 reserved1; /* Nothing as far as I can tell */
223 __u32 signature; /* 0x61417272L */
224 __u32 free_clusters; /* Free cluster count. -1 if unknown */
225 __u32 next_cluster; /* Most recently allocated cluster.
226 * Unused under Linux. */
227 __u32 reserved2[4];
228};
229
230struct msdos_dir_entry {
231 char name[8], ext[3]; /* name and extension */
232 __u8 attr; /* attribute bits */
233 __u8 lcase; /* Case for base and extension */
234 __u8 ctime_ms; /* Creation time, milliseconds */
235 __u16 ctime; /* Creation time */
236 __u16 cdate; /* Creation date */
237 __u16 adate; /* Last access date */
238 __u16 starthi; /* high 16 bits of first cl. (FAT32) */
239 __u16 time, date, start; /* time, date and first cluster */
240 __u32 size; /* file size (in bytes) */
241} __attribute__ ((packed));
242
243/* The "boot code" we put into the filesystem... it writes a message and
244 tells the user to try again */
245
246char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 };
247
248char dummy_boot_jump_m68k[2] = { 0x60, 0x1c };
249
250#define MSG_OFFSET_OFFSET 3
251char dummy_boot_code[BOOTCODE_SIZE] = "\x0e" /* push cs */
252 "\x1f" /* pop ds */
253 "\xbe\x5b\x7c" /* mov si, offset message_txt */
254 /* write_msg: */
255 "\xac" /* lodsb */
256 "\x22\xc0" /* and al, al */
257 "\x74\x0b" /* jz key_press */
258 "\x56" /* push si */
259 "\xb4\x0e" /* mov ah, 0eh */
260 "\xbb\x07\x00" /* mov bx, 0007h */
261 "\xcd\x10" /* int 10h */
262 "\x5e" /* pop si */
263 "\xeb\xf0" /* jmp write_msg */
264 /* key_press: */
265 "\x32\xe4" /* xor ah, ah */
266 "\xcd\x16" /* int 16h */
267 "\xcd\x19" /* int 19h */
268 "\xeb\xfe" /* foo: jmp foo */
269 /* message_txt: */
270 "This is not a bootable disk. Please insert a bootable floppy and\r\n"
271 "press any key to try again ... \r\n";
272
273#define MESSAGE_OFFSET 29 /* Offset of message in above code */
274
275/* Global variables - the root of all evil :-) - see these and weep! */
276
277static char *program_name = "mkdosfs"; /* Name of the program */
278static char *device_name = NULL; /* Name of the device on which to create the filesystem */
279static int atari_format = 0; /* Use Atari variation of MS-DOS FS format */
280static int check = FALSE; /* Default to no readablity checking */
281static int verbose = 0; /* Default to verbose mode off */
282static long volume_id; /* Volume ID number */
283static time_t create_time; /* Creation time */
284static struct timeval create_timeval; /* Creation time */
285static char volume_name[] = " "; /* Volume name */
286static unsigned long long blocks; /* Number of blocks in filesystem */
287static int sector_size = 512; /* Size of a logical sector */
288static int sector_size_set = 0; /* User selected sector size */
289static int backup_boot = 0; /* Sector# of backup boot sector */
290static int reserved_sectors = 0; /* Number of reserved sectors */
291static int badblocks = 0; /* Number of bad blocks in the filesystem */
292static int nr_fats = 2; /* Default number of FATs to produce */
293static int size_fat = 0; /* Size in bits of FAT entries */
294static int size_fat_by_user = 0; /* 1 if FAT size user selected */
295static int dev = -1; /* FS block device file handle */
296static int ignore_full_disk = 0; /* Ignore warning about 'full' disk devices */
297static off_t currently_testing = 0; /* Block currently being tested (if autodetect bad blocks) */
298static struct msdos_boot_sector bs; /* Boot sector data */
299static int start_data_sector; /* Sector number for the start of the data area */
300static int start_data_block; /* Block number for the start of the data area */
301static unsigned char *fat; /* File allocation table */
302static unsigned alloced_fat_length; /* # of FAT sectors we can keep in memory */
303static unsigned char *info_sector; /* FAT32 info sector */
304static struct msdos_dir_entry *root_dir; /* Root directory */
305static int size_root_dir; /* Size of the root directory in bytes */
306static int sectors_per_cluster = 0; /* Number of sectors per disk cluster */
307static int root_dir_entries = 0; /* Number of root directory entries */
308static char *blank_sector; /* Blank sector - all zeros */
309static int hidden_sectors = 0; /* Number of hidden sectors */
310static int malloc_entire_fat = FALSE; /* Whether we should malloc() the entire FAT or not */
311static int align_structures = TRUE; /* Whether to enforce alignment */
312static int orphaned_sectors = 0; /* Sectors that exist in the last block of filesystem */
313
314/* Function prototype definitions */
315
316static void fatal_error(const char *fmt_string) __attribute__ ((noreturn));
317static void mark_FAT_cluster(int cluster, unsigned int value);
318static void mark_FAT_sector(int sector, unsigned int value);
319static long do_check(char *buffer, int try, off_t current_block);
320static void alarm_intr(int alnum);
321static void check_blocks(void);
322static void get_list_blocks(char *filename);
323static int valid_offset(int fd, loff_t offset);
324static unsigned long long count_blocks(char *filename, int *remainder);
325static void check_mount(char *device_name);
326static void establish_params(int device_num, int size);
327static void setup_tables(void);
328static void write_tables(void);
329
330/* The function implementations */
331
332/* Handle the reporting of fatal errors. Volatile to let gcc know that this doesn't return */
333
334static void fatal_error(const char *fmt_string)
335{
336 fprintf(stderr, fmt_string, program_name, device_name);
337 exit(1); /* The error exit code is 1! */
338}
339
340/* Mark the specified cluster as having a particular value */
341
342static void mark_FAT_cluster(int cluster, unsigned int value)
343{
344 switch (size_fat) {
345 case 12:
346 value &= 0x0fff;
347 if (((cluster * 3) & 0x1) == 0) {
348 fat[3 * cluster / 2] = (unsigned char)(value & 0x00ff);
349 fat[(3 * cluster / 2) + 1] =
350 (unsigned char)((fat[(3 * cluster / 2) + 1] & 0x00f0)
351 | ((value & 0x0f00) >> 8));
352 } else {
353 fat[3 * cluster / 2] =
354 (unsigned char)((fat[3 * cluster / 2] & 0x000f) |
355 ((value & 0x000f) << 4));
356 fat[(3 * cluster / 2) + 1] = (unsigned char)((value & 0x0ff0) >> 4);
357 }
358 break;
359
360 case 16:
361 value &= 0xffff;
362 fat[2 * cluster] = (unsigned char)(value & 0x00ff);
363 fat[(2 * cluster) + 1] = (unsigned char)(value >> 8);
364 break;
365
366 case 32:
367 value &= 0xfffffff;
368 fat[4 * cluster] = (unsigned char)(value & 0x000000ff);
369 fat[(4 * cluster) + 1] = (unsigned char)((value & 0x0000ff00) >> 8);
370 fat[(4 * cluster) + 2] = (unsigned char)((value & 0x00ff0000) >> 16);
371 fat[(4 * cluster) + 3] = (unsigned char)((value & 0xff000000) >> 24);
372 break;
373
374 default:
375 die("Bad FAT size (not 12, 16, or 32)");
376 }
377}
378
379/* Mark a specified sector as having a particular value in it's FAT entry */
380
381static void mark_FAT_sector(int sector, unsigned int value)
382{
383 int cluster;
384
385 cluster = (sector - start_data_sector) / (int)(bs.cluster_size) /
386 (sector_size / HARD_SECTOR_SIZE);
387 if (cluster < 0)
388 die("Invalid cluster number in mark_FAT_sector: probably bug!");
389
390 mark_FAT_cluster(cluster, value);
391}
392
393/* Perform a test on a block. Return the number of blocks that could be read successfully */
394
395static long do_check(char *buffer, int try, off_t current_block)
396{
397 long got;
398
399 if (llseek(dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */
400 !=current_block * BLOCK_SIZE)
401 die("seek failed during testing for blocks");
402
403 got = read(dev, buffer, try * BLOCK_SIZE); /* Try reading! */
404 if (got < 0)
405 got = 0;
406
407 if (got & (BLOCK_SIZE - 1))
408 printf("Unexpected values in do_check: probably bugs\n");
409 got /= BLOCK_SIZE;
410
411 return got;
412}
413
414/* Alarm clock handler - display the status of the quest for bad blocks! Then retrigger the alarm for five senconds
415 later (so we can come here again) */
416
417static void alarm_intr(int alnum)
418{
419 if (currently_testing >= blocks)
420 return;
421
422 signal(SIGALRM, alarm_intr);
423 alarm(5);
424 if (!currently_testing)
425 return;
426
427 printf("%lld... ", (unsigned long long)currently_testing);
428 fflush(stdout);
429}
430
431static void check_blocks(void)
432{
433 int try, got;
434 int i;
435 static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
436
437 if (verbose) {
438 printf("Searching for bad blocks ");
439 fflush(stdout);
440 }
441 currently_testing = 0;
442 if (verbose) {
443 signal(SIGALRM, alarm_intr);
444 alarm(5);
445 }
446 try = TEST_BUFFER_BLOCKS;
447 while (currently_testing < blocks) {
448 if (currently_testing + try > blocks)
449 try = blocks - currently_testing;
450 got = do_check(blkbuf, try, currently_testing);
451 currently_testing += got;
452 if (got == try) {
453 try = TEST_BUFFER_BLOCKS;
454 continue;
455 } else
456 try = 1;
457 if (currently_testing < start_data_block)
458 die("bad blocks before data-area: cannot make fs");
459
460 for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */
461 mark_sector_bad(currently_testing * SECTORS_PER_BLOCK + i);
462 badblocks++;
463 currently_testing++;
464 }
465
466 if (verbose)
467 printf("\n");
468
469 if (badblocks)
470 printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : "");
471}
472
473static void get_list_blocks(char *filename)
474{
475 int i;
476 FILE *listfile;
477 unsigned long blockno;
478
479 listfile = fopen(filename, "r");
480 if (listfile == (FILE *) NULL)
481 die("Can't open file of bad blocks");
482
483 while (!feof(listfile)) {
484 fscanf(listfile, "%ld\n", &blockno);
485 for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */
486 mark_sector_bad(blockno * SECTORS_PER_BLOCK + i);
487 badblocks++;
488 }
489 fclose(listfile);
490
491 if (badblocks)
492 printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : "");
493}
494
495/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it
496 isn't valid or TRUE if it is */
497
498static int valid_offset(int fd, loff_t offset)
499{
500 char ch;
501
502 if (llseek(fd, offset, SEEK_SET) < 0)
503 return FALSE;
504 if (read(fd, &ch, 1) < 1)
505 return FALSE;
506 return TRUE;
507}
508
509/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */
510
511static unsigned long long count_blocks(char *filename, int *remainder)
512
513{
514 loff_t high, low;
515 int fd;
516
517 if ((fd = open(filename, O_RDONLY)) < 0) {
518 perror(filename);
519 exit(1);
520 }
521
522 /* first try SEEK_END, which should work on most devices nowadays */
523 if ((low = llseek(fd, 0, SEEK_END)) <= 0) {
524 low = 0;
525 for (high = 1; valid_offset(fd, high); high *= 2)
526 low = high;
527 while (low < high - 1) {
528 const loff_t mid = (low + high) / 2;
529 if (valid_offset(fd, mid))
530 low = mid;
531 else
532 high = mid;
533 }
534 ++low;
535 }
536
537 close(fd);
538 *remainder = (low%BLOCK_SIZE)/sector_size;
539 return(low / BLOCK_SIZE);
540}
541
542/* Check to see if the specified device is currently mounted - abort if it is */
543
544static void check_mount(char *device_name)
545{
546#if ! defined(_USING_BIONIC_)
547 FILE *f;
548 struct mntent *mnt;
549
550 if ((f = setmntent(MOUNTED, "r")) == NULL)
551 return;
552 while ((mnt = getmntent(f)) != NULL)
553 if (strcmp(device_name, mnt->mnt_fsname) == 0)
554 die("%s contains a mounted file system.");
555 endmntent(f);
556#endif
557}
558
559/* Establish the geometry and media parameters for the device */
560
561static void establish_params(int device_num, int size)
562{
563 long loop_size;
564 struct hd_geometry geometry;
565 struct floppy_struct param;
566 int def_root_dir_entries = 512;
567
568 if ((0 == device_num) || ((device_num & 0xff00) == 0x0200))
569 /* file image or floppy disk */
570 {
571 if (0 == device_num) {
572 param.size = size / 512;
573 switch (param.size) {
574 case 720:
575 param.sect = 9;
576 param.head = 2;
577 break;
578 case 1440:
579 param.sect = 9;
580 param.head = 2;
581 break;
582 case 2400:
583 param.sect = 15;
584 param.head = 2;
585 break;
586 case 2880:
587 param.sect = 18;
588 param.head = 2;
589 break;
590 case 5760:
591 param.sect = 36;
592 param.head = 2;
593 break;
594 default:
595 /* fake values */
596 param.sect = 32;
597 param.head = 64;
598 break;
599 }
600
601 } else { /* is a floppy diskette */
602
603 if (ioctl(dev, FDGETPRM, &param)) /* Can we get the diskette geometry? */
604 die("unable to get diskette geometry for '%s'");
605 }
606 bs.secs_track = CT_LE_W(param.sect); /* Set up the geometry information */
607 bs.heads = CT_LE_W(param.head);
608 switch (param.size) { /* Set up the media descriptor byte */
609 case 720: /* 5.25", 2, 9, 40 - 360K */
610 bs.media = (char)0xfd;
611 bs.cluster_size = (char)2;
612 def_root_dir_entries = 112;
613 break;
614
615 case 1440: /* 3.5", 2, 9, 80 - 720K */
616 bs.media = (char)0xf9;
617 bs.cluster_size = (char)2;
618 def_root_dir_entries = 112;
619 break;
620
621 case 2400: /* 5.25", 2, 15, 80 - 1200K */
622 bs.media = (char)0xf9;
623 bs.cluster_size = (char)(atari_format ? 2 : 1);
624 def_root_dir_entries = 224;
625 break;
626
627 case 5760: /* 3.5", 2, 36, 80 - 2880K */
628 bs.media = (char)0xf0;
629 bs.cluster_size = (char)2;
630 def_root_dir_entries = 224;
631 break;
632
633 case 2880: /* 3.5", 2, 18, 80 - 1440K */
634floppy_default:
635 bs.media = (char)0xf0;
636 bs.cluster_size = (char)(atari_format ? 2 : 1);
637 def_root_dir_entries = 224;
638 break;
639
640 default: /* Anything else */
641 if (0 == device_num)
642 goto def_hd_params;
643 else
644 goto floppy_default;
645 }
646 } else if ((device_num & 0xff00) == 0x0700) { /* This is a loop device */
647 if (ioctl(dev, BLKGETSIZE, &loop_size))
648 die("unable to get loop device size");
649
650 switch (loop_size) { /* Assuming the loop device -> floppy later */
651 case 720: /* 5.25", 2, 9, 40 - 360K */
652 bs.secs_track = CF_LE_W(9);
653 bs.heads = CF_LE_W(2);
654 bs.media = (char)0xfd;
655 bs.cluster_size = (char)2;
656 def_root_dir_entries = 112;
657 break;
658
659 case 1440: /* 3.5", 2, 9, 80 - 720K */
660 bs.secs_track = CF_LE_W(9);
661 bs.heads = CF_LE_W(2);
662 bs.media = (char)0xf9;
663 bs.cluster_size = (char)2;
664 def_root_dir_entries = 112;
665 break;
666
667 case 2400: /* 5.25", 2, 15, 80 - 1200K */
668 bs.secs_track = CF_LE_W(15);
669 bs.heads = CF_LE_W(2);
670 bs.media = (char)0xf9;
671 bs.cluster_size = (char)(atari_format ? 2 : 1);
672 def_root_dir_entries = 224;
673 break;
674
675 case 5760: /* 3.5", 2, 36, 80 - 2880K */
676 bs.secs_track = CF_LE_W(36);
677 bs.heads = CF_LE_W(2);
678 bs.media = (char)0xf0;
679 bs.cluster_size = (char)2;
680 bs.dir_entries[0] = (char)224;
681 bs.dir_entries[1] = (char)0;
682 break;
683
684 case 2880: /* 3.5", 2, 18, 80 - 1440K */
685 bs.secs_track = CF_LE_W(18);
686 bs.heads = CF_LE_W(2);
687 bs.media = (char)0xf0;
688 bs.cluster_size = (char)(atari_format ? 2 : 1);
689 def_root_dir_entries = 224;
690 break;
691
692 default: /* Anything else: default hd setup */
693 printf("Loop device does not match a floppy size, using "
694 "default hd params\n");
695 bs.secs_track = CT_LE_W(32); /* these are fake values... */
696 bs.heads = CT_LE_W(64);
697 goto def_hd_params;
698 }
699 } else
700 /* Must be a hard disk then! */
701 {
702 /* Can we get the drive geometry? (Note I'm not too sure about */
703 /* whether to use HDIO_GETGEO or HDIO_REQ) */
704 if (ioctl(dev, HDIO_GETGEO, &geometry) || geometry.sectors == 0
705 || geometry.heads == 0) {
706 printf("unable to get drive geometry, using default 255/63\n");
707 bs.secs_track = CT_LE_W(63);
708 bs.heads = CT_LE_W(255);
709 } else {
710 bs.secs_track = CT_LE_W(geometry.sectors); /* Set up the geometry information */
711 bs.heads = CT_LE_W(geometry.heads);
712 }
713def_hd_params:
714 bs.media = (char)0xf8; /* Set up the media descriptor for a hard drive */
715 if (!size_fat && blocks * SECTORS_PER_BLOCK > 1064960) {
716 if (verbose)
717 printf("Auto-selecting FAT32 for large filesystem\n");
718 size_fat = 32;
719 }
720 if (size_fat == 32) {
721 /* For FAT32, try to do the same as M$'s format command
722 * (see http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20):
723 * fs size <= 260M: 0.5k clusters
724 * fs size <= 8G: 4k clusters
725 * fs size <= 16G: 8k clusters
726 * fs size > 16G: 16k clusters
727 */
728 unsigned long sz_mb =
729 (blocks + (1 << (20 - BLOCK_SIZE_BITS)) - 1) >> (20 -
730 BLOCK_SIZE_BITS);
731 bs.cluster_size =
732 sz_mb > 16 * 1024 ? 32 : sz_mb > 8 * 1024 ? 16 : sz_mb >
733 260 ? 8 : 1;
734 } else {
735 /* FAT12 and FAT16: start at 4 sectors per cluster */
736 bs.cluster_size = (char)4;
737 }
738 }
739
740 if (!root_dir_entries)
741 root_dir_entries = def_root_dir_entries;
742}
743
744/*
745 * If alignment is enabled, round the first argument up to the second; the
746 * latter must be a power of two.
747 */
748static unsigned int align_object(unsigned int sectors, unsigned int clustsize)
749{
750 if (align_structures)
751 return (sectors + clustsize - 1) & ~(clustsize - 1);
752 else
753 return sectors;
754}
755
756/* Create the filesystem data tables */
757
758static void setup_tables(void)
759{
760 unsigned num_sectors;
761 unsigned cluster_count = 0, fat_length;
762 struct tm *ctime;
763 struct msdos_volume_info *vi =
764 (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi);
765
766 if (atari_format)
767 /* On Atari, the first few bytes of the boot sector are assigned
768 * differently: The jump code is only 2 bytes (and m68k machine code
769 * :-), then 6 bytes filler (ignored), then 3 byte serial number. */
770 memcpy(bs.system_id - 1, "mkdosf", 6);
771 else
772 strcpy((char *)bs.system_id, "mkdosfs");
773 if (sectors_per_cluster)
774 bs.cluster_size = (char)sectors_per_cluster;
775 if (size_fat == 32) {
776 /* Under FAT32, the root dir is in a cluster chain, and this is
777 * signalled by bs.dir_entries being 0. */
778 root_dir_entries = 0;
779 }
780
781 if (atari_format) {
782 bs.system_id[5] = (unsigned char)(volume_id & 0x000000ff);
783 bs.system_id[6] = (unsigned char)((volume_id & 0x0000ff00) >> 8);
784 bs.system_id[7] = (unsigned char)((volume_id & 0x00ff0000) >> 16);
785 } else {
786 vi->volume_id[0] = (unsigned char)(volume_id & 0x000000ff);
787 vi->volume_id[1] = (unsigned char)((volume_id & 0x0000ff00) >> 8);
788 vi->volume_id[2] = (unsigned char)((volume_id & 0x00ff0000) >> 16);
789 vi->volume_id[3] = (unsigned char)(volume_id >> 24);
790 }
791
792 if (!atari_format) {
793 memcpy(vi->volume_label, volume_name, 11);
794
795 memcpy(bs.boot_jump, dummy_boot_jump, 3);
796 /* Patch in the correct offset to the boot code */
797 bs.boot_jump[1] = ((size_fat == 32 ?
798 (char *)&bs.fat32.boot_code :
799 (char *)&bs.oldfat.boot_code) - (char *)&bs) - 2;
800
801 if (size_fat == 32) {
802 int offset = (char *)&bs.fat32.boot_code -
803 (char *)&bs + MESSAGE_OFFSET + 0x7c00;
804 if (dummy_boot_code[BOOTCODE_FAT32_SIZE - 1])
805 printf("Warning: message too long; truncated\n");
806 dummy_boot_code[BOOTCODE_FAT32_SIZE - 1] = 0;
807 memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE);
808 bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff;
809 bs.fat32.boot_code[MSG_OFFSET_OFFSET + 1] = offset >> 8;
810 } else {
811 memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE);
812 }
813 bs.boot_sign = CT_LE_W(BOOT_SIGN);
814 } else {
815 memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2);
816 }
817 if (verbose >= 2)
818 printf("Boot jump code is %02x %02x\n",
819 bs.boot_jump[0], bs.boot_jump[1]);
820
821 if (!reserved_sectors)
822 reserved_sectors = (size_fat == 32) ? 32 : 1;
823 else {
824 if (size_fat == 32 && reserved_sectors < 2)
825 die("On FAT32 at least 2 reserved sectors are needed.");
826 }
827 bs.reserved = CT_LE_W(reserved_sectors);
828 if (verbose >= 2)
829 printf("Using %d reserved sectors\n", reserved_sectors);
830 bs.fats = (char)nr_fats;
831 if (!atari_format || size_fat == 32)
832 bs.hidden = CT_LE_L(hidden_sectors);
833 else {
834 /* In Atari format, hidden is a 16 bit field */
835 __u16 hidden = CT_LE_W(hidden_sectors);
836 if (hidden_sectors & ~0xffff)
837 die("#hidden doesn't fit in 16bit field of Atari format\n");
838 memcpy(&bs.hidden, &hidden, 2);
839 }
840
841 num_sectors = (long long)(blocks *BLOCK_SIZE / sector_size)+orphaned_sectors;
842
843 if (!atari_format) {
844 unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */
845 unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */
846 unsigned fatlength12, fatlength16, fatlength32;
847 unsigned maxclust12, maxclust16, maxclust32;
848 unsigned clust12, clust16, clust32;
849 int maxclustsize;
850 unsigned root_dir_sectors = cdiv(root_dir_entries * 32, sector_size);
851
852 /*
853 * If the filesystem is 8192 sectors or less (4 MB with 512-byte
854 * sectors, i.e. floppy size), don't align the data structures.
855 */
856 if (num_sectors <= 8192) {
857 if (align_structures && verbose >= 2)
858 printf("Disabling alignment due to tiny filesystem\n");
859
860 align_structures = FALSE;
861 }
862
863 if (sectors_per_cluster)
864 bs.cluster_size = maxclustsize = sectors_per_cluster;
865 else
866 /* An initial guess for bs.cluster_size should already be set */
867 maxclustsize = 128;
868
869 do {
870 fatdata32 = num_sectors
871 - align_object(reserved_sectors, bs.cluster_size);
872 fatdata1216 = fatdata32
873 - align_object(root_dir_sectors, bs.cluster_size);
874
875 if (verbose >= 2)
876 printf("Trying with %d sectors/cluster:\n", bs.cluster_size);
877
878 /* The factor 2 below avoids cut-off errors for nr_fats == 1.
879 * The "nr_fats*3" is for the reserved first two FAT entries */
880 clust12 = 2 * ((long long)fatdata1216 * sector_size + nr_fats * 3) /
881 (2 * (int)bs.cluster_size * sector_size + nr_fats * 3);
882 fatlength12 = cdiv(((clust12 + 2) * 3 + 1) >> 1, sector_size);
883 fatlength12 = align_object(fatlength12, bs.cluster_size);
884 /* Need to recalculate number of clusters, since the unused parts of the
885 * FATS and data area together could make up space for an additional,
886 * not really present cluster. */
887 clust12 = (fatdata1216 - nr_fats * fatlength12) / bs.cluster_size;
888 maxclust12 = (fatlength12 * 2 * sector_size) / 3;
889 if (maxclust12 > MAX_CLUST_12)
890 maxclust12 = MAX_CLUST_12;
891 if (verbose >= 2)
892 printf("FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
893 clust12, fatlength12, maxclust12, MAX_CLUST_12);
894 if (clust12 > maxclust12 - 2) {
895 clust12 = 0;
896 if (verbose >= 2)
897 printf("FAT12: too much clusters\n");
898 }
899
900 clust16 = ((long long)fatdata1216 * sector_size + nr_fats * 4) /
901 ((int)bs.cluster_size * sector_size + nr_fats * 2);
902 fatlength16 = cdiv((clust16 + 2) * 2, sector_size);
903 fatlength16 = align_object(fatlength16, bs.cluster_size);
904 /* Need to recalculate number of clusters, since the unused parts of the
905 * FATS and data area together could make up space for an additional,
906 * not really present cluster. */
907 clust16 = (fatdata1216 - nr_fats * fatlength16) / bs.cluster_size;
908 maxclust16 = (fatlength16 * sector_size) / 2;
909 if (maxclust16 > MAX_CLUST_16)
910 maxclust16 = MAX_CLUST_16;
911 if (verbose >= 2)
912 printf("FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
913 clust16, fatlength16, maxclust16, MAX_CLUST_16);
914 if (clust16 > maxclust16 - 2) {
915 if (verbose >= 2)
916 printf("FAT16: too much clusters\n");
917 clust16 = 0;
918 }
919 /* The < 4078 avoids that the filesystem will be misdetected as having a
920 * 12 bit FAT. */
921 if (clust16 < FAT12_THRESHOLD
922 && !(size_fat_by_user && size_fat == 16)) {
923 if (verbose >= 2)
924 printf(clust16 < FAT12_THRESHOLD ?
925 "FAT16: would be misdetected as FAT12\n" :
926 "FAT16: too much clusters\n");
927 clust16 = 0;
928 }
929
930 clust32 = ((long long)fatdata32 * sector_size + nr_fats * 8) /
931 ((int)bs.cluster_size * sector_size + nr_fats * 4);
932 fatlength32 = cdiv((clust32 + 2) * 4, sector_size);
933 fatlength32 = align_object(fatlength32, bs.cluster_size);
934 /* Need to recalculate number of clusters, since the unused parts of the
935 * FATS and data area together could make up space for an additional,
936 * not really present cluster. */
937 clust32 = (fatdata32 - nr_fats * fatlength32) / bs.cluster_size;
938 maxclust32 = (fatlength32 * sector_size) / 4;
939 if (maxclust32 > MAX_CLUST_32)
940 maxclust32 = MAX_CLUST_32;
941 if (clust32 && clust32 < MIN_CLUST_32
942 && !(size_fat_by_user && size_fat == 32)) {
943 clust32 = 0;
944 if (verbose >= 2)
945 printf("FAT32: not enough clusters (%d)\n", MIN_CLUST_32);
946 }
947 if (verbose >= 2)
948 printf("FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
949 clust32, fatlength32, maxclust32, MAX_CLUST_32);
950 if (clust32 > maxclust32) {
951 clust32 = 0;
952 if (verbose >= 2)
953 printf("FAT32: too much clusters\n");
954 }
955
956 if ((clust12 && (size_fat == 0 || size_fat == 12)) ||
957 (clust16 && (size_fat == 0 || size_fat == 16)) ||
958 (clust32 && size_fat == 32))
959 break;
960
961 bs.cluster_size <<= 1;
962 } while (bs.cluster_size && bs.cluster_size <= maxclustsize);
963
964 /* Use the optimal FAT size if not specified;
965 * FAT32 is (not yet) choosen automatically */
966 if (!size_fat) {
967 size_fat = (clust16 > clust12) ? 16 : 12;
968 if (verbose >= 2)
969 printf("Choosing %d bits for FAT\n", size_fat);
970 }
971
972 switch (size_fat) {
973 case 12:
974 cluster_count = clust12;
975 fat_length = fatlength12;
976 bs.fat_length = CT_LE_W(fatlength12);
977 memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8);
978 break;
979
980 case 16:
981 if (clust16 < FAT12_THRESHOLD) {
982 if (size_fat_by_user) {
983 fprintf(stderr, "WARNING: Not enough clusters for a "
984 "16 bit FAT! The filesystem will be\n"
985 "misinterpreted as having a 12 bit FAT without "
986 "mount option \"fat=16\".\n");
987 } else {
988 fprintf(stderr, "This filesystem has an unfortunate size. "
989 "A 12 bit FAT cannot provide\n"
990 "enough clusters, but a 16 bit FAT takes up a little "
991 "bit more space so that\n"
992 "the total number of clusters becomes less than the "
993 "threshold value for\n"
994 "distinction between 12 and 16 bit FATs.\n");
995 die("Make the file system a bit smaller manually.");
996 }
997 }
998 cluster_count = clust16;
999 fat_length = fatlength16;
1000 bs.fat_length = CT_LE_W(fatlength16);
1001 memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8);
1002 break;
1003
1004 case 32:
1005 if (clust32 < MIN_CLUST_32)
1006 fprintf(stderr,
1007 "WARNING: Not enough clusters for a 32 bit FAT!\n");
1008 cluster_count = clust32;
1009 fat_length = fatlength32;
1010 bs.fat_length = CT_LE_W(0);
1011 bs.fat32.fat32_length = CT_LE_L(fatlength32);
1012 memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8);
1013 root_dir_entries = 0;
1014 break;
1015
1016 default:
1017 die("FAT not 12, 16 or 32 bits");
1018 }
1019
1020 /* Adjust the reserved number of sectors for alignment */
1021 reserved_sectors = align_object(reserved_sectors, bs.cluster_size);
1022 bs.reserved = CT_LE_W(reserved_sectors);
1023
1024 /* Adjust the number of root directory entries to help enforce alignment */
1025 if (align_structures) {
1026 root_dir_entries = align_object(root_dir_sectors, bs.cluster_size)
1027 * (sector_size >> 5);
1028 }
1029 } else {
1030 unsigned clusters, maxclust, fatdata;
1031
1032 /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on
1033 * hard disks. So use 12 bit if the size of the file system suggests that
1034 * this fs is for a floppy disk, if the user hasn't explicitly requested a
1035 * size.
1036 */
1037 if (!size_fat)
1038 size_fat = (num_sectors == 1440 || num_sectors == 2400 ||
1039 num_sectors == 2880 || num_sectors == 5760) ? 12 : 16;
1040 if (verbose >= 2)
1041 printf("Choosing %d bits for FAT\n", size_fat);
1042
1043 /* Atari format: cluster size should be 2, except explicitly requested by
1044 * the user, since GEMDOS doesn't like other cluster sizes very much.
1045 * Instead, tune the sector size for the FS to fit.
1046 */
1047 bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2;
1048 if (!sector_size_set) {
1049 while (num_sectors > GEMDOS_MAX_SECTORS) {
1050 num_sectors >>= 1;
1051 sector_size <<= 1;
1052 }
1053 }
1054 if (verbose >= 2)
1055 printf("Sector size must be %d to have less than %d log. sectors\n",
1056 sector_size, GEMDOS_MAX_SECTORS);
1057
1058 /* Check if there are enough FAT indices for how much clusters we have */
1059 do {
1060 fatdata = num_sectors - cdiv(root_dir_entries * 32, sector_size) -
1061 reserved_sectors;
1062 /* The factor 2 below avoids cut-off errors for nr_fats == 1 and
1063 * size_fat == 12
1064 * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries
1065 */
1066 clusters =
1067 (2 *
1068 ((long long)fatdata * sector_size -
1069 2 * nr_fats * size_fat / 8)) / (2 * ((int)bs.cluster_size *
1070 sector_size +
1071 nr_fats * size_fat / 8));
1072 fat_length = cdiv((clusters + 2) * size_fat / 8, sector_size);
1073 /* Need to recalculate number of clusters, since the unused parts of the
1074 * FATS and data area together could make up space for an additional,
1075 * not really present cluster. */
1076 clusters = (fatdata - nr_fats * fat_length) / bs.cluster_size;
1077 maxclust = (fat_length * sector_size * 8) / size_fat;
1078 if (verbose >= 2)
1079 printf("ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n",
1080 sector_size, clusters, fat_length, maxclust);
1081
1082 /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd);
1083 * first two numbers are reserved */
1084 if (maxclust <=
1085 (size_fat == 32 ? MAX_CLUST_32 : (1 << size_fat) - 0x10)
1086 && clusters <= maxclust - 2)
1087 break;
1088 if (verbose >= 2)
1089 printf(clusters > maxclust - 2 ?
1090 "Too many clusters\n" : "FAT too big\n");
1091
1092 /* need to increment sector_size once more to */
1093 if (sector_size_set)
1094 die("With this sector size, the maximum number of FAT entries "
1095 "would be exceeded.");
1096 num_sectors >>= 1;
1097 sector_size <<= 1;
1098 } while (sector_size <= GEMDOS_MAX_SECTOR_SIZE);
1099
1100 if (sector_size > GEMDOS_MAX_SECTOR_SIZE)
1101 die("Would need a sector size > 16k, which GEMDOS can't work with");
1102
1103 cluster_count = clusters;
1104 if (size_fat != 32)
1105 bs.fat_length = CT_LE_W(fat_length);
1106 else {
1107 bs.fat_length = 0;
1108 bs.fat32.fat32_length = CT_LE_L(fat_length);
1109 }
1110 }
1111
1112 bs.sector_size[0] = (char)(sector_size & 0x00ff);
1113 bs.sector_size[1] = (char)((sector_size & 0xff00) >> 8);
1114
1115 bs.dir_entries[0] = (char)(root_dir_entries & 0x00ff);
1116 bs.dir_entries[1] = (char)((root_dir_entries & 0xff00) >> 8);
1117
1118 if (size_fat == 32) {
1119 /* set up additional FAT32 fields */
1120 bs.fat32.flags = CT_LE_W(0);
1121 bs.fat32.version[0] = 0;
1122 bs.fat32.version[1] = 0;
1123 bs.fat32.root_cluster = CT_LE_L(2);
1124 bs.fat32.info_sector = CT_LE_W(1);
1125 if (!backup_boot)
1126 backup_boot = (reserved_sectors >= 7) ? 6 :
1127 (reserved_sectors >= 2) ? reserved_sectors - 1 : 0;
1128 else {
1129 if (backup_boot == 1)
1130 die("Backup boot sector must be after sector 1");
1131 else if (backup_boot >= reserved_sectors)
1132 die("Backup boot sector must be a reserved sector");
1133 }
1134 if (verbose >= 2)
1135 printf("Using sector %d as backup boot sector (0 = none)\n",
1136 backup_boot);
1137 bs.fat32.backup_boot = CT_LE_W(backup_boot);
1138 memset(&bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2));
1139 }
1140
1141 if (atari_format) {
1142 /* Just some consistency checks */
1143 if (num_sectors >= GEMDOS_MAX_SECTORS)
1144 die("GEMDOS can't handle more than 65531 sectors");
1145 else if (num_sectors >= OLDGEMDOS_MAX_SECTORS)
1146 printf("Warning: More than 32765 sector need TOS 1.04 "
1147 "or higher.\n");
1148 }
1149 if (num_sectors >= 65536) {
1150 bs.sectors[0] = (char)0;
1151 bs.sectors[1] = (char)0;
1152 bs.total_sect = CT_LE_L(num_sectors);
1153 } else {
1154 bs.sectors[0] = (char)(num_sectors & 0x00ff);
1155 bs.sectors[1] = (char)((num_sectors & 0xff00) >> 8);
1156 if (!atari_format)
1157 bs.total_sect = CT_LE_L(0);
1158 }
1159
1160 if (!atari_format)
1161 vi->ext_boot_sign = MSDOS_EXT_SIGN;
1162
1163 if (!cluster_count) {
1164 if (sectors_per_cluster) /* If yes, die if we'd spec'd sectors per cluster */
1165 die("Too many clusters for file system - try more sectors per cluster");
1166 else
1167 die("Attempting to create a too large file system");
1168 }
1169
1170 /* The two following vars are in hard sectors, i.e. 512 byte sectors! */
1171 start_data_sector = (reserved_sectors + nr_fats * fat_length) *
1172 (sector_size / HARD_SECTOR_SIZE);
1173 start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) /
1174 SECTORS_PER_BLOCK;
1175
1176 if (blocks < start_data_block + 32) /* Arbitrary undersize file system! */
1177 die("Too few blocks for viable file system");
1178
1179 if (verbose) {
1180 printf("%s has %d head%s and %d sector%s per track,\n",
1181 device_name, CF_LE_W(bs.heads),
1182 (CF_LE_W(bs.heads) != 1) ? "s" : "", CF_LE_W(bs.secs_track),
1183 (CF_LE_W(bs.secs_track) != 1) ? "s" : "");
1184 printf("logical sector size is %d,\n", sector_size);
1185 printf("using 0x%02x media descriptor, with %d sectors;\n",
1186 (int)(bs.media), num_sectors);
1187 printf("file system has %d %d-bit FAT%s and %d sector%s per cluster.\n",
1188 (int)(bs.fats), size_fat, (bs.fats != 1) ? "s" : "",
1189 (int)(bs.cluster_size), (bs.cluster_size != 1) ? "s" : "");
1190 printf("FAT size is %d sector%s, and provides %d cluster%s.\n",
1191 fat_length, (fat_length != 1) ? "s" : "",
1192 cluster_count, (cluster_count != 1) ? "s" : "");
1193 printf("There %s %u reserved sector%s.\n",
1194 (reserved_sectors != 1) ? "are" : "is",
1195 reserved_sectors, (reserved_sectors != 1) ? "s" : "");
1196
1197 if (size_fat != 32) {
1198 unsigned root_dir_entries =
1199 bs.dir_entries[0] + ((bs.dir_entries[1]) * 256);
1200 unsigned root_dir_sectors =
1201 cdiv(root_dir_entries * 32, sector_size);
1202 printf("Root directory contains %u slots and uses %u sectors.\n",
1203 root_dir_entries, root_dir_sectors);
1204 }
1205 printf("Volume ID is %08lx, ", volume_id &
1206 (atari_format ? 0x00ffffff : 0xffffffff));
1207 if (strcmp(volume_name, " "))
1208 printf("volume label %s.\n", volume_name);
1209 else
1210 printf("no volume label.\n");
1211 }
1212
1213 /* Make the file allocation tables! */
1214
1215 if (malloc_entire_fat)
1216 alloced_fat_length = fat_length;
1217 else
1218 alloced_fat_length = 1;
1219
1220 if ((fat =
1221 (unsigned char *)malloc(alloced_fat_length * sector_size)) == NULL)
1222 die("unable to allocate space for FAT image in memory");
1223
1224 memset(fat, 0, alloced_fat_length * sector_size);
1225
1226 mark_FAT_cluster(0, 0xffffffff); /* Initial fat entries */
1227 mark_FAT_cluster(1, 0xffffffff);
1228 fat[0] = (unsigned char)bs.media; /* Put media type in first byte! */
1229 if (size_fat == 32) {
1230 /* Mark cluster 2 as EOF (used for root dir) */
1231 mark_FAT_cluster(2, FAT_EOF);
1232 }
1233
1234 /* Make the root directory entries */
1235
1236 size_root_dir = (size_fat == 32) ?
1237 bs.cluster_size * sector_size :
1238 (((int)bs.dir_entries[1] * 256 + (int)bs.dir_entries[0]) *
1239 sizeof(struct msdos_dir_entry));
1240 if ((root_dir = (struct msdos_dir_entry *)malloc(size_root_dir)) == NULL) {
1241 free(fat); /* Tidy up before we die! */
1242 die("unable to allocate space for root directory in memory");
1243 }
1244
1245 memset(root_dir, 0, size_root_dir);
1246 if (memcmp(volume_name, " ", 11)) {
1247 struct msdos_dir_entry *de = &root_dir[0];
1248 memcpy(de->name, volume_name, 8);
1249 memcpy(de->ext, volume_name + 8, 3);
1250 de->attr = ATTR_VOLUME;
1251 ctime = localtime(&create_time);
1252 de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +
1253 (ctime->tm_min << 5) +
1254 (ctime->tm_hour << 11)));
1255 de->date =
1256 CT_LE_W((unsigned short)(ctime->tm_mday +
1257 ((ctime->tm_mon + 1) << 5) +
1258 ((ctime->tm_year - 80) << 9)));
1259 de->ctime_ms = 0;
1260 de->ctime = de->time;
1261 de->cdate = de->date;
1262 de->adate = de->date;
1263 de->starthi = CT_LE_W(0);
1264 de->start = CT_LE_W(0);
1265 de->size = CT_LE_L(0);
1266 }
1267
1268 if (size_fat == 32) {
1269 /* For FAT32, create an info sector */
1270 struct fat32_fsinfo *info;
1271
1272 if (!(info_sector = malloc(sector_size)))
1273 die("Out of memory");
1274 memset(info_sector, 0, sector_size);
1275 /* fsinfo structure is at offset 0x1e0 in info sector by observation */
1276 info = (struct fat32_fsinfo *)(info_sector + 0x1e0);
1277
1278 /* Info sector magic */
1279 info_sector[0] = 'R';
1280 info_sector[1] = 'R';
1281 info_sector[2] = 'a';
1282 info_sector[3] = 'A';
1283
1284 /* Magic for fsinfo structure */
1285 info->signature = CT_LE_L(0x61417272);
1286 /* We've allocated cluster 2 for the root dir. */
1287 info->free_clusters = CT_LE_L(cluster_count - 1);
1288 info->next_cluster = CT_LE_L(2);
1289
1290 /* Info sector also must have boot sign */
1291 *(__u16 *) (info_sector + 0x1fe) = CT_LE_W(BOOT_SIGN);
1292 }
1293
1294 if (!(blank_sector = malloc(sector_size)))
1295 die("Out of memory");
1296 memset(blank_sector, 0, sector_size);
1297}
1298
1299/* Write the new filesystem's data tables to wherever they're going to end up! */
1300
1301#define error(str) \
1302 do { \
1303 free (fat); \
1304 if (info_sector) free (info_sector); \
1305 free (root_dir); \
1306 die (str); \
1307 } while(0)
1308
1309#define seekto(pos,errstr) \
1310 do { \
1311 loff_t __pos = (pos); \
1312 if (llseek (dev, __pos, SEEK_SET) != __pos) \
1313 error ("seek to " errstr " failed whilst writing tables"); \
1314 } while(0)
1315
1316#define writebuf(buf,size,errstr) \
1317 do { \
1318 int __size = (size); \
1319 if (write (dev, buf, __size) != __size) \
1320 error ("failed whilst writing " errstr); \
1321 } while(0)
1322
1323static void write_tables(void)
1324{
1325 int x;
1326 int fat_length;
1327
1328 fat_length = (size_fat == 32) ?
1329 CF_LE_L(bs.fat32.fat32_length) : CF_LE_W(bs.fat_length);
1330
1331 seekto(0, "start of device");
1332 /* clear all reserved sectors */
1333 for (x = 0; x < reserved_sectors; ++x)
1334 writebuf(blank_sector, sector_size, "reserved sector");
1335 /* seek back to sector 0 and write the boot sector */
1336 seekto(0, "boot sector");
1337 writebuf((char *)&bs, sizeof(struct msdos_boot_sector), "boot sector");
1338 /* on FAT32, write the info sector and backup boot sector */
1339 if (size_fat == 32) {
1340 seekto(CF_LE_W(bs.fat32.info_sector) * sector_size, "info sector");
1341 writebuf(info_sector, 512, "info sector");
1342 if (backup_boot != 0) {
1343 seekto(backup_boot * sector_size, "backup boot sector");
1344 writebuf((char *)&bs, sizeof(struct msdos_boot_sector),
1345 "backup boot sector");
1346 }
1347 }
1348 /* seek to start of FATS and write them all */
1349 seekto(reserved_sectors * sector_size, "first FAT");
1350 for (x = 1; x <= nr_fats; x++) {
1351 int y;
1352 int blank_fat_length = fat_length - alloced_fat_length;
1353 writebuf(fat, alloced_fat_length * sector_size, "FAT");
1354 for (y = 0; y < blank_fat_length; y++)
1355 writebuf(blank_sector, sector_size, "FAT");
1356 }
1357 /* Write the root directory directly after the last FAT. This is the root
1358 * dir area on FAT12/16, and the first cluster on FAT32. */
1359 writebuf((char *)root_dir, size_root_dir, "root directory");
1360
1361 if (blank_sector)
1362 free(blank_sector);
1363 if (info_sector)
1364 free(info_sector);
1365 free(root_dir); /* Free up the root directory space from setup_tables */
1366 free(fat); /* Free up the fat table space reserved during setup_tables */
1367}
1368
1369/* Report the command usage and return a failure error code */
1370
1371void usage(void)
1372{
1373 fatal_error("\
1374Usage: mkdosfs [-a][-A][-c][-C][-v][-I][-l bad-block-file][-b backup-boot-sector]\n\
1375 [-m boot-msg-file][-n volume-name][-i volume-id]\n\
1376 [-s sectors-per-cluster][-S logical-sector-size][-f number-of-FATs]\n\
1377 [-h hidden-sectors][-F fat-size][-r root-dir-entries][-R reserved-sectors]\n\
1378 /dev/name [blocks]\n");
1379}
1380
1381/*
1382 * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
1383 * of MS-DOS filesystem by default.
1384 */
1385static void check_atari(void)
1386{
1387#ifdef __mc68000__
1388 FILE *f;
1389 char line[128], *p;
1390
1391 if (!(f = fopen("/proc/hardware", "r"))) {
1392 perror("/proc/hardware");
1393 return;
1394 }
1395
1396 while (fgets(line, sizeof(line), f)) {
1397 if (strncmp(line, "Model:", 6) == 0) {
1398 p = line + 6;
1399 p += strspn(p, " \t");
1400 if (strncmp(p, "Atari ", 6) == 0)
1401 atari_format = 1;
1402 break;
1403 }
1404 }
1405 fclose(f);
1406#endif
1407}
1408
1409/* The "main" entry point into the utility - we pick up the options and attempt to process them in some sort of sensible
1410 way. In the event that some/all of the options are invalid we need to tell the user so that something can be done! */
1411
1412int main(int argc, char **argv)
1413{
1414 int c;
1415 char *tmp;
1416 char *listfile = NULL;
1417 FILE *msgfile;
1418 struct stat statbuf;
1419 int i = 0, pos, ch;
1420 int create = 0;
1421 unsigned long long cblocks = 0;
1422 int min_sector_size;
1423
1424 if (argc && *argv) { /* What's the program name? */
1425 char *p;
1426 program_name = *argv;
1427 if ((p = strrchr(program_name, '/')))
1428 program_name = p + 1;
1429 }
1430
1431 gettimeofday(&create_timeval, NULL);
1432 create_time = create_timeval.tv_sec;
1433 volume_id = (u_int32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); /* Default volume ID = creation time, fudged for more uniqueness */
1434 check_atari();
1435
1436 printf("%s " VERSION " (" VERSION_DATE ")\n", program_name);
1437
1438 while ((c = getopt(argc, argv, "aAb:cCf:F:Ii:l:m:n:r:R:s:S:h:v")) != EOF)
1439 /* Scan the command line for options */
1440 switch (c) {
1441 case 'A': /* toggle Atari format */
1442 atari_format = !atari_format;
1443 break;
1444
1445 case 'a': /* a : skip alignment */
1446 align_structures = FALSE;
1447 break;
1448
1449 case 'b': /* b : location of backup boot sector */
1450 backup_boot = (int)strtol(optarg, &tmp, 0);
1451 if (*tmp || backup_boot < 2 || backup_boot > 0xffff) {
1452 printf("Bad location for backup boot sector : %s\n", optarg);
1453 usage();
1454 }
1455 break;
1456
1457 case 'c': /* c : Check FS as we build it */
1458 check = TRUE;
1459 malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */
1460 break;
1461
1462 case 'C': /* C : Create a new file */
1463 create = TRUE;
1464 break;
1465
1466 case 'f': /* f : Choose number of FATs */
1467 nr_fats = (int)strtol(optarg, &tmp, 0);
1468 if (*tmp || nr_fats < 1 || nr_fats > 4) {
1469 printf("Bad number of FATs : %s\n", optarg);
1470 usage();
1471 }
1472 break;
1473
1474 case 'F': /* F : Choose FAT size */
1475 size_fat = (int)strtol(optarg, &tmp, 0);
1476 if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32)) {
1477 printf("Bad FAT type : %s\n", optarg);
1478 usage();
1479 }
1480 size_fat_by_user = 1;
1481 break;
1482
1483 case 'h': /* h : number of hidden sectors */
1484 hidden_sectors = (int)strtol(optarg, &tmp, 0);
1485 if (*tmp || hidden_sectors < 0) {
1486 printf("Bad number of hidden sectors : %s\n", optarg);
1487 usage();
1488 }
1489 break;
1490
1491 case 'I':
1492 ignore_full_disk = 1;
1493 break;
1494
1495 case 'i': /* i : specify volume ID */
1496 volume_id = strtoul(optarg, &tmp, 16);
1497 if (*tmp) {
1498 printf("Volume ID must be a hexadecimal number\n");
1499 usage();
1500 }
1501 break;
1502
1503 case 'l': /* l : Bad block filename */
1504 listfile = optarg;
1505 malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */
1506 break;
1507
1508 case 'm': /* m : Set boot message */
1509 if (strcmp(optarg, "-")) {
1510 msgfile = fopen(optarg, "r");
1511 if (!msgfile)
1512 perror(optarg);
1513 } else
1514 msgfile = stdin;
1515
1516 if (msgfile) {
1517 /* The boot code ends at offset 448 and needs a null terminator */
1518 i = MESSAGE_OFFSET;
1519 pos = 0; /* We are at beginning of line */
1520 do {
1521 ch = getc(msgfile);
1522 switch (ch) {
1523 case '\r': /* Ignore CRs */
1524 case '\0': /* and nulls */
1525 break;
1526
1527 case '\n': /* LF -> CR+LF if necessary */
1528 if (pos) { /* If not at beginning of line */
1529 dummy_boot_code[i++] = '\r';
1530 pos = 0;
1531 }
1532 dummy_boot_code[i++] = '\n';
1533 break;
1534
1535 case '\t': /* Expand tabs */
1536 do {
1537 dummy_boot_code[i++] = ' ';
1538 pos++;
1539 }
1540 while (pos % 8 && i < BOOTCODE_SIZE - 1);
1541 break;
1542
1543 case EOF:
1544 dummy_boot_code[i++] = '\0'; /* Null terminator */
1545 break;
1546
1547 default:
1548 dummy_boot_code[i++] = ch; /* Store character */
1549 pos++; /* Advance position */
1550 break;
1551 }
1552 }
1553 while (ch != EOF && i < BOOTCODE_SIZE - 1);
1554
1555 /* Fill up with zeros */
1556 while (i < BOOTCODE_SIZE - 1)
1557 dummy_boot_code[i++] = '\0';
1558 dummy_boot_code[BOOTCODE_SIZE - 1] = '\0'; /* Just in case */
1559
1560 if (ch != EOF)
1561 printf("Warning: message too long; truncated\n");
1562
1563 if (msgfile != stdin)
1564 fclose(msgfile);
1565 }
1566 break;
1567
1568 case 'n': /* n : Volume name */
1569 sprintf(volume_name, "%-11.11s", optarg);
1570 break;
1571
1572 case 'r': /* r : Root directory entries */
1573 root_dir_entries = (int)strtol(optarg, &tmp, 0);
1574 if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768) {
1575 printf("Bad number of root directory entries : %s\n", optarg);
1576 usage();
1577 }
1578 break;
1579
1580 case 'R': /* R : number of reserved sectors */
1581 reserved_sectors = (int)strtol(optarg, &tmp, 0);
1582 if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff) {
1583 printf("Bad number of reserved sectors : %s\n", optarg);
1584 usage();
1585 }
1586 break;
1587
1588 case 's': /* s : Sectors per cluster */
1589 sectors_per_cluster = (int)strtol(optarg, &tmp, 0);
1590 if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2
1591 && sectors_per_cluster != 4 && sectors_per_cluster != 8
1592 && sectors_per_cluster != 16
1593 && sectors_per_cluster != 32
1594 && sectors_per_cluster != 64
1595 && sectors_per_cluster != 128)) {
1596 printf("Bad number of sectors per cluster : %s\n", optarg);
1597 usage();
1598 }
1599 break;
1600
1601 case 'S': /* S : Sector size */
1602 sector_size = (int)strtol(optarg, &tmp, 0);
1603 if (*tmp || (sector_size != 512 && sector_size != 1024 &&
1604 sector_size != 2048 && sector_size != 4096 &&
1605 sector_size != 8192 && sector_size != 16384 &&
1606 sector_size != 32768)) {
1607 printf("Bad logical sector size : %s\n", optarg);
1608 usage();
1609 }
1610 sector_size_set = 1;
1611 break;
1612
1613 case 'v': /* v : Verbose execution */
1614 ++verbose;
1615 break;
1616
1617 default:
1618 printf("Unknown option: %c\n", c);
1619 usage();
1620 }
1621 if (optind < argc) {
1622 device_name = argv[optind]; /* Determine the number of blocks in the FS */
1623
1624 if (!device_name) {
1625 printf("No device specified.\n");
1626 usage();
1627 }
1628
1629 if (!create)
1630 cblocks = count_blocks(device_name, &orphaned_sectors); /* Have a look and see! */
1631 }
1632 if (optind == argc - 2) { /* Either check the user specified number */
1633 blocks = strtoull(argv[optind + 1], &tmp, 0);
1634 if (!create && blocks != cblocks) {
1635 fprintf(stderr, "Warning: block count mismatch: ");
1636 fprintf(stderr, "found %llu but assuming %llu.\n", cblocks, blocks);
1637 }
1638 } else if (optind == argc - 1) { /* Or use value found */
1639 if (create)
1640 die("Need intended size with -C.");
1641 blocks = cblocks;
1642 tmp = "";
1643 } else {
1644 fprintf(stderr, "No device specified!\n");
1645 usage();
1646 }
1647 if (*tmp) {
1648 printf("Bad block count : %s\n", argv[optind + 1]);
1649 usage();
1650 }
1651
1652 if (check && listfile) /* Auto and specified bad block handling are mutually */
1653 die("-c and -l are incompatible"); /* exclusive of each other! */
1654
1655 if (!create) {
1656 check_mount(device_name); /* Is the device already mounted? */
1657 dev = open(device_name, O_EXCL | O_RDWR); /* Is it a suitable device to build the FS on? */
1658 if (dev < 0) {
1659 fprintf(stderr, "%s: unable to open %s: %s\n", program_name,
1660 device_name, strerror(errno));
1661 exit(1); /* The error exit code is 1! */
1662 }
1663 } else {
1664 loff_t offset = blocks * BLOCK_SIZE - 1;
1665 char null = 0;
1666 /* create the file */
1667 dev = open(device_name, O_EXCL | O_RDWR | O_CREAT | O_TRUNC, 0666);
1668 if (dev < 0)
1669 die("unable to create %s");
1670 /* seek to the intended end-1, and write one byte. this creates a
1671 * sparse-as-possible file of appropriate size. */
1672 if (llseek(dev, offset, SEEK_SET) != offset)
1673 die("seek failed");
1674 if (write(dev, &null, 1) < 0)
1675 die("write failed");
1676 if (llseek(dev, 0, SEEK_SET) != 0)
1677 die("seek failed");
1678 }
1679
1680 if (fstat(dev, &statbuf) < 0)
1681 die("unable to stat %s");
1682 if (!S_ISBLK(statbuf.st_mode)) {
1683 statbuf.st_rdev = 0;
1684 check = 0;
1685 } else
1686 /*
1687 * Ignore any 'full' fixed disk devices, if -I is not given.
1688 * On a MO-disk one doesn't need partitions. The filesytem can go
1689 * directly to the whole disk. Under other OSes this is known as
1690 * the 'superfloppy' format. As I don't know how to find out if
1691 * this is a MO disk I introduce a -I (ignore) switch. -Joey
1692 */
1693 if (!ignore_full_disk && ((statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */
1694 (statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */
1695 (statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */
1696 (statbuf.st_rdev & 0xff3f) == 0x1600) /* hdc, hdd */
1697 )
1698 die("Device partition expected, not making filesystem on entire device '%s' (use -I to override)");
1699
1700 if (sector_size_set) {
1701 if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0)
1702 if (sector_size < min_sector_size) {
1703 sector_size = min_sector_size;
1704 fprintf(stderr,
1705 "Warning: sector size was set to %d (minimal for this device)\n",
1706 sector_size);
1707 }
1708 } else {
1709 if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) {
1710 sector_size = min_sector_size;
1711 sector_size_set = 1;
1712 }
1713 }
1714
1715 if (sector_size > 4096)
1716 fprintf(stderr,
1717 "Warning: sector size is set to %d > 4096, such filesystem will not propably mount\n",
1718 sector_size);
1719
1720 establish_params(statbuf.st_rdev, statbuf.st_size);
1721 /* Establish the media parameters */
1722
1723 setup_tables(); /* Establish the file system tables */
1724
1725 if (check) /* Determine any bad block locations and mark them */
1726 check_blocks();
1727 else if (listfile)
1728 get_list_blocks(listfile);
1729
1730 write_tables(); /* Write the file system tables away! */
1731
1732 exit(0); /* Terminate with no errors! */
1733}