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

来源:互联网 发布:无印良品 推荐 知乎 编辑:程序博客网 时间:2024/04/29 03:19

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

static void establish_params(int device_num, int size)
{
    long loop_size;
    struct hd_geometry geometry;
    struct floppy_struct param;
    int def_root_dir_entries = 512;

    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, &param)) /*  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;
     def_root_dir_entries = 112;
     break;

 case 1440:  /* 3.5", 2, 9, 80 - 720K */
     bs.media = (char)0xf9;
     bs.cluster_size = (char)2;
     def_root_dir_entries = 112;
     break;

 case 2400:  /* 5.25", 2, 15, 80 - 1200K */
     bs.media = (char)0xf9;
     bs.cluster_size = (char)(atari_format ? 2 : 1);
     def_root_dir_entries = 224;
     break;

 case 5760:  /* 3.5", 2, 36, 80 - 2880K */
     bs.media = (char)0xf0;
     bs.cluster_size = (char)2;
     def_root_dir_entries = 224;
     break;

 case 2880:  /* 3.5", 2, 18, 80 - 1440K */
floppy_default:
     bs.media = (char)0xf0;
     bs.cluster_size = (char)(atari_format ? 2 : 1);
     def_root_dir_entries = 224;
     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;
     def_root_dir_entries = 112;
     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;
     def_root_dir_entries = 112;
     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);
     def_root_dir_entries = 224;
     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);
     def_root_dir_entries = 224;
     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) || geometry.sectors == 0
     || geometry.heads == 0) {
     printf("unable to get drive geometry, using default 255/63\n");
     bs.secs_track = CT_LE_W(63);   //如果ioctl获取不到HDIO_GETGEO命令后的参数,就固定每一磁道为63个扇区。
     bs.heads = CT_LE_W(255);     //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 */   //固定磁盘为0xf8 (表现在目录项还是FAT表中的第0簇?一时忘了)
 if (!size_fat && blocks * SECTORS_PER_BLOCK > 1064960) {   //SECTORS_PER_BLOCK  = 2
     if (verbose)
  printf("Auto-selecting FAT32 for large filesystem\n");
     size_fat = 32;    //如果size_fat没有通过mkdosfs -F 等指定为32,16;且磁盘大小大于520G;就只能为FAT32,不能为FAT16了。
 }
 if (size_fat == 32) {
     /* For FAT32, try to do the same as M$'s format command
      * (see
http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20):
      * fs size <= 260M: 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);         //sz_mb 表示大小,单位转化为MB ;sz_mb = 3993MB
     bs.cluster_size =
  sz_mb > 16 * 1024 ? 32 : sz_mb > 8 * 1024 ? 16 : sz_mb >
  260 ? 8 : 1;         // 1:如果大于16G,每簇为32个扇区;2:如果大于8G,每簇为16个扇区;3:如果大于260M,每簇为8个扇区;4:其它为1扇区。
        printf("blocks = %llu,sz_mb = %lu,BLOCK_SIZE_BITS = %d,bs.cluster_size = %d\n",blocks,sz_mb,BLOCK_SIZE_BITS,bs.cluster_size);//blocks = 4088511,sz_mb = 3993,BLOCK_SIZE_BITS = 10,bs.cluster_size = 8
 } else {
     /* FAT12 and FAT16: start at 4 sectors per cluster */
     bs.cluster_size = (char)4;  //不是FAT32,每簇为4个扇区。
 }
    }

    if (!root_dir_entries)
 root_dir_entries = def_root_dir_entries;    //如果通过mkdosfs -r 参数设置, root_dir_entries = 512,根目录最大目录项为512。
}

原创粉丝点击