mmap: add xip mmap type support
Signed-off-by: wanggang26 <wanggang26@xiaomi.com>
This commit is contained in:
parent
545774eb88
commit
484600bd75
@ -47,8 +47,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int file_mmap_(FAR struct file *filep, FAR void *start,
|
static int file_mmap_(FAR struct file *filep, FAR void *start,
|
||||||
size_t length, int prot, int flags,
|
size_t length, int prot, int flags, off_t offset,
|
||||||
off_t offset, bool kernel, FAR void **mapped)
|
enum mm_map_type_e type, FAR void **mapped)
|
||||||
{
|
{
|
||||||
int ret = -ENOTTY;
|
int ret = -ENOTTY;
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
|
|||||||
|
|
||||||
if ((flags & MAP_ANONYMOUS) != 0)
|
if ((flags & MAP_ANONYMOUS) != 0)
|
||||||
{
|
{
|
||||||
ret = map_anonymous(&entry, kernel);
|
ret = map_anonymous(&entry, type);
|
||||||
|
|
||||||
/* According to the mmap(2) specification, anonymous pages should be
|
/* According to the mmap(2) specification, anonymous pages should be
|
||||||
* initialized to zero unless the MAP_UNINITIALIZED is specified.
|
* initialized to zero unless the MAP_UNINITIALIZED is specified.
|
||||||
@ -161,7 +161,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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = rammap(filep, &entry, kernel);
|
ret = rammap(filep, &entry, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return */
|
/* Return */
|
||||||
@ -193,7 +193,7 @@ int file_mmap(FAR struct file *filep, FAR void *start, size_t length,
|
|||||||
int prot, int flags, off_t offset, FAR void **mapped)
|
int prot, int flags, off_t offset, FAR void **mapped)
|
||||||
{
|
{
|
||||||
return file_mmap_(filep, start, length,
|
return file_mmap_(filep, start, length,
|
||||||
prot, flags, offset, true, mapped);
|
prot, flags, offset, MAP_KERNEL, mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -285,12 +285,8 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = file_mmap_(filep, start, length,
|
ret = file_mmap_(filep, start, length,
|
||||||
prot, flags, offset, false, &mapped);
|
prot, flags, offset, MAP_USER, &mapped);
|
||||||
if (fd != -1)
|
|
||||||
{
|
|
||||||
fs_putfilep(filep);
|
fs_putfilep(filep);
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int file_munmap_(FAR void *start, size_t length, bool kernel)
|
static int file_munmap_(FAR void *start, size_t length,
|
||||||
|
enum mm_map_type_e type)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *tcb = this_task();
|
FAR struct tcb_s *tcb = this_task();
|
||||||
FAR struct task_group_s *group = tcb->group;
|
FAR struct task_group_s *group = tcb->group;
|
||||||
@ -100,7 +101,7 @@ unlock:
|
|||||||
|
|
||||||
int file_munmap(FAR void *start, size_t length)
|
int file_munmap(FAR void *start, size_t length)
|
||||||
{
|
{
|
||||||
return file_munmap_(start, length, true);
|
return file_munmap_(start, length, MAP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -157,7 +158,7 @@ int munmap(FAR void *start, size_t length)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = file_munmap_(start, length, false);
|
ret = file_munmap_(start, length, MAP_USER);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
set_errno(-ret);
|
set_errno(-ret);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
@ -55,7 +56,7 @@ static int unmap_rammap(FAR struct task_group_s *group,
|
|||||||
{
|
{
|
||||||
FAR void *newaddr = NULL;
|
FAR void *newaddr = NULL;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
bool kernel = entry->priv.i;
|
enum mm_map_type_e type = entry->priv.i;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
/* Get the offset from the beginning of the region and the actual number
|
/* Get the offset from the beginning of the region and the actual number
|
||||||
@ -84,11 +85,11 @@ static int unmap_rammap(FAR struct task_group_s *group,
|
|||||||
{
|
{
|
||||||
/* Free the region */
|
/* Free the region */
|
||||||
|
|
||||||
if (kernel)
|
if (type == MAP_KERNEL)
|
||||||
{
|
{
|
||||||
kmm_free(entry->vaddr);
|
kmm_free(entry->vaddr);
|
||||||
}
|
}
|
||||||
else
|
else if (type == MAP_USER)
|
||||||
{
|
{
|
||||||
kumm_free(entry->vaddr);
|
kumm_free(entry->vaddr);
|
||||||
}
|
}
|
||||||
@ -104,11 +105,11 @@ static int unmap_rammap(FAR struct task_group_s *group,
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (kernel)
|
if (type == MAP_KERNEL)
|
||||||
{
|
{
|
||||||
newaddr = kmm_realloc(entry->vaddr, length);
|
newaddr = kmm_realloc(entry->vaddr, length);
|
||||||
}
|
}
|
||||||
else
|
else if (type == MAP_USER)
|
||||||
{
|
{
|
||||||
newaddr = kumm_realloc(entry->vaddr, length);
|
newaddr = kumm_realloc(entry->vaddr, length);
|
||||||
}
|
}
|
||||||
@ -135,7 +136,7 @@ static int unmap_rammap(FAR struct task_group_s *group,
|
|||||||
* filep file descriptor of the backing file -- required.
|
* filep file descriptor of the backing file -- required.
|
||||||
* entry mmap entry information.
|
* entry mmap entry information.
|
||||||
* field offset and length must be initialized correctly.
|
* field offset and length must be initialized correctly.
|
||||||
* kernel kmm_zalloc or kumm_zalloc
|
* type kmm_zalloc or kumm_zalloc or xip_base
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success, rammap returns 0 and entry->vaddr points to memory mapped.
|
* On success, rammap returns 0 and entry->vaddr points to memory mapped.
|
||||||
@ -151,7 +152,7 @@ static int unmap_rammap(FAR struct task_group_s *group,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
||||||
bool kernel)
|
enum mm_map_type_e type)
|
||||||
{
|
{
|
||||||
FAR uint8_t *rdbuffer;
|
FAR uint8_t *rdbuffer;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
@ -159,6 +160,13 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
|||||||
int ret;
|
int ret;
|
||||||
size_t length = entry->length;
|
size_t length = entry->length;
|
||||||
|
|
||||||
|
ret = file_ioctl(filep, BIOC_XIPBASE, (unsigned long)&entry->vaddr);
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
type = MAP_XIP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
* file and can be shared by many threads. That is, given a filename a
|
* file and can be shared by many threads. That is, given a filename a
|
||||||
@ -174,7 +182,7 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
|||||||
|
|
||||||
/* Allocate a region of memory of the specified size */
|
/* Allocate a region of memory of the specified size */
|
||||||
|
|
||||||
rdbuffer = kernel ? kmm_malloc(length) : kumm_malloc(length);
|
rdbuffer = type == MAP_KERNEL ? kmm_malloc(length) : kumm_malloc(length);
|
||||||
if (!rdbuffer)
|
if (!rdbuffer)
|
||||||
{
|
{
|
||||||
ferr("ERROR: Region allocation failed, length: %zu\n", length);
|
ferr("ERROR: Region allocation failed, length: %zu\n", length);
|
||||||
@ -239,7 +247,8 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
|||||||
|
|
||||||
/* Add the buffer to the list of regions */
|
/* Add the buffer to the list of regions */
|
||||||
|
|
||||||
entry->priv.i = kernel;
|
out:
|
||||||
|
entry->priv.i = type;
|
||||||
entry->munmap = unmap_rammap;
|
entry->munmap = unmap_rammap;
|
||||||
|
|
||||||
ret = mm_map_add(get_current_mm(), entry);
|
ret = mm_map_add(get_current_mm(), entry);
|
||||||
@ -251,11 +260,11 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
|||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_region:
|
errout_with_region:
|
||||||
if (kernel)
|
if (type == MAP_KERNEL)
|
||||||
{
|
{
|
||||||
kmm_free(entry->vaddr);
|
kmm_free(entry->vaddr);
|
||||||
}
|
}
|
||||||
else
|
else if (type == MAP_USER)
|
||||||
{
|
{
|
||||||
kumm_free(entry->vaddr);
|
kumm_free(entry->vaddr);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,15 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <nuttx/mm/map.h>
|
#include <nuttx/mm/map.h>
|
||||||
|
|
||||||
|
/* A memory mapping type definition */
|
||||||
|
|
||||||
|
enum mm_map_type_e
|
||||||
|
{
|
||||||
|
MAP_USER = 0,
|
||||||
|
MAP_KERNEL,
|
||||||
|
MAP_XIP,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_FS_RAMMAP
|
#ifdef CONFIG_FS_RAMMAP
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -72,8 +81,7 @@
|
|||||||
* length The length of the mapping. For exception #1 above, this length
|
* length The length of the mapping. For exception #1 above, this length
|
||||||
* ignored: The entire underlying media is always accessible.
|
* ignored: The entire underlying media is always accessible.
|
||||||
* offset The offset into the file to map
|
* offset The offset into the file to map
|
||||||
* kernel kmm_zalloc or kumm_zalloc
|
* type kmm_zalloc or kumm_zalloc or xip_base
|
||||||
* mapped The pointer to the mapped area
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success rammmap returns 0. Otherwise errno is returned appropriately.
|
* On success rammmap returns 0. Otherwise errno is returned appropriately.
|
||||||
@ -88,9 +96,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
|
||||||
bool kernel);
|
enum mm_map_type_e type);
|
||||||
#else
|
#else
|
||||||
# define rammap(file, entry, kernel) (-ENOSYS)
|
# define rammap(file, entry, type) (-ENOSYS)
|
||||||
#endif /* CONFIG_FS_RAMMAP */
|
#endif /* CONFIG_FS_RAMMAP */
|
||||||
|
|
||||||
#endif /* __FS_MMAP_FS_RAMMAP_H */
|
#endif /* __FS_MMAP_FS_RAMMAP_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user