You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2021/07/06 02:18:25 UTC

[incubator-nuttx] 02/03: fs: Implement file_mmap and file_munmap API

This is an automated email from the ASF dual-hosted git repository.

masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 8612af4ae59a94cc27d57680acfc55ed926f9067
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sat Mar 20 05:06:08 2021 +0800

    fs: Implement file_mmap and file_munmap API
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 fs/mmap/fs_mmap.c     | 250 ++++++++++++++++++++++++++++----------------------
 fs/mmap/fs_munmap.c   | 171 +++++++++++++++++++++-------------
 fs/mmap/fs_rammap.c   |  37 +++++---
 fs/mmap/fs_rammap.h   |  10 +-
 include/nuttx/fs/fs.h |  24 +++++
 5 files changed, 302 insertions(+), 190 deletions(-)

diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index baab91f..c764af2 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -38,88 +38,18 @@
 #include "fs_rammap.h"
 
 /****************************************************************************
- * Public Functions
+ * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: mmap
- *
- * Description:
- *   NuttX operates in a flat open address space.  Therefore, it generally
- *   does not require mmap() functionality.  There are two exceptions:
- *
- *   1. mmap() is the API that is used to support direct access to random
- *     access media under the following very restrictive conditions:
- *
- *     a. The filesystem supports the FIOC_MMAP ioctl command.  Any file
- *        system that maps files contiguously on the media should support
- *        this ioctl. (vs. file system that scatter files over the media
- *        in non-contiguous sectors).  As of this writing, ROMFS is the
- *        only file system that meets this requirement.
- *     b. The underlying block driver supports the BIOC_XIPBASE ioctl
- *        command that maps the underlying media to a randomly accessible
- *        address. At  present, only the RAM/ROM disk driver does this.
- *
- *   2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will
- *      support simulation of memory mapped files by copying files whole
- *      into RAM.
- *
- * Input Parameters:
- *   start   A hint at where to map the memory -- ignored.  The address
- *           of the underlying media is fixed and cannot be re-mapped without
- *           MMU support.
- *   length  The length of the mapping.  For exception #1 above, this length
- *           ignored:  The entire underlying media is always accessible.
- *   prot    See the PROT_* definitions in sys/mman.h.
- *           PROT_NONE      - Will cause an error
- *           PROT_READ      - PROT_WRITE and PROT_EXEC also assumed
- *           PROT_WRITE     - PROT_READ and PROT_EXEC also assumed
- *           PROT_EXEC      - PROT_READ and PROT_WRITE also assumed
- *   flags   See the MAP_* definitions in sys/mman.h.
- *           MAP_SHARED     - MAP_PRIVATE or MAP_SHARED required
- *           MAP_PRIVATE    - MAP_PRIVATE or MAP_SHARED required
- *           MAP_FIXED      - Will cause an error
- *           MAP_FILE       - Ignored
- *           MAP_ANONYMOUS  - Optional
- *           MAP_ANON       - Will cause an error
- *           MAP_GROWSDOWN  - Ignored
- *           MAP_DENYWRITE  - Will cause an error
- *           MAP_EXECUTABLE - Ignored
- *           MAP_LOCKED     - Ignored
- *           MAP_NORESERVE  - Ignored
- *           MAP_POPULATE   - Ignored
- *           MAP_NONBLOCK   - Ignored
- *   fd      file descriptor of the backing file -- required.
- *   offset  The offset into the file to map
- *
- * Returned Value:
- *   On success, mmap() returns a pointer to the mapped area. On error, the
- *   value MAP_FAILED is returned, and errno is set appropriately.
- *
- *     EACCES
- *       The fd argument is not open for read, regardless of the
- *       protection specified, or fd is not open for write and PROT_WRITE
- *       was specified for a MAP_SHARED type mapping.
- *     ENOSYS
- *       Returned if any of the unsupported mmap() features are attempted
- *     EBADF
- *       'fd' is not a valid file descriptor.
- *     EINVAL
- *       Length is 0. flags contained neither MAP_PRIVATE or MAP_SHARED, or
- *       contained both of these values.
- *     ENODEV
- *       The underlying filesystem of the specified file does not support
- *       memory mapping.
- *     ENOMEM
- *       Insufficient memory is available to map the file.
- *
+ * Name: file_mmap_
  ****************************************************************************/
 
-FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
-               int fd, off_t offset)
+static int file_mmap_(FAR struct file *filep, FAR void *start,
+                      size_t length, int prot, int flags,
+                      off_t offset, bool kernel, FAR void **mapped)
 {
   FAR void *addr;
-  FAR struct file *filep;
   int ret;
 
   /* Since only a tiny subset of mmap() functionality, we have to verify many
@@ -135,8 +65,7 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
   if ((flags & (MAP_FIXED | MAP_DENYWRITE)) != 0)
     {
       ferr("ERROR: Unsupported options, prot=%x flags=%04x\n", prot, flags);
-      ret = -ENOSYS;
-      goto errout;
+      return -ENOSYS;
     }
 
 #ifndef CONFIG_FS_RAMMAP
@@ -144,8 +73,7 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
     {
       ferr("ERROR: MAP_PRIVATE is not supported without file mapping"
            "emulation\n");
-      ret = -ENOSYS;
-      goto errout;
+      return -ENOSYS;
     }
 #endif /* CONFIG_FS_RAMMAP */
 
@@ -154,33 +82,22 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
   if (length == 0)
     {
       ferr("ERROR: Invalid length, length=%zu\n", length);
-      ret = -EINVAL;
-      goto errout;
+      return -EINVAL;
     }
 #endif /* CONFIG_DEBUG_FEATURES */
 
-  if (fs_getfilep(fd, &filep) < 0)
-    {
-      ferr("ERROR: Invalid file descriptor, fd=%d\n", fd);
-      ret = -EBADF;
-      goto errout;
-    }
-
   if ((filep->f_oflags & O_WROK) == 0 && prot == PROT_WRITE &&
       (flags & MAP_SHARED) != 0)
     {
       ferr("ERROR: Unsupported options for read-only file descriptor,"
-           "fd=%d prot=%x flags=%04x\n", fd, prot, flags);
-      ret = -EACCES;
-      goto errout;
+           "prot=%x flags=%04x\n", prot, flags);
+      return -EACCES;
     }
 
   if ((filep->f_oflags & O_RDOK) == 0)
     {
-      ferr("ERROR: File descriptor does not have read permission,"
-           "fd=%d\n", fd);
-      ret = -EACCES;
-      goto errout;
+      ferr("ERROR: File descriptor does not have read permission\n");
+      return -EACCES;
     }
 
   /* Check if we are just be asked to allocate memory, i.e., MAP_ANONYMOUS
@@ -191,23 +108,20 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
 
   if ((flags & MAP_ANONYMOUS) != 0)
     {
-      FAR void *alloc;
-
       /* REVISIT:  Should reside outside of the heap.  That is really the
        * only purpose of MAP_ANONYMOUS:  To get non-heap memory.  In KERNEL
        * build, this could be accomplished using pgalloc(), provided that
        * you had logic in place to assign a virtual address to the mapping.
        */
 
-      alloc = kumm_zalloc(length);
-      if (alloc == NULL)
+      *mapped = kernel ? kmm_zalloc(length) : kumm_zalloc(length);
+      if (*mapped == NULL)
         {
           ferr("ERROR: kumm_alloc() failed: %d\n", ret);
-          ret = -ENOMEM;
-          goto errout;
+          return -ENOMEM;
         }
 
-      return alloc;
+      return OK;
     }
 
   if ((flags & MAP_PRIVATE) != 0)
@@ -217,7 +131,7 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
        * do much better in the KERNEL build using the MMU.
        */
 
-      return rammap(fd, length, offset);
+      return rammap(filep, length, offset, kernel, mapped);
 #endif
     }
 
@@ -227,7 +141,7 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
    * a pointer).
    */
 
-  ret = nx_ioctl(fd, FIOC_MMAP, (unsigned long)((uintptr_t)&addr));
+  ret = file_ioctl(filep, FIOC_MMAP, (unsigned long)((uintptr_t)&addr));
   if (ret < 0)
     {
       /* Not directly mappable, probably because the underlying media does
@@ -239,16 +153,136 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
        * do much better in the KERNEL build using the MMU.
        */
 
-      return rammap(fd, length, offset);
+      return rammap(filep, length, offset, kernel, mapped);
 #else
-      ferr("ERROR: nx_ioctl(FIOC_MMAP) failed: %d\n", ret);
-      goto errout;
+      ferr("ERROR: file_ioctl(FIOC_MMAP) failed: %d\n", ret);
+      return ret;
 #endif
     }
 
   /* Return the offset address */
 
-  return (FAR void *)(((FAR uint8_t *)addr) + offset);
+  *mapped = (FAR void *)(((FAR uint8_t *)addr) + offset);
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: file_mmap
+ *
+ * Description:
+ *   Equivalent to the standard mmap() function except that is accepts
+ *   a struct file instance instead of a file descriptor and it does not set
+ *   the errno variable.
+ *
+ ****************************************************************************/
+
+int file_mmap(FAR struct file *filep, FAR void *start, size_t length,
+              int prot, int flags, off_t offset, FAR void **mapped)
+{
+  return file_mmap_(filep, start, length,
+                    prot, flags, offset, true, mapped);
+}
+
+/****************************************************************************
+ * Name: mmap
+ *
+ * Description:
+ *   NuttX operates in a flat open address space.  Therefore, it generally
+ *   does not require mmap() functionality.  There are two exceptions:
+ *
+ *   1. mmap() is the API that is used to support direct access to random
+ *     access media under the following very restrictive conditions:
+ *
+ *     a. The filesystem supports the FIOC_MMAP ioctl command.  Any file
+ *        system that maps files contiguously on the media should support
+ *        this ioctl. (vs. file system that scatter files over the media
+ *        in non-contiguous sectors).  As of this writing, ROMFS is the
+ *        only file system that meets this requirement.
+ *     b. The underlying block driver supports the BIOC_XIPBASE ioctl
+ *        command that maps the underlying media to a randomly accessible
+ *        address. At  present, only the RAM/ROM disk driver does this.
+ *
+ *   2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will
+ *      support simulation of memory mapped files by copying files whole
+ *      into RAM.
+ *
+ * Input Parameters:
+ *   start   A hint at where to map the memory -- ignored.  The address
+ *           of the underlying media is fixed and cannot be re-mapped without
+ *           MMU support.
+ *   length  The length of the mapping.  For exception #1 above, this length
+ *           ignored:  The entire underlying media is always accessible.
+ *   prot    See the PROT_* definitions in sys/mman.h.
+ *           PROT_NONE      - Will cause an error
+ *           PROT_READ      - PROT_WRITE and PROT_EXEC also assumed
+ *           PROT_WRITE     - PROT_READ and PROT_EXEC also assumed
+ *           PROT_EXEC      - PROT_READ and PROT_WRITE also assumed
+ *   flags   See the MAP_* definitions in sys/mman.h.
+ *           MAP_SHARED     - MAP_PRIVATE or MAP_SHARED required
+ *           MAP_PRIVATE    - MAP_PRIVATE or MAP_SHARED required
+ *           MAP_FIXED      - Will cause an error
+ *           MAP_FILE       - Ignored
+ *           MAP_ANONYMOUS  - Optional
+ *           MAP_ANON       - Will cause an error
+ *           MAP_GROWSDOWN  - Ignored
+ *           MAP_DENYWRITE  - Will cause an error
+ *           MAP_EXECUTABLE - Ignored
+ *           MAP_LOCKED     - Ignored
+ *           MAP_NORESERVE  - Ignored
+ *           MAP_POPULATE   - Ignored
+ *           MAP_NONBLOCK   - Ignored
+ *   fd      file descriptor of the backing file -- required.
+ *   offset  The offset into the file to map
+ *
+ * Returned Value:
+ *   On success, mmap() returns a pointer to the mapped area. On error, the
+ *   value MAP_FAILED is returned, and errno is set appropriately.
+ *
+ *     EACCES
+ *       The fd argument is not open for read, regardless of the
+ *       protection specified, or fd is not open for write and PROT_WRITE
+ *       was specified for a MAP_SHARED type mapping.
+ *     ENOSYS
+ *       Returned if any of the unsupported mmap() features are attempted
+ *     EBADF
+ *       'fd' is not a valid file descriptor.
+ *     EINVAL
+ *       Length is 0. flags contained neither MAP_PRIVATE or MAP_SHARED, or
+ *       contained both of these values.
+ *     ENODEV
+ *       The underlying filesystem of the specified file does not support
+ *       memory mapping.
+ *     ENOMEM
+ *       Insufficient memory is available to map the file.
+ *
+ ****************************************************************************/
+
+FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
+               int fd, off_t offset)
+{
+  FAR struct file *filep;
+  FAR void *mapped;
+  int ret;
+
+  if (fs_getfilep(fd, &filep) < 0)
+    {
+      ferr("ERROR: Invalid file descriptor, fd=%d\n", fd);
+      ret = -EBADF;
+      goto errout;
+    }
+
+  ret = file_mmap_(filep, start, length,
+                   prot, flags, offset, false, &mapped);
+  if (ret < 0)
+    {
+      goto errout;
+    }
+
+  return mapped;
 
 errout:
   set_errno(-ret);
diff --git a/fs/mmap/fs_munmap.c b/fs/mmap/fs_munmap.c
index bb4f127..9ef45f4 100644
--- a/fs/mmap/fs_munmap.c
+++ b/fs/mmap/fs_munmap.c
@@ -38,60 +38,10 @@
 #include "fs_rammap.h"
 
 /****************************************************************************
- * Public Functions
+ * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: munmap
- *
- * Description:
- *
- *   munmap() system call deletes mappings for the specified address range.
- *   All memory starting with 'start' and continuing for a length of 'length'
- *   bytes are removed.
- *
- *   NuttX operates in a flat open address space.  Therefore, it generally
- *   does not require mmap() and, hence, munmap functionality.  There are
- *   two exceptions where mmap() is available:
- *
- *   1. mmap() is the API that is used to support direct access to random
- *     access media under the following very restrictive conditions:
- *
- *     a. The filesystem supports the FIOC_MMAP ioctl command.  Any file
- *        system that maps files contiguously on the media should support
- *        this ioctl. (vs. file system that scatter files over the media
- *        in non-contiguous sectors).  As of this writing, ROMFS is the
- *        only file system that meets this requirement.
- *     b. The underlying block driver supports the BIOC_XIPBASE ioctl
- *        command that maps the underlying media to a randomly accessible
- *        address. At  present, only the RAM/ROM disk driver does this.
- *
- *     munmap() is still not required in this first case.  In this first
- *     The mapped address is a static address in the MCUs address space
- *     does not need to be munmapped.  Support for munmap() in this case
- *     provided by the simple definition in sys/mman.h:
- *
- *        #define munmap(start, length)
- *
- *   2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will
- *      support simulation of memory mapped files by copying files whole
- *      into RAM.  munmap() is required in this case to free the allocated
- *      memory holding the shared copy of the file.
- *
- * Input Parameters:
- *   start   The start address of the mapping to delete.  For this
- *           simplified munmap() implementation, the *must* be the start
- *           address of the memory region (the same address returned by
- *           mmap()).
- *   length  The length region to be umapped.
- *
- * Returned Value:
- *   On success, munmap() returns 0, on failure -1, and errno is set
- *   (probably to EINVAL).
- *
- ****************************************************************************/
-
-int munmap(FAR void *start, size_t length)
+static int file_munmap_(FAR void *start, size_t length, bool kernel)
 {
 #ifdef CONFIG_FS_RAMMAP
   FAR struct fs_rammap_s *prev;
@@ -99,15 +49,13 @@ int munmap(FAR void *start, size_t length)
   FAR void *newaddr;
   unsigned int offset;
   int ret;
-  int errcode;
 
   /* Find a region containing this start and length in the list of regions */
 
   ret = nxsem_wait(&g_rammaps.exclsem);
   if (ret < 0)
     {
-      errcode = ret;
-      goto errout;
+      return ret;
     }
 
   /* Search the list of regions */
@@ -129,7 +77,7 @@ int munmap(FAR void *start, size_t length)
   if (!curr)
     {
       ferr("ERROR: Region not found\n");
-      errcode = EINVAL;
+      ret = -EINVAL;
       goto errout_with_semaphore;
     }
 
@@ -144,7 +92,7 @@ int munmap(FAR void *start, size_t length)
   if (offset + length < curr->length)
     {
       ferr("ERROR: Cannot umap without unmapping to the end\n");
-      errcode = ENOSYS;
+      ret = -ENOSYS;
       goto errout_with_semaphore;
     }
 
@@ -171,7 +119,14 @@ int munmap(FAR void *start, size_t length)
 
       /* Then free the region */
 
-      kumm_free(curr);
+      if (curr->kernel)
+        {
+          kmm_free(curr)
+        }
+      else
+        {
+          kumm_free(curr);
+        }
     }
 
   /* No.. We have been asked to "unmap' only a portion of the memory
@@ -180,8 +135,17 @@ int munmap(FAR void *start, size_t length)
 
   else
     {
-      newaddr = kumm_realloc(curr->addr,
-                             sizeof(struct fs_rammap_s) + length);
+      if (kernel)
+        {
+          newaddr = kmm_realloc(curr->addr,
+                               sizeof(struct fs_rammap_s) + length);
+        }
+      else
+        {
+          newaddr = kumm_realloc(curr->addr,
+                                sizeof(struct fs_rammap_s) + length);
+        }
+
       DEBUGASSERT(newaddr == (FAR void *)(curr->addr));
       UNUSED(newaddr); /* May not be used */
       curr->length = length;
@@ -192,11 +156,90 @@ int munmap(FAR void *start, size_t length)
 
 errout_with_semaphore:
   nxsem_post(&g_rammaps.exclsem);
-
-errout:
-  set_errno(errcode);
-  return ERROR;
+  return ret;
 #else
   return OK;
 #endif /* CONFIG_FS_RAMMAP */
 }
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: file_mummap
+ *
+ * Description:
+ *   Equivalent to the standard file_mummap() function except it does not set
+ *   the errno variable.
+ *
+ ****************************************************************************/
+
+int file_munmap(FAR void *start, size_t length)
+{
+  return file_munmap_(start, length, true);
+}
+
+/****************************************************************************
+ * Name: munmap
+ *
+ * Description:
+ *
+ *   munmap() system call deletes mappings for the specified address range.
+ *   All memory starting with 'start' and continuing for a length of 'length'
+ *   bytes are removed.
+ *
+ *   NuttX operates in a flat open address space.  Therefore, it generally
+ *   does not require mmap() and, hence, munmap functionality.  There are
+ *   two exceptions where mmap() is available:
+ *
+ *   1. mmap() is the API that is used to support direct access to random
+ *     access media under the following very restrictive conditions:
+ *
+ *     a. The filesystem supports the FIOC_MMAP ioctl command.  Any file
+ *        system that maps files contiguously on the media should support
+ *        this ioctl. (vs. file system that scatter files over the media
+ *        in non-contiguous sectors).  As of this writing, ROMFS is the
+ *        only file system that meets this requirement.
+ *     b. The underlying block driver supports the BIOC_XIPBASE ioctl
+ *        command that maps the underlying media to a randomly accessible
+ *        address. At  present, only the RAM/ROM disk driver does this.
+ *
+ *     munmap() is still not required in this first case.  In this first
+ *     The mapped address is a static address in the MCUs address space
+ *     does not need to be munmapped.  Support for munmap() in this case
+ *     provided by the simple definition in sys/mman.h:
+ *
+ *        #define munmap(start, length)
+ *
+ *   2. If CONFIG_FS_RAMMAP is defined in the configuration, then mmap() will
+ *      support simulation of memory mapped files by copying files whole
+ *      into RAM.  munmap() is required in this case to free the allocated
+ *      memory holding the shared copy of the file.
+ *
+ * Input Parameters:
+ *   start   The start address of the mapping to delete.  For this
+ *           simplified munmap() implementation, the *must* be the start
+ *           address of the memory region (the same address returned by
+ *           mmap()).
+ *   length  The length region to be umapped.
+ *
+ * Returned Value:
+ *   On success, munmap() returns 0, on failure -1, and errno is set
+ *   (probably to EINVAL).
+ *
+ ****************************************************************************/
+
+int munmap(FAR void *start, size_t length)
+{
+  int ret;
+
+  ret = file_munmap_(start, length, false);
+  if (ret < 0)
+    {
+      set_errno(-ret);
+      ret = ERROR;
+    }
+
+  return ret;
+}
diff --git a/fs/mmap/fs_rammap.c b/fs/mmap/fs_rammap.c
index 2145a7a..30f5d61 100644
--- a/fs/mmap/fs_rammap.c
+++ b/fs/mmap/fs_rammap.c
@@ -62,14 +62,15 @@ struct fs_allmaps_s g_rammaps =
  *   Support simulation of memory mapped files by copying files into RAM.
  *
  * Input Parameters:
- *   fd      file descriptor of the backing file -- required.
+ *   filep   file descriptor of the backing file -- required.
  *   length  The length of the mapping.  For exception #1 above, this length
  *           ignored:  The entire underlying media is always accessible.
  *   offset  The offset into the file to map
+ *   kernel  kmm_zalloc or kumm_zalloc
+ *   mapped  The pointer to the mapped area
  *
  * Returned Value:
- *   On success, rammmap() returns a pointer to the mapped area. On error,
- *   the value MAP_FAILED is returned, and errno is set  appropriately.
+ *  On success, rammmap returns 0. Otherwise errno is returned appropriately.
  *
  *     EBADF
  *      'fd' is not a valid file descriptor.
@@ -80,7 +81,8 @@ struct fs_allmaps_s g_rammaps =
  *
  ****************************************************************************/
 
-FAR void *rammap(int fd, size_t length, off_t offset)
+int rammap(FAR struct file *filep, size_t length,
+           off_t offset, bool kernel, FAR void **mapped)
 {
   FAR struct fs_rammap_s *map;
   FAR uint8_t *alloc;
@@ -104,12 +106,13 @@ FAR void *rammap(int fd, size_t length, off_t offset)
 
   /* Allocate a region of memory of the specified size */
 
-  alloc = (FAR uint8_t *)kumm_malloc(sizeof(struct fs_rammap_s) + length);
+  alloc = (FAR uint8_t *)kernel ?
+    kmm_malloc(sizeof(struct fs_rammap_s) + length);
+    kumm_malloc(sizeof(struct fs_rammap_s) + length);
   if (!alloc)
     {
       ferr("ERROR: Region allocation failed, length: %d\n", (int)length);
-      ret = -ENOMEM;
-      goto errout;
+      return -ENOMEM;
     }
 
   /* Initialize the region */
@@ -122,7 +125,7 @@ FAR void *rammap(int fd, size_t length, off_t offset)
 
   /* Seek to the specified file offset */
 
-  fpos = nx_seek(fd, offset,  SEEK_SET);
+  fpos = file_seek(filep, offset, SEEK_SET);
   if (fpos < 0)
     {
       /* Seek failed... errno has already been set, but EINVAL is probably
@@ -139,7 +142,7 @@ FAR void *rammap(int fd, size_t length, off_t offset)
   rdbuffer = map->addr;
   while (length > 0)
     {
-      nread = nx_read(fd, rdbuffer, length);
+      nread = file_read(filep, rdbuffer, length);
       if (nread < 0)
         {
           /* Handle the special case where the read was interrupted by a
@@ -187,14 +190,20 @@ FAR void *rammap(int fd, size_t length, off_t offset)
   g_rammaps.head = map;
 
   nxsem_post(&g_rammaps.exclsem);
-  return map->addr;
+  *mapped = map->addr;
+  return OK;
 
 errout_with_region:
-  kumm_free(alloc);
+  if (kernel)
+    {
+      kmm_free(alloc);
+    }
+  else
+    {
+      kumm_free(alloc);
+    }
 
-errout:
-  set_errno(-ret);
-  return MAP_FAILED;
+  return ret;
 }
 
 #endif /* CONFIG_FS_RAMMAP */
diff --git a/fs/mmap/fs_rammap.h b/fs/mmap/fs_rammap.h
index 096c9c3..ec4fbbc 100644
--- a/fs/mmap/fs_rammap.h
+++ b/fs/mmap/fs_rammap.h
@@ -88,14 +88,15 @@ extern struct fs_allmaps_s g_rammaps;
  *   Support simulation of memory mapped files by copying files into RAM.
  *
  * Input Parameters:
- *   fd      file descriptor of the backing file -- required.
+ *   filep   file descriptor of the backing file -- required.
  *   length  The length of the mapping.  For exception #1 above, this length
  *           ignored:  The entire underlying media is always accessible.
  *   offset  The offset into the file to map
+ *   kernel  kmm_zalloc or kumm_zalloc
+ *   mapped  The pointer to the mapped area
  *
  * Returned Value:
- *   On success, rammmap() returns a pointer to the mapped area. On error,
- *   the value MAP_FAILED is returned, and errno is set  appropriately.
+ *   On success rammmap returns 0. Otherwise errno is returned appropriately.
  *
  *     EBADF
  *      'fd' is not a valid file descriptor.
@@ -106,7 +107,8 @@ extern struct fs_allmaps_s g_rammaps;
  *
  ****************************************************************************/
 
-FAR void *rammap(int fd, size_t length, off_t offset);
+int rammap(FAR struct file *filep, size_t length,
+           off_t offset, bool kernel, FAR void **mapped);
 
 #endif /* CONFIG_FS_RAMMAP */
 #endif /* __FS_MMAP_RAMMAP_H */
diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index 6a2a557..af6157e 100644
--- a/include/nuttx/fs/fs.h
+++ b/include/nuttx/fs/fs.h
@@ -1169,6 +1169,30 @@ int file_truncate(FAR struct file *filep, off_t length);
 #endif
 
 /****************************************************************************
+ * Name: file_mmap
+ *
+ * Description:
+ *   Equivalent to the standard mmap() function except that is accepts
+ *   a struct file instance instead of a file descriptor and it does not set
+ *   the errno variable.
+ *
+ ****************************************************************************/
+
+int file_mmap(FAR struct file *filep, FAR void *start, size_t length,
+              int prot, int flags, off_t offset, FAR void **mapped);
+
+/****************************************************************************
+ * Name: file_mummap
+ *
+ * Description:
+ *   Equivalent to the standard mummap() function except it does not set
+ *   the errno variable.
+ *
+ ****************************************************************************/
+
+int file_munmap(FAR void *start, size_t length);
+
+/****************************************************************************
  * Name: file_ioctl
  *
  * Description: