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, 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;

View File

@ -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);

View File

@ -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);
} }

View File

@ -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 */