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