mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
Move rammaps to use mm_map list
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
committed by
Xiang Xiao
parent
a5ed8014e8
commit
b8f23fc3f7
+2
-2
@@ -135,7 +135,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
|
|||||||
* do much better in the KERNEL build using the MMU.
|
* do much better in the KERNEL build using the MMU.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return rammap(filep, length, offset, kernel, mapped);
|
return rammap(filep, &entry, kernel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
|
|||||||
* do much better in the KERNEL build using the MMU.
|
* do much better in the KERNEL build using the MMU.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return rammap(filep, length, offset, kernel, mapped);
|
return rammap(filep, &entry, kernel);
|
||||||
#else
|
#else
|
||||||
ferr("ERROR: mmap not supported \n");
|
ferr("ERROR: mmap not supported \n");
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|||||||
@@ -44,122 +44,6 @@
|
|||||||
|
|
||||||
static int file_munmap_(FAR void *start, size_t length, bool kernel)
|
static int file_munmap_(FAR void *start, size_t length, bool kernel)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FS_RAMMAP
|
|
||||||
FAR struct fs_rammap_s *prev;
|
|
||||||
FAR struct fs_rammap_s *curr;
|
|
||||||
FAR void *newaddr;
|
|
||||||
unsigned int offset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Find a region containing this start and length in the list of regions */
|
|
||||||
|
|
||||||
ret = nxmutex_lock(&g_rammaps.lock);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search the list of regions */
|
|
||||||
|
|
||||||
for (prev = NULL, curr = g_rammaps.head; curr;
|
|
||||||
prev = curr, curr = curr->flink)
|
|
||||||
{
|
|
||||||
/* Does this region include any part of the specified range? */
|
|
||||||
|
|
||||||
if ((uintptr_t)start < (uintptr_t)curr->addr + curr->length &&
|
|
||||||
(uintptr_t)start + length >= (uintptr_t)curr->addr)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Did we find the region */
|
|
||||||
|
|
||||||
if (!curr)
|
|
||||||
{
|
|
||||||
ferr("ERROR: Region not found\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto errout_with_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the offset from the beginning of the region and the actual number
|
|
||||||
* of bytes to "unmap". All mappings must extend to the end of the region.
|
|
||||||
* There is no support for free a block of memory but leaving a block of
|
|
||||||
* memory at the end. This is a consequence of using kumm_realloc() to
|
|
||||||
* simulate the unmapping.
|
|
||||||
*/
|
|
||||||
|
|
||||||
offset = start - curr->addr;
|
|
||||||
if (offset + length < curr->length)
|
|
||||||
{
|
|
||||||
ferr("ERROR: Cannot umap without unmapping to the end\n");
|
|
||||||
ret = -ENOSYS;
|
|
||||||
goto errout_with_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Okay.. the region is beging umapped to the end. Make sure the length
|
|
||||||
* indicates that.
|
|
||||||
*/
|
|
||||||
|
|
||||||
length = curr->length - offset;
|
|
||||||
|
|
||||||
/* Are we unmapping the entire region (offset == 0)? */
|
|
||||||
|
|
||||||
if (length >= curr->length)
|
|
||||||
{
|
|
||||||
/* Yes.. remove the mapping from the list */
|
|
||||||
|
|
||||||
if (prev)
|
|
||||||
{
|
|
||||||
prev->flink = curr->flink;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_rammaps.head = curr->flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then free the region */
|
|
||||||
|
|
||||||
if (kernel)
|
|
||||||
{
|
|
||||||
kmm_free(curr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kumm_free(curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No.. We have been asked to "unmap' only a portion of the memory
|
|
||||||
* (offset > 0).
|
|
||||||
*/
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
nxmutex_unlock(&g_rammaps.lock);
|
|
||||||
return OK;
|
|
||||||
|
|
||||||
errout_with_lock:
|
|
||||||
nxmutex_unlock(&g_rammaps.lock);
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
|
|
||||||
FAR struct tcb_s *tcb = nxsched_self();
|
FAR struct tcb_s *tcb = nxsched_self();
|
||||||
FAR struct task_group_s *group = tcb->group;
|
FAR struct task_group_s *group = tcb->group;
|
||||||
FAR struct mm_map_entry_s *entry = NULL;
|
FAR struct mm_map_entry_s *entry = NULL;
|
||||||
@@ -185,7 +69,6 @@ errout_with_lock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
#endif /* CONFIG_FS_RAMMAP */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
+90
-35
@@ -23,9 +23,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -35,7 +33,6 @@
|
|||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
|
||||||
#include "inode/inode.h"
|
|
||||||
#include "fs_rammap.h"
|
#include "fs_rammap.h"
|
||||||
|
|
||||||
#ifdef CONFIG_FS_RAMMAP
|
#ifdef CONFIG_FS_RAMMAP
|
||||||
@@ -44,12 +41,83 @@
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This is the list of all mapped files */
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
struct fs_allmaps_s g_rammaps =
|
static int unmap_rammap(FAR struct task_group_s *group,
|
||||||
|
FAR struct mm_map_entry_s *entry,
|
||||||
|
FAR void *start,
|
||||||
|
size_t length)
|
||||||
{
|
{
|
||||||
NXMUTEX_INITIALIZER
|
FAR void *newaddr;
|
||||||
};
|
unsigned int offset;
|
||||||
|
bool kernel = entry->priv.i != 0 ? true : false;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get the offset from the beginning of the region and the actual number
|
||||||
|
* of bytes to "unmap". All mappings must extend to the end of the region.
|
||||||
|
* There is no support for freeing a block of memory but leaving a block of
|
||||||
|
* memory at the end. This is a consequence of using kumm_realloc() to
|
||||||
|
* simulate the unmapping.
|
||||||
|
*/
|
||||||
|
|
||||||
|
offset = start - entry->vaddr;
|
||||||
|
if (offset + length < entry->length)
|
||||||
|
{
|
||||||
|
ferr("ERROR: Cannot umap without unmapping to the end\n");
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Okay.. the region is being unmapped to the end. Make sure the length
|
||||||
|
* indicates that.
|
||||||
|
*/
|
||||||
|
|
||||||
|
length = entry->length - offset;
|
||||||
|
|
||||||
|
/* Are we unmapping the entire region (offset == 0)? */
|
||||||
|
|
||||||
|
if (length >= entry->length)
|
||||||
|
{
|
||||||
|
/* Free the region */
|
||||||
|
|
||||||
|
if (kernel)
|
||||||
|
{
|
||||||
|
kmm_free(entry->vaddr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kumm_free(entry->vaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then remove the mapping from the list */
|
||||||
|
|
||||||
|
ret = mm_map_remove(get_group_mm(group), entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No.. We have been asked to "unmap' only a portion of the memory
|
||||||
|
* (offset > 0).
|
||||||
|
*/
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (kernel)
|
||||||
|
{
|
||||||
|
newaddr = kmm_realloc(entry->vaddr, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newaddr = kumm_realloc(entry->vaddr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(newaddr == entry->vaddr);
|
||||||
|
UNUSED(newaddr); /* May not be used */
|
||||||
|
entry->length = length;
|
||||||
|
ret = OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -81,15 +149,14 @@ struct fs_allmaps_s g_rammaps =
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int rammap(FAR struct file *filep, size_t length,
|
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
||||||
off_t offset, bool kernel, FAR void **mapped)
|
bool kernel)
|
||||||
{
|
{
|
||||||
FAR struct fs_rammap_s *map;
|
|
||||||
FAR uint8_t *alloc;
|
|
||||||
FAR uint8_t *rdbuffer;
|
FAR uint8_t *rdbuffer;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
off_t fpos;
|
off_t fpos;
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t length = entry->length;
|
||||||
|
|
||||||
/* There is a major design flaw that I have not yet thought of fix for:
|
/* There is a major design flaw that I have not yet thought of fix for:
|
||||||
* The goal is to have a single region of memory that represents a single
|
* The goal is to have a single region of memory that represents a single
|
||||||
@@ -106,40 +173,29 @@ int rammap(FAR struct file *filep, size_t length,
|
|||||||
|
|
||||||
/* Allocate a region of memory of the specified size */
|
/* Allocate a region of memory of the specified size */
|
||||||
|
|
||||||
alloc = kernel ?
|
rdbuffer = kernel ? kmm_malloc(length) : kumm_malloc(length);
|
||||||
kmm_malloc(sizeof(struct fs_rammap_s) + length) :
|
if (!rdbuffer)
|
||||||
kumm_malloc(sizeof(struct fs_rammap_s) + length);
|
|
||||||
if (!alloc)
|
|
||||||
{
|
{
|
||||||
ferr("ERROR: Region allocation failed, length: %d\n", (int)length);
|
ferr("ERROR: Region allocation failed, length: %d\n", (int)length);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the region */
|
|
||||||
|
|
||||||
map = (FAR struct fs_rammap_s *)alloc;
|
|
||||||
memset(map, 0, sizeof(struct fs_rammap_s));
|
|
||||||
map->addr = alloc + sizeof(struct fs_rammap_s);
|
|
||||||
map->length = length;
|
|
||||||
map->offset = offset;
|
|
||||||
|
|
||||||
/* Seek to the specified file offset */
|
/* Seek to the specified file offset */
|
||||||
|
|
||||||
fpos = file_seek(filep, offset, SEEK_SET);
|
fpos = file_seek(filep, entry->offset, SEEK_SET);
|
||||||
if (fpos < 0)
|
if (fpos < 0)
|
||||||
{
|
{
|
||||||
/* Seek failed... errno has already been set, but EINVAL is probably
|
/* Seek failed... errno has already been set, but EINVAL is probably
|
||||||
* the correct response.
|
* the correct response.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ferr("ERROR: Seek to position %d failed\n", (int)offset);
|
ferr("ERROR: Seek to position %d failed\n", (int)entry->offset);
|
||||||
ret = fpos;
|
ret = fpos;
|
||||||
goto errout_with_region;
|
goto errout_with_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the file data into the memory region */
|
/* Read the file data into the memory region */
|
||||||
|
|
||||||
rdbuffer = map->addr;
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
nread = file_read(filep, rdbuffer, length);
|
nread = file_read(filep, rdbuffer, length);
|
||||||
@@ -154,7 +210,7 @@ int rammap(FAR struct file *filep, size_t length,
|
|||||||
/* All other read errors are bad. */
|
/* All other read errors are bad. */
|
||||||
|
|
||||||
ferr("ERROR: Read failed: offset=%d ret=%d\n",
|
ferr("ERROR: Read failed: offset=%d ret=%d\n",
|
||||||
(int)offset, (int)nread);
|
(int)entry->offset, (int)nread);
|
||||||
|
|
||||||
ret = nread;
|
ret = nread;
|
||||||
goto errout_with_region;
|
goto errout_with_region;
|
||||||
@@ -180,27 +236,26 @@ int rammap(FAR struct file *filep, size_t length,
|
|||||||
|
|
||||||
/* Add the buffer to the list of regions */
|
/* Add the buffer to the list of regions */
|
||||||
|
|
||||||
ret = nxmutex_lock(&g_rammaps.lock);
|
entry->vaddr = rdbuffer;
|
||||||
|
entry->priv.i = kernel ? 1 : 0;
|
||||||
|
entry->munmap = unmap_rammap;
|
||||||
|
|
||||||
|
ret = mm_map_add(entry);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout_with_region;
|
goto errout_with_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
map->flink = g_rammaps.head;
|
|
||||||
g_rammaps.head = map;
|
|
||||||
|
|
||||||
nxmutex_unlock(&g_rammaps.lock);
|
|
||||||
*mapped = map->addr;
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_region:
|
errout_with_region:
|
||||||
if (kernel)
|
if (kernel)
|
||||||
{
|
{
|
||||||
kmm_free(alloc);
|
kmm_free(rdbuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kumm_free(alloc);
|
kumm_free(rdbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+18
-38
@@ -18,25 +18,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef __FS_MMAP_FS_RAMMAP_H
|
/* This driver manages files that have been copied to memory and
|
||||||
#define __FS_MMAP_FS_RAMMAP_H
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Included Files
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <nuttx/mutex.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_FS_RAMMAP
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* This structure describes one file that has been copied to memory and
|
|
||||||
* managed as a share-able "memory mapped" file. This functionality is
|
* managed as a share-able "memory mapped" file. This functionality is
|
||||||
* intended to provide a substitute for memory mapped files for architectures
|
* intended to provide a substitute for memory mapped files for architectures
|
||||||
* that do not have MMUs and, hence, cannot support on demand paging of
|
* that do not have MMUs and, hence, cannot support on demand paging of
|
||||||
@@ -53,30 +35,28 @@
|
|||||||
* - There are not access privileges.
|
* - There are not access privileges.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct fs_rammap_s
|
#ifndef __FS_MMAP_FS_RAMMAP_H
|
||||||
{
|
#define __FS_MMAP_FS_RAMMAP_H
|
||||||
struct fs_rammap_s *flink; /* Implements a singly linked list */
|
|
||||||
FAR void *addr; /* Start of allocated memory */
|
|
||||||
size_t length; /* Length of region */
|
|
||||||
off_t offset; /* File offset */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This structure defines all "mapped" files */
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
struct fs_allmaps_s
|
#include <nuttx/config.h>
|
||||||
{
|
|
||||||
mutex_t lock; /* Provides exclusive access the list */
|
#include <sys/types.h>
|
||||||
struct fs_rammap_s *head; /* List of mapped files */
|
#include <nuttx/mm/map.h>
|
||||||
};
|
|
||||||
|
#ifdef CONFIG_FS_RAMMAP
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This is the list of all mapped files */
|
|
||||||
|
|
||||||
extern struct fs_allmaps_s g_rammaps;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -107,8 +87,8 @@ extern struct fs_allmaps_s g_rammaps;
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int rammap(FAR struct file *filep, size_t length,
|
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
||||||
off_t offset, bool kernel, FAR void **mapped);
|
bool kernel);
|
||||||
|
|
||||||
#endif /* CONFIG_FS_RAMMAP */
|
#endif /* CONFIG_FS_RAMMAP */
|
||||||
#endif /* __FS_MMAP_FS_RAMMAP_H */
|
#endif /* __FS_MMAP_FS_RAMMAP_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user