mmap: add xip mmap type support

Signed-off-by: wanggang26 <wanggang26@xiaomi.com>
This commit is contained in:
wanggang26 2024-05-16 22:40:34 +08:00 committed by Xiang Xiao
parent 545774eb88
commit 484600bd75
4 changed files with 43 additions and 29 deletions

View File

@ -47,8 +47,8 @@
****************************************************************************/
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)
size_t length, int prot, int flags, off_t offset,
enum mm_map_type_e type, FAR void **mapped)
{
int ret = -ENOTTY;
@ -107,7 +107,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
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
* 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.
*/
ret = rammap(filep, &entry, kernel);
ret = rammap(filep, &entry, type);
}
/* 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)
{
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,
prot, flags, offset, false, &mapped);
if (fd != -1)
{
fs_putfilep(filep);
}
prot, flags, offset, MAP_USER, &mapped);
fs_putfilep(filep);
if (ret < 0)
{
goto errout;

View File

@ -43,7 +43,8 @@
* 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 task_group_s *group = tcb->group;
@ -100,7 +101,7 @@ unlock:
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;
ret = file_munmap_(start, length, false);
ret = file_munmap_(start, length, MAP_USER);
if (ret < 0)
{
set_errno(-ret);

View File

@ -24,6 +24,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <debug.h>
@ -55,7 +56,7 @@ static int unmap_rammap(FAR struct task_group_s *group,
{
FAR void *newaddr = NULL;
off_t offset;
bool kernel = entry->priv.i;
enum mm_map_type_e type = entry->priv.i;
int ret = OK;
/* 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 */
if (kernel)
if (type == MAP_KERNEL)
{
kmm_free(entry->vaddr);
}
else
else if (type == MAP_USER)
{
kumm_free(entry->vaddr);
}
@ -104,11 +105,11 @@ static int unmap_rammap(FAR struct task_group_s *group,
else
{
if (kernel)
if (type == MAP_KERNEL)
{
newaddr = kmm_realloc(entry->vaddr, length);
}
else
else if (type == MAP_USER)
{
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.
* entry mmap entry information.
* 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:
* 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,
bool kernel)
enum mm_map_type_e type)
{
FAR uint8_t *rdbuffer;
ssize_t nread;
@ -159,6 +160,13 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
int ret;
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:
* 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
@ -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 */
rdbuffer = kernel ? kmm_malloc(length) : kumm_malloc(length);
rdbuffer = type == MAP_KERNEL ? kmm_malloc(length) : kumm_malloc(length);
if (!rdbuffer)
{
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 */
entry->priv.i = kernel;
out:
entry->priv.i = type;
entry->munmap = unmap_rammap;
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;
errout_with_region:
if (kernel)
if (type == MAP_KERNEL)
{
kmm_free(entry->vaddr);
}
else
else if (type == MAP_USER)
{
kumm_free(entry->vaddr);
}

View File

@ -47,6 +47,15 @@
#include <sys/types.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
/****************************************************************************
@ -72,8 +81,7 @@
* 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
* type kmm_zalloc or kumm_zalloc or xip_base
*
* Returned Value:
* 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,
bool kernel);
enum mm_map_type_e type);
#else
# define rammap(file, entry, kernel) (-ENOSYS)
# define rammap(file, entry, type) (-ENOSYS)
#endif /* CONFIG_FS_RAMMAP */
#endif /* __FS_MMAP_FS_RAMMAP_H */