disk/format: FAT32 support
This commit is contained in:
parent
fb948ee521
commit
d0007933f2
2 changed files with 90 additions and 32 deletions
|
@ -713,10 +713,6 @@ disk/format -b /386/pbs -d -r 2 /dev/sdC0/9fat \e
|
||||||
.IR 9boot (8),
|
.IR 9boot (8),
|
||||||
.IR partfs (8)
|
.IR partfs (8)
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.I Format
|
|
||||||
can create FAT12 and FAT16
|
|
||||||
file systems, but not FAT32 file systems.
|
|
||||||
.PP
|
|
||||||
If
|
If
|
||||||
.L "prep -p"
|
.L "prep -p"
|
||||||
doesn't find a Plan 9 partition table,
|
doesn't find a Plan 9 partition table,
|
||||||
|
|
|
@ -45,6 +45,8 @@ struct Dosboot{
|
||||||
uchar nheads[2];
|
uchar nheads[2];
|
||||||
uchar nhidden[4];
|
uchar nhidden[4];
|
||||||
uchar bigvolsize[4];
|
uchar bigvolsize[4];
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
uchar driveno;
|
uchar driveno;
|
||||||
uchar reserved0;
|
uchar reserved0;
|
||||||
uchar bootsig;
|
uchar bootsig;
|
||||||
|
@ -52,6 +54,24 @@ struct Dosboot{
|
||||||
uchar label[11];
|
uchar label[11];
|
||||||
uchar type[8];
|
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 PUTSHORT(p, v) { (p)[1] = (v)>>8; (p)[0] = (v); }
|
||||||
#define PUTLONG(p, v) { PUTSHORT((p), (v)); PUTSHORT((p)+2, (v)>>16); }
|
#define PUTLONG(p, v) { PUTSHORT((p), (v)); PUTSHORT((p)+2, (v)>>16); }
|
||||||
#define GETSHORT(p) (((p)[1]<<8)|(p)[0])
|
#define GETSHORT(p) (((p)[1]<<8)|(p)[0])
|
||||||
|
@ -533,6 +553,12 @@ Tryagain:
|
||||||
rootfiles = 512;
|
rootfiles = 512;
|
||||||
rootsecs = rootfiles/(secsize/sizeof(Dosdir));
|
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;
|
data = nresrv + 2*fatsecs + (rootfiles*sizeof(Dosdir) + secsize-1)/secsize;
|
||||||
newclusters = 2 + (volsecs - data)/clustersize;
|
newclusters = 2 + (volsecs - data)/clustersize;
|
||||||
if(newclusters == clusters)
|
if(newclusters == clusters)
|
||||||
|
@ -547,44 +573,50 @@ if(chatty) print("clusters %d\n", clusters);
|
||||||
if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clustersize);
|
if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clustersize);
|
||||||
switch(fatbits){
|
switch(fatbits){
|
||||||
case 12:
|
case 12:
|
||||||
if(clusters >= 4087){
|
if(clusters >= 0xff7){
|
||||||
fatbits = 16;
|
fatbits = 16;
|
||||||
goto Tryagain;
|
goto Tryagain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
if(clusters >= 65527)
|
if(clusters >= 0xfff7){
|
||||||
fatal("disk too big; implement fat32");
|
fatbits = 32;
|
||||||
|
goto Tryagain;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
if(clusters >= 0xffffff7)
|
||||||
|
fatal("filesystem too big");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PUTSHORT(b->sectsize, secsize);
|
PUTSHORT(b->sectsize, secsize);
|
||||||
b->clustsize = clustersize;
|
b->clustsize = clustersize;
|
||||||
PUTSHORT(b->nresrv, nresrv);
|
PUTSHORT(b->nresrv, nresrv);
|
||||||
b->nfats = 2;
|
b->nfats = 2;
|
||||||
PUTSHORT(b->rootsize, rootfiles);
|
PUTSHORT(b->rootsize, fatbits == 32 ? 0 : rootfiles);
|
||||||
if(volsecs < (1<<16))
|
PUTSHORT(b->volsize, volsecs >= (1<<16) ? 0 : volsecs);
|
||||||
PUTSHORT(b->volsize, volsecs);
|
|
||||||
b->mediadesc = t->media;
|
b->mediadesc = t->media;
|
||||||
PUTSHORT(b->fatsize, fatsecs);
|
PUTSHORT(b->fatsize, fatbits == 32 ? 0 : fatsecs);
|
||||||
PUTSHORT(b->trksize, t->sectors);
|
PUTSHORT(b->trksize, t->sectors);
|
||||||
PUTSHORT(b->nheads, t->heads);
|
PUTSHORT(b->nheads, t->heads);
|
||||||
PUTLONG(b->nhidden, disk->offset);
|
PUTLONG(b->nhidden, disk->offset);
|
||||||
PUTLONG(b->bigvolsize, volsecs);
|
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);
|
sprint(r, "FAT%d ", fatbits);
|
||||||
|
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));
|
memmove(b->type, r, sizeof(b->type));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buf[secsize-2] = 0x55;
|
buf[secsize-2] = 0x55;
|
||||||
buf[secsize-1] = 0xAA;
|
buf[secsize-1] = 0xAA;
|
||||||
|
@ -617,13 +649,33 @@ if(chatty) print("fat @%lluX\n", seek(disk->wfd, 0, 1));
|
||||||
fat[0] = t->media;
|
fat[0] = t->media;
|
||||||
fat[1] = 0xff;
|
fat[1] = 0xff;
|
||||||
fat[2] = 0xff;
|
fat[2] = 0xff;
|
||||||
if(fatbits == 16)
|
if(fatbits >= 16)
|
||||||
fat[3] = 0xff;
|
fat[3] = 0xff;
|
||||||
|
if(fatbits == 32){
|
||||||
|
fat[4] = 0xff;
|
||||||
|
fat[5] = 0xff;
|
||||||
|
fat[6] = 0xff;
|
||||||
|
fat[7] = 0xff;
|
||||||
|
}
|
||||||
fatlast = 1;
|
fatlast = 1;
|
||||||
if(seek(disk->wfd, 2*fatsecs*secsize, 1) < 0) /* 2 fats */
|
if(seek(disk->wfd, 2*fatsecs*secsize, 1) < 0) /* 2 fats */
|
||||||
fatal("seek to root: %r");
|
fatal("seek to root: %r");
|
||||||
if(chatty) print("root @%lluX\n", seek(disk->wfd, 0LL, 1));
|
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
|
* allocate an in memory root
|
||||||
*/
|
*/
|
||||||
|
@ -730,7 +782,7 @@ clustalloc(int flag)
|
||||||
ulong o, x;
|
ulong o, x;
|
||||||
|
|
||||||
if(flag != Sof){
|
if(flag != Sof){
|
||||||
x = (flag == Eof) ? 0xffff : (fatlast+1);
|
x = (flag == Eof) ? ~0 : (fatlast+1);
|
||||||
if(fatbits == 12){
|
if(fatbits == 12){
|
||||||
x &= 0xfff;
|
x &= 0xfff;
|
||||||
o = (3*fatlast)/2;
|
o = (3*fatlast)/2;
|
||||||
|
@ -741,11 +793,21 @@ clustalloc(int flag)
|
||||||
fat[o] = x;
|
fat[o] = x;
|
||||||
fat[o+1] = (fat[o+1]&0xf0) | ((x>>8) & 0x0F);
|
fat[o+1] = (fat[o+1]&0xf0) | ((x>>8) & 0x0F);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if(fatbits == 16){
|
||||||
|
x &= 0xffff;
|
||||||
o = 2*fatlast;
|
o = 2*fatlast;
|
||||||
fat[o] = x;
|
fat[o] = x;
|
||||||
fat[o+1] = x>>8;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag == Eof)
|
if(flag == Eof)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue