mkdos: Drop from image. Use mkfs -t fat
Change-Id: If79f67126e23bea6c8dbb348f075832cd0bf8360 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5107 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
d188fff30b
commit
8fed6717a7
@@ -9,7 +9,7 @@ SYSTEM_BIN += [ FFilterByBuildFeatures
|
|||||||
dpms
|
dpms
|
||||||
FirstBootPrompt
|
FirstBootPrompt
|
||||||
<bin>i2c@x86,x86_64 installsound
|
<bin>i2c@x86,x86_64 installsound
|
||||||
mail mail2mbox mbox2mail media_client mkdos mount_nfs
|
mail mail2mbox mbox2mail media_client mount_nfs
|
||||||
play recover screenshot setcontrollook setdecor spamdbm
|
play recover screenshot setcontrollook setdecor spamdbm
|
||||||
translate
|
translate
|
||||||
WindowShade
|
WindowShade
|
||||||
|
|||||||
@@ -265,7 +265,6 @@ SubInclude HAIKU_TOP src bin locale ;
|
|||||||
SubInclude HAIKU_TOP src bin makebootable ;
|
SubInclude HAIKU_TOP src bin makebootable ;
|
||||||
SubInclude HAIKU_TOP src bin mail_utils ;
|
SubInclude HAIKU_TOP src bin mail_utils ;
|
||||||
SubInclude HAIKU_TOP src bin media_client ;
|
SubInclude HAIKU_TOP src bin media_client ;
|
||||||
SubInclude HAIKU_TOP src bin mkdos ;
|
|
||||||
SubInclude HAIKU_TOP src bin mkfs ;
|
SubInclude HAIKU_TOP src bin mkfs ;
|
||||||
SubInclude HAIKU_TOP src bin multiuser ;
|
SubInclude HAIKU_TOP src bin multiuser ;
|
||||||
SubInclude HAIKU_TOP src bin package ;
|
SubInclude HAIKU_TOP src bin package ;
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src bin mkdos ;
|
|
||||||
|
|
||||||
BinCommand mkdos :
|
|
||||||
mkdos.cpp
|
|
||||||
;
|
|
||||||
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
mkdos shell tool
|
|
||||||
|
|
||||||
Initialize FAT16 or FAT32 partitions, FAT12 floppy disks not supported
|
|
||||||
|
|
||||||
Copyright (c) 2002 Marcus Overhagen <[email protected]>, Haiku project
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ATTRIBUTE_PACKED __attribute__((packed))
|
|
||||||
|
|
||||||
struct bootsector1216 {
|
|
||||||
uint8 BS_jmpBoot[3];
|
|
||||||
uint8 BS_OEMName[8];
|
|
||||||
uint16 BPB_BytsPerSec;
|
|
||||||
uint8 BPB_SecPerClus;
|
|
||||||
uint16 BPB_RsvdSecCnt;
|
|
||||||
uint8 BPB_NumFATs;
|
|
||||||
uint16 BPB_RootEntCnt;
|
|
||||||
uint16 BPB_TotSec16;
|
|
||||||
uint8 BPB_Media;
|
|
||||||
uint16 BPB_FATSz16;
|
|
||||||
uint16 BPB_SecPerTrk;
|
|
||||||
uint16 BPB_NumHeads;
|
|
||||||
uint32 BPB_HiddSec;
|
|
||||||
uint32 BPB_TotSec32;
|
|
||||||
uint8 BS_DrvNum;
|
|
||||||
uint8 BS_Reserved1;
|
|
||||||
uint8 BS_BootSig;
|
|
||||||
uint8 BS_VolID[4];
|
|
||||||
uint8 BS_VolLab[11];
|
|
||||||
uint8 BS_FilSysType[8];
|
|
||||||
uint8 bootcode[448];
|
|
||||||
uint16 signature;
|
|
||||||
} ATTRIBUTE_PACKED;
|
|
||||||
|
|
||||||
struct bootsector32 {
|
|
||||||
uint8 BS_jmpBoot[3];
|
|
||||||
uint8 BS_OEMName[8];
|
|
||||||
uint16 BPB_BytsPerSec;
|
|
||||||
uint8 BPB_SecPerClus;
|
|
||||||
uint16 BPB_RsvdSecCnt;
|
|
||||||
uint8 BPB_NumFATs;
|
|
||||||
uint16 BPB_RootEntCnt;
|
|
||||||
uint16 BPB_TotSec16;
|
|
||||||
uint8 BPB_Media;
|
|
||||||
uint16 BPB_FATSz16;
|
|
||||||
uint16 BPB_SecPerTrk;
|
|
||||||
uint16 BPB_NumHeads;
|
|
||||||
uint32 BPB_HiddSec;
|
|
||||||
uint32 BPB_TotSec32;
|
|
||||||
uint32 BPB_FATSz32;
|
|
||||||
uint16 BPB_ExtFlags;
|
|
||||||
uint16 BPB_FSVer;
|
|
||||||
uint32 BPB_RootClus;
|
|
||||||
uint16 BPB_FSInfo;
|
|
||||||
uint16 BPB_BkBootSec;
|
|
||||||
uint8 BPB_Reserved[12];
|
|
||||||
uint8 BS_DrvNum;
|
|
||||||
uint8 BS_Reserved1;
|
|
||||||
uint8 BS_BootSig;
|
|
||||||
uint8 BS_VolID[4];
|
|
||||||
uint8 BS_VolLab[11];
|
|
||||||
uint8 BS_FilSysType[8];
|
|
||||||
uint8 bootcode[420];
|
|
||||||
uint16 signature;
|
|
||||||
} ATTRIBUTE_PACKED;
|
|
||||||
|
|
||||||
struct fsinfosector32 {
|
|
||||||
uint32 FSI_LeadSig;
|
|
||||||
uint8 FSI_Reserved1[480];
|
|
||||||
uint32 FSI_StrucSig;
|
|
||||||
uint32 FSI_Free_Count;
|
|
||||||
uint32 FSI_Nxt_Free;
|
|
||||||
uint8 FSI_Reserved2[12];
|
|
||||||
uint32 FSI_TrailSig;
|
|
||||||
} ATTRIBUTE_PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
// a FAT directory entry
|
|
||||||
struct dirent {
|
|
||||||
uint8 Name[11];
|
|
||||||
uint8 Attr;
|
|
||||||
uint8 NTRes;
|
|
||||||
uint8 CrtTimeTenth;
|
|
||||||
uint16 CrtTime;
|
|
||||||
uint16 CrtDate;
|
|
||||||
uint16 LstAccDate;
|
|
||||||
uint16 FstClusHI;
|
|
||||||
uint16 WrtTime;
|
|
||||||
uint16 WrtDate;
|
|
||||||
uint16 FstClusLO;
|
|
||||||
uint32 FileSize;
|
|
||||||
} ATTRIBUTE_PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
//maximum size of a 2,88 MB floppy
|
|
||||||
#define FLOPPY_MAX_SIZE (2 * 80 * 36 * 512)
|
|
||||||
|
|
||||||
//maximum size of a cluster
|
|
||||||
#define CLUSTER_MAX_SIZE 32768
|
|
||||||
|
|
||||||
//not sure if that's correct
|
|
||||||
#define FAT12_CLUSTER_MAX_SIZE 1024
|
|
||||||
|
|
||||||
//limits
|
|
||||||
#define FAT12_MAX_CLUSTER_COUNT 4084LL
|
|
||||||
#define FAT16_MAX_CLUSTER_COUNT 65524LL
|
|
||||||
#define FAT32_MAX_CLUSTER_COUNT 0x0fffffffLL
|
|
||||||
|
|
||||||
|
|
||||||
#define BOOTJMP_START_OFFSET 0x00
|
|
||||||
uint8 bootjmp[] = {
|
|
||||||
0xeb, 0x7e, 0x90
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BOOTCODE_START_OFFSET 0x80
|
|
||||||
uint8 bootcode[] = {
|
|
||||||
0x31, 0xc0, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e,
|
|
||||||
0xd8, 0xb4, 0x0e, 0x31, 0xdb, 0xbe, 0x00, 0x7d,
|
|
||||||
0xfc, 0xac, 0x08, 0xc0, 0x74, 0x04, 0xcd, 0x10,
|
|
||||||
0xeb, 0xf7, 0xb4, 0x00, 0xcd, 0x16, 0xcd, 0x19,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x53, 0x6f, 0x72, 0x72, 0x79, 0x2c, 0x20, 0x74,
|
|
||||||
0x68, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x6b,
|
|
||||||
0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20,
|
|
||||||
0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65,
|
|
||||||
0x2e, 0x0d, 0x0a, 0x50, 0x6c, 0x65, 0x61, 0x73,
|
|
||||||
0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20,
|
|
||||||
0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20,
|
|
||||||
0x74, 0x6f, 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f,
|
|
||||||
0x74, 0x2e, 0x0d, 0x0a, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BOOT_SECTOR_NUM 0
|
|
||||||
#define FSINFO_SECTOR_NUM 1
|
|
||||||
#define BACKUP_SECTOR_NUM 6
|
|
||||||
#define FAT32_ROOT_CLUSTER 2
|
|
||||||
|
|
||||||
@@ -1,675 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
mkdos shell tool
|
|
||||||
|
|
||||||
Initialize FAT16 or FAT32 partitions, FAT12 floppy disks not supported
|
|
||||||
|
|
||||||
Copyright (c) 2002 Marcus Overhagen <[email protected]>, Haiku project
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <ByteOrder.h>
|
|
||||||
#include <Drivers.h>
|
|
||||||
#include <OS.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "fat.h"
|
|
||||||
|
|
||||||
#define WITH_FLOPPY_SUPPORT
|
|
||||||
|
|
||||||
void PrintUsage();
|
|
||||||
void CreateVolumeLabel(void *sector, const char *label);
|
|
||||||
status_t Initialize(int fatbits, const char *device, const char *label, bool noprompt, bool testmode);
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (sizeof(bootsector1216) != 512 || sizeof(bootsector32) != 512 || sizeof(fsinfosector32) != 512) {
|
|
||||||
printf("compilation error: struct alignment wrong\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *device = NULL;
|
|
||||||
const char *label = NULL;
|
|
||||||
bool noprompt = false;
|
|
||||||
bool test = false;
|
|
||||||
int fat = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int c;
|
|
||||||
int option_index = 0;
|
|
||||||
static struct option long_options[] =
|
|
||||||
{
|
|
||||||
{"noprompt", no_argument, 0, 'n'},
|
|
||||||
{"test", no_argument, 0, 't'},
|
|
||||||
{"fat", required_argument, 0, 'f'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "ntf:", long_options, &option_index);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'n':
|
|
||||||
noprompt = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 't':
|
|
||||||
test = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
fat = strtol(optarg, NULL, 10);
|
|
||||||
if (fat == 0)
|
|
||||||
fat = -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("\n");
|
|
||||||
PrintUsage();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind < argc)
|
|
||||||
device = argv[optind];
|
|
||||||
if ((optind + 1) < argc)
|
|
||||||
label = argv[optind + 1];
|
|
||||||
|
|
||||||
if (fat != 0 && fat != 12 && fat != 16 && fat != 32) {
|
|
||||||
printf("mkdos error: fat must be 12, 16, or 32 bits\n");
|
|
||||||
PrintUsage();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device == NULL) {
|
|
||||||
printf("mkdos error: you must specify a device or partition or image\n");
|
|
||||||
printf(" such as /dev/disk/ide/ata/1/master/0/0_0\n");
|
|
||||||
PrintUsage();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label == NULL) {
|
|
||||||
label = "no name";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noprompt)
|
|
||||||
printf("will not prompt for confirmation\n");
|
|
||||||
|
|
||||||
if (test)
|
|
||||||
printf("test mode enabled (no writes will occur)\n");
|
|
||||||
|
|
||||||
status_t s;
|
|
||||||
s = Initialize(fat, device, label, noprompt, test);
|
|
||||||
|
|
||||||
if (s != 0) {
|
|
||||||
printf("Initializing failed!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (s == B_OK) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Initialize(int fatbits, const char *device, const char *label, bool noprompt, bool testmode)
|
|
||||||
{
|
|
||||||
if (fatbits != 0 && fatbits != 12 && fatbits != 16 && fatbits != 32) {
|
|
||||||
fprintf(stderr,"Error: don't know how to create a %d bit fat\n",fatbits);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
//XXX the following two checks can be removed when this is fixed:
|
|
||||||
#ifndef WITH_FLOPPY_SUPPORT
|
|
||||||
if (0 != strstr(device,"floppy")) {
|
|
||||||
fprintf(stderr,"Error: floppy B_GET_GEOMETRY and B_GET_BIOS_GEOMETRY calls are broken, floppy not supported\n");
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
if (fatbits == 12) {
|
|
||||||
fprintf(stderr,"Error: can't create a 12 bit fat on a device other than floppy\n");
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("device = %s\n",device);
|
|
||||||
|
|
||||||
int fd = open(device, O_RDWR);
|
|
||||||
if (fd < 0) {
|
|
||||||
fprintf(stderr, "Error: couldn't open file for device %s (%s)\n", device, strerror(errno));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isRawDevice;
|
|
||||||
bool hasBiosGeometry;
|
|
||||||
bool hasDeviceGeometry;
|
|
||||||
bool hasPartitionInfo;
|
|
||||||
device_geometry biosGeometry;
|
|
||||||
device_geometry deviceGeometry;
|
|
||||||
partition_info partitionInfo;
|
|
||||||
|
|
||||||
isRawDevice = 0 != strstr(device, "/raw");
|
|
||||||
hasBiosGeometry = B_OK == ioctl(fd, B_GET_BIOS_GEOMETRY, &biosGeometry, sizeof(biosGeometry));
|
|
||||||
hasDeviceGeometry = B_OK == ioctl(fd, B_GET_GEOMETRY, &deviceGeometry, sizeof(deviceGeometry));
|
|
||||||
hasPartitionInfo = B_OK == ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo, sizeof(partitionInfo));
|
|
||||||
|
|
||||||
if (!isRawDevice && !hasBiosGeometry && !hasDeviceGeometry && !hasPartitionInfo)
|
|
||||||
isRawDevice = true;
|
|
||||||
|
|
||||||
if (hasBiosGeometry) {
|
|
||||||
printf("bios geometry: %" B_PRIu32 " heads, "
|
|
||||||
"%" B_PRIu32 " cylinders, "
|
|
||||||
"%" B_PRIu32 " sectors/track, "
|
|
||||||
"%" B_PRIu32 " bytes/sector\n",
|
|
||||||
biosGeometry.head_count,
|
|
||||||
biosGeometry.cylinder_count,
|
|
||||||
biosGeometry.sectors_per_track,
|
|
||||||
biosGeometry.bytes_per_sector);
|
|
||||||
}
|
|
||||||
if (hasBiosGeometry) {
|
|
||||||
printf("device geometry: %" B_PRIu32 " heads, "
|
|
||||||
"%" B_PRIu32 " cylinders, "
|
|
||||||
"%" B_PRIu32 " sectors/track, "
|
|
||||||
"%" B_PRIu32 " bytes/sector\n",
|
|
||||||
deviceGeometry.head_count,
|
|
||||||
deviceGeometry.cylinder_count,
|
|
||||||
deviceGeometry.sectors_per_track,
|
|
||||||
deviceGeometry.bytes_per_sector);
|
|
||||||
}
|
|
||||||
if (hasPartitionInfo) {
|
|
||||||
printf("partition info: start at %" B_PRIdOFF " bytes "
|
|
||||||
"(%" B_PRIdOFF " sectors), "
|
|
||||||
"%" B_PRIdOFF " KB, "
|
|
||||||
"%" B_PRIdOFF " MB, "
|
|
||||||
"%" B_PRIdOFF " GB\n",
|
|
||||||
partitionInfo.offset,
|
|
||||||
partitionInfo.offset / 512,
|
|
||||||
partitionInfo.offset / 1024,
|
|
||||||
partitionInfo.offset / (1024 * 1024),
|
|
||||||
partitionInfo.offset / (1024 * 1024 * 1024));
|
|
||||||
printf("partition info: size %" B_PRIdOFF " bytes, "
|
|
||||||
"%" B_PRIdOFF " KB, "
|
|
||||||
"%" B_PRIdOFF " MB, "
|
|
||||||
"%" B_PRIdOFF " GB\n",
|
|
||||||
partitionInfo.size,
|
|
||||||
partitionInfo.size / 1024,
|
|
||||||
partitionInfo.size / (1024 * 1024),
|
|
||||||
partitionInfo.size / (1024 * 1024 * 1024));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isRawDevice && !hasPartitionInfo) {
|
|
||||||
fprintf(stderr,"Warning: couldn't get partition information\n");
|
|
||||||
}
|
|
||||||
if ((hasBiosGeometry && biosGeometry.bytes_per_sector != 512)
|
|
||||||
|| (hasDeviceGeometry && deviceGeometry.bytes_per_sector != 512)) {
|
|
||||||
fprintf(stderr,"Error: geometry block size not 512 bytes\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
} else if (hasPartitionInfo && partitionInfo.logical_block_size != 512) {
|
|
||||||
printf("partition logical block size is not 512, "
|
|
||||||
"it's %" B_PRId32 " bytes\n",
|
|
||||||
partitionInfo.logical_block_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasDeviceGeometry && deviceGeometry.read_only) {
|
|
||||||
fprintf(stderr,"Error: this is a read-only device\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
if (hasDeviceGeometry && deviceGeometry.write_once) {
|
|
||||||
fprintf(stderr,"Error: this is a write-once device\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
uint64 size = 0;
|
|
||||||
|
|
||||||
if (hasPartitionInfo) {
|
|
||||||
size = partitionInfo.size;
|
|
||||||
} else if (hasDeviceGeometry) {
|
|
||||||
size = uint64(deviceGeometry.bytes_per_sector) * deviceGeometry.sectors_per_track * deviceGeometry.cylinder_count * deviceGeometry.head_count;
|
|
||||||
} else if (hasBiosGeometry) {
|
|
||||||
size = uint64(biosGeometry.bytes_per_sector) * biosGeometry.sectors_per_track * biosGeometry.cylinder_count * biosGeometry.head_count;
|
|
||||||
} else {
|
|
||||||
// maybe it's just a file
|
|
||||||
struct stat stat;
|
|
||||||
if (fstat(fd, &stat) < 0) {
|
|
||||||
fprintf(stderr, "Error: couldn't get device partition or geometry information, nor size\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
size = stat.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO still valid on Haiku ?
|
|
||||||
/*if (isRawDevice && size > FLOPPY_MAX_SIZE) {
|
|
||||||
fprintf(stderr,"Error: device too large for floppy, or raw devices not supported\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
printf("size = %" B_PRIu64 " bytes "
|
|
||||||
"(%" B_PRIu64 " sectors), "
|
|
||||||
"%" B_PRIu64 " KB, "
|
|
||||||
"%" B_PRIu64 " MB, "
|
|
||||||
"%" B_PRIu64 " GB\n",
|
|
||||||
size,
|
|
||||||
size / 512,
|
|
||||||
size / 1024,
|
|
||||||
size / (1024 * 1024),
|
|
||||||
size / (1024 * 1024 * 1024));
|
|
||||||
|
|
||||||
if (fatbits == 0) {
|
|
||||||
//auto determine fat type
|
|
||||||
if (isRawDevice && size <= FLOPPY_MAX_SIZE && (size / FAT12_CLUSTER_MAX_SIZE) < FAT12_MAX_CLUSTER_COUNT) {
|
|
||||||
fatbits = 12;
|
|
||||||
} else if ((size / CLUSTER_MAX_SIZE) < FAT16_MAX_CLUSTER_COUNT) {
|
|
||||||
fatbits = 16;
|
|
||||||
} else if ((size / CLUSTER_MAX_SIZE) < FAT32_MAX_CLUSTER_COUNT) {
|
|
||||||
fatbits = 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fatbits == 0) {
|
|
||||||
fprintf(stderr,"Error: device too large for 32 bit fat\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sectorPerCluster;
|
|
||||||
|
|
||||||
sectorPerCluster = 0;
|
|
||||||
if (fatbits == 12) {
|
|
||||||
sectorPerCluster = 0;
|
|
||||||
if (size <= 4182016LL)
|
|
||||||
sectorPerCluster = 2; // XXX don't know the correct value
|
|
||||||
if (size <= 2091008LL)
|
|
||||||
sectorPerCluster = 1; // XXX don't know the correct value
|
|
||||||
} else if (fatbits == 16) {
|
|
||||||
// special BAD_CLUSTER value is 0xFFF7,
|
|
||||||
// but this should work anyway, since space required by
|
|
||||||
// two FATs will make maximum cluster count smaller.
|
|
||||||
// at least, this is what I think *should* happen
|
|
||||||
sectorPerCluster = 0; //larger than 2 GB must fail
|
|
||||||
if (size <= (2048 * 1024 * 1024LL)) // up to 2GB, use 32k clusters
|
|
||||||
sectorPerCluster = 64;
|
|
||||||
if (size <= (1024 * 1024 * 1024LL)) // up to 1GB, use 16k clusters
|
|
||||||
sectorPerCluster = 32;
|
|
||||||
if (size <= (512 * 1024 * 1024LL)) // up to 512MB, use 8k clusters
|
|
||||||
sectorPerCluster = 16;
|
|
||||||
if (size <= (256 * 1024 * 1024LL)) // up to 256MB, use 4k clusters
|
|
||||||
sectorPerCluster = 8;
|
|
||||||
if (size <= (128 * 1024 * 1024LL)) // up to 128MB, use 2k clusters
|
|
||||||
sectorPerCluster = 4;
|
|
||||||
if (size <= (16 * 1024 * 1024LL)) // up to 16MB, use 2k clusters
|
|
||||||
sectorPerCluster = 2;
|
|
||||||
if (size <= 4182016LL) // smaller than fat32 must fail
|
|
||||||
sectorPerCluster = 0;
|
|
||||||
} else if (fatbits == 32) {
|
|
||||||
sectorPerCluster = 64; // default is 32k clusters
|
|
||||||
if (size <= (32 * 1024 * 1024 * 1024LL)) // up to 32GB, use 16k clusters
|
|
||||||
sectorPerCluster = 32;
|
|
||||||
if (size <= (16 * 1024 * 1024 * 1024LL)) // up to 16GB, use 8k clusters
|
|
||||||
sectorPerCluster = 16;
|
|
||||||
if (size <= (8 * 1024 * 1024 * 1024LL)) // up to 8GB, use 4k clusters
|
|
||||||
sectorPerCluster = 8;
|
|
||||||
if (size <= (532480 * 512LL)) // up to 260 MB, use 0.5k clusters
|
|
||||||
sectorPerCluster = 1;
|
|
||||||
if (size <= (66600 * 512LL)) // smaller than 32.5 MB must fail
|
|
||||||
sectorPerCluster = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectorPerCluster == 0) {
|
|
||||||
fprintf(stderr,"Error: failed to determine sector per cluster value, partition too large for %d bit fat\n",fatbits);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int reservedSectorCount = 0; // avoid compiler warning
|
|
||||||
int rootEntryCount = 0; // avoid compiler warning
|
|
||||||
int numFATs;
|
|
||||||
int sectorSize;
|
|
||||||
uint8 biosDriveId;
|
|
||||||
|
|
||||||
// get bios drive-id, or use 0x80
|
|
||||||
if (B_OK != ioctl(fd, B_GET_BIOS_DRIVE_ID, &biosDriveId, sizeof(biosDriveId))) {
|
|
||||||
biosDriveId = 0x80;
|
|
||||||
} else {
|
|
||||||
printf("bios drive id: 0x%02x\n", (int)biosDriveId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// default parameters for the bootsector
|
|
||||||
numFATs = 2;
|
|
||||||
sectorSize = 512;
|
|
||||||
if (fatbits == 12 || fatbits == 16)
|
|
||||||
reservedSectorCount = 1;
|
|
||||||
if (fatbits == 32)
|
|
||||||
reservedSectorCount = 32;
|
|
||||||
if (fatbits == 12)
|
|
||||||
rootEntryCount = 128; // XXX don't know the correct value
|
|
||||||
if (fatbits == 16)
|
|
||||||
rootEntryCount = 512;
|
|
||||||
if (fatbits == 32)
|
|
||||||
rootEntryCount = 0;
|
|
||||||
|
|
||||||
// Determine FATSize
|
|
||||||
// calculation done as MS recommends
|
|
||||||
uint64 dskSize = size / sectorSize;
|
|
||||||
uint32 rootDirSectors = ((rootEntryCount * 32) + (sectorSize - 1)) / sectorSize;
|
|
||||||
uint64 tmpVal1 = dskSize - (reservedSectorCount + rootDirSectors);
|
|
||||||
uint64 tmpVal2 = (256 * sectorPerCluster) + numFATs;
|
|
||||||
if (fatbits == 32)
|
|
||||||
tmpVal2 = tmpVal2 / 2;
|
|
||||||
uint32 FATSize = (tmpVal1 + (tmpVal2 - 1)) / tmpVal2;
|
|
||||||
// FATSize should now contain the size of *one* FAT, measured in sectors
|
|
||||||
// RootDirSectors should now contain the size of the fat12/16 root directory, measured in sectors
|
|
||||||
|
|
||||||
printf("fatbits = %d, clustersize = %d\n", fatbits, sectorPerCluster * 512);
|
|
||||||
printf("FAT size is %" B_PRIu32 " sectors\n", FATSize);
|
|
||||||
printf("disk label: %s\n", label);
|
|
||||||
|
|
||||||
char bootsector[512];
|
|
||||||
memset(bootsector,0x00,512);
|
|
||||||
memcpy(bootsector + BOOTJMP_START_OFFSET, bootjmp, sizeof(bootjmp));
|
|
||||||
memcpy(bootsector + BOOTCODE_START_OFFSET, bootcode, sizeof(bootcode));
|
|
||||||
|
|
||||||
if (fatbits == 32) {
|
|
||||||
bootsector32 *bs = (bootsector32 *)bootsector;
|
|
||||||
uint16 temp16;
|
|
||||||
uint32 temp32;
|
|
||||||
memcpy(bs->BS_OEMName,"Haiku ",8);
|
|
||||||
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(sectorSize);
|
|
||||||
bs->BPB_SecPerClus = sectorPerCluster;
|
|
||||||
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(reservedSectorCount);
|
|
||||||
bs->BPB_NumFATs = numFATs;
|
|
||||||
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(rootEntryCount);
|
|
||||||
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(0);
|
|
||||||
bs->BPB_Media = 0xF8;
|
|
||||||
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(0);
|
|
||||||
temp16 = hasBiosGeometry ? biosGeometry.sectors_per_track : 63;
|
|
||||||
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
|
||||||
temp16 = hasBiosGeometry ? biosGeometry.head_count : 255;
|
|
||||||
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
|
||||||
temp32 = hasPartitionInfo ? (partitionInfo.size / 512) : 0;
|
|
||||||
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
|
||||||
temp32 = size / 512;
|
|
||||||
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
|
||||||
bs->BPB_FATSz32 = B_HOST_TO_LENDIAN_INT32(FATSize);
|
|
||||||
bs->BPB_ExtFlags = B_HOST_TO_LENDIAN_INT16(0);
|
|
||||||
bs->BPB_FSVer = B_HOST_TO_LENDIAN_INT16(0);
|
|
||||||
bs->BPB_RootClus = B_HOST_TO_LENDIAN_INT32(FAT32_ROOT_CLUSTER);
|
|
||||||
bs->BPB_FSInfo = B_HOST_TO_LENDIAN_INT16(FSINFO_SECTOR_NUM);
|
|
||||||
bs->BPB_BkBootSec = B_HOST_TO_LENDIAN_INT16(BACKUP_SECTOR_NUM);
|
|
||||||
memset(bs->BPB_Reserved,0,12);
|
|
||||||
bs->BS_DrvNum = biosDriveId;
|
|
||||||
bs->BS_Reserved1 = 0x00;
|
|
||||||
bs->BS_BootSig = 0x29;
|
|
||||||
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
|
||||||
memcpy(bs->BS_VolLab,"NO NAME ",11);
|
|
||||||
memcpy(bs->BS_FilSysType,"FAT32 ",8);
|
|
||||||
bs->signature = B_HOST_TO_LENDIAN_INT16(0xAA55);
|
|
||||||
} else {
|
|
||||||
bootsector1216 *bs = (bootsector1216 *)bootsector;
|
|
||||||
uint16 temp16;
|
|
||||||
uint32 temp32;
|
|
||||||
uint32 sectorcount = size / 512;
|
|
||||||
memcpy(bs->BS_OEMName, "Haiku ", 8);
|
|
||||||
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(sectorSize);
|
|
||||||
bs->BPB_SecPerClus = sectorPerCluster;
|
|
||||||
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(reservedSectorCount);
|
|
||||||
bs->BPB_NumFATs = numFATs;
|
|
||||||
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(rootEntryCount);
|
|
||||||
temp16 = (sectorcount <= 65535) ? sectorcount : 0;
|
|
||||||
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(temp16);
|
|
||||||
bs->BPB_Media = 0xF8;
|
|
||||||
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(FATSize);
|
|
||||||
temp16 = hasBiosGeometry ? biosGeometry.sectors_per_track : 63;
|
|
||||||
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
|
||||||
temp16 = hasBiosGeometry ? biosGeometry.head_count : 255;
|
|
||||||
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
|
||||||
temp32 = hasPartitionInfo ? (partitionInfo.size / 512) : 0;
|
|
||||||
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
|
||||||
temp32 = (sectorcount <= 65535) ? 0 : sectorcount;
|
|
||||||
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
|
||||||
bs->BS_DrvNum = biosDriveId;
|
|
||||||
bs->BS_Reserved1 = 0x00;
|
|
||||||
bs->BS_BootSig = 0x29;
|
|
||||||
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
|
||||||
memcpy(bs->BS_VolLab,"NO NAME ",11);
|
|
||||||
memcpy(bs->BS_FilSysType,(fatbits == 12) ? "FAT12 " : "FAT16 ",8);
|
|
||||||
bs->signature = B_HOST_TO_LENDIAN_INT16(0xAA55);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!noprompt) {
|
|
||||||
printf("\n");
|
|
||||||
printf("Initializing will erase all existing data on the drive.\n");
|
|
||||||
printf("Do you wish to proceed? ");
|
|
||||||
char answer[1000];
|
|
||||||
char *p;
|
|
||||||
memset(answer, 0, 1000);
|
|
||||||
fflush(stdout);
|
|
||||||
p = fgets(answer, 1000, stdin);
|
|
||||||
if (p && (p=strchr(p, '\n')))
|
|
||||||
*p = '\0'; /* remove newline */
|
|
||||||
if ((p == NULL) || (strlen(answer) < 1) || (0 != strncasecmp(answer, "yes", strlen(answer)))) {
|
|
||||||
printf("drive NOT initialized\n");
|
|
||||||
close(fd);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (testmode) {
|
|
||||||
close(fd);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disk layout:
|
|
||||||
// 0) reserved sectors, this includes the bootsector, fsinfosector and bootsector backup
|
|
||||||
// 1) FAT
|
|
||||||
// 2) root directory (not on fat32)
|
|
||||||
// 3) file & directory data
|
|
||||||
|
|
||||||
ssize_t written;
|
|
||||||
|
|
||||||
// initialize everything with zero first
|
|
||||||
// avoid doing 512 byte writes here, they are slow
|
|
||||||
printf("Writing FAT\n");
|
|
||||||
char * zerobuffer = (char *)malloc(65536);
|
|
||||||
if (zerobuffer == NULL) {
|
|
||||||
fprintf(stderr,"Error: out of memory\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
memset(zerobuffer,0,65536);
|
|
||||||
int64 bytes_to_write = 512LL * (reservedSectorCount + (numFATs * FATSize) + rootDirSectors);
|
|
||||||
int64 pos = 0;
|
|
||||||
while (bytes_to_write > 0) {
|
|
||||||
ssize_t writesize = min_c(bytes_to_write, 65536);
|
|
||||||
written = write_pos(fd, pos, zerobuffer, writesize);
|
|
||||||
if (written != writesize) {
|
|
||||||
fprintf(stderr, "Error: write error near sector %" B_PRId64 "\n",
|
|
||||||
pos / 512);
|
|
||||||
close(fd);
|
|
||||||
free(zerobuffer);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
bytes_to_write -= writesize;
|
|
||||||
pos += writesize;
|
|
||||||
}
|
|
||||||
free(zerobuffer);
|
|
||||||
|
|
||||||
//write boot sector
|
|
||||||
printf("Writing boot block\n");
|
|
||||||
written = write_pos(fd, BOOT_SECTOR_NUM * 512, bootsector, 512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr,"Error: write error at sector %d\n", BOOT_SECTOR_NUM);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fatbits == 32) {
|
|
||||||
written = write_pos(fd, BACKUP_SECTOR_NUM * 512, bootsector, 512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr,"Error: write error at sector %d\n", BACKUP_SECTOR_NUM);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//write first fat sector
|
|
||||||
printf("Writing first FAT sector\n");
|
|
||||||
uint8 sec[512];
|
|
||||||
memset(sec,0,512);
|
|
||||||
if (fatbits == 12) {
|
|
||||||
//FAT[0] contains media byte in lower 8 bits, all other bits set to 1
|
|
||||||
//FAT[1] contains EOF marker
|
|
||||||
sec[0] = 0xF8;
|
|
||||||
sec[1] = 0xFF;
|
|
||||||
sec[2] = 0xFF;
|
|
||||||
} else if (fatbits == 16) {
|
|
||||||
//FAT[0] contains media byte in lower 8 bits, all other bits set to 1
|
|
||||||
sec[0] = 0xF8;
|
|
||||||
sec[1] = 0xFF;
|
|
||||||
//FAT[1] contains EOF marker
|
|
||||||
sec[2] = 0xFF;
|
|
||||||
sec[3] = 0xFF;
|
|
||||||
} else if (fatbits == 32) {
|
|
||||||
//FAT[0] contains media byte in lower 8 bits, all other bits set to 1
|
|
||||||
sec[0] = 0xF8;
|
|
||||||
sec[1] = 0xFF;
|
|
||||||
sec[2] = 0xFF;
|
|
||||||
sec[3] = 0xFF;
|
|
||||||
//FAT[1] contains EOF marker
|
|
||||||
sec[4] = 0xFF;
|
|
||||||
sec[5] = 0xFF;
|
|
||||||
sec[6] = 0xFF;
|
|
||||||
sec[7] = 0x0F;
|
|
||||||
//FAT[2] contains EOF marker, used to terminate root directory
|
|
||||||
sec[8] = 0xFF;
|
|
||||||
sec[9] = 0xFF;
|
|
||||||
sec[10] = 0xFF;
|
|
||||||
sec[11] = 0x0F;
|
|
||||||
}
|
|
||||||
written = write_pos(fd, reservedSectorCount * 512, sec, 512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr,"Error: write error at sector %d\n", reservedSectorCount);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
if (numFATs > 1) {
|
|
||||||
written = write_pos(fd, (reservedSectorCount + FATSize) * 512,sec,512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr, "Error: write error at sector %" B_PRIu32 "\n",
|
|
||||||
reservedSectorCount + FATSize);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//write fsinfo sector
|
|
||||||
if (fatbits == 32) {
|
|
||||||
printf("Writing boot info\n");
|
|
||||||
//calculate total sector count first
|
|
||||||
uint64 free_count = size / 512;
|
|
||||||
//now account for already by metadata used sectors
|
|
||||||
free_count -= reservedSectorCount + (numFATs * FATSize) + rootDirSectors;
|
|
||||||
//convert from sector to clustercount
|
|
||||||
free_count /= sectorPerCluster;
|
|
||||||
//and account for 1 already used cluster of root directory
|
|
||||||
free_count -= 1;
|
|
||||||
fsinfosector32 fsinfosector;
|
|
||||||
memset(&fsinfosector,0x00,512);
|
|
||||||
fsinfosector.FSI_LeadSig = B_HOST_TO_LENDIAN_INT32(0x41615252);
|
|
||||||
fsinfosector.FSI_StrucSig = B_HOST_TO_LENDIAN_INT32(0x61417272);
|
|
||||||
fsinfosector.FSI_Free_Count = B_HOST_TO_LENDIAN_INT32((uint32)free_count);
|
|
||||||
fsinfosector.FSI_Nxt_Free = B_HOST_TO_LENDIAN_INT32(3);
|
|
||||||
fsinfosector.FSI_TrailSig = B_HOST_TO_LENDIAN_INT32(0xAA550000);
|
|
||||||
written = write_pos(fd, FSINFO_SECTOR_NUM * 512, &fsinfosector, 512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr,"Error: write error at sector %d\n", FSINFO_SECTOR_NUM);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//write volume label into root directory
|
|
||||||
printf("Writing root directory\n");
|
|
||||||
if (fatbits == 12 || fatbits == 16) {
|
|
||||||
uint8 data[512];
|
|
||||||
memset(data, 0, 512);
|
|
||||||
CreateVolumeLabel(data, label);
|
|
||||||
uint32 rootDirSector = reservedSectorCount + (numFATs * FATSize);
|
|
||||||
written = write_pos(fd, rootDirSector * 512, data, 512);
|
|
||||||
if (written != 512) {
|
|
||||||
fprintf(stderr, "Error: write error at sector %" B_PRIu32 "\n",
|
|
||||||
rootDirSector);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
} else if (fatbits == 32) {
|
|
||||||
int size = 512 * sectorPerCluster;
|
|
||||||
uint8 *cluster = (uint8*)malloc(size);
|
|
||||||
if (cluster == NULL) {
|
|
||||||
fprintf(stderr,"Error: out of memory\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
memset(cluster, 0, size);
|
|
||||||
CreateVolumeLabel(cluster, label);
|
|
||||||
uint32 rootDirSector = reservedSectorCount + (numFATs * FATSize) + rootDirSectors;
|
|
||||||
written = write_pos(fd, rootDirSector * 512, cluster, size);
|
|
||||||
free(cluster);
|
|
||||||
if (written != size) {
|
|
||||||
fprintf(stderr, "Error: write error at sector %" B_PRIu32 "\n",
|
|
||||||
rootDirSector);
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ioctl(fd, B_FLUSH_DRIVE_CACHE);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateVolumeLabel(void *sector, const char *label)
|
|
||||||
{
|
|
||||||
// create a volume name directory entry in the 512 byte sector
|
|
||||||
// XXX convert from UTF8, and check for valid characters
|
|
||||||
// XXX this could be changed to use long file name entrys,
|
|
||||||
// XXX but the dosfs would have to be updated, too
|
|
||||||
|
|
||||||
dirent *d = (dirent *)sector;
|
|
||||||
memset(d, 0, sizeof(*d));
|
|
||||||
memset(d->Name, 0x20, 11);
|
|
||||||
memcpy(d->Name, label, min_c(11, strlen(label)));
|
|
||||||
d->Attr = 0x08;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintUsage()
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
printf("(c) 2002 by Marcus Overhagen\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("usage: mkdos [-n] [-t] [-f 12|16|32] device [volume_label]\n");
|
|
||||||
printf(" -n, --noprompt do not prompt before writing\n");
|
|
||||||
printf(" -t, --test enable test mode (will not write to disk)\n");
|
|
||||||
printf(" -f, --fat use FAT entries of the specified size\n");
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@ run_fstorture() # ${1} => block size
|
|||||||
{
|
{
|
||||||
echo "Run test with bs=${1} ..."
|
echo "Run test with bs=${1} ..."
|
||||||
|
|
||||||
mkdos --fat 32 ${TEST_DEV}
|
mkfs -t fat ${TEST_DEV} TESTVOL
|
||||||
|
|
||||||
mkdir -p ${TEST_MP}
|
mkdir -p ${TEST_MP}
|
||||||
mount -t fat ${TEST_DEV} ${TEST_MP}
|
mount -t fat ${TEST_DEV} ${TEST_MP}
|
||||||
@@ -48,7 +48,7 @@ run_fsx() # ${1} => block size ${2} => features list
|
|||||||
{
|
{
|
||||||
echo "Run run_fsx_combined_parallel with bs=${1}"
|
echo "Run run_fsx_combined_parallel with bs=${1}"
|
||||||
|
|
||||||
mkdos --fat 32 ${TEST_DEV}
|
mkfs -t fat ${TEST_DEV} TESTVOL
|
||||||
|
|
||||||
mkdir -p ${TEST_MP}
|
mkdir -p ${TEST_MP}
|
||||||
mount -t fat ${TEST_DEV} ${TEST_MP}
|
mount -t fat ${TEST_DEV} ${TEST_MP}
|
||||||
|
|||||||
Reference in New Issue
Block a user