⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkdosfs.c~

📁 linux下格式化U盘的函数,从mkdosfs而来
💻 C~
📖 第 1 页 / 共 4 页
字号:
static intsetup_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);  }  if (verbose >= 2)    printf( "Boot jump code is %02x %02x\n",	    bs.boot_jump[0], bs.boot_jump[1] );  if (!reserved_sectors)      reserved_sectors = (size_fat == 32) ? 32 : 1;  else {      if (size_fat == 32 && reserved_sectors < 2)			return(_ERROR_);	  	//die("On FAT32 at least 2 reserved sectors are needed.");  }  bs.reserved = CT_LE_W(reserved_sectors);  if (verbose >= 2)    printf( "Using %d reserved sectors\n", reserved_sectors );  bs.fats = (char) nr_fats;  if (!atari_format || size_fat == 32)    bs.hidden = CT_LE_L(hidden_sectors);  else {    /* In Atari format, hidden is a 16 bit field */    __u16 hidden = CT_LE_W(hidden_sectors);    if (hidden_sectors & ~0xffff)		return(_ERROR_);     		// die("#hidden doesn't fit in 16bit field of Atari format\n");    memcpy( &bs.hidden, &hidden, 2 );  }  num_sectors = (long long)blocks*BLOCK_SIZE/sector_size;  if (!atari_format) {    unsigned fatlength12, fatlength16, fatlength32;    unsigned maxclust12, maxclust16, maxclust32;    unsigned clust12, clust16, clust32;    int maxclustsize;        fatdata = num_sectors - cdiv (root_dir_entries * 32, sector_size) -	      reserved_sectors;    if (sectors_per_cluster)      bs.cluster_size = maxclustsize = sectors_per_cluster;    else      /* An initial guess for bs.cluster_size should already be set */      maxclustsize = 128;    if (verbose >= 2)      printf( "%d sectors for FAT+data, starting with %d sectors/cluster\n",	      fatdata, bs.cluster_size );    do {      if (verbose >= 2)	printf( "Trying with %d sectors/cluster:\n", bs.cluster_size );      /* The factor 2 below avoids cut-off errors for nr_fats == 1.       * The "nr_fats*3" is for the reserved first two FAT entries */      clust12 = 2*((long long) fatdata *sector_size + nr_fats*3) /	(2*(int) bs.cluster_size * sector_size + nr_fats*3);      fatlength12 = cdiv (((clust12+2) * 3 + 1) >> 1, sector_size);      /* Need to recalculate number of clusters, since the unused parts of the       * FATS and data area together could make up space for an additional,       * not really present cluster. */      clust12 = (fatdata - nr_fats*fatlength12)/bs.cluster_size;      maxclust12 = (fatlength12 * 2 * sector_size) / 3;      if (maxclust12 > MAX_CLUST_12)	maxclust12 = MAX_CLUST_12;      if (verbose >= 2)	printf( "FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",		clust12, fatlength12, maxclust12, MAX_CLUST_12 );      if (clust12 > maxclust12-2) {	clust12 = 0;	if (verbose >= 2)	  printf( "FAT12: too much clusters\n" );      }      clust16 = ((long long) fatdata *sector_size + nr_fats*4) /	((int) bs.cluster_size * sector_size + nr_fats*2);      fatlength16 = cdiv ((clust16+2) * 2, sector_size);      /* Need to recalculate number of clusters, since the unused parts of the       * FATS and data area together could make up space for an additional,       * not really present cluster. */      clust16 = (fatdata - nr_fats*fatlength16)/bs.cluster_size;      maxclust16 = (fatlength16 * sector_size) / 2;      if (maxclust16 > MAX_CLUST_16)	maxclust16 = MAX_CLUST_16;      if (verbose >= 2)	printf( "FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",		clust16, fatlength16, maxclust16, MAX_CLUST_16 );      if (clust16 > maxclust16-2) {	if (verbose >= 2)	  printf( "FAT16: too much clusters\n" );	clust16 = 0;      }      /* The < 4078 avoids that the filesystem will be misdetected as having a       * 12 bit FAT. */      if (clust16 < FAT12_THRESHOLD && !(size_fat_by_user && size_fat == 16)) {	if (verbose >= 2)	  printf( clust16 < FAT12_THRESHOLD ?		  "FAT16: would be misdetected as FAT12\n" :		  "FAT16: too much clusters\n" );	clust16 = 0;      }      clust32 = ((long long) fatdata *sector_size + nr_fats*8) /	((int) bs.cluster_size * sector_size + nr_fats*4);      fatlength32 = cdiv ((clust32+2) * 4, sector_size);      /* Need to recalculate number of clusters, since the unused parts of the       * FATS and data area together could make up space for an additional,       * not really present cluster. */      clust32 = (fatdata - nr_fats*fatlength32)/bs.cluster_size;      maxclust32 = (fatlength32 * sector_size) / 4;      if (maxclust32 > MAX_CLUST_32)	maxclust32 = MAX_CLUST_32;      if (clust32 && clust32 < MIN_CLUST_32 && !(size_fat_by_user && size_fat == 32)) {       clust32 = 0;       if (verbose >= 2)         printf( "FAT32: not enough clusters (%d)\n", MIN_CLUST_32);      }      if (verbose >= 2)	printf( "FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",		clust32, fatlength32, maxclust32, MAX_CLUST_32 );      if (clust32 > maxclust32) {	clust32 = 0;	if (verbose >= 2)	  printf( "FAT32: too much clusters\n" );      }      if ((clust12 && (size_fat == 0 || size_fat == 12)) ||	  (clust16 && (size_fat == 0 || size_fat == 16)) ||	  (clust32 && size_fat == 32))	break;      bs.cluster_size <<= 1;    } while (bs.cluster_size && bs.cluster_size <= maxclustsize);    /* Use the optimal FAT size if not specified;     * FAT32 is (not yet) choosen automatically */    if (!size_fat) {	size_fat = (clust16 > clust12) ? 16 : 12;	if (verbose >= 2)	  printf( "Choosing %d bits for FAT\n", size_fat );    }    switch (size_fat) {      case 12:				cluster_count = clust12;				fat_length = fatlength12;				bs.fat_length = CT_LE_W(fatlength12);				memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8);			break; 	   case 16:	if (clust16 < FAT12_THRESHOLD) {	    if (size_fat_by_user) {		fprintf( stderr, "WARNING: Not enough clusters for a "			 "16 bit FAT! The filesystem will be\n"			 "misinterpreted as having a 12 bit FAT without "			 "mount option \"fat=16\".\n" );	    }	    else {		fprintf( stderr, "This filesystem has an unfortunate size. "			 "A 12 bit FAT cannot provide\n"			 "enough clusters, but a 16 bit FAT takes up a little "			 "bit more space so that\n"			 "the total number of clusters becomes less than the "			 "threshold value for\n"			 "distinction between 12 and 16 bit FATs.\n" );			return(_ERROR_);		//die( "Make the file system a bit smaller manually." );	    }	}			cluster_count = clust16;			fat_length = fatlength16;			bs.fat_length = CT_LE_W(fatlength16);			memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8);			break;      case 32:			cluster_count = clust32;			fat_length = fatlength32;			bs.fat_length = CT_LE_W(0);			bs.fat32.fat32_length = CT_LE_L(fatlength32);			memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8);			break;	      default:			return(_ERROR_);		//die("FAT not 12, 16 or 32 bits");    }  }  else {    unsigned clusters, maxclust;          /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on     * hard disks. So use 12 bit if the size of the file system suggests that     * this fs is for a floppy disk, if the user hasn't explicitly requested a     * size.     */    if (!size_fat)      size_fat = (num_sectors == 1440 || num_sectors == 2400 ||		  num_sectors == 2880 || num_sectors == 5760) ? 12 : 16;    if (verbose >= 2)      printf( "Choosing %d bits for FAT\n", size_fat );    /* Atari format: cluster size should be 2, except explicitly requested by     * the user, since GEMDOS doesn't like other cluster sizes very much.     * Instead, tune the sector size for the FS to fit.     */    bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2;    if (!sector_size_set) {      while( num_sectors > GEMDOS_MAX_SECTORS ) {	num_sectors >>= 1;	sector_size <<= 1;      }    }    if (verbose >= 2)      printf( "Sector size must be %d to have less than %d log. sectors\n",	      sector_size, GEMDOS_MAX_SECTORS );    /* Check if there are enough FAT indices for how much clusters we have */    do {      fatdata = num_sectors - cdiv (root_dir_entries * 32, sector_size) -		reserved_sectors;      /* The factor 2 below avoids cut-off errors for nr_fats == 1 and       * size_fat == 12       * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries       */      clusters = (2*((long long)fatdata*sector_size - 2*nr_fats*size_fat/8)) /		 (2*((int)bs.cluster_size*sector_size + nr_fats*size_fat/8));      fat_length = cdiv( (clusters+2)*size_fat/8, sector_size );      /* Need to recalculate number of clusters, since the unused parts of the       * FATS and data area together could make up space for an additional,       * not really present cluster. */      clusters = (fatdata - nr_fats*fat_length)/bs.cluster_size;      maxclust = (fat_length*sector_size*8)/size_fat;      if (verbose >= 2)	printf( "ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n",		sector_size, clusters, fat_length, maxclust );            /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd);       * first two numbers are reserved */      if (maxclust <= (size_fat == 32 ? MAX_CLUST_32 : (1<<size_fat)-0x10) &&	  clusters <= maxclust-2)	break;      if (verbose >= 2)	printf( clusters > maxclust-2 ?		"Too many clusters\n" : "FAT too big\n" );      /* need to increment sector_size once more to  */      if (sector_size_set)			return _ERROR_;	  //die( "With this sector size, the maximum number of FAT entries "	       "would be exceeded." );      num_sectors >>= 1;      sector_size <<= 1;    } while( sector_size <= GEMDOS_MAX_SECTOR_SIZE );        if (sector_size > GEMDOS_MAX_SECTOR_SIZE)		return(_ERROR_);      		//die( "Would need a sector size > 16k, which GEMDOS can't work with");    cluster_count = clusters;    if (size_fat != 32)	bs.fat_length = CT_LE_W(fat_length);    else {	bs.fat_length = 0;	bs.fat32.fat32_length = CT_LE_L(fat_length);    }  }  bs.sector_size[0] = (char) (sector_size & 0x00ff);  bs.sector_size[1] = (char) ((sector_size & 0xff00) >> 8);  if (size_fat == 32)    {      /* set up additional FAT32 fields */      bs.fat32.flags = CT_LE_W(0);      bs.fat32.version[0] = 0;      bs.fat32.version[1] = 0;      bs.fat32.root_cluster = CT_LE_L(2);      bs.fat32.info_sector = CT_LE_W(1);      if (!backup_boot)	backup_boot = (reserved_sectors >= 7) ? 6 :		      (reserved_sectors >= 2) ? reserved_sectors-1 : 0;      else	{	  if (backup_boot == 1)	   return _ERROR_;	//die("Backup boot sector must be after sector 1");	  else if (backup_boot >= reserved_sectors)	   return _ERROR_;	// die("Backup boot sector must be a reserved sector");	}      if (verbose >= 2)	printf( "Using sector %d as backup boot sector (0 = none)\n",		backup_boot );      bs.fat32.backup_boot = CT_LE_W(backup_boot);      memset( &bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2) );    }    if (atari_format) {      /* Just some consistency checks */      if (num_sectors >= GEMDOS_MAX_SECTORS)	  		return _ERROR_;	//die( "GEMDOS can't handle more than 65531 sectors" );      else if (num_sectors >= OLDGEMDOS_MAX_SECTORS)	  printf( "Warning: More than 32765 sector need TOS 1.04 "		  "or higher.\n" );  }  if (num_sectors >= 65536)    {      bs.sectors[0] = (char) 0;      bs.sectors[1] = (char) 0;      bs.total_sect = CT_LE_L(num_sectors);    }  else    {      bs.sectors[0] = (char) (num_sectors & 0x00ff);      bs.sectors[1] = (char) ((num_sectors & 0xff00) >> 8);      if (!atari_format)	  bs.total_sect = CT_LE_L(0);    }  if (!atari_format)    vi->ext_boot_sign = MSDOS_EXT_SIGN;  if (!cluster_count)    {  	return(_ERROR_); //   if (sectors_per_cluster)	/* If yes, die if we'd spec'd sectors per cluster */	//die ("Too many clusters for file system - try more sectors per cluster");     // else	//die ("Attempting to create a too large file system");    }    /* The two following vars are in hard sectors, i.e. 512 byte sectors! */  start_data_sector = (reserved_sectors + nr_fats * fat_length) *		      (sector_size/HARD_SECTOR_SIZE);  start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) /		     SECTORS_PER_BLOCK;  if (blocks < start_data_block + 32)	/* Arbitrary undersize file system! */   return(_ERROR_);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -