📄 mkdosfs.c
字号:
{ if (currently_testing >= blocks) return; signal (SIGALRM, alarm_intr); alarm (5); if (!currently_testing) return; printf ("%lld... ", (unsigned long long)currently_testing); fflush (stdout);}static voidcheck_blocks (void){ int try, got; int i; static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; if (verbose) { printf ("Searching for bad blocks "); fflush (stdout); } currently_testing = 0; if (verbose) { signal (SIGALRM, alarm_intr); alarm (5); } try = TEST_BUFFER_BLOCKS; while (currently_testing < blocks) { if (currently_testing + try > blocks) try = blocks - currently_testing; got = do_check (blkbuf, try, currently_testing); currently_testing += got; if (got == try) { try = TEST_BUFFER_BLOCKS; continue; } else try = 1; if (currently_testing < start_data_block) die ("bad blocks before data-area: cannot make fs"); for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ mark_sector_bad (currently_testing * SECTORS_PER_BLOCK + i); badblocks++; currently_testing++; } if (verbose) printf ("\n"); if (badblocks) printf ("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : "");}static voidget_list_blocks (char *filename){ int i; FILE *listfile; unsigned long blockno; listfile = fopen (filename, "r"); if (listfile == (FILE *) NULL) die ("Can't open file of bad blocks"); while (!feof (listfile)) { fscanf (listfile, "%ld\n", &blockno); for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ mark_sector_bad (blockno * SECTORS_PER_BLOCK + i); badblocks++; } fclose (listfile); if (badblocks) printf ("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : "");}/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it isn't valid or TRUE if it is */static intvalid_offset (int fd, loff_t offset){ char ch; if (llseek (fd, offset, SEEK_SET) < 0) return FALSE; if (read (fd, &ch, 1) < 1) return FALSE; return TRUE;}/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */static unsigned long longcount_blocks (char *filename){ off_t high, low; int fd; if ((fd = open (filename, O_RDONLY)) < 0) { perror (filename); exit (1); } /* first try SEEK_END, which should work on most devices nowadays */ if ((low = llseek(fd, 0, SEEK_END)) <= 0) { low = 0; for (high = 1; valid_offset (fd, high); high *= 2) low = high; while (low < high - 1) { const loff_t mid = (low + high) / 2; if (valid_offset (fd, mid)) low = mid; else high = mid; } ++low; } close (fd); return low / BLOCK_SIZE;}/* Check to see if the specified device is currently mounted - abort if it is */static voidcheck_mount (char *device_name){ FILE *f; struct mntent *mnt; if ((f = setmntent (MOUNTED, "r")) == NULL) return; while ((mnt = getmntent (f)) != NULL) if (strcmp (device_name, mnt->mnt_fsname) == 0) die ("%s contains a mounted file system."); endmntent (f);}/* Establish the geometry and media parameters for the device */static voidestablish_params (int device_num,int size){ long loop_size; struct hd_geometry geometry; struct floppy_struct param; if ((0 == device_num) || ((device_num & 0xff00) == 0x0200)) /* file image or floppy disk */ { if (0 == device_num) { param.size = size/512; switch(param.size) { case 720: param.sect = 9 ; param.head = 2; break; case 1440: param.sect = 9; param.head = 2; break; case 2400: param.sect = 15; param.head = 2; break; case 2880: param.sect = 18; param.head = 2; break; case 5760: param.sect = 36; param.head = 2; break; default: /* fake values */ param.sect = 32; param.head = 64; break; } } else /* is a floppy diskette */ { if (ioctl (dev, FDGETPRM, ¶m)) /* Can we get the diskette geometry? */ die ("unable to get diskette geometry for '%s'"); } bs.secs_track = CT_LE_W(param.sect); /* Set up the geometry information */ bs.heads = CT_LE_W(param.head); switch (param.size) /* Set up the media descriptor byte */ { case 720: /* 5.25", 2, 9, 40 - 360K */ bs.media = (char) 0xfd; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 112; bs.dir_entries[1] = (char) 0; break; case 1440: /* 3.5", 2, 9, 80 - 720K */ bs.media = (char) 0xf9; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 112; bs.dir_entries[1] = (char) 0; break; case 2400: /* 5.25", 2, 15, 80 - 1200K */ bs.media = (char) 0xf9; bs.cluster_size = (char)(atari_format ? 2 : 1); bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; case 5760: /* 3.5", 2, 36, 80 - 2880K */ bs.media = (char) 0xf0; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; case 2880: /* 3.5", 2, 18, 80 - 1440K */ floppy_default: bs.media = (char) 0xf0; bs.cluster_size = (char)(atari_format ? 2 : 1); bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; default: /* Anything else */ if (0 == device_num) goto def_hd_params; else goto floppy_default; } } else if ((device_num & 0xff00) == 0x0700) /* This is a loop device */ { if (ioctl (dev, BLKGETSIZE, &loop_size)) die ("unable to get loop device size"); switch (loop_size) /* Assuming the loop device -> floppy later */ { case 720: /* 5.25", 2, 9, 40 - 360K */ bs.secs_track = CF_LE_W(9); bs.heads = CF_LE_W(2); bs.media = (char) 0xfd; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 112; bs.dir_entries[1] = (char) 0; break; case 1440: /* 3.5", 2, 9, 80 - 720K */ bs.secs_track = CF_LE_W(9); bs.heads = CF_LE_W(2); bs.media = (char) 0xf9; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 112; bs.dir_entries[1] = (char) 0; break; case 2400: /* 5.25", 2, 15, 80 - 1200K */ bs.secs_track = CF_LE_W(15); bs.heads = CF_LE_W(2); bs.media = (char) 0xf9; bs.cluster_size = (char)(atari_format ? 2 : 1); bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; case 5760: /* 3.5", 2, 36, 80 - 2880K */ bs.secs_track = CF_LE_W(36); bs.heads = CF_LE_W(2); bs.media = (char) 0xf0; bs.cluster_size = (char) 2; bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; case 2880: /* 3.5", 2, 18, 80 - 1440K */ bs.secs_track = CF_LE_W(18); bs.heads = CF_LE_W(2); bs.media = (char) 0xf0; bs.cluster_size = (char)(atari_format ? 2 : 1); bs.dir_entries[0] = (char) 224; bs.dir_entries[1] = (char) 0; break; default: /* Anything else: default hd setup */ printf("Loop device does not match a floppy size, using " "default hd params\n"); bs.secs_track = CT_LE_W(32); /* these are fake values... */ bs.heads = CT_LE_W(64); goto def_hd_params; } } else /* Must be a hard disk then! */ { /* Can we get the drive geometry? (Note I'm not too sure about */ /* whether to use HDIO_GETGEO or HDIO_REQ) */ if (ioctl (dev, HDIO_GETGEO, &geometry)) { printf ("unable to get drive geometry, using default 255/63"); bs.secs_track = CT_LE_W(63); bs.heads = CT_LE_W(255); } else { bs.secs_track = CT_LE_W(geometry.sectors); /* Set up the geometry information */ bs.heads = CT_LE_W(geometry.heads); } def_hd_params: bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */ bs.dir_entries[0] = (char) 0; /* Default to 512 entries */ bs.dir_entries[1] = (char) 2; if (!size_fat && blocks*SECTORS_PER_BLOCK > 1064960) { if (verbose) printf("Auto-selecting FAT32 for large filesystem\n"); size_fat = 32; } if (size_fat == 32) { /* For FAT32, try to do the same as M$'s format command: * fs size < 256M: 0.5k clusters * fs size < 8G: 4k clusters * fs size < 16G: 8k clusters * fs size >= 16G: 16k clusters */ unsigned long sz_mb = (blocks+(1<<(20-BLOCK_SIZE_BITS))-1) >> (20-BLOCK_SIZE_BITS); bs.cluster_size = sz_mb >= 16*1024 ? 32 : sz_mb >= 8*1024 ? 16 : sz_mb >= 256 ? 8 : 1; } else { /* FAT12 and FAT16: start at 4 sectors per cluster */ bs.cluster_size = (char) 4; } }}/* Create the filesystem data tables */static voidsetup_tables (void){ unsigned num_sectors; unsigned cluster_count = 0, fat_length; unsigned fatdata; /* Sectors for FATs + data area */ struct tm *ctime; struct msdos_volume_info *vi = (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi); if (atari_format) /* On Atari, the first few bytes of the boot sector are assigned * differently: The jump code is only 2 bytes (and m68k machine code * :-), then 6 bytes filler (ignored), then 3 byte serial number. */ strncpy( bs.system_id-1, "mkdosf", 6 ); else strcpy (bs.system_id, "mkdosfs"); if (sectors_per_cluster) bs.cluster_size = (char) sectors_per_cluster; if (size_fat == 32) { /* Under FAT32, the root dir is in a cluster chain, and this is * signalled by bs.dir_entries being 0. */ bs.dir_entries[0] = bs.dir_entries[1] = (char) 0; root_dir_entries = 0; } else if (root_dir_entries) { /* Override default from establish_params() */ bs.dir_entries[0] = (char) (root_dir_entries & 0x00ff); bs.dir_entries[1] = (char) ((root_dir_entries & 0xff00) >> 8); } else root_dir_entries = bs.dir_entries[0] + (bs.dir_entries[1] << 8); if (atari_format) { bs.system_id[5] = (unsigned char) (volume_id & 0x000000ff); bs.system_id[6] = (unsigned char) ((volume_id & 0x0000ff00) >> 8); bs.system_id[7] = (unsigned char) ((volume_id & 0x00ff0000) >> 16); } else { vi->volume_id[0] = (unsigned char) (volume_id & 0x000000ff); vi->volume_id[1] = (unsigned char) ((volume_id & 0x0000ff00) >> 8); vi->volume_id[2] = (unsigned char) ((volume_id & 0x00ff0000) >> 16); vi->volume_id[3] = (unsigned char) (volume_id >> 24); } if (!atari_format) { memcpy(vi->volume_label, volume_name, 11); memcpy(bs.boot_jump, dummy_boot_jump, 3); /* Patch in the correct offset to the boot code */ bs.boot_jump[1] = ((size_fat == 32 ? (char *)&bs.fat32.boot_code : (char *)&bs.oldfat.boot_code) - (char *)&bs) - 2; if (size_fat == 32) { int offset = (char *)&bs.fat32.boot_code - (char *)&bs + MESSAGE_OFFSET + 0x7c00; if (dummy_boot_code[BOOTCODE_FAT32_SIZE-1]) printf ("Warning: message too long; truncated\n"); dummy_boot_code[BOOTCODE_FAT32_SIZE-1] = 0; memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE); bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff; bs.fat32.boot_code[MSG_OFFSET_OFFSET+1] = offset >> 8; } else { memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE); } bs.boot_sign = CT_LE_W(BOOT_SIGN); } else { memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -