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, ¶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;
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。
}