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

Reply via email to