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