diff --git a/ChangeLog b/ChangeLog
index 280e7bb4a79c89b806181d134e7f612b3a2755c6..d3a5f291cb0f2f3912433ce58acc97e8c0b43bb3 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -11140,8 +11140,3 @@
 	  of the block driver (2015-11-21).
 	* libc/stdio/lib_freopen.c and include/stdio.h:  Add support for
 	  freopen() (2015-11-22).
-	* drivers/mtd/smart.c:  Add option to specify logical sector size
-	  during low level format plus adds some run-time geometry tests.  From
-	  Ken Petit (2015-11-22).
-	* fs/smartfs: Remove the 'mksmartfs()' code from the kernel 'fs'
-	  directory and build.  From Ken Petit (2015-11-22).
diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index 08bae53c0d697507725c83f0ae749873286e1566..a07bd220971b85d8d8c04549202925b91dcadfa6 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -994,10 +994,6 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size)
         {
           dev->availSectPerBlk = 255;
         }
-      else if (dev->sectorsPerBlk == 0)
-        {
-          return -EINVAL;
-        }
       else
         {
           dev->availSectPerBlk = dev->sectorsPerBlk;
@@ -1446,7 +1442,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi
               /* Calculate the read address for this sector */
 
               readaddress = block * dev->erasesize +
-                  sector * dev->sectorsize;
+                  sector * CONFIG_MTD_SMART_SECTOR_SIZE;
 
               /* Read the header for this sector */
 
@@ -1822,10 +1818,6 @@ static int smart_scan(FAR struct smart_struct_s *dev)
       offset >>= 1;
       if (offset < 256 && sectorsize == 0xFFFF)
         {
-          /* No valid sectors found on device.  Default the
-           * sector size to the CONFIG value
-           */
-
           sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE;
         }
     }
@@ -2301,17 +2293,6 @@ static int smart_scan(FAR struct smart_struct_s *dev)
   fdbg("   Erase count:  %10d\n", dev->neraseblocks);
   fdbg("   Sect/block:   %10d\n", dev->sectorsPerBlk);
   fdbg("   MTD Blk/Sect: %10d\n", dev->mtdBlksPerSector);
-
-  /* Validate the geometry */
-
-  if (dev->mtdBlksPerSector == 0 || dev->sectorsPerBlk == 0 ||
-      dev->sectorsPerBlk == 0 || dev->sectorsize == 0)
-    {
-      fdbg("Invalid Geometry!\n");
-      ret = -EINVAL;
-      goto err_out;
-    }
-
 #ifdef CONFIG_MTD_SMART_ALLOC_DEBUG
   fdbg("   Allocations:\n");
   for (sector = 0; sector < SMART_MAX_ALLOCS; sector++)
@@ -2800,11 +2781,6 @@ static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev)
  *               involves erasing the device and writing a valid sector
  *               zero (logical) with proper format signature.
  *
- * Input Parameters:
- *
- *   arg:        Upper 16 bits contains the sector size
- *               Lower 16 bits contains the number of root dir entries
- *
  ****************************************************************************/
 
 #ifdef CONFIG_FS_WRITABLE
@@ -2815,29 +2791,18 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
   int         x;
   int         ret;
   uint8_t     sectsize, prerelease;
-  uint16_t    sectorsize;
 
   fvdbg("Entry\n");
 
-  /* Get the sector size from the provided arg */
-
-  sectorsize = arg >> 16;
-  if (sectorsize == 0)
-    {
-      sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE;
-    }
-
-  /* Set the sector size for the device */
-
-  smart_setsectorsize(dev, sectorsize);
+  smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE);
 
   /* Check for invalid format */
 
-  if (dev->erasesize == 0 || dev->sectorsPerBlk == 0)
+  if (dev->erasesize == 0)
     {
       dev->erasesize = dev->geo.erasesize;
 
-      dbg("ERROR:  Invalid geometery ... Sectors per erase block must be 1-256\n");
+      dbg("ERROR:  Invalid geometery ... Sectors per erase block must be 256 or less\n");
       dbg("        Erase block size    = %d\n", dev->erasesize);
       dbg("        Sector size         = %d\n", dev->sectorsize);
       dbg("        Sectors/erase block = %d\n", dev->erasesize / dev->sectorsize);
@@ -2863,22 +2828,18 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
   /* CRC enabled.  Using an 8-bit sequence number */
 
   sectorheader->seq = 0;
-
 #else
   /* CRC not enabled.  Using a 16-bit sequence number */
 
   *((FAR uint16_t *) &sectorheader->seq) = 0;
-
 #endif
 #else   /* SMART_STATUS_VERSION == 1 */
-
   sectorheader->seq = 0;
-
 #endif  /* SMART_STATUS_VERSION == 1 */
 
   /* Set the sector size of this sector */
 
-  sectsize = (sectorsize >> 9) << 2;
+  sectsize = (CONFIG_MTD_SMART_SECTOR_SIZE >> 9) << 2;
 
   /* Set the sector logical sector to zero and setup the header status */
 
@@ -2912,7 +2873,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
 
   /* Record the number of root directory entries we have */
 
-  dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) (arg & 0xFF);
+  dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) arg;
 
 #ifdef CONFIG_SMART_CRC_8
   sectorheader->crc8 = smart_calc_sector_crc(dev);
@@ -2939,7 +2900,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a
 
   /* Now initialize our internal control variables */
 
-  ret = smart_setsectorsize(dev, sectorsize);
+  ret = smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE);
   if (ret != OK)
     {
       return ret;
diff --git a/fs/smartfs/Make.defs b/fs/smartfs/Make.defs
index 3be1487cde4a9f4b8665d431910822398b91557b..97bf50fbb910737bfba1f4e80898ecf4cc30ebbc 100644
--- a/fs/smartfs/Make.defs
+++ b/fs/smartfs/Make.defs
@@ -40,6 +40,11 @@ ifeq ($(CONFIG_FS_SMARTFS),y)
 ASRCS +=
 CSRCS += smartfs_smart.c smartfs_utils.c smartfs_procfs.c
 
+# Files required for mksmartfs utility function
+
+ASRCS +=
+CSRCS += smartfs_mksmartfs.c
+
 # Include SMART build support
 
 DEPPATH += --dep-path smartfs
diff --git a/fs/smartfs/smartfs.h b/fs/smartfs/smartfs.h
index 189d521d72edbfbb8250e95ebbe7cdba64d88cac..36ed65b41b872602825ac6feca15a550193af287 100644
--- a/fs/smartfs/smartfs.h
+++ b/fs/smartfs/smartfs.h
@@ -188,6 +188,15 @@
 #define FS_BOPS(f)        (f)->fs_blkdriver->u.i_bops
 #define FS_IOCTL(f,c,a)   (FS_BOPS(f)->ioctl ? FS_BOPS(f)->ioctl((f)->fs_blkdriver,c,a) : (-ENOSYS))
 
+/* The logical sector number of the root directory. */
+
+#define SMARTFS_ROOT_DIR_SECTOR   3
+
+/* Defines the sector types */
+
+#define SMARTFS_SECTOR_TYPE_DIR   1
+#define SMARTFS_SECTOR_TYPE_FILE  2
+
 #ifndef CONFIG_SMARTFS_DIRDEPTH
 #  define CONFIG_SMARTFS_DIRDEPTH 8
 #endif
diff --git a/fs/smartfs/smartfs_mksmartfs.c b/fs/smartfs/smartfs_mksmartfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..076915e169c0792d96961a54ceeb5aaa66eeaaee
--- /dev/null
+++ b/fs/smartfs/smartfs_mksmartfs.c
@@ -0,0 +1,191 @@
+/****************************************************************************
+ * fs/smartfs/smartfs_mksmartfs.c
+ *
+ *   Copyright (C) 2013 Ken Pettit. All rights reserved.
+ *   Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/mksmartfs.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/fs/smart.h>
+
+#include "smartfs.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mksmartfs
+ *
+ * Description:
+ *   Make a SMART Flash file system image on the specified block device
+ *
+ * Inputs:
+ *   pathname - the full path to a registered block driver
+ *   nrootdirs - Number of root directory entries to create.
+ *
+ * Return:
+ *   Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately:
+ *
+ *   EINVAL  - NULL block driver string, bad number of FATS in 'fmt', bad FAT
+ *     size in 'fmt', bad cluster size in 'fmt'
+ *   ENOENT  - 'pathname' does not refer to anything in the filesystem.
+ *   ENOTBLK - 'pathname' does not refer to a block driver
+ *   EACCES  - block driver does not support wrie or geometry methods
+ *
+ * Assumptions:
+ *   - The caller must assure that the block driver is not mounted and not in
+ *     use when this function is called.  The result of formatting a mounted
+ *     device is indeterminate (but likely not good).
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+int mksmartfs(FAR const char *pathname, uint8_t nrootdirs)
+#else
+int mksmartfs(FAR const char *pathname)
+#endif
+{
+  FAR struct inode *inode;
+  struct smart_format_s fmt;
+  int ret;
+  int x;
+  uint8_t type;
+  struct smart_read_write_s request;
+
+  /* Find the inode of the block driver indentified by 'source' */
+
+  ret = open_blockdriver(pathname, 0, &inode);
+  if (ret < 0)
+    {
+      fdbg("Failed to open %s\n", pathname);
+      goto errout;
+    }
+
+  /* Make sure that the inode supports the write and geometry methods at a minimum */
+
+  if (!inode->u.i_bops->write || !inode->u.i_bops->geometry)
+    {
+      fdbg("%s does not support write or geometry methods\n", pathname);
+      ret = -EACCES;
+      goto errout_with_driver;
+    }
+
+  /* Validate the block device is a SMART device */
+
+  /* Perform a low-level SMART format */
+
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+  ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, nrootdirs);
+#else
+  ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, 0);
+#endif
+  if (ret != OK)
+    {
+      fdbg("Error creating low-level format: %d\n", ret);
+      goto errout_with_driver;
+    }
+
+  /* Get the format information so we know how big the sectors are */
+
+  ret = inode->u.i_bops->ioctl(inode, BIOC_GETFORMAT, (unsigned long) &fmt);
+
+  /* Now Write the filesystem to media.  Loop for each root dir entry and
+   * allocate the reserved Root Dir Enty, then write a blank root dir for it.
+   */
+
+  type = SMARTFS_SECTOR_TYPE_DIR;
+  request.offset = 0;
+  request.count = 1;
+  request.buffer = &type;
+  x = 0;
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+  for (; x < nrootdirs; x++)
+#endif
+    {
+      ret = inode->u.i_bops->ioctl(inode, BIOC_ALLOCSECT, SMARTFS_ROOT_DIR_SECTOR + x);
+      if (ret != SMARTFS_ROOT_DIR_SECTOR + x)
+        {
+          ret = -EIO;
+          goto errout_with_driver;
+        }
+
+      /* Mark this block as a directory entry */
+
+      request.logsector = SMARTFS_ROOT_DIR_SECTOR + x;
+
+      /* Issue a write to the sector, single byte */
+
+      ret = inode->u.i_bops->ioctl(inode, BIOC_WRITESECT, (unsigned long) &request);
+      if (ret != 0)
+        {
+          ret = -EIO;
+          goto errout_with_driver;
+        }
+    }
+
+errout_with_driver:
+  /* Close the driver */
+
+  (void)close_blockdriver(inode);
+
+errout:
+  /* Release all allocated memory */
+
+  /* Return any reported errors */
+
+  if (ret < 0)
+    {
+      set_errno(-ret);
+      return ERROR;
+    }
+
+  return OK;
+}
diff --git a/include/nuttx/fs/mksmartfs.h b/include/nuttx/fs/mksmartfs.h
new file mode 100644
index 0000000000000000000000000000000000000000..f907ba305abfd1ba7b7ffbe91ff168335b44f02a
--- /dev/null
+++ b/include/nuttx/fs/mksmartfs.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * include/nuttx/fs/mksmartfs.h
+ *
+ *   Copyright (C) 2013, 2015 Ken Pettit. All rights reserved.
+ *   Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_SMART_MKSMARTFS_H
+#define __INCLUDE_NUTTX_SMART_MKSMARTFS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: mksmartfs
+ *
+ * Description:
+ *   Make a SMART (Sector Mapped Allocation for Really Tiny) Flash file
+ *   system image on the specified block device (must be a SMART device).
+ *
+ * Inputs:
+ *   pathname - the full path to a registered block driver
+ *   nrootdirs - the number of Root Directory entries to support
+ *               on this device (supports multiple mount points).
+ *
+ * Return:
+ *   Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately:
+ *
+ *   EINVAL - NULL block driver string
+ *   ENOENT - 'pathname' does not refer to anything in the filesystem.
+ *   ENOTBLK - 'pathname' does not refer to a block driver
+ *   EACCESS - block driver does not support write or geometry methods or
+ *             is not a SMART device
+ *
+ * Assumptions:
+ *   - The caller must assure that the block driver is not mounted and not in
+ *     use when this function is called.  The result of formatting a mounted
+ *     device is indeterminate (but likely not good).
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+int mksmartfs(FAR const char *pathname, uint8_t nrootdirs);
+#else
+int mksmartfs(FAR const char *pathname);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_SMART_MKSMARTFS_H */
diff --git a/include/nuttx/fs/smart.h b/include/nuttx/fs/smart.h
index f3bff10cb679663cba39ef49e62ce46498bf888e..2621dd77f626d79d077668ff59961aa42a72ad2a 100644
--- a/include/nuttx/fs/smart.h
+++ b/include/nuttx/fs/smart.h
@@ -55,15 +55,6 @@
 #define SMART_FMT_ISFORMATTED   0x01
 #define SMART_FMT_HASBYTEWRITE  0x02
 
-/* The logical sector number of the root directory. */
-
-#define SMARTFS_ROOT_DIR_SECTOR   3
-
-/* Defines the sector types */
-
-#define SMARTFS_SECTOR_TYPE_DIR   1
-#define SMARTFS_SECTOR_TYPE_FILE  2
-
 /****************************************************************************
  * Public Types
  ****************************************************************************/