mirror of
https://github.com/apache/nuttx.git
synced 2026-08-21 05:28:19 +00:00
binfmt: Support arch copy section by self for dynamic code loading
This option enables architecture-specific memory copy for dynamic code loading. For example, Ambiq has MRAM regions for instruction which can't load by the memcpy directly. Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
parent
c749e4bfbd
commit
8a13da322d
3 changed files with 73 additions and 7 deletions
15
arch/Kconfig
15
arch/Kconfig
|
|
@ -401,6 +401,12 @@ config ARCH_HAVE_TEXT_HEAP
|
||||||
---help---
|
---help---
|
||||||
Special memory region for dynamic code loading
|
Special memory region for dynamic code loading
|
||||||
|
|
||||||
|
config ARCH_HAVE_COPY_SECTION
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Section copying for dynamic code loading
|
||||||
|
|
||||||
config ARCH_HAVE_MULTICPU
|
config ARCH_HAVE_MULTICPU
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
@ -623,6 +629,15 @@ menuconfig ARCH_ADDRENV
|
||||||
Support per-task address environments using the MMU... i.e., support
|
Support per-task address environments using the MMU... i.e., support
|
||||||
"processes"
|
"processes"
|
||||||
|
|
||||||
|
config ARCH_USE_COPY_SECTION
|
||||||
|
bool "Enable arch copy section by self for dynamic code loading"
|
||||||
|
default n
|
||||||
|
depends on ARCH_HAVE_COPY_SECTION
|
||||||
|
---help---
|
||||||
|
This option enables architecture-specific memory copy for
|
||||||
|
dynamic code loading. For example, Ambiq has MRAM regions
|
||||||
|
for instruction which can't load by the memcpy directly.
|
||||||
|
|
||||||
if ARCH_ADDRENV && ARCH_NEED_ADDRENV_MAPPING
|
if ARCH_ADDRENV && ARCH_NEED_ADDRENV_MAPPING
|
||||||
|
|
||||||
config ARCH_TEXT_VBASE
|
config ARCH_TEXT_VBASE
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,23 @@ static inline void elf_dumpreaddata(FAR char *buffer, size_t buflen)
|
||||||
int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||||
size_t readsize, off_t offset)
|
size_t readsize, off_t offset)
|
||||||
{
|
{
|
||||||
size_t nsize = readsize;
|
size_t nsize = readsize; /* Bytes to read from the object file */
|
||||||
ssize_t nbytes; /* Number of bytes read */
|
ssize_t nbytes; /* Number of bytes read */
|
||||||
off_t rpos; /* Position returned by lseek */
|
off_t rpos; /* Position returned by lseek */
|
||||||
|
int ret = OK; /* Return value */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_COPY_SECTION
|
||||||
|
FAR uint8_t *dest = buffer; /* Destination address - `buffer` */
|
||||||
|
|
||||||
|
/* Redirect `buffer` to temporary allocated memory */
|
||||||
|
|
||||||
|
buffer = kmm_malloc(readsize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
berr("ERROR: Failed to allocate memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
binfo("Read %zu bytes from offset %" PRIdOFF "\n", readsize, offset);
|
binfo("Read %zu bytes from offset %" PRIdOFF "\n", readsize, offset);
|
||||||
|
|
||||||
|
|
@ -115,7 +129,8 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||||
{
|
{
|
||||||
berr("Failed to seek to position %" PRIdOFF ": %" PRIdOFF "\n",
|
berr("Failed to seek to position %" PRIdOFF ": %" PRIdOFF "\n",
|
||||||
offset, rpos);
|
offset, rpos);
|
||||||
return rpos;
|
ret = rpos;
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the file data at offset into the user buffer */
|
/* Read the file data at offset into the user buffer */
|
||||||
|
|
@ -130,13 +145,15 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||||
{
|
{
|
||||||
berr("Read from offset %" PRIdOFF " failed: %zd\n",
|
berr("Read from offset %" PRIdOFF " failed: %zd\n",
|
||||||
offset, nbytes);
|
offset, nbytes);
|
||||||
return nbytes;
|
ret = nbytes;
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nbytes == 0)
|
else if (nbytes == 0)
|
||||||
{
|
{
|
||||||
berr("Unexpected end of file\n");
|
berr("Unexpected end of file\n");
|
||||||
return -ENODATA;
|
ret = -ENODATA;
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -145,6 +162,25 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_COPY_SECTION
|
||||||
|
/* Copy the requested data from temporary memory to destination */
|
||||||
|
|
||||||
|
ret = up_copy_section(dest, buffer, nsize);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
berr("ERROR: Failed to copy section at offset %"PRIdOFF"\n", offset);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
elf_dumpreaddata(buffer, nsize);
|
elf_dumpreaddata(buffer, nsize);
|
||||||
return OK;
|
|
||||||
|
errout:
|
||||||
|
#ifdef CONFIG_ARCH_USE_COPY_SECTION
|
||||||
|
/* Free the temporary memory */
|
||||||
|
|
||||||
|
kmm_free(buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -772,6 +772,21 @@ void up_textheap_free(FAR void *p);
|
||||||
bool up_textheap_heapmember(FAR void *p);
|
bool up_textheap_heapmember(FAR void *p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_copy_section
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Copy section from general temporary buffer(src) to special addr(dest).
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_USE_COPY_SECTION)
|
||||||
|
int up_copy_section(FAR void *dest, FAR const void *src, size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_setpicbase and up_getpicbase
|
* Name: up_setpicbase and up_getpicbase
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue