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