ref: d0007933f27f2cc8a821987af86c3429c7443c6f
parent: fb948ee521c5102aedafc661fb4af5d432514f74
author: cinap_lenrek <[email protected]>
date: Mon May 7 14:06:17 EDT 2012
disk/format: FAT32 support
--- a/sys/man/8/prep
+++ b/sys/man/8/prep
@@ -713,10 +713,6 @@
.IR 9boot (8),
.IR partfs (8)
.SH BUGS
-.I Format
-can create FAT12 and FAT16
-file systems, but not FAT32 file systems.
-.PP
If
.L "prep -p"
doesn't find a Plan 9 partition table,
--- a/sys/src/cmd/disk/format.c
+++ b/sys/src/cmd/disk/format.c
@@ -45,13 +45,33 @@
uchar nheads[2];
uchar nhidden[4];
uchar bigvolsize[4];
- uchar driveno;
- uchar reserved0;
- uchar bootsig;
- uchar volid[4];
- uchar label[11];
- uchar type[8];
+ union {
+ struct {
+ uchar driveno;
+ uchar reserved0;
+ uchar bootsig;
+ uchar volid[4];
+ uchar label[11];
+ uchar type[8];
+ };
+ struct {
+ uchar fatsize[4];
+ uchar flags[2];
+ uchar ver[2];
+ uchar rootclust[4];
+ uchar fsinfo[2];
+ uchar bootbak[2];
+ uchar reserved0[12];
+ uchar driveno;
+ uchar reserved1;
+ uchar bootsig;
+ uchar volid[4];
+ uchar label[11];
+ uchar type[8];
+ } fat32;
+ };
};
+
#define PUTSHORT(p, v) { (p)[1] = (v)>>8; (p)[0] = (v); }
#define PUTLONG(p, v) { PUTSHORT((p), (v)); PUTSHORT((p)+2, (v)>>16); }
#define GETSHORT(p) (((p)[1]<<8)|(p)[0])
@@ -533,6 +553,12 @@
rootfiles = 512;
rootsecs = rootfiles/(secsize/sizeof(Dosdir));
}
+ if(fatbits == 32){
+ rootsecs -= (rootsecs % clustersize);
+ if(rootsecs <= 0)
+ rootsecs = clustersize;
+ rootfiles = rootsecs * (secsize/sizeof(Dosdir));
+ }
data = nresrv + 2*fatsecs + (rootfiles*sizeof(Dosdir) + secsize-1)/secsize;
newclusters = 2 + (volsecs - data)/clustersize;
if(newclusters == clusters)
@@ -547,43 +573,49 @@
if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clustersize);
switch(fatbits){
case 12:
- if(clusters >= 4087){
+ if(clusters >= 0xff7){
fatbits = 16;
goto Tryagain;
}
break;
case 16:
- if(clusters >= 65527)
- fatal("disk too big; implement fat32");
+ if(clusters >= 0xfff7){
+ fatbits = 32;
+ goto Tryagain;
+ }
break;
+ case 32:
+ if(clusters >= 0xffffff7)
+ fatal("filesystem too big");
+ break;
}
PUTSHORT(b->sectsize, secsize);
b->clustsize = clustersize;
PUTSHORT(b->nresrv, nresrv);
b->nfats = 2;
- PUTSHORT(b->rootsize, rootfiles);
- if(volsecs < (1<<16))
- PUTSHORT(b->volsize, volsecs);
+ PUTSHORT(b->rootsize, fatbits == 32 ? 0 : rootfiles);
+ PUTSHORT(b->volsize, volsecs >= (1<<16) ? 0 : volsecs);
b->mediadesc = t->media;
- PUTSHORT(b->fatsize, fatsecs);
+ PUTSHORT(b->fatsize, fatbits == 32 ? 0 : fatsecs);
PUTSHORT(b->trksize, t->sectors);
PUTSHORT(b->nheads, t->heads);
PUTLONG(b->nhidden, disk->offset);
PUTLONG(b->bigvolsize, volsecs);
- /*
- * Extended BIOS Parameter Block.
- */
- if(t->media == 0xF8)
- b->driveno = getdriveno(disk);
- else
- b->driveno = 0;
-if(chatty) print("driveno = %ux\n", b->driveno);
-
- b->bootsig = 0x29;
- memmove(b->label, label, sizeof(b->label));
sprint(r, "FAT%d ", fatbits);
- memmove(b->type, r, sizeof(b->type));
+ if(fatbits == 32){
+ PUTLONG(b->fat32.fatsize, fatsecs);
+ PUTLONG(b->fat32.rootclust, 2);
+ b->fat32.bootsig = 0x29;
+ b->fat32.driveno = (t->media == 0xF8) ? getdriveno(disk) : 0;
+ memmove(b->fat32.label, label, sizeof(b->fat32.label));
+ memmove(b->fat32.type, r, sizeof(b->fat32.type));
+ } else {
+ b->bootsig = 0x29;
+ b->driveno = (t->media == 0xF8) ? getdriveno(disk) : 0;
+ memmove(b->label, label, sizeof(b->label));
+ memmove(b->type, r, sizeof(b->type));
+ }
}
buf[secsize-2] = 0x55;
@@ -617,13 +649,33 @@
fat[0] = t->media;
fat[1] = 0xff;
fat[2] = 0xff;
- if(fatbits == 16)
+ if(fatbits >= 16)
fat[3] = 0xff;
+ if(fatbits == 32){
+ fat[4] = 0xff;
+ fat[5] = 0xff;
+ fat[6] = 0xff;
+ fat[7] = 0xff;
+ }
fatlast = 1;
if(seek(disk->wfd, 2*fatsecs*secsize, 1) < 0) /* 2 fats */
fatal("seek to root: %r");
if(chatty) print("root @%lluX\n", seek(disk->wfd, 0LL, 1));
+ if(fatbits == 32){
+ /*
+ * allocate clusters for root directory
+ */
+ if(rootsecs % clustersize)
+ abort();
+ length = rootsecs / clustersize;
+ if(clustalloc(Sof) != 2)
+ abort();
+ for(n = 0; n < length-1; n++)
+ clustalloc(0);
+ clustalloc(Eof);
+ }
+
/*
* allocate an in memory root
*/
@@ -730,7 +782,7 @@
ulong o, x;
if(flag != Sof){
- x = (flag == Eof) ? 0xffff : (fatlast+1);
+ x = (flag == Eof) ? ~0 : (fatlast+1);
if(fatbits == 12){
x &= 0xfff;
o = (3*fatlast)/2;
@@ -741,10 +793,20 @@
fat[o] = x;
fat[o+1] = (fat[o+1]&0xf0) | ((x>>8) & 0x0F);
}
- } else {
+ }
+ else if(fatbits == 16){
+ x &= 0xffff;
o = 2*fatlast;
fat[o] = x;
fat[o+1] = x>>8;
+ }
+ else if(fatbits == 32){
+ x &= 0xfffffff;
+ o = 4*fatlast;
+ fat[o] = x;
+ fat[o+1] = x>>8;
+ fat[o+2] = x>>16;
+ fat[o+3] = x>>24;
}
}