Module Name: src
Committed By: perseant
Date: Wed Jul 24 00:46:19 UTC 2024
Modified Files:
src/sbin/newfs_exfatfs [perseant-exfatfs]: extern.h make_exfatfs.c
newfs.c
Log Message:
Add -b option to allow the user to specify bootcode.
Add -u option to allow the user to specify the upcase table.
Correct a bug that always computed a cluster size of 8k; instead, use
the SD Card Association recommended cluster sizes according to the size
of the partition.
To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sbin/newfs_exfatfs/extern.h \
src/sbin/newfs_exfatfs/newfs.c
cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sbin/newfs_exfatfs/make_exfatfs.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sbin/newfs_exfatfs/extern.h
diff -u src/sbin/newfs_exfatfs/extern.h:1.1.2.1 src/sbin/newfs_exfatfs/extern.h:1.1.2.2
--- src/sbin/newfs_exfatfs/extern.h:1.1.2.1 Sat Jun 29 19:43:25 2024
+++ src/sbin/newfs_exfatfs/extern.h Wed Jul 24 00:46:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.1.2.1 2024/06/29 19:43:25 perseant Exp $ */
+/* $NetBSD: extern.h,v 1.1.2.2 2024/07/24 00:46:18 perseant Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -34,7 +34,7 @@
void fatal(const char *fmt, ...)
__attribute__((__format__(__printf__,1,2)));
int make_exfatfs(int, uint, struct dkwedge_info *, uint,
- uint16_t *, int, uint32_t);
+ uint16_t *, int, uint32_t, uint16_t *, size_t, char *);
extern char *progname;
extern char *special;
Index: src/sbin/newfs_exfatfs/newfs.c
diff -u src/sbin/newfs_exfatfs/newfs.c:1.1.2.1 src/sbin/newfs_exfatfs/newfs.c:1.1.2.2
--- src/sbin/newfs_exfatfs/newfs.c:1.1.2.1 Sat Jun 29 19:43:25 2024
+++ src/sbin/newfs_exfatfs/newfs.c Wed Jul 24 00:46:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: newfs.c,v 1.1.2.1 2024/06/29 19:43:25 perseant Exp $ */
+/* $NetBSD: newfs.c,v 1.1.2.2 2024/07/24 00:46:18 perseant Exp $ */
/*-
* Copyright (c) 1989, 1992, 1993
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19
#if 0
static char sccsid[] = "@(#)newfs.c 8.5 (Berkeley) 5/24/95";
#else
-__RCSID("$NetBSD: newfs.c,v 1.1.2.1 2024/06/29 19:43:25 perseant Exp $");
+__RCSID("$NetBSD: newfs.c,v 1.1.2.2 2024/07/24 00:46:18 perseant Exp $");
#endif
#endif /* not lint */
@@ -116,6 +116,9 @@ main(int argc, char **argv)
uint16_t uclabel[11];
uint16_t uclabellen;
uint64_t diskbytes;
+ char *bootcodefile = NULL, *bootcode = NULL;
+ char *uctablefile = NULL, *uctable = NULL;
+ size_t uctablesize = 0;
int r;
if ((progname = strrchr(*argv, '/')) != NULL)
@@ -129,7 +132,7 @@ main(int argc, char **argv)
debug = force = 0;
memset(&dkw, 0, sizeof(dkw));
- while ((ch = getopt(argc, argv, "a:c:Dh:FL:l:No:S:s:T:v#:")) != -1)
+ while ((ch = getopt(argc, argv, "a:b:c:Dh:FL:l:No:S:s:T:u:v#:")) != -1)
switch(ch) {
case 'D':
debug = 1;
@@ -156,6 +159,9 @@ main(int argc, char **argv)
align = strsuftoi64("alignment", optarg,
MINBLOCKSIZE, INT64_MAX, NULL);
break;
+ case 'b':
+ bootcodefile = optarg;
+ break;
case 'c':
csize = strsuftoi64("cluster size", optarg,
MINBLOCKSIZE, INT64_MAX, NULL);
@@ -174,6 +180,9 @@ main(int argc, char **argv)
fssize = strsuftoi64("file system size", optarg,
0, INT64_MAX, &byte_sized);
break;
+ case 'u':
+ uctablefile = optarg;
+ break;
case 'v':
Vflag++;
break;
@@ -274,7 +283,7 @@ main(int argc, char **argv)
/* If csize not specified, switch based on the partition size */
/* This table is based on Windows defaults */
- diskbytes = secsize * (off_t)dev_bsize;
+ diskbytes = dkw.dkw_size * (off_t)dev_bsize;
if (csize <= 0) {
#define KILOBYTE (off_t)1024
#define MEGABYTE (1024 * KILOBYTE)
@@ -287,6 +296,10 @@ main(int argc, char **argv)
csize = 32 * KILOBYTE;
else
csize = 128 * KILOBYTE;
+ if (Vflag)
+ printf("Using Windows default cluster size %d"
+ " for filesystem size %lld\n",
+ (int)csize, (unsigned long long)diskbytes);
#else /* SD Card Association recommendations */
if (diskbytes <= 8 * MEGABYTE)
csize = 8 * KILOBYTE;
@@ -300,7 +313,15 @@ main(int argc, char **argv)
csize = 256 * KILOBYTE;
else
csize = 512 * KILOBYTE;
+ if (Vflag)
+ printf("Using SD Card Association recommended"
+ " cluster size %d"
+ " for filesystem size %lld\n",
+ (int)csize, (unsigned long long)diskbytes);
#endif
+ } else {
+ if (Vflag)
+ printf("Using specified cluster size %d", (int)csize);
}
if (align <= 0) {
@@ -331,9 +352,38 @@ main(int argc, char **argv)
strlen(label), uclabel,
EXFATFS_LABELMAX);
+ /* Load bootcode from file if requested */
+ if (bootcodefile != NULL) {
+ bootcode = (char *)malloc(390);
+ FILE *fp = fopen(bootcodefile, "rb");
+ if (fp == NULL || fread(bootcode, 390, 1, fp) != 1) {
+ perror(bootcodefile);
+ exit(1);
+ }
+ fclose(fp);
+ }
+
+ /* Load upcase table from file if requested */
+ if (uctablefile != NULL) {
+ FILE *fp;
+ if (stat(uctablefile, &st) != 0) {
+ perror(uctablefile);
+ exit(1);
+ }
+ uctablesize = st.st_size;
+ uctable = malloc(uctablesize);
+ fp = fopen(uctablefile, "rb");
+ if (fp == NULL || fread(uctable, uctablesize, 1, fp) != 1) {
+ perror(uctablefile);
+ exit(1);
+ }
+ fclose(fp);
+ }
+
/* Make the filesystem */
r = make_exfatfs(fso, secsize, &dkw, csize,
- uclabel, uclabellen, serial);
+ uclabel, uclabellen, serial,
+ (uint16_t *)uctable, uctablesize, bootcode);
if (debug)
bufstats();
exit(r);
Index: src/sbin/newfs_exfatfs/make_exfatfs.c
diff -u src/sbin/newfs_exfatfs/make_exfatfs.c:1.1.2.3 src/sbin/newfs_exfatfs/make_exfatfs.c:1.1.2.4
--- src/sbin/newfs_exfatfs/make_exfatfs.c:1.1.2.3 Fri Jul 19 16:19:16 2024
+++ src/sbin/newfs_exfatfs/make_exfatfs.c Wed Jul 24 00:46:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: make_exfatfs.c,v 1.1.2.3 2024/07/19 16:19:16 perseant Exp $ */
+/* $NetBSD: make_exfatfs.c,v 1.1.2.4 2024/07/24 00:46:18 perseant Exp $ */
/*-
* Copyright (c) 2022 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
#if 0
static char sccsid[] = "@(#)lfs.c 8.5 (Berkeley) 5/24/95";
#else
-__RCSID("$NetBSD: make_exfatfs.c,v 1.1.2.3 2024/07/19 16:19:16 perseant Exp $");
+__RCSID("$NetBSD: make_exfatfs.c,v 1.1.2.4 2024/07/24 00:46:18 perseant Exp $");
#endif
#endif /* not lint */
@@ -492,7 +492,8 @@ efun(int eval, const char *fmt, ...)
int
make_exfatfs(int devfd, uint secsize, struct dkwedge_info *dkw, uint bsize,
- uint16_t *uclabel, int uclabellen, uint32_t serial)
+ uint16_t *uclabel, int uclabellen, uint32_t serial,
+ uint16_t *uctable, size_t uctablesize, char *bootcode)
{
struct exfatfs *fs;
struct uvnode *devvp;
@@ -524,6 +525,12 @@ make_exfatfs(int devfd, uint secsize, st
if (heapalign == 0)
heapalign = align;
+ /* If no table given, use recommendation */
+ if (uctable == NULL || uctablesize == 0) {
+ uctable = exfatfs_recommended_upcase_table_compressed;
+ uctablesize = sizeof (exfatfs_recommended_upcase_table_compressed);
+ }
+
/* Use random serial number if not given */
if (serial == 0)
serial = (uint32_t)random();
@@ -587,11 +594,10 @@ make_exfatfs(int devfd, uint secsize, st
fs->xf_NumberOfFats = 1; /* XXX maybe two? */
fs->xf_DriveSelect = 0x80; /* An arbitrary value, from the spec */
fs->xf_PercentInUse = 0;
-#ifdef WINDOWS_BOOTCODE /* XXX take bootcode from a file via option */
- memcpy(fs->xf_BootCode, WINDOWS_BOOTCODE, sizeof(fs->xf_BootCode));
-#else /* ! defined WINDOWS_BOOTCODE */
- memset(fs->xf_BootCode, 0xf4, sizeof(fs->xf_BootCode));
-#endif /* ! defined WINDOWS_BOOTCODE */
+ if (bootcode == NULL)
+ memset(fs->xf_BootCode, 0xf4, sizeof(fs->xf_BootCode));
+ else
+ memcpy(fs->xf_BootCode, bootcode, sizeof(fs->xf_BootCode));
fs->xf_BootSignature = EXFAT_BOOT_SIGNATURE;
if (Vflag)
@@ -599,11 +605,6 @@ make_exfatfs(int devfd, uint secsize, st
(unsigned long)fs->xf_ClusterHeapOffset,
(unsigned long long)fs->xf_ClusterHeapOffset << fs->xf_BytesPerSectorShift);
- if (Vflag)
- printf("First cluster of root directory: 0x%lx (byte 0x%llx)\n",
- (unsigned long)fs->xf_FirstClusterOfRootDirectory,
- (unsigned long long)EXFATFS_LC2D(fs, fs->xf_FirstClusterOfRootDirectory) * secsize);
-
/*
* Prepare root directory entries.
* There are three of these at 32B each.
@@ -642,10 +643,9 @@ make_exfatfs(int devfd, uint secsize, st
| XD_ENTRYTYPE_INUSE_MASK;
dirent_upcase.xd_firstCluster = dirent_bitmap.xd_firstCluster
+ bitmap_cluster_size;
- dirent_upcase.xd_dataLength = sizeof(exfatfs_recommended_upcase_table_compressed);
+ dirent_upcase.xd_dataLength = uctablesize;
dirent_upcase.xd_tableChecksum =
- exfatfs_cksum32(0, (uint8_t *)exfatfs_recommended_upcase_table_compressed,
- sizeof(exfatfs_recommended_upcase_table_compressed),
+ exfatfs_cksum32(0, (uint8_t *)uctable, uctablesize,
NULL, 0);
if (Vflag)
printf("First cluster of upcase map: 0x%lx\n",
@@ -658,15 +658,16 @@ make_exfatfs(int devfd, uint secsize, st
* Write the upcase table to disk.
*/
daddr = EXFATFS_LC2D(fs, dirent_upcase.xd_firstCluster);
- resid = sizeof(exfatfs_recommended_upcase_table_compressed);
+ resid = uctablesize;
for (i = 0; resid > 0; i += EXFATFS_LSIZE(fs), resid -= EXFATFS_LSIZE(fs)) {
if (!Nflag) {
bp = getblk(devvp, daddr, EXFATFS_LSIZE(fs));
memset(bp->b_data, 0, EXFATFS_LSIZE(fs));
- memcpy(bp->b_data, ((const char *)exfatfs_recommended_upcase_table_compressed) + i, MIN(EXFATFS_LSIZE(fs), resid));
+ memcpy(bp->b_data, ((const char *)uctable) + i,
+ MIN(EXFATFS_LSIZE(fs), resid));
if (Vflag)
- printf(" write upcase sector size %d at bn 0x%lx\n",
- EXFATFS_LSIZE(fs), (unsigned long)bp->b_blkno);
+ printf(" write upcase sector size %d (%d) at bn 0x%lx\n",
+ EXFATFS_LSIZE(fs), (int)resid, (unsigned long)bp->b_blkno);
bwrite(bp);
++daddr;
}
@@ -674,6 +675,11 @@ make_exfatfs(int devfd, uint secsize, st
fs->xf_FirstClusterOfRootDirectory = dirent_upcase.xd_firstCluster
+ upcase_cluster_size;
+ if (Vflag)
+ printf("First cluster of root directory: 0x%lx (byte 0x%llx)\n",
+ (unsigned long)fs->xf_FirstClusterOfRootDirectory,
+ (unsigned long long)EXFATFS_LC2D(fs, fs->xf_FirstClusterOfRootDirectory) * secsize);
+
/*
* Write the first bitmap sector.
@@ -684,14 +690,16 @@ make_exfatfs(int devfd, uint secsize, st
bp = getblk(devvp, daddr, EXFATFS_LSIZE(fs));
memset(bp->b_data, 0, EXFATFS_LSIZE(fs));
+ /* Mark off the clusters we've allocated */
for (i = start; i <= fs->xf_FirstClusterOfRootDirectory; i++) {
+ /* It might take more than one bitmap cluster */
if ((i - start) == NBBY * EXFATFS_LSIZE(fs)) {
if (Vflag)
printf(" write used bitmap sector size %d at bn 0x%lx\n",
EXFATFS_LSIZE(fs), (unsigned long)bp->b_blkno);
bwrite(bp);
start = i;
- ++daddr;
+ daddr += EXFATFS_L2D(fs, 1);
bp = getblk(devvp, daddr, EXFATFS_LSIZE(fs));
memset(bp->b_data, 0, EXFATFS_LSIZE(fs));
}
@@ -709,8 +717,8 @@ make_exfatfs(int devfd, uint secsize, st
/* Now write blank pages for the rest of the bitmap */
progress = oprogress = 0;
- start = ++daddr;
- end = EXFATFS_LC2D(fs, fs->xf_FirstClusterOfRootDirectory);
+ start = daddr + EXFATFS_L2D(fs, 1);
+ end = EXFATFS_LC2D(fs, dirent_upcase.xd_firstCluster);
for (daddr = start; daddr < end; ++daddr) {
if (!Nflag) {
size_t size = EXFATFS_LSIZE(fs);