mkdosfs 建立硬盘启动扇区参数 (bs结构体 二)

mkdosfs 建立硬盘启动扇区参数 (bs结构体 二)

/* Create the filesystem data tables */

static void setup_tables(void)
{
    unsigned num_sectors;
    unsigned cluster_count = 0, fat_length;
    struct tm *ctime;
    struct msdos_volume_info *vi =
 (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi); //设置vi指针

    if (atari_format)  //atari_format = 0
 /* 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. */
 memcpy(bs.system_id - 1, "mkdosf", 6);
    else
 strcpy((char *)bs.system_id, "mkdosfs");
    if (sectors_per_cluster)  // 每簇扇区数sectors_per_cluster暂时为0
 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. */
 root_dir_entries = 0;
    }

    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);
    printf("volume_id = 0x%08lx,,vi->volume_id[0] = 0x%02x,vi->volume_id[1] = 0x%02x,vi->volume_id[2] = 0x%02x,vi->volume_id[3] = 0x%02x\n",volume_id,vi->volume_id[0],vi->volume_id[1],vi->volume_id[2],vi->volume_id[3]);

//volume_id = 0x0fee11bb,,vi->volume_id[0] = 0xbb,vi->volume_id[1] = 0x11,vi->volume_id[2] = 0xee,vi->volume_id[3] = 0x0f  //volume_id 是一个随机值.
    }

    if (!atari_format) {
 memcpy(vi->volume_label, volume_name, 11);
    printf("volume_name = [%s]\n",volume_name);//volume_name = [           ]

 memcpy(bs.boot_jump,dummy_boot_jump, 3);  //char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 }; 这三个字节是汇编跳转指令.
 /* 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); //BOOTCODE_FAT32_SIZE = 420 ,将默认的启动代码dummy_boot_code拷到bs.fat32.boot_code里.
        printf("dummy_boot_code:%s\n",dummy_boot_code);
     bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff;    //MSG_OFFSET_OFFSET  = 3
     bs.fat32.boot_code[MSG_OFFSET_OFFSET + 1] = offset>> 8;   //将默认启动代码的前420字节,计算好了的偏移量,赋给bs.fat32.boot_code的第3第4个字节进行更改.
 } else {
     memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE);
 }
 bs.boot_sign = CT_LE_W(BOOT_SIGN);    //0xAA55 结束,启动扇区标记忆 .小端存储变成 55  AA.
    } 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)   //未通过mkdosfs -R 设置.reserved_sectors = 0

       reserved_sectors= (size_fat == 32) ? 32 : 1;   //保留扇区数为32
    else {
 if (size_fat == 32 && reserved_sectors < 2)
     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;   //nr_fats 未通过mkdosfs -f 设置.默认为2. bs.fats = 2 个fats表.
    if (!atari_format || size_fat == 32)
 bs.hidden = CT_LE_L(hidden_sectors);     //隐藏扇区 未通过mkdosfs -h设置.默认为0.
    else {
 /* In Atari format, hidden is a 16 bit field */
 __u16 hidden = CT_LE_W(hidden_sectors);
 if (hidden_sectors & ~0xffff)
     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)+orphaned_sectors;  //总扇区数 = 总块数*1024/512 + 最后一块未能包含一扇区数.

    if (!atari_format) {
 unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */
 unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */
 unsigned fatlength12, fatlength16, fatlength32;
 unsigned maxclust12, maxclust16, maxclust32;
 unsigned clust12, clust16, clust32;
 int maxclustsize;
 unsigned root_dir_sectors = cdiv(root_dir_entries * 32, sector_size);

 /*
  * If the filesystem is 8192 sectors or less (4 MB with 512-byte
  * sectors, i.e. floppy size), don't align the data structures.
  */
 if (num_sectors <= 8192) {         //扇区数小于8192 ,就不进行对齐.
     if (align_structures && verbose >= 2)
  printf("Disabling alignment due to tiny filesystem\n");

     align_structures= FALSE;
 }

 if (sectors_per_cluster)     //sectors_per_cluster 每簇的扇区数未通过mkdosfs -s设置,默认为0.
     bs.cluster_size = maxclustsize = sectors_per_cluster;
 else
     /* An initial guess for bs.cluster_size should already be set */
     maxclustsize = 128;
printf("1111111111111111111111\n");
 do {     //这个do while 循环是找找出合适的簇大小.
     fatdata32 = num_sectors
  - align_object(reserved_sectors, bs.cluster_size);
     fatdata1216 = fatdata32
  - align_object(root_dir_sectors, bs.cluster_size);

printf("2222222222222222222222\n");
     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)fatdata1216 * sector_size + nr_fats * 3) /
  (2 * (int)bs.cluster_size * sector_size + nr_fats * 3);
     fatlength12 = cdiv(((clust12 + 2) * 3 + 1) >> 1, sector_size);
     fatlength12 = align_object(fatlength12, bs.cluster_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 = (fatdata1216 - 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)fatdata1216 * sector_size + nr_fats * 4) /
  ((int)bs.cluster_size * sector_size + nr_fats * 2);
     fatlength16 = cdiv((clust16 + 2) * 2, sector_size);
     fatlength16 = align_object(fatlength16, bs.cluster_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 = (fatdata1216 - 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)fatdata32 * sector_size + nr_fats * 8) /
  ((int)bs.cluster_size * sector_size + nr_fats * 4);
     fatlength32 = cdiv((clust32 + 2) * 4, sector_size);
     fatlength32 = align_object(fatlength32, bs.cluster_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 = (fatdata32 - 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);

printf("3333333333333333333333\n");
 /* 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);
 }

printf("4444444444444444444444size_fat = %d\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");
      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:
     if (clust32 < MIN_CLUST_32)   //#define MIN_CLUST_32    65529
  fprintf(stderr,
   "WARNING: Not enough clusters for a 32 bit FAT!\n");
        printf("clust32 = %d,MIN_CLUST_32 = %d\n",clust32,MIN_CLUST_32);  //clust32 = 2092804,MIN_CLUST_32 = 65529
     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);    //#define MSDOS_FAT32_SIGN "FAT32   "      /* FAT32 filesystem signature */
     root_dir_entries = 0;
     break;

 default:
     die("FAT not 12, 16 or 32 bits");
 }

 /* Adjust the reserved number of sectors for alignment */
 reserved_sectors = align_object(reserved_sectors, bs.cluster_size);
 bs.reserved = CT_LE_W(reserved_sectors);     //保留的扇区数.

    printf("align_structures = %d\n",align_structures);
 /* Adjust the number of root directory entries to help enforce alignment */
 if (align_structures) {    //未通过mkdosfs -a设置.默认为true ,强制对齐目录项.root_dir_entries = 0;
     root_dir_entries = align_object(root_dir_sectors, bs.cluster_size)
  * (sector_size >> 5);
        printf("root_dir_entries = %d\n",root_dir_entries);
 }
    } else {
 unsigned clusters, maxclust, fatdata;

 /* 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)
  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)
     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);
 }
    }

    printf("sector_size = %d,root_dir_entries = %d\n",sector_size,root_dir_entries);   //sector_size = 512,root_dir_entries = 0
    bs.sector_size[0] = (char)(sector_size & 0x00ff);
    bs.sector_size[1] = (char)((sector_size & 0xff00) >> 8);

    bs.dir_entries[0] = (char)(root_dir_entries & 0x00ff);
    bs.dir_entries[1] = (char)((root_dir_entries & 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未通过mkdosfs -b设置.默认为0.

     backup_boot = (reserved_sectors >= 7) ? 6  //保留扇区reserved_sectors 为 32;
  (reserved_sectors >= 2) ? reserved_sectors - 1 : 0;
 else {
     if (backup_boot == 1)
  die("Backup boot sector must be after sector 1");
     else if (backup_boot >= reserved_sectors)
  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);
    printf("backup_boot = %d\n",backup_boot);     //backup_boot = 6
 memset(&bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2));
    }

    if (atari_format) {
 /* Just some consistency checks */
 if (num_sectors >= GEMDOS_MAX_SECTORS)
     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");
    }
    printf("num_sectors = %d\n",num_sectors);//num_sectors = 16775168
    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;  //#define MSDOS_EXT_SIGN 0x29 /* extended boot sector signature */

    if (!cluster_count) {
 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);
    printf("reserved_sectors = %d, nr_fats = %d, fat_length = %d, sector_size = %d, HARD_SECTOR_SIZE = %d\n",reserved_sectors , nr_fats , fat_length , sector_size , HARD_SECTOR_SIZE);
    //reserved_sectors = 32, nr_fats = 2, fat_length = 16352, sector_size = 512, HARD_SECTOR_SIZE = 512
    start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) /
 SECTORS_PER_BLOCK;

    if (blocks < start_data_block + 32) /* Arbitrary undersize file system! */
 die("Too few blocks for viable file system");

    printf("verbose = %d\n",verbose);    //verbose = 0  ,感觉这一变量是调试用的.
    if (verbose) {
 printf("%s has %d head%s and %d sector%s per track,\n",
        device_name, CF_LE_W(bs.heads),
        (CF_LE_W(bs.heads) != 1) ? "s" : "", CF_LE_W(bs.secs_track),
        (CF_LE_W(bs.secs_track) != 1) ? "s" : "");
 printf("logical sector size is %d,\n", sector_size);
 printf("using 0x%02x media descriptor, with %d sectors;\n",
        (int)(bs.media), num_sectors);
 printf("file system has %d %d-bit FAT%s and %d sector%s per cluster.\n",
        (int)(bs.fats), size_fat, (bs.fats != 1) ? "s" : "",
        (int)(bs.cluster_size), (bs.cluster_size != 1) ? "s" : "");
 printf("FAT size is %d sector%s, and provides %d cluster%s.\n",
        fat_length, (fat_length != 1) ? "s" : "",
        cluster_count, (cluster_count != 1) ? "s" : "");
 printf("There %s %u reserved sector%s.\n",
        (reserved_sectors != 1) ? "are" : "is",
        reserved_sectors, (reserved_sectors != 1) ? "s" : "");

 if (size_fat != 32) {
     unsigned root_dir_entries =
  bs.dir_entries[0] + ((bs.dir_entries[1]) * 256);
     unsigned root_dir_sectors =
  cdiv(root_dir_entries * 32, sector_size);
     printf("Root directory contains %u slots and uses %u sectors.\n",
     root_dir_entries, root_dir_sectors);
 }
 printf("Volume ID is %08lx, ", volume_id &
        (atari_format ? 0x00ffffff : 0xffffffff));
 if (strcmp(volume_name, "           "))
     printf("volume label %s.\n", volume_name);
 else
     printf("no volume label.\n");
    }

    /* Make the file allocation tables! */

    printf("malloc_entire_fat = %d,alloced_fat_length = %d,fat_length = %d\n",malloc_entire_fat,alloced_fat_length,fat_length);

//malloc_entire_fat = 0,alloced_fat_length = 0,fat_length = 16352
    if (malloc_entire_fat)
 alloced_fat_length = fat_length;
    else
 alloced_fat_length = 1;

    if ((fat =
  (unsigned char *)malloc(alloced_fat_length * sector_size)) == NULL)
 die("unable to allocate space for FAT image in memory");

    memset(fat, 0, alloced_fat_length * sector_size);

    mark_FAT_cluster(0, 0xffffffff); /* Initial fat entries */
    mark_FAT_cluster(1, 0xffffffff);  //前两个簇,初始化,用户只能从第2簇开始。
    fat[0] = (unsigned char)bs.media; /* Put media type in first byte! */
    if (size_fat == 32) {
 /* Mark cluster 2 as EOF (used for root dir) */
 mark_FAT_cluster(2, FAT_EOF);  //#define FAT_EOF      (atari_format ? 0x0fffffff : 0x0ffffff8)
    }

    /* Make the root directory entries */

    printf("bs.cluster_size = %d , sector_size = %d\n",bs.cluster_size , sector_size);  //bs.cluster_size = 8 , sector_size = 512   一个簇=8扇区=8*512bytes
    size_root_dir = (size_fat == 32) ?
 bs.cluster_size * sector_size :
 (((int)bs.dir_entries[1] * 256 + (int)bs.dir_entries[0]) *
  sizeof(struct msdos_dir_entry));                      //根目录项size_root_dir =bs.cluster_size * sector_size = 8 个簇

    if ((root_dir = (struct msdos_dir_entry *)malloc(size_root_dir)) == NULL) {
 free(fat);  /* Tidy up before we die! */
 die("unable to allocate space for root directory in memory");
    }

    memset(root_dir, 0, size_root_dir);
    //设置磁盘卷名volume_name
    if (memcmp(volume_name, "           ", 11)) {
 struct msdos_dir_entry *de = &root_dir[0];  //struct msdos_dir_entry目录项信息结构体.
 memcpy(de->name, volume_name, 8);
 memcpy(de->ext, volume_name + 8, 3);
 de->attr = ATTR_VOLUME;
 ctime = localtime(&create_time);
 de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +
         (ctime->tm_min << 5) +
         (ctime->tm_hour << 11)));
 de->date =
     CT_LE_W((unsigned short)(ctime->tm_mday +
         ((ctime->tm_mon + 1) << 5) +
         ((ctime->tm_year - 80) << 9)));
 de->ctime_ms = 0;
 de->ctime = de->time;
 de->cdate = de->date;
 de->adate = de->date;
 de->starthi = CT_LE_W(0);
 de->start = CT_LE_W(0);
 de->size = CT_LE_L(0);
    }

    if (size_fat == 32) {
 /* For FAT32, create an info sector */
 struct fat32_fsinfo *info;

 if (!(info_sector = malloc(sector_size)))
     die("Out of memory");
 memset(info_sector, 0, sector_size);
 /* fsinfo structure is at offset 0x1e0 in info sector by observation */
 info = (struct fat32_fsinfo *)(info_sector + 0x1e0);

 /* Info sector magic */
 info_sector[0] = 'R';
 info_sector[1] = 'R';
 info_sector[2] = 'a';
 info_sector[3] = 'A';

 /* Magic for fsinfo structure */
 info->signature = CT_LE_L(0x61417272);
 /* We've allocated cluster 2 for the root dir. */
 info->free_clusters = CT_LE_L(cluster_count - 1);
 info->next_cluster = CT_LE_L(2);       //2簇为根目录.

 /* Info sector also must have boot sign */
 *(__u16 *) (info_sector + 0x1fe) = CT_LE_W(BOOT_SIGN);
    }

    if (!(blank_sector = malloc(sector_size)))
 die("Out of memory");
    memset(blank_sector, 0, sector_size);
}

你可能感兴趣的:(linux,存储,磁盘,mkdosfs)